arizuko › components › discd
discd is the Discord channel adapter. It opens a Discord gateway websocket (via discordgo), posts inbound messages and reactions to gated, and sends outbound via the Discord REST API. JID prefix is discord:; messages are keyed by discord:<channel_id> for direct/guild chats and discord:<guild>/<channel> for the routing layer.
Discord is the canonical community channel for arizuko deployments — guild channels for team chat, threads for tasks, DMs for one-on-one. Talking to the Discord gateway directly is what lets discd surface reactions as like / dislike events and keep the websocket alive across rolling restarts.
Discord (gateway.discord.gg)
| websocket: MESSAGE_CREATE, MESSAGE_REACTION_ADD, ...
v
discd (LISTEN_ADDR=:8080)
| POST /v1/messages (signed by CHANNEL_SECRET)
v
gated
| POST /v1/send (callback to discd)
v
discd (REST: channels/.../messages, reactions, ...)
|
v
Discord
Wired verbs (discd/bot.go, discd/server.go): send (chunked at 2000 chars, honours reply_to via message_reference), send_file (multipart), typing, edit, delete, like (default 👍), quote. dislike, forward, post, repost are 501-with-hint — the agent gets pointers like like(emoji='👎') rather than a generic capability error.
Inbound: messages where the bot is in m.Mentions or is the parent author of a reply ride verb=mention; everything else in guilds is verb=message (v0.39.1 made reply-to-bot and reactions count as mentions). Reactions MessageReactionAdd emit synthetic like/dislike inbound rows classified by chanlib.ClassifyEmoji.
Attachments use direct Discord CDN URLs cached via the shared chanlib.URLCache.
discd is a plain Go binary. It needs a reachable gated and a Discord bot or user token.
export ROUTER_URL=http://gated:8080
export CHANNEL_SECRET=$(grep ^CHANNEL_SECRET .env | cut -d= -f2)
export LISTEN_ADDR=:8080
export DISCORD_BOT_TOKEN=...
export ASSISTANT_NAME=arizuko
./discd
Discord-side setup: create an application at discord.com/developers, add a bot, copy the token. Required gateway intents: GUILDS, GUILD_MESSAGES, GUILD_MESSAGE_REACTIONS, MESSAGE_CONTENT, DIRECT_MESSAGES. Invite the bot with the OAuth URL.
User mode (DISCORD_USER_TOKEN instead of bot token) authenticates as a Discord user account — useful where a bot account is not allowed. It skips gateway intents, which user tokens cannot request.
GET /health returns 503 when the websocket is disconnected; discordgo reconnects automatically, so a persistent 503 means token revoked or Discord-side outage.
discd/README.md — verb table, file map.