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

OneBot11 Platform Feature Documentation

OneBot11Adapter is an adapter built based on the OneBot V11 protocol.


Document Information

Basic Information

v5 Paradigm Update (4.3.0)

The adapter has completed alignment with the v5 paradigm (incremental upgrade, API compatible):

Existing capabilities (supported since 4.2.0): Multi-account support, standard action mapping for Api DSL (e.g., get_self_info → get_login_info), Request DSL (friend/group request approval: event.approve() / event.reject()), EventMixin, and i18n.

Standard API Actions (API DSL)

The adapter automatically maps OneBot12 standard action names to OB11 action names, allowing modules to uniformly invoke actions across platforms:

OB12 Standard Action OB11 Action Description
get_self_info get_login_info Standardized fields: user_id/user_name/user_displayname
get_user_info get_stranger_info Standardized fields
delete_message delete_msg Recall message
leave_group set_group_leave Leave group
get_friend_list get_friend_list Action names are consistent, default pass-through
get_group_info get_group_info Action names are consistent, default pass-through
upload_file upload_group_file / upload_private_file Optional group_id/user_id parameters, filetype automatically detected and routed to appropriate function

Basic Usage

from ErisPulse import sdk
onebot = sdk.adapter.get("onebot11")

# Get bot information
result = await onebot.Api.get_self_info()
print(result["data"]["user_id"], result["data"]["user_name"])

# Recall message
await onebot.Api.delete_message(message_id=123456)

# Upload group file (filetype automatically detected and routed to upload_group_file)
result = await onebot.Api.upload_file(group_id=123456, file="/path/to/file.zip")

# Specify account (multi-account)
result = await onebot.Api.Using("main").get_self_info()

# Unmapped OB11 actions can be called via the call() escape hatch (works with extensions like NapCat/Lagrange)
result = await onebot.Api.call("send_poke", group_id=123, user_id=456)

Supported Message Sending Types

All sending methods are implemented using a fluent interface, for example:

from ErisPulse.Core import adapter
onebot = adapter.get("onebot11")

# Send using the default account
await onebot.Send.To("group", group_id).Text("Hello World!")

# Send using a specific account
await onebot.Send.Using("main").To("group", group_id).Text("Message from main account")

# Chained modifiers: @user + reply
await onebot.Send.To("group", group_id).At(123456).Reply(msg_id).Text("Reply message")

# @all members
await onebot.Send.To("group", group_id).AtAll().Text("Announcement message")

Basic Sending Methods

Group Operation Methods

The following methods must be used with To("group", group_id) to specify the target group, and are executed within the group context:

Query Methods

Friend Operation Methods

Chained Modifier Methods (Combinable)

Chained modifier methods return self, enabling fluent chaining, and must be called before the final sending method:

Chained Call Examples

# Basic sending
await onebot.Send.To("group", 123456).Text("Hello")

# Mention a single user
await onebot.Send.To("group", 123456).At(789012).Text("你好")

# Mention multiple users
await onebot.Send.To("group", 123456).At(111).At(222).At(333).Text("大家好")

# Send a OneBot12 format message
ob12_msg = [{"type": "text", "data": {"text": "Hello"}}]
await onebot.Send.To("group", 123456).Raw_ob12(ob12_msg)

# Send a like
await onebot.Send.Like(123456, times=10)

# Mute a group member
await onebot.Send.To("group", 123456).Ban(789012, duration=3600)

# Unmute
await onebot.Send.To("group", 123456).Ban(789012, duration=0)

# Kick a member
await onebot.Send.To("group", 123456).Kick(789012)

# Set a group admin
await onebot.Send.To("group", 123456).SetAdmin(789012)

# Change group name
await onebot.Send.To("group", 123456).SetGroupName("New Group Name")

# Retrieve group information
result = await onebot.Send.To("group", 123456).GetGroupInfo()

# Specify account for operation
await onebot.Send.Using("main").To("group", 123456).Ban(789012)

Handling Unsupported Types

If an undefined sending method is called, the adapter will return a text prompt:

# Call an unsupported method
await onebot.Send.To("group", 123456).SomeUnsupportedMethod(arg1, arg2)
# Actually sends: "[Unsupported sending type] Method name: SomeUnsupportedMethod, Parameters: [...]"

Request Operations (Request DSL)

The adapter provides a Request Operations DSL for handling approval/rejection of friend requests and group requests (group join/invite).

Event Shortcut Methods

Request events support event.approve() and event.reject() shortcut methods, which internally automatically call the Request DSL:

from ErisPulse.Core.Event import request

@request.on_friend_request()
async def handle_friend_request(event):
    comment = event.get("comment", "")

    if comment == "passphrase":
        await event.approve()
    else:
        await event.reject()

@request.on_group_request()
async def handle_group_request(event):
    group_id = event.get("group_id")
    await event.approve()

Manual Call to Request DSL

# Approve request
await onebot.Request("flag_string").accept()

# Reject request
await onebot.Request("flag_string").reject()

# Specify account for operation
await onebot.Request("flag_string").Using("main").accept()

Complete Example

from ErisPulse.Core.Event import request

@request.on_friend_request()
async def handle_friend_request(event):
    comment = event.get("comment", "")

    # Method 1: Using Event shortcut methods
    if comment == "passphrase":
        await event.approve()
    else:
        await event.reject()

    # Method 2: Using Request DSL
    flag = event.get("flag")
    if comment == "passphrase":
        await onebot.Request(flag).accept()
    else:
        await onebot.Request(flag).reject()

Request Operation Return Value

{
    "status": "ok",
    "retcode": 0,
    "data": {...},
    "message_id": "",
    "message": ""
}

Event Type Mapping

Standard OB12 Mapping

OB11 Original Type Converted detail_type Description
message_type: private private Private chat message
message_type: group group Group chat message
request_type: friend friend Friend request
request_type: group group Group request
meta_event_type: heartbeat heartbeat Heartbeat
notice_type: group_upload group_file_upload Group file upload
notice_type: group_admin group_admin_change Group admin change
notice_type: group_increase group_member_increase Group member increase
notice_type: group_decrease group_member_decrease Group member decrease
notice_type: group_ban group_ban Group ban
notice_type: friend_add friend_increase Friend added
notice_type: friend_delete friend_decrease Friend removed
notice_type: group_recall / friend_recall message_recall Message recall

Platform-Specific Events (onebot11_ prefix)

OB11 Original Type Converted detail_type Description
meta_event_type: lifecycle onebot11_lifecycle OneBot implementation lifecycle
notify + sub_type: honor onebot11_honor Group honor change
notify + sub_type: poke onebot11_poke Poke
notify + sub_type: lucky_king onebot11_lucky_king Group red packet lucky king
Unknown CQ Code Type Message Segment onebot11_{type} Unrecognized CQ Code

Event Examples

// Friend Request
{
  "type": "request",
  "detail_type": "friend",
  "user_id": "789012",
  "comment": "Please add as friend",
  "request_id": "flag_abc123",
  "flag": "flag_abc123"
}

// Heartbeat
{
  "type": "meta_event",
  "detail_type": "heartbeat",
  "interval": 5000,
  "status": {...}
}

// Lifecycle (Platform-specific)
{
  "type": "meta_event",
  "detail_type": "onebot11_lifecycle",
  "sub_type": "enable"
}

// Poke (Platform-specific)
{
  "type": "notice",
  "detail_type": "onebot11_poke",
  "group_id": "123456",
  "user_id": "789012",
  "target_id": "345678"
}

// Group Red Packet Lucky King (Platform-specific)
{
  "type": "notice",
  "detail_type": "onebot11_lucky_king",
  "group_id": "123456",
  "user_id": "789012",
  "target_id": "345678"
}

// Honor Change (Platform-specific)
{
  "type": "notice",
  "detail_type": "onebot11_honor",
  "group_id": "123456",
  "user_id": "789012",
  "honor_type": "talkative"
}

// CQ Code Extended Message Segment
{
  "type": "message",
  "message": [
    {"type": "onebot11_shake", "data": {}}
  ]
}

Extension Field Description

Event Extension Methods

The OneBot11 adapter registers the following platform-specific methods for event objects, which can be directly called within event handlers:

from ErisPulse.Core.Event import message

@message.on_message()
async def handle_message(event):
    raw_self_id = event.get_raw_self_id()
    sender_info = event.get_sender_info()
    sender_role = event.get_sender_role()

Method List

Method Return Type Description
get_raw_event() dict Get the complete raw OneBot11 event data
get_raw_self_id() str Get the raw self_id (Bot's QQ number)
get_sender_info() dict Get complete sender information (including nickname, role, level, etc.)
get_sender_role() str Get the sender's role within the group (owner/admin/member)
get_sender_level() int Get the sender's level
get_sender_title() str Get the sender's group title
is_system_message() bool Check if it is a system message (sub_type == "system")

Usage Examples

from ErisPulse.Core.Event import message, command

@message.on_group_message()
async def handle_group(event):
    role = event.get_sender_role()
    if role == "admin" or role == "owner":
        await event.reply("Hello, admin!")

    title = event.get_sender_title()
    if title:
        await event.reply(f"Your title is: {title}")

@command("whoami")
async def whoami(event):
    info = event.get_sender_info()
    nickname = info.get("nickname", "Unknown")
    level = event.get_sender_level()
    await event.reply(f"Nickname: {nickname}, Level: {level}")

Configuration Options

The OneBot11 adapter adopts a multi-account architecture, where each account is independently configured. The configuration key name is OneBotAdapter.

Account Configuration Fields

Field Type Required Default Description
bot_id str Yes "" The robot's QQ number, used to identify the account
mode str No "server" Running mode: "server" (passive listening) or "client" (active connection)
url str No "ws://127.0.0.1:3001" WebSocket address for Client mode
token str No "" Authentication Token (Token for Client mode connection / Token for Server mode verification)
server_path str No "/" WebSocket path for Server mode
enabled bool No true Whether to enable this account
name str No "" Account comment name

Built-in Defaults

Configuration Example

[OneBotAdapter.accounts.main]
bot_id = "123456789"
mode = "server"
server_path = "/onebot-main"
token = "main_token"
enabled = true

[OneBotAdapter.accounts.backup]
bot_id = "987654321"
mode = "client"
url = "ws://127.0.0.1:3002"
token = "backup_token"
enabled = true

[OneBotAdapter.accounts.test]
bot_id = "111222333"
mode = "client"
url = "ws://127.0.0.1:3003"
enabled = false

Default Configuration

If no account is configured, the adapter will automatically create:

[OneBotAdapter.accounts.default]
bot_id = ""
mode = "server"
server_path = "/"
enabled = true

Send Method Return Values

All send methods return a Task object, which can be directly awaited to obtain the sending result. The returned result follows the ErisPulse adapter's standardized return specification:

{
    "status": "ok",
    "retcode": 0,
    "data": {...},
    "message_id": "123456",
    "message": "",
    "onebot11_raw": {...}
}

Multi-Account Sending Syntax

# Account selection method
await onebot.Send.Using("main").To("group", 123456).Text("Main account message")
await onebot.Send.Using("backup").To("group", 123456).Image("http://example.com/image.jpg")

# Select account via bot_id
await onebot.Send.Using("123456789").To("group", 123456).Text("Selected by QQ number")

# API call method
await onebot.call_api("send_msg", account_id="main", group_id=123456, message="Hello")

Account Resolution Priority

The resolution priority for the account_id parameter in call_api and Using():

  1. Exact match with account name
  2. Match bot_id field
  3. Match any str type field of the account
  4. Fall back to the first enabled account

Asynchronous Processing Mechanism

The OneBot11 adapter adopts an asynchronous non-blocking design, ensuring that:

  1. Message sending does not block the event handling loop.
  2. Multiple concurrent sending operations can proceed simultaneously.
  3. API responses can be handled promptly.
  4. WebSocket connections remain active.
  5. Concurrent processing of multiple accounts, with each account running independently.

Error Handling

The adapter provides a comprehensive error handling mechanism:

  1. Automatic reconnection for network connection exceptions (supports independent reconnection for each account, with a 30-second interval)
  2. Handling of API call timeouts (fixed 30-second timeout)
  3. Automatic retry at intervals when connection fails

Event Handling Enhancements

In multi-account mode, all events automatically include account information:

{
    "type": "message",
    "detail_type": "private",
    "self": {"user_id": "123456789", "platform": "onebot11"},
    "platform": "onebot11",
    // ... other event fields
}

The adapter automatically maintains the self_id → account_name mapping, allowing event.reply() to correctly route back to the originating account without manually specifying the account.

Management Interface

# Get all account information
accounts = onebot.accounts

# Check account connection status
connection_status = {
    account_id: connection is not None and not connection.closed
    for account_id, connection in onebot.connections.items()
}

# Dynamically enable/disable accounts (adapter needs to be restarted)
onebot.accounts["test"].enabled = False

self_id Auto Mapping

The adapter automatically establishes a mapping between OneBot self_id (QQ number) and account_name, which is used for event routing:

# Automatically completed by the adapter internally
# When an event is received, the self.user_id field is filled with bot_id
# The adapter automatically records: self_id("123456789") → account_name("main")

# Therefore, event.reply() can automatically find the correct account to send messages
@message.on_message()
async def handler(event):
    await event.reply("Automatically routed to the correct account")