Skip to main content

ErisPulse Discord Adapter

English | 中文


English

A Discord Bot adapter for the ErisPulse framework, implementing multi-account support, diverse message types, and platform-specific event handling via Discord Gateway (WebSocket) and REST API v10.

Features

  • Multi-Account: Run multiple Discord Bots simultaneously
  • Gateway WebSocket: Full HELLO / IDENTIFY / Heartbeat / RESUME flow
  • Auto-Reconnect: RESUME session recovery, no message loss
  • REST API v10: Complete Discord HTTP API access
  • Embed Support: Send and receive rich embed messages
  • File Upload: multipart/form-data attachment uploads
  • DM: Auto-create DM channels for private messaging
  • Thread Support: Track and interact with Discord threads

Installation

epsdk install Discord

Configuration

Add to config/config.toml:

[DiscordAdapter.accounts.default]
token = "YOUR_BOT_TOKEN"
intents = 33281
enabled = true

# Multi-account example
[DiscordAdapter.accounts.bot2]
token = "ANOTHER_BOT_TOKEN"
intents = 33281
enabled = true

Configuration Fields

Field Type Required Description
token string Yes Discord Bot Token
intents int No Gateway Intents bitmask (default 33281)
enabled bool No Enable this account (default true)

bot_id is discovered automatically at runtime from the Gateway READY event — no need to configure it.

Intents

Intents is a bitmask, default 33281 = GUILDS | GUILD_MESSAGES | MESSAGE_CONTENT:

Intent Value Description
GUILDS 1 << 0 (1) Guild-related events
GUILD_MEMBERS 1 << 1 (2) Member events (requires Privileged)
GUILD_MESSAGES 1 << 9 (512) Guild message events
MESSAGE_CONTENT 1 << 15 (32768) Message content (requires Privileged)

Note: MESSAGE_CONTENT and GUILD_MEMBERS are Privileged Intents. Enable them in the Discord Developer Portal → Bot → Privileged Gateway Intents.

Inviting the Bot

The bot must be invited to a server before it can send/receive messages. Construct an OAuth2 URL:

https://discord.com/api/oauth2/authorize?client_id=YOUR_BOT_ID&permissions=8&scope=bot
  • client_id = your Bot's Application ID (the bot_id shown in logs after READY)
  • permissions=8 = Administrator (adjust as needed via Discord Permission Calculator)
  • Add applications.commands to scope if using slash commands

Quick Start

from ErisPulse import sdk
from ErisPulse.Core.Event import message

discord = sdk.adapter.get("discord")

@message.on_message()
async def handle_message(event):
    if event.get_platform() != "discord":
        return

    text = event.get_text()
    channel_id = event.get_channel_id()  # Discord channel ID

    if text == "hello":
        # Reply to the channel where the message was received
        await event.reply("Hello from Discord!")

async def main():
    await sdk.run(keep_running=True)

Sending Messages

Text

# Guild channel message
await discord.Send.To("channel", channel_id).Text("Hello World!")

# Private message (auto-creates DM channel)
await discord.Send.To("user", user_id).Text("DM content")

Embed

embed = {
    "title": "Title",
    "description": "Description",
    "color": 5814783,
    "fields": [
        {"name": "Field", "value": "Value", "inline": False}
    ],
    "footer": {"text": "Footer text"},
}
await discord.Send.To("channel", channel_id).Embed(embed)

Media

# Image (URL)
await discord.Send.To("channel", channel_id).Image("https://example.com/image.png")

# Image (binary)
with open("image.png", "rb") as f:
    image_data = f.read()
await discord.Send.To("channel", channel_id).Image(image_data, filename="photo.png")

# File
await discord.Send.To("channel", channel_id).File("https://example.com/doc.pdf")
await discord.Send.To("channel", channel_id).File(file_bytes, filename="report.pdf")

Reply

# Chain modifier
await discord.Send.To("channel", channel_id).Reply(msg_id).Text("Reply content")

# One-shot
await discord.Send.To("channel", channel_id).Reply("Reply content", msg_id)

Mentions

# @single user
await discord.Send.To("channel", channel_id).At("user_id").Text("Hello")

# @multiple users
await discord.Send.To("channel", channel_id).At("user1").At("user2").Text("Hi everyone")

# @everyone
await discord.Send.To("channel", channel_id).AtAll().Text("Announcement")

Message Operations

# Delete (recall) a message
await discord.Send.To("channel", channel_id).Recall(msg_id)

OneBot12 Format

ob12_msg = [{"type": "text", "data": {"text": "Hello"}}]
await discord.Send.To("channel", channel_id).Raw_ob12(ob12_msg)

Multi-Account

# By bot_id (recommended)
await discord.Send.Using(event.get("self", {}).get("user_id")).To("channel", channel_id).Text("Hello")

# By account name
await discord.Send.Using("bot2").To("channel", channel_id).Text("Hello")

Discord-Specific Event Methods

The event object provides Discord-specific methods (requires platform == "discord"):

@message.on_message()
async def handle(event):
    if event.get_platform() != "discord":
        return

    channel_id = event.get_channel_id()    # Discord channel ID
    guild_id = event.get_guild_id()        # Guild ID (empty for DMs)
    username = event.get_username()         # Sender username
    global_name = event.get_global_name()   # Display name
    is_dm = event.is_dm()                   # Is a DM?
    embeds = event.get_embeds()             # Embed list
    attachments = event.get_attachments()   # Attachment list

Event Types

Message Events

Discord Event OB12 detail_type Description
MESSAGE_CREATE channel / private Guild channel / DM message
MESSAGE_UPDATE channel / private Message edited
MESSAGE_DELETE group_message_delete Message deleted

Notice Events

detail_type Description
group_member_increase Member joined guild
group_member_decrease Member left guild
group_member_update Member info updated
group_role_create / group_role_delete / group_role_update Role changes
channel_create / channel_delete / channel_update Channel changes
group_message_reaction_add / group_message_reaction_remove Reaction changes
typing User typing

Request Events

detail_type Description
interaction Slash command / button interaction

Message Segment Types

Type Description
text Plain text
mention / mention_all @user / @everyone
reply Reply reference
image / file / video / audio Media (URL or bytes)
discord_embed Discord Embed (extension)

Session Types

Scenario Receive detail_type Send type Target ID
Guild channel channel channel channel_id
DM private user user_id

Contributing

Issues and Pull Requests are welcome.

License

MIT


中文

基于 ErisPulse 框架的 Discord Bot 适配器,通过 Discord Gateway (WebSocket) 和 REST API v10 实现多账户支持、多种消息类型收发和平台特有事件处理。

特性

  • 多账户支持:同时运行多个 Discord Bot
  • Gateway WebSocket:完整实现 HELLO / IDENTIFY / 心跳 / RESUME 流程
  • 自动断线重连:支持 RESUME 恢复会话,消息不丢失
  • REST API v10:完整的 Discord HTTP API 调用
  • Embed 支持:发送和接收富文本嵌入消息
  • 文件上传:支持 multipart/form-data 上传附件
  • DM 私信:自动创建 DM 频道,支持私信收发
  • Thread 支持:跟踪和交互 Discord 话题

安装

epsdk install Discord

配置

config/config.toml 中添加:

[DiscordAdapter.accounts.default]
token = "YOUR_BOT_TOKEN"
intents = 33281
enabled = true

# 多账户示例
[DiscordAdapter.accounts.bot2]
token = "ANOTHER_BOT_TOKEN"
intents = 33281
enabled = true

配置字段

字段 类型 必填 说明
token string Discord Bot Token
intents int Gateway Intents 位掩码(默认 33281)
enabled bool 是否启用(默认 true)

bot_id 运行时从 Gateway READY 事件自动发现,无需配置。

Intents 说明

Intents 是位掩码,默认 33281 = GUILDS | GUILD_MESSAGES | MESSAGE_CONTENT

Intent 说明
GUILDS 1 << 0 (1) 服务器相关事件
GUILD_MEMBERS 1 << 1 (2) 成员相关事件(需 Privileged)
GUILD_MESSAGES 1 << 9 (512) 服务器消息事件
MESSAGE_CONTENT 1 << 15 (32768) 消息内容(需 Privileged)

注意MESSAGE_CONTENTGUILD_MEMBERS 是 Privileged Intents,需在 Discord Developer Portal 的 Bot 设置页开启。

邀请机器人

机器人必须先被邀请加入服务器才能收发消息。构造 OAuth2 邀请链接:

https://discord.com/api/oauth2/authorize?client_id=你的BOT_ID&permissions=8&scope=bot
  • client_id = 你的 Bot Application ID(READY 后日志中显示的 bot_id
  • permissions=8 = 管理员权限(可通过 Discord Permission Calculator 自行计算)
  • 如需使用斜杠命令,在 scope 中添加 applications.commands

快速开始

from ErisPulse import sdk
from ErisPulse.Core.Event import message

discord = sdk.adapter.get("discord")

@message.on_message()
async def handle_message(event):
    if event.get_platform() != "discord":
        return

    text = event.get_text()
    channel_id = event.get_channel_id()  # Discord 频道 ID

    if text == "hello":
        # 回复到收到消息的频道
        await event.reply("Hello from Discord!")

async def main():
    await sdk.run(keep_running=True)

发送消息

文本消息

# 服务器频道消息
await discord.Send.To("channel", channel_id).Text("Hello World!")

# 私信(自动创建 DM 频道)
await discord.Send.To("user", user_id).Text("私信内容")

Embed 嵌入消息

embed = {
    "title": "标题",
    "description": "描述内容",
    "color": 5814783,
    "fields": [
        {"name": "字段名", "value": "字段值", "inline": False}
    ],
    "footer": {"text": "页脚文字"},
}
await discord.Send.To("channel", channel_id).Embed(embed)

媒体消息

# 发送图片(URL)
await discord.Send.To("channel", channel_id).Image("https://example.com/image.png")

# 发送图片(二进制数据)
with open("image.png", "rb") as f:
    image_data = f.read()
await discord.Send.To("channel", channel_id).Image(image_data, filename="photo.png")

# 发送文件
await discord.Send.To("channel", channel_id).File("https://example.com/doc.pdf")
await discord.Send.To("channel", channel_id).File(file_bytes, filename="report.pdf")

回复消息

# 链式修饰回复
await discord.Send.To("channel", channel_id).Reply(msg_id).Text("回复内容")

# 便捷方法(一步发送)
await discord.Send.To("channel", channel_id).Reply("回复内容", msg_id)

链式 @提及

# @单个用户
await discord.Send.To("channel", channel_id).At("user_id").Text("你好")

# @多个用户
await discord.Send.To("channel", channel_id).At("user1").At("user2").Text("大家好")

# @全体
await discord.Send.To("channel", channel_id).AtAll().Text("公告")

消息操作

# 撤回消息
await discord.Send.To("channel", channel_id).Recall(msg_id)

OneBot12 格式消息

ob12_msg = [{"type": "text", "data": {"text": "Hello"}}]
await discord.Send.To("channel", channel_id).Raw_ob12(ob12_msg)

多账户发送

# 通过 bot_id(推荐)
await discord.Send.Using(event.get("self", {}).get("user_id")).To("channel", channel_id).Text("Hello")

# 通过账户名
await discord.Send.Using("bot2").To("channel", channel_id).Text("Hello")

Discord 特有方法

事件对象提供以下 Discord 专属方法(需 platform == "discord"):

@message.on_message()
async def handle(event):
    if event.get_platform() != "discord":
        return

    channel_id = event.get_channel_id()    # Discord 频道 ID
    guild_id = event.get_guild_id()        # 服务器 ID(私信为空)
    username = event.get_username()         # 发送者用户名
    global_name = event.get_global_name()   # 显示名
    is_dm = event.is_dm()                   # 是否私信
    embeds = event.get_embeds()             # Embed 列表
    attachments = event.get_attachments()   # 附件列表

事件类型

消息事件

Discord 事件 OB12 detail_type 说明
MESSAGE_CREATE channel / private 服务器频道 / 私信消息
MESSAGE_UPDATE channel / private 消息编辑
MESSAGE_DELETE group_message_delete 消息删除

通知事件

detail_type 说明
group_member_increase 成员加入服务器
group_member_decrease 成员离开服务器
group_member_update 成员信息更新
group_role_create / group_role_delete / group_role_update 身份组变更
channel_create / channel_delete / channel_update 频道变更
group_message_reaction_add / group_message_reaction_remove 表情回应变更
typing 用户正在输入

请求事件

detail_type 说明
interaction 斜杠命令 / 按钮交互

消息段类型

类型 说明
text 纯文本
mention / mention_all @用户 / @全体
reply 回复引用
image / file / video / audio 媒体(URL 或二进制)
discord_embed Discord Embed(扩展)

会话类型

场景 接收 detail_type 发送类型 目标 ID
服务器频道 channel channel channel_id
私信 private user user_id

贡献

欢迎提交 Issue 和 Pull Request。

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

erispulse_discordadapter-4.1.0.tar.gz (18.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

erispulse_discordadapter-4.1.0-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

Details for the file erispulse_discordadapter-4.1.0.tar.gz.

File metadata

  • Download URL: erispulse_discordadapter-4.1.0.tar.gz
  • Upload date:
  • Size: 18.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for erispulse_discordadapter-4.1.0.tar.gz
Algorithm Hash digest
SHA256 777184edf7720d5f01e3cd2b82a41ee940d6b2ca1cfdcfd4926cac023d0da2a7
MD5 c094368d223ced2aae9a080627356f43
BLAKE2b-256 3470e230c6189ff97fe64e92f7e8ca7278d59c1a9a274edf039d0b285fe8baf2

See more details on using hashes here.

Provenance

The following attestation bundles were made for erispulse_discordadapter-4.1.0.tar.gz:

Publisher: python-publish.yml on ErisPulse/ErisPulse-DiscordAdapter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file erispulse_discordadapter-4.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for erispulse_discordadapter-4.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2562a5edd4e7e86aa117378092819b242f761fd416c53e047181d9eaf62f9220
MD5 c9c22bb8a57be00f11802db133516a7a
BLAKE2b-256 110190472dfd34ae326b2a96a7c591fd0bf8e46026db284059cff87a0f9eb16f

See more details on using hashes here.

Provenance

The following attestation bundles were made for erispulse_discordadapter-4.1.0-py3-none-any.whl:

Publisher: python-publish.yml on ErisPulse/ErisPulse-DiscordAdapter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

4.1.0 This release

2 files

4.0.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page