Skip to content

Discord Logging

Discord Logging

BUPA Chat has two independent Discord features. This page covers outgoing webhook logging (chat → Discord). The incoming channel bridge (Discord → chat), configured in shared/config/discord.lua, is a separate feature described at the end.

Webhook logging (chat → Discord)

Webhook URLs live in server/webhook.lua — an escrow_ignore file you edit directly. Three keys are defined:

server/webhook.lua
local webhooks = {
    chatMessage  = "https://.../webhook-proxy/....",
    emoteCommand = "https://.../webhook-proxy/....",
    pmMessage    = "https://.../webhook-proxy/....",
}

Replace the placeholder proxy URLs with your own Discord webhook URLs. If a key's URL is empty, nothing is sent for it.

How messages map to webhooks

Config entries reference a webhook by its key via webhookKey:

  • Categories — each category may set webhookKey (see Chat Categories).
  • Private messagesconfig.pm.webhookKey (defaults to chatMessage).
  • Emotes — each emote command may set webhookKey (/me and /do use emoteCommand).

Every normal chat message is always logged to the chatMessage webhook. When a category also defines its own webhookKey, that category's messages are logged to both the category webhook and the chatMessage webhook.

Logging is handled by sendDiscordLog(webhookKey, message, src), which posts a standalone JSON payload to the mapped URL — no external Discord resource is required:

server/webhook.lua
function sendDiscordLog(webhook, msg, src)
    local url = webhooks[webhook]
    if not url or url == "" then return end
    local payload = type(msg) == "table" and { embeds = { msg } } or { content = tostring(msg) }
    PerformHttpRequest(url, function() end, "POST", json.encode(payload),
        { ["Content-Type"] = "application/json" })
end

To add a new log target, add a key to the webhooks table and reference it from a category, PM or emote via webhookKey.

Channel bridge (Discord → chat)

Separately, shared/config/discord.lua (config.discord) can poll Discord channels and relay their messages into the game chat. It is disabled by default.

shared/config/discord.lua
config.discord = {
    active = false,
    pollInterval = 15000,   -- ms between polls
    channels = {
        {
            channelId = "",   -- Discord channel to read from
            -- permissions = { "admin" },   -- optional: who can see these messages
            -- jobs  = { police = true },
            -- gangs = { whiteGang = true },
            tags = { { tag = "Discord", textColor = { 51, 51, 51 }, bgColor = { 88, 101, 242 } } },
            color = { 200, 200, 200 },
        },
        -- more channels: Discord Admin / PD / EMS / Gang examples included
    },
}

Each channel entry can be gated by permissions, jobs or gangs, so a channel's messages only appear for the right players. The bridge reads messages through the Discord bot API and requires a bot token + guild ID — supplied either in config.discord or reused from config.adminChatName.discord in general.lua. Messages authored by bots are ignored.