OneBot11 Platform Feature Documentation
OneBot11Adapter is an adapter built based on the OneBot V11 protocol.
Document Information
- Corresponding Module Version: 4.3.0
- Maintainer: ErisPulse
Basic Information
- Platform Introduction: OneBot is a chatbot application interface standard
- Adapter Name: OneBotAdapter
- Supported Protocol/API Version: OneBot V11
- Multi-account Support: Default multi-account architecture, supports configuring and running multiple OneBot accounts simultaneously
- Configuration Key Name:
OneBotAdapter
v5 Paradigm Update (4.3.0)
The adapter has completed alignment with the v5 paradigm (incremental upgrade, API compatible):
- BaseConverter Inheritance: Common fields of converters (id/time/platform/self/raw) are built by the framework's build_base_event, and are overridden according to OB11 field names (echo/time/self_id).
- spawn_background Task Ownership: For Client mode connections, the task now uses runtime.spawn_background (owner assignment, automatic shutdown cleanup).
- Framework Soft Dependency: Installing the adapter no longer declares a hard dependency on ErisPulse, avoiding pip resolution issues when adjusting framework versions; at runtime, it checks for ErisPulse>=2.7.1 and logs a warning if the version is too low.
- Startup Version Log: Outputs "OneBotAdapter v4.3.0 loaded" during initialization.
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
.Text(text: str): Sends plain text messages..Image(file: Union[str, bytes], filename: str = "image.png"): Sends images (supports URL, Base64, or bytes)..Voice(file: Union[str, bytes], filename: str = "voice.amr"): Sends voice messages..Video(file: Union[str, bytes], filename: str = "video.mp4"): Sends video messages..Face(id: Union[str, int]): Sends QQ emoticons..File(file: Union[str, bytes], filename: str = "file.dat"): Sends files (automatically detects type)..Raw_ob12(message: List[Dict], **kwargs): Sends OneBot12 format messages (automatically converts to OB11)..Recall(message_id: Union[str, int]): Recalls a message.
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:
.Kick(user_id, reject_add_request=False): Kicks a group member..Ban(user_id, duration=1800): Mutes a group member (duration in seconds; 0 means unmute)..WholeBan(enable=True): Enables/Disables global mute for the group..SetAdmin(user_id, enable=True): Sets/unsets a group admin..SetCard(user_id, card=""): Sets a group member's nickname..SetGroupName(name): Changes the group name..Leave(is_dismiss=False): Leaves the group (group owner can dismiss)..SetTitle(user_id, title=""): Sets a group title for a member..SetPortrait(file): Sets the group portrait.
Query Methods
.GetMsg(message_id): Retrieves the content of a message..GetForwardMsg(id): Retrieves a forwarded message..GetLoginInfo(): Retrieves information about the current logged-in account..GetFriendList(): Retrieves the friend list..GetGroupInfo(): Retrieves group information (requiresTo("group", group_id))..GetGroupList(): Retrieves the list of groups..GetGroupMemberInfo(user_id): Retrieves group member information (requiresTo("group", group_id))..GetGroupMemberList(): Retrieves the list of group members (requiresTo("group", group_id)).
Friend Operation Methods
.Like(user_id, times=1): Sends a like to a friend (maximum 10 times).
Chained Modifier Methods (Combinable)
Chained modifier methods return self, enabling fluent chaining, and must be called before the final sending method:
.At(user_id: Union[str, int], name: str = None): Mentions a specific user (can be called multiple times)..AtAll(): Mentions all group members..Reply(message_id: Union[str, int]): Replies to a specific message.
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
- All specific fields are prefixed with
onebot11_ - Original event data is retained in the
onebot11_rawfield - Original event type is retained in the
onebot11_raw_typefield - CQ codes within message content are converted into corresponding message segments (standard types without prefix, unknown types with
onebot11_prefix) - Reply messages add a
replytype message segment - @ messages add a
mentiontype message segment
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
- Reconnection interval: 30 seconds
- API call timeout: 30 seconds
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():
- Exact match with account name
- Match
bot_idfield - Match any
strtype field of the account - Fall back to the first enabled account
Asynchronous Processing Mechanism
The OneBot11 adapter adopts an asynchronous non-blocking design, ensuring that:
- Message sending does not block the event handling loop.
- Multiple concurrent sending operations can proceed simultaneously.
- API responses can be handled promptly.
- WebSocket connections remain active.
- Concurrent processing of multiple accounts, with each account running independently.
Error Handling
The adapter provides a comprehensive error handling mechanism:
- Automatic reconnection for network connection exceptions (supports independent reconnection for each account, with a 30-second interval)
- Handling of API call timeouts (fixed 30-second timeout)
- 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")