Discord, Teams, Telegram, and Twilio

Purpose and Scope

This page groups eve integrations that connect an agent to real-time messaging products rather than to the default eve HTTP client. A messaging channel is the adapter layer that accepts platform-native events, decides whether those events should become an agent turn, assigns an auth identity, and delivers agent output back to the same conversation surface. In this family, the platform owns the conversation UX: slash commands, bot messages, mentions, callbacks, cards, inline controls, or SMS-style replies. eve owns the durable session, tool execution, continuations, and event stream behind that surface.

Discord is the repository-backed example for this page. Its documentation shows the complete pattern: create a channel file under agent/channels/, import a first-party channel factory, provide credentials through environment variables or a credentials object, expose a platform webhook route, customize dispatch with a hook, and optionally override event delivery. Teams and Telegram follow the same channel contract in the official docs, but use their platform protocols: Bot Framework Activity POSTs for Teams and Bot API webhooks for Telegram. Sources: docs/channels/discord.mdx

Use these integrations when users already live in a messaging app and the agent should participate there with native identity and delivery semantics. That differs from the eve channel, which exposes generic session routes for applications, SDK clients, and the terminal UI. It also differs from connections, which give an agent access to external systems as capabilities; messaging channels are ingress and egress surfaces for conversations. The practical design question is not only “can the agent receive a message?” but also “which messages should wake it, who is the authenticated principal, and how should long-running or approval-oriented work be rendered back to people?”

Relevant Source Files

  • docs/channels/discord.mdx — Documents the first-party Discord channel, including discordChannel(), default route and credential names, command registration expectations, dispatch hooks, delivery behavior, HITL rendering, proactive sessions, and attachment limitations.

Shared Messaging Channel Model

A messaging channel begins with a small filesystem convention: add a file such as agent/channels/discord.ts and export the channel definition as the default export. For Discord, that definition is discordChannel() from eve/channels/discord. The file location matters because eve treats channel modules as part of the agent surface; they are discovered alongside instructions, tools, skills, schedules, and other channel files in a filesystem-first project. Sources: docs/channels/discord.mdx

The platform webhook route is the public edge of the integration. Discord mounts POST /eve/v1/discord by default, and that URL is pasted into the Discord application's Interactions Endpoint URL. The channel verifies Discord's Ed25519 signature headers, acknowledges the interaction within Discord's three-second deadline, and runs eve work in the background. That ordering is important: platform protocols often require a fast acknowledgement even when the agent turn itself may involve model calls, tools, approvals, or durable continuations. Sources: docs/channels/discord.mdx

Credentials are intentionally separable from channel code. Discord reads DISCORD_PUBLIC_KEY, DISCORD_APPLICATION_ID, and DISCORD_BOT_TOKEN, or accepts equivalent values through credentials: { applicationId, botToken, publicKey }. The public key verifies X-Signature-Ed25519 and X-Signature-Timestamp; the application id is used for deferred response edits and followups; the bot token enables proactive messages, fallback channel messages, and typing indicators. This split lets local, preview, and production deployments share the same channel source while using environment-specific secrets. Sources: docs/channels/discord.mdx

Teams and Telegram have analogous setup concerns, but their platform-specific responsibilities differ. Teams checks Bot Connector bearer JWTs, receives Activity objects, and returns human-in-the-loop prompts as Adaptive Cards. Telegram checks X-Telegram-Bot-Api-Secret-Token, accepts private chats and selected group messages, and renders interactive prompts through inline keyboards. The shared eve concept remains the same: authenticate the inbound event, filter it, convert it into an agent message and continuation, then translate eve runtime events back into platform-native delivery.

Dispatch, Auth, and Conversation Selection

Dispatch is the decision point between “an event arrived” and “the agent should run.” In Discord, onCommand(ctx, interaction) returns { auth } to proceed or null to drop the interaction. The default auth is derived from the invoking user, while custom auth can set fields such as principalId, principalType, authenticator, and platform attributes like channel_id or guild_id. This is where a multi-tenant app should bind platform identity to the application's trust model instead of treating all webhook traffic as equivalent. Sources: docs/channels/discord.mdx

Discord command registration is deliberately outside the channel implementation. The docs show registering an ask application command through Discord's API with a required string option named message, which lines up with eve's default prompt extraction. During development, guild commands propagate faster than global commands. Keeping registration separate means eve does not own Discord application lifecycle; the channel owns runtime handling once Discord calls the endpoint. Sources: docs/channels/discord.mdx

The same dispatch idea applies to mention-based and group-chat surfaces. Telegram group chats typically need an explicit command, bot mention, or reply to a bot message before the bot should wake. Teams defaults to personal-chat messages and channel or group-chat messages that mention the bot directly. Those defaults prevent ambient conversation from becoming agent input unintentionally, and they create a clear place for developers to loosen or tighten behavior by overriding the channel hook when their product needs a different policy.

Delivery, HITL, and Proactive Sessions

After a turn starts, delivery is event-driven. Discord's default message.completed handler edits the deferred response for the first reply and sends followups after that. If an interaction token is rejected, it falls back to a bot-authenticated channel message. The channel also splits long text to Discord's 2000-character limit and defaults generated messages to allowed_mentions: { parse: [] }, which avoids accidentally pinging users or roles from model-generated text. Sources: docs/channels/discord.mdx

Human-in-the-loop, often abbreviated HITL, is the pattern where the agent pauses to ask a person for confirmation, selection, or freeform input before continuing. Discord renders HITL as components: confirmations and options become buttons, select requests become string selects, and freeform input opens a modal. When the user responds, the parked session resumes. Teams and Telegram use different UI primitives, but the same durable-session idea applies: the runtime waits for human input and then continues the existing agent workflow rather than starting over.

Proactive sessions let a channel initiate work without an inbound user interaction at that moment. Discord supports receive(discord, { message, target, auth }) from a schedule run handler, and args.receive(discord, ...) from another channel. The proactive target shape is { channelId, conversationId?, initialMessage? }, and either path requires DISCORD_BOT_TOKEN. This is useful for reminders, scheduled summaries, cross-channel handoff, or workflow notifications that should appear in a conversation the agent can address. Sources: docs/channels/discord.mdx

Compact Reference

ConcernDiscord referenceNotes for the messaging-channel family
Channel fileagent/channels/discord.tsMessaging integrations are authored as channel modules under agent/channels/.
FactorydiscordChannel() from eve/channels/discordOther first-party channels expose their own factories, such as Teams and Telegram variants.
Default routePOST /eve/v1/discordPlatform developer portals or webhook settings should point at the deployed public URL.
CredentialsDISCORD_PUBLIC_KEY, DISCORD_APPLICATION_ID, DISCORD_BOT_TOKENCredentials can be supplied through environment variables or channel config when supported.
Dispatch hookonCommand(ctx, interaction)Return { auth } to run the agent or null to ignore the event.
Event deliveryevents["message.completed"](eventData, channel, ctx)Custom handlers receive platform handles on the channel object.
HITLDiscord components, selects, and modalsTeams and Telegram render equivalent pauses with their own UI controls.
Proactive sendreceive(discord, { message, target, auth })Requires bot credentials for platform-authenticated outbound delivery.
AttachmentsInbound file attachments are not supported for Discord today.Check each channel's own docs before relying on attachments.

Next Steps

Start with the platform where your users already work, then implement the smallest channel file and verify the webhook route locally or in a preview deployment. For Discord, register a development guild command with a message option, set the three credential environment variables, and test that the channel acknowledges quickly while the agent response arrives asynchronously. After basic delivery works, add an explicit onCommand auth mapping and decide whether the default HITL and long-message behavior are acceptable for your product. Sources: docs/channels/discord.mdx

Read the channels overview next for the common channel contract, then move to the dedicated Discord, Teams, Telegram, or Twilio documentation for platform setup details. If the messaging surface is not first-party, use the custom channels guide to implement the same route, dispatch, continuation, and event-delivery lifecycle yourself.