Discord Webhooks
On this page10
Seven channels. Every one of them is optional, and all of them are off until you give them a URL.
The channels
ServerConfig.Webhooks = {
Default = '',
Proofs = '',
Deaths = '',
Admin = '',
Exports = '',
Errors = '',
Anomalies = '',
}| Channel | Convar | What lands there |
|---|---|---|
Default | recognition_webhook_default | Anything without its own channel. |
Proofs | recognition_webhook_proofs | Aim, damage, kill, cuff, rob and search snapshots. |
Deaths | recognition_webhook_deaths | New Life Rule resets, and admin restores of them. |
Admin | recognition_webhook_admin | Admin edits, deletes, identity resets, settings changes. |
Exports | recognition_webhook_exports | One-click "Export to Discord" from the admin panel. |
Errors | recognition_webhook_errors | Script errors — refund failures and the like. |
Anomalies | recognition_webhook_anomalies | Possible cheating or abuse, for staff to review. |
Set them from server.cfg instead, which is the better habit:
set recognition_webhook_default "https://discord.com/api/webhooks/..."
set recognition_webhook_proofs "https://discord.com/api/webhooks/..."
set recognition_webhook_deaths "https://discord.com/api/webhooks/..."
set recognition_webhook_admin "https://discord.com/api/webhooks/..."
set recognition_webhook_exports "https://discord.com/api/webhooks/..."
set recognition_webhook_errors "https://discord.com/api/webhooks/..."
set recognition_webhook_anomalies "https://discord.com/api/webhooks/..."The convar always wins over the value in the file. An empty or unset convar leaves the file value alone.
A channel that is off
A URL that does not start with https:// is treated as not configured. Discord
logging is optional, so a channel you simply left empty gets no line of its own.
At boot you see one line in total:
[5code-recognition] Discord log webhooks: none configured (optional).or, when some channels have a URL, the list of the ones that post:
[5code-recognition] Discord log webhooks on: admin, proofs.or, when default has a URL (every channel without a URL of its own then posts
to it, the usual one-webhook setup):
[5code-recognition] Discord log webhooks on: all 7 channels.A channel whose value was set but typed wrongly gets a warning of its own, naming
the reason — it is an http:// URL, it does not start with https://, it is not a URL, the value is not text — so a typo never hides behind "I did not use that
channel":
[5code-recognition] Webhook 'proofs' was ignored (it is an http:// URL), so it is off. Set an https:// URL in config_server.lua or its convar.When default has a URL, the end of that line says so it posts to the default webhook instead. The lines are printed once per start, not again when settings are
reloaded.
What a message contains
ServerConfig.Discord = {
Name = '5code-recognition',
Avatar = '',
IncludeServerIds = true,
IncludeNames = true,
IncludeCharKeys = true,
IncludeLicenses = false,
AttachFullData = true,
MaxFileBytes = 1048576,
ExportCooldownSeconds = 10,
ExportsPerHour = 30,
ThreadIds = {},
SuppressNotifications = false,
}| Key | Default | Allowed | What it does |
|---|---|---|---|
Name | '5code-recognition' | text | Webhook user name. |
Avatar | '' | URL | Webhook avatar. '' = Discord default. |
IncludeServerIds | true | true / false | Include server ids. |
IncludeNames | true | true / false | Include character names. |
IncludeCharKeys | true | true / false | Include character keys (citizenid and equivalents). |
IncludeLicenses | false | true / false | Include license identifiers. |
AttachFullData | true | true / false | Attach a file with the full data to exports. |
MaxFileBytes | 1048576 (1 MB) | bytes | Largest attached file. |
ExportCooldownSeconds | 10 | seconds | Per admin, between exports. |
ExportsPerHour | 30 | count | Per admin. |
ThreadIds | {} | { Exports = '123…' } | Post into a thread or forum post instead of the channel. |
SuppressNotifications | false | true / false | Send messages silently. |
Presentation
Chart style and attachment format live in config.lua, because they are about how
the export looks, not what it contains.
| Key | Default | Allowed | What it does |
|---|---|---|---|
Config.Discord.Chart | 'sparkline' | 'sparkline' · 'none' | The trend line in an export. sparkline = text bars, which always work and need nothing. none = no trend line. (The other values listed in config.lua send the same text sparkline in this version.) |
Config.Discord.AttachFormat | 'both' | 'json' · 'csv' · 'both' | Format of the attached full-data file. |
The sending queue
Discord rate-limits webhooks hard. The queue keeps us inside their limits and backs off when we hit one anyway.
| Key | Default | What it does |
|---|---|---|
Queue.MinGapMs | 400 | Minimum gap between two messages on the same URL. |
Queue.BurstPer2s | 5 | Messages allowed in any two seconds. |
Queue.PerMinute | 30 | Messages per minute. |
Queue.Backoff429After | 3 | Repeated 429s before a hard back-off. |
Queue.Backoff429Seconds | 60 | How long that back-off lasts. |
Queue.MaxQueue | 200 | Queue depth per URL. |
Queue.MaxRetries | 5 | Retries per message. |
Queue.TimeoutMs | 15000 | Request timeout. |
The proof log check value
| Key | Default | What it does |
|---|---|---|
AnchorEveryRows | 100 | Post a check value of the proof log to the Proofs webhook every N proofs, and at shutdown. |
That message is an outside copy nobody on the server can edit, so you can compare the proof log with it later. Check the log in game or in the console with:
recognition:verifyproofs [fromId]Filtering proofs
A busy server produces a lot of on-duty police cuffs that nobody will read. Two keys thin them out without touching what is stored:
| Key | Default | What it does |
|---|---|---|
Config.Proof.DiscordCauses | all true | Per-cause switch: aim, damage, kill, cuff, uncuff, rob, search, escort, kidnap, custom. |
Config.Proof.DiscordOnlyBelow | false | true = only proofs below the act line go to Discord. |
Config.Proof.DiscordSkipOnDutyJobs | {} | e.g. { 'police' } — on-duty actions of those jobs skip Discord. |
Config.Proof.DiscordBatchSeconds | 5 | Batching window. |
Everything is still written to recognition_proofs either way. See
Proofs.
Admin actions
| Key | Default | What it does |
|---|---|---|
Config.Admin.DiscordActions | true | true = every logged admin action goes to the Admin webhook. false = none. A list = only those actions, e.g. { 'settings_save', 'settings_reset', 'identity_reset' }. |
Photos
Photos have their own optional webhook, used only when
ServerConfig.PhotoHost = 'discord':
ServerConfig.PhotoDiscord = {
Webhook = '', -- convar: recognition_photo_webhook
}See Photos & Screenshots.
Checklist
- URLs are in
config_server.luaor insetconvars — notconfig.lua, notsetr. IncludeLicensesisfalseunless you have a written reason.- The channels are private to staff.
ErrorsandAnomaliespoint somewhere a human actually reads.- The
Proofschannel is filtered, or it will be unreadable by week two.