Skip to main content

Discord Plugin

Overview

The Discord Plugin integrates Discord with TokenRing agents, enabling natural conversations through Discord's messaging system. Each Discord user gets their own persistent agent instance that maintains conversation history and context. The plugin listens for messages, creates dedicated agents for authorized users, and routes AI responses back to Discord channels.

Key Features

  • Per-User Agents: Each Discord user gets a dedicated agent with persistent chat history
  • @Mentions: Respond to mentions in channels with intelligent AI responses
  • Direct Messages: Private conversations with the bot in your DMs
  • Authorization: Restricts access to a list of authorized user IDs
  • Event-Driven Communication: Handles agent events and sends responses back to Discord
  • Automatic Agent Management: Creates and manages agents for each user automatically
  • Plugin Architecture: Automatically integrates with TokenRing applications
  • State Preservation: Maintains agent state and conversation history across sessions
  • Timeout Handling: Configurable response timeouts with automatic agent cleanup
  • Message Formatting: System messages with proper formatting (info, warning, error levels)
  • Multiple Output Types: Supports chat messages, info messages, warnings, and error messages
  • Message Chunking: Automatically splits long messages to respect Discord's 2000 character limit

Integration with TokenRing Ecosystem

This plugin seamlessly integrates with TokenRing's agent system, allowing Discord users to interact with AI agents through Discord's messaging platform. The plugin creates a separate agent for each Discord user, maintaining individual conversation contexts.

Core Components

DiscordService

The primary service class responsible for managing Discord bot interactions.

  • Responsibilities: Handles incoming messages, manages per-user agents, processes events, and sends responses to Discord channels.
  • Configuration Schema: Validates and processes the Discord service configuration options.
  • Event Handling: Processes AgentEventState events including output.chat, output.info, output.warning, output.error, and input.handled.

DiscordServiceConfigSchema

Configuration schema for the Discord service, defined using Zod:

const DiscordServiceConfigSchema = z.object({
botToken: z.string().min(1, "Bot token is required"),
channelId: z.string().min(1, "Channel ID is required"),
authorizedUserIds: z.array(z.string().min(1), "Authorized user IDs are required"),
defaultAgentType: z.string().min(1, "Default agent type is required")
});

DiscordServiceConfig

Type definition for the configuration:

type DiscordServiceConfig = {
botToken: string;
channelId: string;
authorizedUserIds: string[];
defaultAgentType: string;
};

Services and APIs

DiscordService Class

The main service class that implements TokenRingService interface.

Constructor

constructor(app: TokenRingApp, config: DiscordServiceConfig)

Parameters:

  • app: TokenRingApp instance
  • config: DiscordServiceConfig object containing:
    • botToken: Discord bot token (required)
    • channelId: Channel ID for startup announcement message (required)
    • authorizedUserIds: List of authorized user IDs (required)
    • defaultAgentType: Default agent type to spawn for users (required)

Properties

PropertyTypeDescription
namestringService name, always "DiscordService"
descriptionstringService description
runningbooleanIndicates if the service is currently running
clientClient | nullDiscord.js client instance
userAgentsMap<string, Agent>Map of user IDs to their associated agents

Methods

MethodSignatureDescription
runrun(signal: AbortSignal): Promise<void>Starts the Discord bot and begins listening for messages. The service will automatically handle cleanup when the signal is aborted.
handleChatOutputhandleChatOutput(message: Message, content: string): Promise<void>Formats and sends chat messages to Discord, splitting long messages into chunks to respect Discord's character limits.
handleSystemOutputhandleSystemOutput(message: Message, messageText: string, level: string): Promise<void>Formats system messages (info, warning, error) with appropriate labels.
chunkTextchunkText(text: string, maxLength: number): string[]Splits text into chunks of specified maximum length.
getOrCreateAgentForUsergetOrCreateAgentForUser(userId: string): Promise<Agent>Gets or creates an agent for the specified user.

Plugin Interface

The plugin provides a TokenRingPlugin that:

export default {
name: packageJSON.name,
version: packageJSON.version,
description: packageJSON.description,
install(app, config) {
if (config.discord) {
app.addServices(new DiscordService(app, config.discord));
}
},
config: packageConfigSchema
} satisfies TokenRingPlugin<typeof packageConfigSchema>;

Commands and Tools

Chat Commands

The Discord plugin supports interaction via Discord messages:

  • Mentions in Channels: When mentioned in a channel (e.g., @BotName what is the weather today?), the bot processes the message and responds with agent-generated content.
  • Direct Messages: Users can send private messages to the bot for conversations without channel context.

Message Processing Flow

  1. Bot receives a message (via mention or DM)
  2. Message is cleaned by removing the bot mention
  3. Agent waits for idle state before processing
  4. Message is sent to the agent via handleInput
  5. Agent events are subscribed to for output handling
  6. Responses are sent back to Discord

Output Formats

  • Chat Messages: Normal messages sent as Discord replies.
  • System Messages: Formatted as [LEVEL]: message where LEVEL is INFO, WARNING, or ERROR.
  • Timeout Messages: Sent when agent exceeds maxRunTime configuration.

Event Types

The service handles the following AgentEventState events:

Event TypeFormatDescription
output.chatDirect responseRegular chat messages from the agent
output.info[INFO]: messageInformational messages
output.warning[WARNING]: messageWarning messages
output.error[ERROR]: messageError messages
input.handledN/AIndicates agent processing completion

Configuration

Plugin Configuration

The Discord service can be configured via the TokenRing app configuration or manually.

import TokenRingApp from "@tokenring-ai/app";

const app = new TokenRingApp({
plugins: ["@tokenring-ai/discord"]
});

app.config({
discord: {
botToken: process.env.DISCORD_BOT_TOKEN!,
channelId: process.env.DISCORD_CHANNEL_ID!,
authorizedUserIds: ['123456789012345678'],
defaultAgentType: 'teamLeader'
}
});

Manual Usage

import TokenRingApp from "@tokenring-ai/app";
import { DiscordService } from "@tokenring-ai/discord";

const app = new TokenRingApp();
const discordService = new DiscordService(app, {
botToken: process.env.DISCORD_BOT_TOKEN!,
channelId: process.env.DISCORD_CHANNEL_ID!,
authorizedUserIds: ['123456789012345678'],
defaultAgentType: 'teamLeader'
});

app.addServices(discordService);
await app.start();

Configuration Options

OptionTypeRequiredDefaultDescription
botTokenstringYes-Discord bot token from Discord Developer Portal
channelIdstringYes-Channel ID for startup announcement message
authorizedUserIdsstring[]Yes-List of user IDs authorized to interact with the bot
defaultAgentTypestringYes-Default agent type to spawn for users

Environment Variables

  • DISCORD_BOT_TOKEN (required): Discord bot token.
  • DISCORD_CHANNEL_ID (required): Channel ID for startup announcements.
  • DISCORD_AUTHORIZED_USERS (required): Comma-separated list of authorized user IDs.
  • DISCORD_DEFAULT_AGENT_TYPE (required): Default agent type (required).

Usage Examples

Basic Interaction

  • Mention in channel: @BotName what is the weather today?
  • Direct message: Send a message directly to the bot.

Environment Variables Setup

DISCORD_BOT_TOKEN=your-bot-token-here
DISCORD_CHANNEL_ID=123456789012345678
DISCORD_AUTHORIZED_USERS=123456789012345678,987654321098765432
DISCORD_DEFAULT_AGENT_TYPE=teamLeader

Complete App Configuration

import TokenRingApp from "@tokenring-ai/app";

const app = new TokenRingApp({
name: "My Discord Bot",
plugins: [
"@tokenring-ai/discord",
// other plugins...
]
});

app.config({
discord: {
botToken: process.env.DISCORD_BOT_TOKEN!,
channelId: process.env.DISCORD_CHANNEL_ID!,
authorizedUserIds: ['123456789012345678'],
defaultAgentType: 'teamLeader'
}
});

await app.start();

Integration

Agent System Integration

Each Discord user is assigned a dedicated agent instance that maintains conversation history. The plugin integrates with the TokenRing agent manager to create and manage these agents.

Agent Lifecycle

  1. Agent Creation: When a user messages the bot for the first time, a new agent is created via AgentManager.spawnAgent()
  2. Message Processing: Messages are sent to the agent via agent.handleInput()
  3. Event Subscription: The plugin subscribes to agent events to process responses
  4. Cleanup: When the service stops, all user agents are deleted via AgentManager.deleteAgent()

Event Handling

The Discord service processes agent events including:

  • output.chat: Sent as regular Discord messages
  • output.info, output.warning, output.error: Formatted as system messages with appropriate labels
  • input.handled: Indicates agent processing completion and triggers timeout check

Service Registration

The plugin registers itself with the TokenRing app via the plugin architecture, automatically adding the DiscordService to the application when configured.

Gateway Intents

The Discord client uses the following Gateway Intents:

  • GatewayIntentBits.Guilds: Server/guild operations
  • GatewayIntentBits.GuildMessages: Guild message events
  • GatewayIntentBits.MessageContent: Message content access
  • GatewayIntentBits.DirectMessages: Direct message events

Monitoring and Debugging

Common Issues

IssueSolution
Bot not respondingEnsure Message Content Intent is enabled in Discord Developer Portal
Authorization errorsAdd your user ID to the authorized list or remove restrictions
Bot offlineVerify bot token validity and invite status
Agent timeoutsAdjust maxRunTime in agent configuration
Long messagesAutomatically chunked, but may require manual splitting for very large responses

Debug Tips

  1. Verify Bot Token: Ensure the token is valid and has correct permissions
  2. Check Message Content Intent: Must be enabled in Discord Developer Portal
  3. Verify Server Invitation: Bot must be invited to the server with correct permissions
  4. Monitor Agent State: Check if agents are being created correctly
  5. Check Event Subscriptions: Verify events are being processed correctly

Logging

The service outputs logs via the agent's info/warning/error methods:

  • agent.infoMessage(): General information about agent actions
  • agent.warningMessage(): Warnings about agent configuration
  • agent.errorMessage(): Errors during agent processing

Development

Testing

To run tests for the Discord plugin:

bun install
bun test

Test Configuration

The plugin uses Vitest with the following configuration:

import {defineConfig} from "vitest/config";

export default defineConfig({
test: {
include: ["**/*.test.ts"],
environment: "node",
globals: true,
isolate: true,
},
});

Test Coverage

Tests include:

  • Configuration validation
  • Schema parsing
  • Edge cases handling
  • Type inference verification

Build

The plugin uses TypeScript and can be built with:

bun build

Package Structure

pkg/discord/
├── DiscordService.ts # Main service implementation
├── plugin.ts # Plugin interface
├── index.ts # Exports
├── package.json # Package metadata
├── vitest.config.ts # Test configuration
├── LICENSE # MIT license
└── README.md # Package documentation

Exports

export {default as DiscordService} from "./DiscordService.ts";
export type { DiscordServiceConfig } from "./DiscordService.ts";
export { DiscordServiceConfigSchema } from "./DiscordService.ts";

Best Practices

Authorization

  • Use authorizedUserIds to restrict access to specific users
  • This list is required - all users must be in the list to interact
  • Add user IDs as strings, not mentions

Agent Configuration

  • Set appropriate maxRunTime for your use case
  • Use defaultAgentType to specify which agent type to spawn
  • Consider agent capabilities when choosing agent types

Message Handling

  • Long messages are automatically chunked to 2000 characters
  • System messages use special formatting for easy identification
  • Consider the context window size when designing prompts

Performance

  • Each user gets their own agent instance
  • Agents persist until the service stops
  • Consider memory usage with many concurrent users
  • @tokenring-ai/agent: Agent system and management
  • @tokenring-ai/chat: Chat service for agent interactions
  • @tokenring-ai/app: Application framework and plugin system

License

MIT License - see LICENSE for details.