7.9 KiB
Discord EBA Adapter
Status
Discord has been migrated from the legacy source adapter:
src/langbot/pkg/platform/sources/discord.py
src/langbot/pkg/platform/sources/discord.yaml
EBA adapter directory:
src/langbot/pkg/platform/adapters/discord/
├── adapter.py
├── api_impl.py
├── event_converter.py
├── manifest.yaml
├── message_converter.py
├── platform_api.py
├── types.py
└── voice.py
The adapter is registered as discord-eba.
Configuration
| Field | Required | Default | Description |
|---|---|---|---|
client_id |
Yes | "" |
Discord application client ID. |
token |
Yes | "" |
Discord bot token. |
The bot needs gateway permissions and intents for the target test server. Message Content intent is required for message bodies, Server Members intent is required for member APIs/events, and reaction events require the Reactions intent and channel permissions.
Events
Discord declares these EBA events:
message.receivedmessage.editedmessage.deletedmessage.reactiongroup.member_joinedgroup.member_leftgroup.member_bannedbot.invited_to_groupbot.removed_from_groupplatform.specific
Discord-specific events that do not map cleanly to common events should be surfaced as platform.specific.
Common APIs
| API | Status | Notes |
|---|---|---|
send_message |
Supported | Supports text, image, file, and mixed message chains through Discord messages and attachments. |
reply_message |
Supported | Uses Discord message references when replying to a received EBA message event. |
edit_message |
Supported | Bot can edit its own messages. File edits are implemented by clearing old attachments and sending replacement files when needed. |
delete_message |
Supported | Requires message management permissions for non-bot messages. |
forward_message |
Emulated | Discord has no native forward API; the adapter copies content and attachments. |
get_group_info |
Supported | Maps Discord guild metadata to EBA group info. |
get_group_member_list |
Supported | Requires member cache or the Server Members intent/fetch permission. |
get_group_member_info |
Supported | Maps Discord roles/permissions into EBA member roles. |
get_user_info |
Supported | Uses Discord user fetch/cache. |
upload_file |
Not supported | Discord uploads files as message attachments; standalone upload raises NotSupportedError. |
get_file_url |
Supported | Discord attachment URLs are already downloadable URLs, so the adapter returns the input URL. |
mute_member |
Supported where possible | Uses Discord timeout API and requires guild moderation permission. |
unmute_member |
Supported where possible | Clears timeout and requires guild moderation permission. |
kick_member |
Supported | Destructive; test only with a disposable account/bot. |
leave_group |
Supported | Bot leaves a guild; destructive and should run last. |
call_platform_api |
Supported | Discord-specific actions live here. |
Platform-Specific APIs
call_platform_api(action, params) supports:
get_channelget_guildget_guild_channelsget_guild_rolescreate_invitepin_messageunpin_messageadd_reactionremove_reactiontyping
Voice helpers are intentionally kept Discord-specific:
join_voice_channelleave_voice_channelget_voice_connection_statuslist_active_voice_connectionsget_voice_channel_info
Live Test Record
The live probe is:
uv run python tests/e2e/live_discord_eba_probe.py --help
Verified on May 7, 2026 with a newly created Discord application/bot named LangBot EBA Test 0507, the LangBot Discord server, and the #🐞-debugging channel:
- SDK standalone runtime started with WebSocket control/debug ports, and the
EBAEventProbeplugin connected throughlbp run. - Plugin runtime received real Discord events through LangBot:
BotInvitedToGroup,MessageReceived,MessageReactionReceivedadd/remove,MessageEdited, andMessageDeleted. - Plugin runtime API calls succeeded through the standalone runtime:
get_langbot_version,get_bots,get_bot_info,send_message, plugin storage APIs, workspace storage APIs,list_plugins_manifest,list_commands,list_tools, andlist_knowledge_bases. - Direct live adapter probe observed
message.received,message.edited,message.deleted, andbot.removed_from_group. - Message APIs verified: send, reply, edit, delete, forward, text/image/file mixed message chains.
- User and guild APIs verified:
get_user_info,get_group_info,get_group_member_list,get_group_member_info. - Platform-specific APIs verified:
get_channel,get_guild,get_guild_channels,get_guild_roles,create_invite,typing,pin_message,unpin_message,add_reaction,remove_reaction. - Unsupported API behavior verified:
upload_fileraisesNotSupportedError. - Destructive API verified at the end:
leave_group, which emittedbot.removed_from_group.
Not verified in the shared LangBot server live run: mute_member, unmute_member, and kick_member, because the run did not use a disposable target member. They are implemented through Discord timeout/kick APIs and should only be exercised against a disposable account or bot.
The test fixed one real test-fixture issue: EBAEventProbe previously assumed get_bots() returned UUID strings. The current standalone runtime returns bot dictionaries, so the probe now selects an enabled bot dictionary and passes its uuid to get_bot_info and send_message. The probe also now subscribes to MessageDeleted.
Standalone Runtime Plugin E2E Record
Verified again on May 10, 2026 with SDK standalone runtime, LangBot --standalone-runtime, Discord web client, the LangBot server, and #🐞-debugging.
Evidence:
- Main plugin JSONL:
data/temp/discord-plugin-e2e-20260510-final.jsonl - LangBot runtime log:
data/temp/discord-langbot-e2e-20260510-rerun.log
Observed and verified:
- A newly invited Discord bot connected to the LangBot server and received a real web-client message in
#🐞-debugging. MessageReceivedreached the plugin withbot_uuid=eba-discord-live,adapter_name=discord, commonSource/Plainmessage components, commonUser, and commonUserGroupfor the guild.- SDK API calls succeeded:
get_langbot_version,get_bots,get_bot_info,send_message, plugin storage, workspace storage,list_plugins_manifest,list_commands,list_tools, andlist_knowledge_bases. - Outbound component sweep succeeded: plain text plus user mention,
AtAll/@everyone, base64 image, quoted reply, file attachment, and flattened forward fallback. - Common APIs succeeded:
get_user_info,get_group_info,get_group_member_list, andget_group_member_info. - Discord platform APIs succeeded through
call_platform_api:get_channel,typing,get_guild,get_guild_channels, andget_guild_roles.
Documented limits in this E2E run:
- Real Discord UI inbound attachment/image/file, reply/quote, and fresh mention-chain messages were not completed in the plugin E2E evidence. Outbound image/file attachments from the bot do not prove inbound attachment conversion.
- A later May 10 UI retry could write text into the Discord message box, but the client kept the send button disabled and did not send the message, so it produced no new plugin evidence.
get_message,get_friend_list, andget_group_listare not supported by this Discord adapter.- Destructive moderation and guild-leave APIs were not repeated against the shared LangBot server.
- Native Discord voice is not represented as common
Voice; audio-like payloads are treated as file attachments. create_invite, pin/unpin, and reaction mutation were covered by prior direct live probes but were not repeated by the final plugin run to avoid extra shared-server side effects.