Discord Channel
The Discord channel enables ZeroClaw to communicate via Discord’s Gateway WebSocket API with support for guilds, direct messages, attachments, and interactive components.Overview
- Channel Name:
discord - Transport: Gateway WebSocket (real-time)
- Authentication: Bot token
- Public Port Required: No
- Supports: Text, images, documents, attachments, message components
Configuration
Required Settings
Complete Configuration
Environment Variables
Authentication
Getting a Bot Token
- Go to Discord Developer Portal
- Click “New Application” and name your bot
- Navigate to the “Bot” tab
- Click “Add Bot” and confirm
- Copy the bot token
- Under “Privileged Gateway Intents”, enable:
- Message Content Intent
- Server Members Intent (optional)
- Presence Intent (optional)
Adding Bot to Server
- In Developer Portal, go to “OAuth2” → “URL Generator”
- Select scopes:
bot,applications.commands - Select bot permissions:
- Read Messages/View Channels
- Send Messages
- Read Message History
- Add Reactions
- Attach Files
- Embed Links
- Copy generated URL and open in browser
- Select server and authorize
User Authorization
Discord uses numeric user IDs (snowflakes):- Enable Developer Mode in Discord (Settings → Advanced)
- Right-click your username
- Click “Copy ID”
Features
Message Splitting
Discord has a 2000 character limit. ZeroClaw automatically:- Splits long messages at word boundaries
- Prefers splitting at newlines (if found in last 50% of chunk)
- Falls back to space boundaries
- Hard splits at 2000 chars if no good break point
Gateway Connection
The channel uses Discord’s Gateway v10:- Intents:
GUILDS | GUILD_MESSAGES | MESSAGE_CONTENT | DIRECT_MESSAGES(37377) - Heartbeat: Automatic based on server interval
- Reconnection: Automatic on disconnect
- Resume: Supported via sequence tracking
Guild Filtering
Restrict bot to one guild:- Guild messages: Only process if
guild_idmatches - DMs: Always processed (no
guild_idpresent) - Multi-guild: Omit
guild_idto listen everywhere
Bot Message Filtering
By default, ignores messages from other bots:true to process bot messages (use with caution - can cause loops).
Group Chat Control
Mention-Only Mode
- Explicitly mentioned:
@YourBot hello - In DMs
- Sender is in
allowed_sender_ids
<@BOT_USER_ID>(standard)<@!BOT_USER_ID>(nickname)
VIP Senders
Attachment Support
Incoming Attachments
Images: Detected by MIME type and file extension- MIME:
image/* - Extensions:
.png,.jpg,.jpeg,.gif,.webp,.bmp,.tif,.tiff,.svg,.avif,.heic,.heif - Converted to
[IMAGE:url]markers
text/*
- Downloaded and inlined:
[filename]\ncontent
Outgoing Attachments
Send attachments using markers:[IMAGE:path]or[PHOTO:path][DOCUMENT:path]or[FILE:path][VIDEO:path][AUDIO:path][VOICE:path]
- Workspace-relative:
file.txt→/workspace/file.txt - Absolute:
/workspace/subdir/file.txt /workspace/prefix:/workspace/data/image.png
- All paths validated against workspace root
- Directory traversal blocked
- Symlinks validated
- Max 10 files per message (Discord limit)
Reactions
Add/remove emoji reactions:- Unicode:
👍,❤️,🔥 - Custom guild emojis:
name:idformat
- ⚡️, 🦀, 🙌, 💪, 👌, 👀, 👣 (random)
Typing Indicator
The bot can show typing status:Tool Approval Components
Interactive approval prompts with buttons:- Style 3 (green) for Approve
- Style 4 (red) for Deny
- Custom IDs:
zcapr:yes:<request_id>,zcapr:no:<request_id>
/approve-allow <request_id>/approve-deny <request_id>
Implementation Details
Source Location
src/channels/discord.rs (1265+ lines)
Key Components
DiscordChannel Struct
Gateway Events Handled
| Opcode | Event | Action |
|---|---|---|
| 0 | Dispatch | Process events |
| 1 | Heartbeat Request | Send heartbeat |
| 7 | Reconnect | Close and reconnect |
| 9 | Invalid Session | Close and restart |
| 10 | Hello | Send Identify |
| 11 | Heartbeat ACK | (Tracked internally) |
Dispatch Events
MESSAGE_CREATE: New message receivedINTERACTION_CREATE: Button click (type 3 = MessageComponent)
Message Processing Flow
- Connect to Gateway WebSocket
- Receive Hello (op 10) with heartbeat interval
- Send Identify (op 2) with intents
- Track sequence number for all dispatches
- Process MESSAGE_CREATE events:
- Skip bot’s own messages
- Skip other bots (unless
listen_to_bots = true) - Check allowlist
- Check guild filter
- Check mention requirements
- Download attachments
- Convert to
ChannelMessage - Send to agent
- Process INTERACTION_CREATE for approval buttons
- Send heartbeat every N seconds (op 1)
Bot User ID Extraction
The bot’s own user ID is extracted from the bot token:- Ignore its own messages
- Detect mentions (
<@user_id>,<@!user_id>)
Reconnection Strategy
Normal Close: Gateway sends op 7 (Reconnect) or op 9 (Invalid Session)- Log warning
- Break listen loop
- Supervisor restarts channel
- Fresh connection established
- Propagate error
- Supervisor restarts with backoff
Error Handling
Common Errors
Invalid Token (401):- Standard: 8 MB
- Nitro Classic: 50 MB
- Nitro: 100 MB
Error Sanitization
All Discord API errors pass through:- Authorization headers
- Bot tokens
- Internal API details
Runtime Commands
Available in Discord chat:/new- Start new conversation/model- Show/switch current model/models- Show/switch provider/approve-allow <id>- Approve tool execution/approve-deny <id>- Deny tool execution
Best Practices
- Enable Message Content Intent: Required for reading message text
- Use User IDs: More stable than usernames
- Guild Filtering: Restrict to specific servers if needed
- Mention Mode: Use in public servers to avoid spam
- Allowlist: Start with specific users, not
* - Workspace Setup: Configure for attachment support
Troubleshooting
Bot Doesn’t Respond
Check Allowlist:Discord: connected and identifiedDiscord: ignoring message from unauthorized user:Discord: received Invalid Session (op 9)
- View Channel
- Send Messages
- Read Message History
Guild Messages Not Working
Bot Not in Guild:- Re-invite bot with OAuth2 URL
- Check bot shows in member list
Attachments Not Working
Workspace Not Set: Configure workspace directory:/workspace/ or are relative
Missing Permissions:
Grant bot “Attach Files” and “Embed Links” permissions
Performance
Message Throughput
- Gateway: Real-time via WebSocket
- Latency: Typically <100ms from send to receive
- Concurrent: One message at a time per channel
Optimization Tips
- Guild Filtering: Reduce event volume with
guild_id - Bot Filtering: Keep
listen_to_bots = false - Attachment Download: Lazy - only when needed
- Typing Indicator: Use sparingly (API rate limited)
Security
Token Protection
- Tokens never logged
- Redacted from error messages
- Store in config file (protect with permissions)
User Verification
- Allowlist checked before processing
- Bot self-messages always ignored
- Guild filter enforced
Workspace Sandboxing
- All paths validated against workspace root
- Directory traversal blocked (
../) - Symlink targets validated
- Non-workspace paths rejected