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

ErisPulse Session Type Standards

This document defines the session type standards supported by ErisPulse, including receiving event types and sending target types.

1. Core Concepts

1.1 Receive Type && Send Type

ErisPulse distinguishes two session types:

1.2 Type Mapping Relationship

Receive Type (detail_type)    Send Type (Send.To)
─────────────────             ────────────────
private                       →        user
group                         →        group
channel                       →        channel
guild                         →        guild
thread                        →        thread
user                          →        user

Key Points:

2. Standard Session Types

2.1 OneBot12 Standard Types

private

group

user

2.2 ErisPulse Extended Types

channel

guild

thread

3. Platform Type Mapping

3.1 Mapping Principles

The adapter is responsible for mapping the native types of platforms to ErisPulse standard types:

Platform native type → ErisPulse standard type → Sending type

3.2 Common Platform Mapping Examples

Telegram

Telegram Type          ErisPulse Receive Type    Sending Type
─────────────────      ────────────────       ───────────
private                private                 user
group                  group                   group
supergroup             group                   group  # Mapped to group
channel                channel                 channel

Discord

Discord Type          ErisPulse Receive Type    Sending Type
─────────────────      ────────────────       ───────────
Direct Message         private                user
Text Channel           channel                channel
Guild                  guild                  guild
Thread                 thread                 thread

OneBot11

OneBot11 Type        ErisPulse Receive Type    Sending Type
─────────────────      ────────────────       ───────────
private                private                user
group                  group                  group
discuss                group                  group  # Mapped to group

4. Custom Type Extension

4.1 Register Custom Type

The adapter can register custom session types:

from ErisPulse.Core.Event import register_custom_type

# Register custom type
register_custom_type(
    receive_type="my_custom_type",
    send_type="custom",
    id_field="custom_id",
    platform="MyPlatform"
)

4.2 Use Custom Type

After registration, the system will automatically handle conversion and inference for this type:

# Automatic inference
receive_type = infer_receive_type(event, platform="MyPlatform")
# Returns: "my_custom_type"

# Convert to send type
send_type = convert_to_send_type(receive_type, platform="MyPlatform")
# Returns: "custom"

# Get corresponding ID
target_id = get_target_id(event, platform="MyPlatform")
# Returns: event["custom_id"]

4.3 Unregister Custom Type

from ErisPulse.Core.Event import unregister_custom_type

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

5. Automatic Type Inference

When an event does not have an explicit detail_type field, the system automatically infers the type based on the available ID fields:

Note

Behavior change in 2.7.0+: detail_type is directly adopted only if it is a known session type (standard or custom). For notice/request events, detail_type (e.g., group_member_increase, friend_increase) is a semantic subtype rather than a session type, and the correct session type will be inferred from the ID field instead.

5.1 Inference Priority

Priority (from highest to lowest):
1. group_id     → group
2. channel_id   → channel
3. guild_id     → guild
4. thread_id    → thread
5. user_id      → private

5.2 Usage Examples

# Event has only group_id
event = {"group_id": "123", "user_id": "456"}
receive_type = infer_receive_type(event)
# Returns: "group" (group_id is prioritized)

# Event has only user_id
event = {"user_id": "123"}
receive_type = infer_receive_type(event)
# Returns: "private"

# For notice events, detail_type is a semantic subtype; 2.7.0+ will infer from ID fields
event = {"type": "notice", "detail_type": "group_member_increase", "group_id": "123"}
receive_type = infer_receive_type(event)
# Returns: "group" (not "group_member_increase")

6. API Usage Examples

6.1 Sending Messages

from ErisPulse import adapter

# Send to a user
await adapter.myplatform.Send.To("user", "123").Text("Hello")

# Send to a group
await adapter.myplatform.Send.To("group", "456").Text("Hello")

# Automatically convert private → user (not recommended, may cause compatibility issues)
await adapter.myplatform.Send.To("private", "789").Text("Hello")
# Internally automatically converted to: Send.To("user", "789") # Using user as session type directly is a better choice

6.2 Event Reply

from ErisPulse.Core.Event import Event

# Event.reply() automatically handles type conversion
await event.reply("Reply content")
# Internally automatically uses the correct sending type

6.3 Command Handling

from ErisPulse.Core.Event import command

@command(name="test")
async def handle_test(event):
    # The system automatically handles session type
    # No need to manually determine group_id or user_id
    await event.reply("Command executed successfully")

7. Core API Reference

7.1 Type Conversion

from ErisPulse.Core.Event import convert_to_send_type, convert_to_receive_type

# Receive type → Send type
convert_to_send_type("private")  # → "user"
convert_to_send_type("group")    # → "group"

# Send type → Receive type
convert_to_receive_type("user")   # → "private"
convert_to_receive_type("group")  # → "group"

7.2 ID Field Query

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 One-step Retrieval of Send Information

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"

# Directly used in Send.To()
await adapter.Send.To(send_type, target_id).Text("Hello")

7.4 Retrieve Target ID

from ErisPulse.Core.Event import get_target_id

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

8. Utility Methods

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 all
clear_custom_types(platform="discord")  # Clear only for the specified platform

9. Best Practices

7.1 Adapter Developers

  1. Use Standard Mappings: Map to standard types as much as possible, rather than creating new types.
  2. Correct Conversion: Ensure the mapping relationship between received and sent types is correct.
  3. Retain Raw Data: Keep the raw event type in {platform}_raw.
  4. Document Mappings: Explain the type mapping relationships in the adapter documentation.

7.2 Module Developers

  1. Use Utility Methods: Use utility methods like get_send_type_and_target_id().
  2. Avoid Hardcoding: Do not write code like if group_id else "private".
  3. Consider All Types: Code should support all standard types, not just private/group.
  4. Flexible Design: Use event wrapper methods, rather than directly accessing fields.

9. Type Inference

10. Frequently Asked Questions

Q1: Why is private converted to user when sending?

A: This is a requirement of the OneBot12 specification. private is a concept for receiving, and using user when sending is more semantically appropriate.

Q2: How to support new session types?

A: Register custom types using register_custom_type(), or directly use standard types such as channel and guild.

Q3: What to do if an event does not have a detail_type?

A: The system will automatically infer based on the available ID fields. The priority order is: group > channel > guild > thread > user.

Q4: How does the adapter map Telegram supergroup?

A: In the adapter's conversion logic, map supergroup to the standard group type.

Q5: How to handle special platforms such as email?

A: For non-generic or platform-specific types, use {platform}_raw and {platform}_raw_type to preserve raw data, and let the adapter handle it.