This package is now maintained in the wopr-plugins monorepo.
This repository is archived and no longer accepts contributions.
Discord bot integration for WOPR - enables AI conversations in Discord channels with full context awareness.
Part of the WOPR ecosystem - Self-sovereign AI session management over P2P.
- Slash Commands - 13 native Discord slash commands for full control
- Model Switching - Switch between Haiku, Sonnet, and Opus models
- @mention Responses - Bot responds when mentioned
- Reaction Feedback - Custom emoji reactions (configurable per agent identity)
- Full Conversation Context - Captures all channel messages for context
- Session Management - Per-channel sessions with reset/compact commands
- Owner Pairing - Secure pairing code system for bot ownership
- Friend Request Buttons - Interactive Accept/Deny buttons for P2P friend requests
- Attachment Handling - Automatic download and processing of file attachments
- Bot-to-Bot Flow Control - Smart message queue with human priority
- Channel Provider API - Extensibility for other plugins to register commands
- TypeScript - Written in TypeScript with full type support
wopr plugin install github:TSavo/wopr-plugin-discord
wopr plugin enable wopr-plugin-discord# Bot token (from Discord Developer Portal -> Bot)
wopr config set plugins.data.wopr-plugin-discord.token "YOUR_BOT_TOKEN"
# Application ID (from Discord Developer Portal -> General Information)
wopr config set plugins.data.wopr-plugin-discord.clientId "YOUR_APPLICATION_ID"# Restrict to specific guild (faster command registration during development)
wopr config set plugins.data.wopr-plugin-discord.guildId "YOUR_GUILD_ID"
# Owner User ID (receives friend request notifications)
wopr config set plugins.data.wopr-plugin-discord.ownerUserId "YOUR_USER_ID"# Old style config (still supported)
wopr config set discord.token YOUR_BOT_TOKEN
wopr config set discord.clientId YOUR_CLIENT_ID
wopr config set discord.guildId YOUR_GUILD_ID- Go to Discord Developer Portal
- Create a new application
- Go to "Bot" section
- Enable MESSAGE CONTENT INTENT
- Enable SERVER MEMBERS INTENT
- Copy the bot token
- Note the Application ID (for slash commands)
- Add the bot to your server via OAuth2 URL Generator:
- Select
botscope - Select
applications.commandsscope - Required permissions: Send Messages, Read Message History, Add Reactions
- Select
| Command | Description | Options |
|---|---|---|
/wopr <message> |
Send a message to WOPR | message (required) |
/status |
Show session status and configuration | - |
/new |
Start a new session (reset conversation) | - |
/reset |
Alias for /new | - |
/compact |
Compact session context (summarize) | - |
/think <level> |
Set thinking level | off/minimal/low/medium/high/xhigh |
/verbose <enabled> |
Toggle verbose mode | true/false |
/usage <mode> |
Set usage tracking display | off/tokens/full |
/model <model> |
Switch AI model | haiku/sonnet/opus |
/session <name> |
Switch to a named session | name (required) |
/cancel |
Cancel the current AI response | - |
/claim <code> |
Claim bot ownership (DM only) | code (required) |
/help |
Show available commands | - |
/wopr Explain quantum computing
/think high
/model opus
/wopr Solve this complex problem
/status
/cancel
/reset
Mention the bot directly in any channel:
@WOPR Hello! What's your name?
The bot will:
- Add reaction emoji (configurable per agent identity)
- Send message to WOPR session with conversation context
- Stream the AI response in real-time
- Remove processing reaction on completion
The plugin captures all messages in the channel (not just @mentions) and includes them as context. This enables natural conversation:
User: My name is Alice
User: I work at Acme Corp
User: @WOPR What do you know about me?
Bot: You're Alice and you work at Acme Corp!
The bot maintains a buffer of recent messages (up to 20) for context building.
Sessions are automatically named based on the channel:
| Channel Type | Session Key Format |
|---|---|
| Guild channel | discord:guild-name:#channel-name |
| Thread | discord:guild-name:#parent-channel/thread-name |
| DM | discord:dm:username |
Examples:
discord:my-server:#generaldiscord:my-server:#dev/feature-discussiondiscord:dm:alice
When the bot has no owner configured, DMing the bot generates a pairing code:
- DM the bot (any message)
- Receive a pairing code:
Your pairing code is: ABCD1234 - Claim ownership:
wopr discord claim ABCD1234 - Or use the slash command in DM:
/claim ABCD1234
The owner receives:
- Friend request notifications with Accept/Deny buttons
- Private DM notifications for important events
The plugin automatically handles Discord attachments:
- Attachments are downloaded to
/data/attachments/(or./attachments/) - File paths are appended to the message
- WOPR can then process images and files
File naming: timestamp-userId-originalname
The plugin includes intelligent bot-to-bot flow control:
- Human Priority: Human messages take immediate priority
- Cooldown: 5 second cooldown between bot responses
- Typing Detection: Pauses when humans are typing (15s window)
- Context Buffer: Accumulates conversation context between responses
The plugin exposes a Channel Provider interface for other plugins:
// Other plugins can register commands
discordProvider.registerCommand({
name: "mycommand",
description: "My custom command",
handler: async (ctx) => {
await ctx.reply("Hello from my plugin!");
}
});
// Or register message parsers
discordProvider.addMessageParser({
id: "my-parser",
pattern: /PATTERN:.+/,
handler: async (ctx) => {
// Process matching messages
}
});Bot doesn't respond:
- Check daemon is running:
wopr daemon status - Check logs:
wopr daemon logs | grep -i discord - Verify token:
wopr config get plugins.data.wopr-plugin-discord
Slash commands not appearing:
- Verify
clientIdis set correctly - Wait up to 1 hour for global propagation, or set
guildIdfor instant registration - Check that bot was invited with
applications.commandsscope
Bot responds to @everyone:
- Should not happen in current version - the bot checks
message.mentions.users.has(botId)
Session key format:
- Sessions use format
discord:guildname:#channelname, not channel IDs - Check with:
wopr session list | grep discord
Attachments not processing:
- Check
/data/attachments/directory exists and is writable - Check daemon logs for download errors
- docs/COMMANDS.md - Detailed command reference
- docs/CONFIGURATION.md - Configuration options
- docs/TROUBLESHOOTING.md - Common issues
MIT