arizuko

arizuko › components › discd

discd

discd holds a gateway connection to Discord, turns messages and reactions into events for routd, and sends the replies of the agent.

discd connects Discord to arizuko

discd connects Discord to arizuko, so the agent can read and reply in Discord channels and DMs.

discd is the Discord channel adapter. It opens a Discord gateway websocket with discordgo, posts inbound messages and reactions to routd, and sends outbound messages with the Discord REST API. The JID prefix is discord:. A guild channel has the JID discord:<guild>/<channel>, and a DM has discord:dm/<channel>.

A direct gateway connection turns reactions into events

Discord is the main community channel of arizuko deployments: guild channels for team chat, threads for tasks and DMs for one-to-one talk. A direct connection to the Discord gateway lets discd report reactions as like and dislike events and keep the websocket alive across restarts.

discd sits between Discord and routd

Discord (gateway.discord.gg)
        │  websocket: MESSAGE_CREATE, MESSAGE_REACTION_ADD, ...
        ▼
      discd     (LISTEN_ADDR=:8080)
        │  POST /v1/messages    (service:<daemon> ES256 bearer)
        ▼
      routd
        │  POST /send           (callback to discd)
        ▼
      discd     (REST: channels/.../messages, reactions, ...)
        │
        ▼
      Discord

The wired verbs are in discd/bot.go and discd/server.go:

send
Split at 2000 characters, with reply_to as a message_reference.
send_file
A multipart upload.
like
A reaction, 👍 by default.
typing, edit, delete, quote
Plain REST calls.

dislike, forward, post and repost return 501 with a hint. The agent gets a pointer such as like(emoji='👎'), not a general capability error.

A message that lists the bot in m.Mentions, or that replies to a message of the bot, gets verb=mention. Every other guild message gets verb=message. A reaction from MessageReactionAdd becomes a synthetic like or dislike inbound row, classified by chanlib.ClassifyEmoji.

Attachments use direct Discord CDN URLs, cached in the shared chanlib.URLCache.

Discord guild chats start reply threads by default. Change a chat's setting from the group dashboard or with arizuko chat thread-replies <jid> on|off|default. Replies and progress inside an existing thread stay there. A deliberate send can address the parent channel.

discd runs alone with routd and a token

discd is a plain Go binary. It needs a reachable routd and a Discord bot token or user token.

export ROUTER_URL=http://routd:8080
export AUTHD_URL=http://authd:8080
export AUTHD_SERVICE_KEY=$(grep ^AUTHD_SERVICE_KEY .env | cut -d= -f2)
export LISTEN_ADDR=:8080
export DISCORD_BOT_TOKEN=<bot token>
export ASSISTANT_NAME=arizuko
./discd

On the Discord side, create an application at discord.com/developers, add a bot and copy the token. The bot needs the gateway intents GUILDS, GUILD_MESSAGES, GUILD_MESSAGE_REACTIONS, MESSAGE_CONTENT and DIRECT_MESSAGES. Invite the bot with the OAuth URL.

User mode, with DISCORD_USER_TOKEN instead of a bot token, signs in as a Discord user account. Use it where a bot account is not allowed. User mode skips the gateway intents, which a user token cannot request.

GET /health returns 503 when the websocket is down. discordgo reconnects automatically, so a 503 that stays means a revoked token or an outage at Discord.

Two sources cover the details