简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

ErisPulse 会话类型标准

本文档定义了 ErisPulse 支持的会话类型标准,包括接收事件类型和发送目标类型。

1. 核心概念

1.1 接收类型 && 发送类型

ErisPulse 区分两种会话类型:

1.2 类型映射关系

接收类型 (detail_type)     发送类型 (Send.To)
─────────────────        ────────────────
private                 →        user
group                   →        group
channel                 →        channel
guild                   →        guild
thread                  →        thread
user                    →        user

关键点:

2. 标准会话类型

2.1 OneBot12 标准类型

private

group

user

2.2 ErisPulse 扩展类型

channel

guild

thread

3. 平台类型映射

3.1 映射原则

适配器负责将平台的原生类型映射到 ErisPulse 标准类型:

平台原生类型 → ErisPulse 标准类型 → 发送类型

3.2 常见平台映射示例

Telegram

Telegram 类型          ErisPulse 接收类型    发送类型
─────────────────      ────────────────       ───────────
private                private                 user
group                  group                   group
supergroup             group                   group  # 映射到 group
channel                channel                 channel

Discord

Discord 类型          ErisPulse 接收类型    发送类型
─────────────────      ────────────────       ───────────
Direct Message         private                user
Text Channel           channel                channel
Guild                  guild                  guild
Thread                 thread                 thread

OneBot11

OneBot11 类型        ErisPulse 接收类型    发送类型
─────────────────      ────────────────       ───────────
private                private                user
group                  group                  group
discuss                group                  group  # 映射到 group

4. 自定义类型扩展

4.1 注册自定义类型

适配器可以注册自定义会话类型:

from ErisPulse.Core.Event import register_custom_type

# 注册自定义类型
register_custom_type(
    receive_type="my_custom_type",
    send_type="custom",
    id_field="custom_id",
    platform="MyPlatform"
)

4.2 使用自定义类型

注册后,系统会自动处理该类型的转换和推断:

# 自动推断
receive_type = infer_receive_type(event, platform="MyPlatform")
# 返回: "my_custom_type"

# 转换为发送类型
send_type = convert_to_send_type(receive_type, platform="MyPlatform")
# 返回: "custom"

# 获取对应ID
target_id = get_target_id(event, platform="MyPlatform")
# 返回: event["custom_id"]

4.3 注销自定义类型

from ErisPulse.Core.Event import unregister_custom_type

unregister_custom_type("my_custom_type", platform="MyPlatform")

5. 自动类型推断

当事件没有明确的 detail_type 字段时,系统会根据存在的 ID 字段自动推断类型:

Note

2.7.0+ 行为变更:detail_type 只有在是已知会话类型(标准或自定义)时才直接采用。notice/request 事件的 detail_type(如 group_member_increase、friend_increase)是语义子类型而非会话类型,会转而根据 ID 字段推断正确的会话类型。

5.1 推断优先级

优先级(从高到低):
1. group_id     → group
2. channel_id   → channel
3. guild_id     → guild
4. thread_id    → thread
5. user_id      → private

5.2 使用示例

# 事件只有 group_id
event = {"group_id": "123", "user_id": "456"}
receive_type = infer_receive_type(event)
# 返回: "group"(优先使用 group_id)

# 事件只有 user_id
event = {"user_id": "123"}
receive_type = infer_receive_type(event)
# 返回: "private"

# notice 事件的 detail_type 是语义子类型,2.7.0+ 会从 ID 字段推断
event = {"type": "notice", "detail_type": "group_member_increase", "group_id": "123"}
receive_type = infer_receive_type(event)
# 返回: "group"(而非 "group_member_increase")

6. API 使用示例

6.1 发送消息

from ErisPulse import adapter

# 发送给用户
await adapter.myplatform.Send.To("user", "123").Text("Hello")

# 发送给群组
await adapter.myplatform.Send.To("group", "456").Text("Hello")

# 自动转换 private → user(不推荐,可能会有兼容性问题)
await adapter.myplatform.Send.To("private", "789").Text("Hello")
# 内部自动转换为: Send.To("user", "789") # 直接使用user作为会话类型是更优的选择

6.2 事件回复

from ErisPulse.Core.Event import Event

# Event.reply() 自动处理类型转换
await event.reply("回复内容")
# 内部自动使用正确的发送类型

6.3 命令处理

from ErisPulse.Core.Event import command

@command(name="test")
async def handle_test(event):
    # 系统自动处理会话类型
    # 无需手动判断 group_id 还是 user_id
    await event.reply("命令执行成功")

7. 核心 API 参考

7.1 类型转换

from ErisPulse.Core.Event import convert_to_send_type, convert_to_receive_type

# 接收类型 → 发送类型
convert_to_send_type("private")  # → "user"
convert_to_send_type("group")    # → "group"

# 发送类型 → 接收类型
convert_to_receive_type("user")   # → "private"
convert_to_receive_type("group")  # → "group"

7.2 ID 字段查询

from ErisPulse.Core.Event import get_id_field, get_receive_type

get_id_field("group")    # → "group_id"
get_id_field("private")  # → "user_id"

get_receive_type("group_id")  # → "group"
get_receive_type("user_id")   # → "private"

7.3 一步获取发送信息

from ErisPulse.Core.Event import get_send_type_and_target_id

event = {"detail_type": "private", "user_id": "123"}
send_type, target_id = get_send_type_and_target_id(event)
# send_type = "user", target_id = "123"

# 直接用于 Send.To()
await adapter.Send.To(send_type, target_id).Text("Hello")

7.4 获取目标 ID

from ErisPulse.Core.Event import get_target_id

event = {"detail_type": "group", "group_id": "456"}
get_target_id(event)  # → "456"

8. 工具方法

from ErisPulse.Core.Event import (
    is_standard_type,
    is_valid_send_type,
    get_standard_types,
    get_send_types,
    clear_custom_types,
)

is_standard_type("private")     # True
is_standard_type("custom_type") # False

is_valid_send_type("user")      # True
is_valid_send_type("invalid")   # False

get_standard_types()  # {"private", "group", "channel", "guild", "thread", "user"}
get_send_types()      # {"user", "group", "channel", "guild", "thread"}

clear_custom_types()                # 清除所有
clear_custom_types(platform="discord")  # 只清除指定平台的

9. 最佳实践

7.1 适配器开发者

  1. 使用标准映射:尽可能映射到标准类型,而非创建新类型
  2. 正确转换:确保接收类型和发送类型的映射关系正确
  3. 保留原始数据:在 {platform}_raw 中保留原始事件类型
  4. 文档说明:在适配器文档中说明类型映射关系

7.2 模块开发者

  1. 使用工具方法:使用 get_send_type_and_target_id() 等工具方法
  2. 避免硬编码:不要写 if group_id else "private" 这样的代码
  3. 考虑所有类型:代码要支持所有标准类型,不仅是 private/group
  4. 灵活设计:使用事件包装器的方法,而非直接访问字段

7.3 类型推断

10. 常见问题

Q1: 为什么发送时 private 要转换为 user?

A: 这是 OneBot12 标准的要求。private 是接收时的概念,发送时使用 user 更符合语义。

Q2: 如何支持新的会话类型?

A: 通过 register_custom_type() 注册自定义类型,或直接使用标准类型中的 channel、guild 等。

Q3: 事件没有 detail_type 怎么办?

A: 系统会根据存在的 ID 字段自动推断。优先级为:group > channel > guild > thread > user。

Q4: 适配器如何映射 Telegram supergroup?

A: 在适配器的转换逻辑中,将 supergroup 映射为标准的 group 类型。

Q5: 邮箱等特殊平台如何处理?

A: 对于不通用或平台特有的类型,使用 {platform}_raw 和 {platform}_raw_type 保留原始数据,适配器自行处理。

11. 相关文档