Setup Steps
Follow the Discord setup guide in the production docs. Required configuration:DISCORD_BOT_TOKEN(Bot token from the Developer Portal)DISCORD_PUBLIC_KEY(Application public key for signature verification)DISCORD_APPLICATION_ID(Application ID for webhook API calls)- A registered
/askslash command - An ngrok tunnel (for local development) with the Interactions Endpoint URL pointing to
/discord/interactions
Example Usage
Create an agent, expose it with theDiscord interface, and serve via AgentOS:
basic.py
Core Components
Discord(interface): Wraps an AgnoAgent,Team, orWorkflowfor Discord integration via FastAPI.AgentOS.serve: Serves the FastAPI app using Uvicorn.
Discord Interface
Main entry point for Agno Discord applications.
Initialization Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
agent | Optional[Agent] | None | Agno Agent instance. |
team | Optional[Team] | None | Agno Team instance. |
workflow | Optional[Workflow] | None | Agno Workflow instance. |
prefix | str | "/discord" | Custom FastAPI route prefix. |
tags | Optional[List[str]] | None | FastAPI route tags. Defaults to ["Discord"]. |
stream | bool | False | Enable streaming responses that progressively update the message. Only works for Agent and Team. |
show_reasoning | bool | True | Show reasoning content (wrapped in italics) before the final answer. |
max_message_chars | int | 1900 | Maximum characters per message. Discord’s limit is 2000; 1900 leaves room for the [1/N] prefix on multi-part messages. |
allowed_guild_ids | Optional[List[str]] | None | Restrict the bot to specific guild (server) IDs. |
allowed_channel_ids | Optional[List[str]] | None | Restrict the bot to specific channel IDs. |
discord_bot_token | Optional[str] | None | Bot token. Falls back to DISCORD_BOT_TOKEN env var. |
reply_in_thread | bool | True | Create a new thread for each @mention conversation in guild channels. |
agent, team, or workflow.
Key Method
| Method | Return Type | Description |
|---|---|---|
get_router | APIRouter | Returns the FastAPI router with Discord endpoints attached. |
get_lifespan | Optional[Any] | Returns a FastAPI lifespan that manages the Gateway WebSocket and HTTP session cleanup. |
Transports
HTTP Webhook (Slash Commands)
Always available. Handles the/ask slash command via Discord’s Interactions API.
Flow:
- User runs
/ask message:Hello - Discord sends a signed POST to
/discord/interactions - Bot verifies the Ed25519 signature and responds with a deferred message
- Background task processes the request and edits the response
POST /discord/interactions
- Handles PING verification and APPLICATION_COMMAND interactions
- Verifies Ed25519 signatures using
DISCORD_PUBLIC_KEY - Includes replay protection (rejects requests older than 5 minutes)
Gateway WebSocket (@Mentions and DMs)
Auto-activates whendiscord.py is installed and a bot token is available. Falls back to HTTP-only otherwise.
Flow:
- User @mentions the bot or sends a DM
- Bot receives the message via WebSocket
- Bot creates a thread (if
reply_in_thread=True) and processes the message - Response is sent to the thread/channel
- Typing indicator shown while processing
- Auto-thread creation for guild @mentions
- Replies in-place for existing threads and DMs
Streaming Mode
Whenstream=True, the bot progressively updates the response message as content is generated:
- Sends an initial message with the first content chunk
- Edits the message every ~1 second as more content arrives
- Final edit with the complete response when generation finishes
- Overflow content (beyond 2000 chars) is sent as follow-up messages
Session ID Scheme
Session IDs use adc: prefix to namespace Discord sessions:
| Format | Context |
|---|---|
dc:dm:{channel_id} | Direct messages |
dc:thread:{channel_id} | Thread channels (including auto-created threads) |
dc:channel:{channel_id}:user:{user_id} | Guild channels (scoped per user) |
Media Support
Inbound (User to Bot)
The bot accepts attachments on the/ask slash command and on @mention messages. Files are classified by content type:
| Content Type | Agno Media Type |
|---|---|
image/* | Image |
video/* | Video |
audio/* | Audio |
| Everything else | File |
Outbound (Bot to User)
Tool-generated media (e.g., DALL-E images, ElevenLabs audio) is sent as Discord file attachments.Testing the Integration
- Start the server:
python my_bot.py - Start ngrok:
ngrok http 7777 - Set the Interactions Endpoint URL in the Developer Portal
- Test slash commands:
/ask message:Hello - Test @mentions:
@YourBot What is quantum computing? - Test DMs: Send a direct message to the bot
Troubleshooting
- 403 Invalid signature — Verify
DISCORD_PUBLIC_KEYis set correctly - Bot not responding to @mentions — Ensure the Gateway is connected (check logs for “Discord Gateway connected as …”)
- Slash command not appearing — Register commands via the API (see setup guide) and wait a few minutes for propagation
- Thread creation fails — Bot needs
Manage Threadspermission in the channel - “This interaction failed” — Check that your server is reachable via ngrok and the Interactions Endpoint URL is correct