Log webhook Discord da un server FiveM: guida PerformHttpRequest
Invia log a Discord da FiveM con PerformHttpRequest e JSON embed. Solo lato server, URL in una convar, una coda per i limiti di frequenza, e cosa registrare.
Vuoi sapere chi ha comprato cosa, chi ha dato soldi, chi ha eseguito un comando admin e chi è entrato, senza guardare la console tutto il giorno. Un webhook Discord lo fa: il tuo server pubblica un messaggio in un canale. Questa guida mostra il Lua lato server con PerformHttpRequest, come costruire embed, come mantenere l'URL al sicuro e come evitare il limite di frequenza.
Crea il webhook
Su Discord, apri le impostazioni del canale, poi Integrazioni, poi Webhook, creane uno e copia il suo URL. Somiglia a https://discord.com/api/webhooks/<id>/<token>. Chiunque abbia quell'URL può postare nel tuo canale, quindi trattalo come una password.
Mantieni l'URL in una convar
Mettilo in server.cfg:
set discord_webhook_logs "https://discord.com/api/webhooks/ID/TOKEN"Usa set, non setr o sets. Una convar replicata viene inviata ad ogni client, il che farebbe perdere l'URL. Leggila sul server:
local WEBHOOK = GetConvar('discord_webhook_logs', '')Se la convar è vuota, salta l'invio invece di errare. Puoi mantenere una convar per tipo di log (soldi, admin, ingressi) per inviarli a canali diversi.
Invia un messaggio
local function sendLog(title, description, color, fields)
if WEBHOOK == '' then return end
local embed = {
title = title,
description = description,
color = color or 3447003,
fields = fields,
timestamp = os.date('!%Y-%m-%dT%H:%M:%SZ'),
}
PerformHttpRequest(WEBHOOK, function(status, body, headers)
if status ~= 204 and status ~= 200 then
print(('webhook failed: %s'):format(status))
end
end, 'POST', json.encode({ username = 'Server logs', embeds = { embed } }), {
['Content-Type'] = 'application/json',
})
endPunti da conoscere:
colorè un numero decimale, non una stringa hex.3447003è blu e15158332è rosso. Converti hex contonumber('FF0000', 16).timestampdeve essere una data ISO 8601 in UTC. Il!nel formato fa usare aos.datel'UTC.fieldsè una lista di{ name = '...', value = '...', inline = true }. Un valore del campo non può essere vuoto.- Una chiamata webhook di successo restituisce lo stato 204, con un corpo vuoto.
- Discord limita le dimensioni. I titoli sono brevi (256 caratteri), le descrizioni sono lunghe ma limitate (4096), e un messaggio contiene un numero limitato di campi ed embed. Taglia il testo lungo prima di inviarlo.
Un'esempio di chiamata, per un giocatore che ha inviato soldi:
sendLog('Money transfer', 'A player sent money', 3066993, {
{ name = 'From', value = ('%s (id %d)'):format(GetPlayerName(src), src), inline = true },
{ name = 'To', value = ('%s (id %d)'):format(GetPlayerName(target), target), inline = true },
{ name = 'Amount', value = ('$%d'):format(amount), inline = false },
})Solo lato server, mai dal client
Attenzione: non chiamare
PerformHttpRequestper un webhook in uno script client, e non inviare l'URL al client. I file client possono essere letti da ogni giocatore, quindi l'URL si perde e chiunque può inondare il tuo canale.
Se un evento nel client dovrebbe essere registrato, invia un evento al server, e lascia che il server decida cosa registrare dai dati di cui si fida. Un client che può attivare "registra questo testo" può anche attivare log falsi. Per la sicurezza generale degli eventi, leggi secure events in FiveM. Registra quello che il server ha fatto, non quello che il client dice di aver fatto.
Limiti di frequenza: usa una coda
Discord rifiuta le chiamate webhook che arrivano troppo velocemente, con una risposta 429. Un'ondata di log, come 50 giocatori che attivano lo stesso evento, può colpirla. Invia i messaggi da una coda a un ritmo costante:
local queue = {}
local function enqueue(payload)
queue[#queue + 1] = payload
end
CreateThread(function()
while true do
local item = table.remove(queue, 1)
if item then
PerformHttpRequest(WEBHOOK, function(status, _, headers)
if status == 429 then
-- put it back and wait a bit longer
table.insert(queue, 1, item)
Wait(5000)
end
end, 'POST', json.encode(item), { ['Content-Type'] = 'application/json' })
end
Wait(2000)
end
end)Aspettando due secondi tra i messaggi rimani sotto il limite. Se ne hai bisogno di più, raggruppa diversi embed in un messaggio: una richiesta può portare fino a 10 embed nella sua lista embeds. Per l'uso di Wait, vedi Wait explained.
Cosa registrare
Registra gli eventi che vorresti quando qualcosa va storto:
- Soldi: trasferimenti grandi, acquisti, qualsiasi cosa che crei soldi. Questo è dove l'abuso si mostra prima.
- Azioni admin: chi ha usato quale comando admin su chi, ban, avvertimenti, teleport. Vedi ban and warn players.
- Ingressi e uscite, con gli identificatori del giocatore, che aiuta con le dispute e i ban.
- Spawning di articoli e uso di armi, se lo consenti.
Non registrare tutto. Un canale con un messaggio ogni secondo è un canale che nessuno legge. Scegli pochi canali, metti i più importanti dove guarda lo staff, e mantieni il resto breve. Mantieni i dati personali a quelli di cui hai bisogno, e non registrare la chat privata.
Consiglio: metti la tua funzione di logging in una piccola risorsa e chiamala con un export dai tuoi altri script, così l'URL del webhook e la coda del limite di frequenza vivono in un unico posto. Vedi exports in FiveM.
Checklist
| Sintomo | Soluzione |
|---|---|
| Nulla arriva | Controlla il nome della convar, che l'URL sia completo e che la chiamata venga eseguita sul server |
| Status 400 | Il JSON non è valido: valore di campo vuoto, testo troppo lungo, o una stringa colore hex |
| Status 429 | Invia attraverso una coda con una pausa tra i messaggi |
| Timestamp ignorato | Usa UTC ISO 8601: os.date('!%Y-%m-%dT%H:%M:%SZ') |
| URL perso | Elimina il webhook in Discord, creane uno nuovo, e mantienilo in una convar set |
| Troppi messaggi | Registra solo soldi, azioni admin e ingressi |
Risposte rapide
Posso inviare un webhook Discord dal client?
No. Chiunque può leggere il codice client e rubare l'URL del webhook, quindi spammando il tuo canale. Attiva il log sul server e invialo da lì.
Quanti messaggi webhook posso inviare?
Discord applica limiti di frequenza ai webhook, e approssimativamente 30 messaggi al minuto per webhook è un limite di sicurezza. Oltre questo ottieni una risposta 429, quindi metti in coda i tuoi messaggi e invialli a un ritmo costante.
Dove dovrei tenere l'URL del webhook?
In una convar del server impostata con set in server.cfg, letta con GetConvar. Non metterla mai in un file client o in una convar impostata con setr o sets.
Script senza questo problema
Advanced BoostingBoosting di veicoli dal tablet: contratti dalla classe D alla S+, crew e coda in tempo reale.Vedi script →
Crypto MiningCompra un magazzino, costruisci rig pezzo per pezzo e mina monete su un mercato che si muove.Vedi script →
Shop CreatorCrea un negozio in meno di un minuto — proprietari, dipendenti, casseforti e rapine inclusi.Vedi script →