OneBot12 Platform Feature Documentation
OneBot12Adapter is an adapter built based on the OneBot V12 protocol, serving as the baseline protocol adapter for the ErisPulse framework.
Document Information
- Corresponding Module Version: 4.3.0
- Maintainer: ErisPulse
- Protocol Version: OneBot V12
Basic Information
- Platform Overview: OneBot V12 is a general-purpose chatbot application interface standard, serving as the baseline protocol for the ErisPulse framework.
- Adapter Name: OneBot12Adapter
- Supported Protocol/API Version: OneBot V12
- Multi-Account Support: Fully multi-account architecture, supporting the configuration and operation of multiple OneBot12 accounts simultaneously.
v5 Paradigm Update (4.3.0)
This adapter has completed alignment with the v5 paradigm (incremental upgrade, API compatible):
- BaseConverter Inheritance: Common fields of the converter (id/time/platform/self/raw) are built by the framework's
build_base_event, and are overridden by OB11 field names (echo/time/self_id). - spawn_background Task Ownership: The Client mode connection 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 that adjust framework versions; at runtime, ErisPulse>=2.7.1 is detected, and a log warning is issued 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, standard API DSL action mapping (e.g., get_self_info → get_login_info), Request DSL (friend/group request approval: event.approve() / event.reject()), EventMixin, i18n.
Standard API Actions (Api DSL)
OneBot12 backends natively support all OB12 standard action names. The Api DSL is by default directly delegated to call_api for transparent transmission (no mapping required):
from ErisPulse import sdk
ob12 = sdk.adapter.get("onebot12")
result = await ob12.Api.get_self_info()
result = await ob12.Api.get_friend_list()
await ob12.Api.delete_message(message_id="MSG_ID")
# Specify account (multi-account)
result = await ob12.Api.Using("main").get_self_info()
# Platform extension actions
result = await ob12.Api.call("extend_action", param=1)
Supported actions are subject to backend implementation (NapCat/Lagrange/LLOneBot, etc.); unsupported actions will return errors from the backend and be transparently transmitted.
Request Operations (Request DSL)
Based on the OneBot12 standard handle_quick_request action, handle the approval/rejection of friend requests and group invitation requests:
Event Convenience Methods
from ErisPulse.Core.Event import request
@request.on_friend_request()
async def handle_friend_request(event):
if event.get("platform") != "onebot12":
return
comment = event.get("comment", "")
if comment == "passphrase":
await event.approve() # Approve
else:
await event.reject() # Reject
Manual Request DSL Calls
await ob12.Request("request_flag").accept()
await ob12.Request("request_flag").reject()
await ob12.Request("request_flag").Using("main").accept()
Supported Message Sending Types
All sending methods are implemented using a fluent interface syntax, for example:
from ErisPulse.Core import adapter
onebot12 = adapter.get("onebot12")
# Send using the default account
await onebot12.Send.To("group", group_id).Text("Hello World!")
# Specify a particular account for sending
await onebot12.Send.To("group", group_id).Account("main").Text("Message from main account")
Case-Insensitive Method Calls
All sending methods and fluent modifiers support case-insensitive calls, and the adapter automatically maps them to the correct standard method names:
# All of the following calls are equivalent
await onebot12.Send.To("user", 123).Text("hello")
await onebot12.Send.To("user", 123).text("hello")
await onebot12.Send.To("user", 123).TEXT("hello")
# Fluent modifiers also support case-insensitivity
await onebot12.Send.To("group", 123).At(456).Text("hello")
await onebot12.Send.To("group", 123).at(456).TEXT("hello")
await onebot12.Send.To("group", 123).AT(456).text("hello")
Unsupported Method Calls
When calling an unsupported method, the adapter returns a friendly text message instead of throwing an exception:
# Calling an unsupported method
result = await onebot12.Send.To("user", 123).UnsupportedMethod("test")
# The returned result is the sent text message
# Message content: [Unsupported sending type] Method name: UnsupportedMethod, Parameters: [args[0]: 'test']
Basic Message Types
.Text(text: str)- Send plain text message.Image(file: Union[str, bytes], filename: str = "image.png")- Send image message (supports URL, Base64, or bytes).Audio(file: Union[str, bytes], filename: str = "audio.ogg")- Send audio message.Voice(file: Union[str, bytes], filename: str = "voice.ogg")- Send voice message (alias of Audio, compatible with OneBot11).Video(file: Union[str, bytes], filename: str = "video.mp4")- Send video message
Fluent Modifier Methods (return self to support fluent chaining)
.At(user_id: Union[str, int])- Mention user (can be called multiple times).AtAll()- Mention all group members.Reply(message_id: Union[str, int])- Reply to a message
Raw Message Sending
.Raw_ob12(message: Union[Dict, List[Dict]], **kwargs)- Send raw OneBot12 format message (follows naming conventions)
Other Message Types
.Sticker(file_id: str)- Send sticker/gift.Location(latitude: float, longitude: float, title: str = "", content: str = "")- Send location
Management Functions
.Recall(message_id: Union[str, int])- Recall message.Edit(message_id: Union[str, int], content: Union[str, List[Dict]])- Edit message.Raw(message_segments: List[Dict])- Send native OneBot12 message segments.Batch(target_ids: List[str], message: Union[str, List[Dict]], target_type: str = "user")- Batch send messages
OneBot12 Standard Events
The OneBot12 adapter fully complies with the OneBot12 standard, and event formats do not require conversion, they are directly submitted to the framework.
New Feature: Raw Event Type Field
In accordance with the standards/event-conversion.md specification, all events will retain the raw event type field onebot12_raw_type:
{
"id": "event-id",
"type": "message", # Event type
"onebot12_raw_type": "message", # Raw event type (same as type)
"detail_type": "private",
"self": {"user_id": "bot-id"},
"user_id": "user-id",
"message": [{"type": "text", "data": {"text": "Hello"}}],
"alt_message": "Hello",
"time": 1234567890
}
Message Events
# Private message
{
"id": "event-id",
"type": "message",
"onebot12_raw_type": "message",
"detail_type": "private",
"self": {"user_id": "bot-id"},
"user_id": "user-id",
"message": [{"type": "text", "data": {"text": "Hello"}}],
"alt_message": "Hello",
"time": 1234567890
}
# Group message
{
"id": "event-id",
"type": "message",
"onebot12_raw_type": "message",
"detail_type": "group",
"self": {"user_id": "bot-id"},
"user_id": "user-id",
"group_id": "group-id",
"message": [{"type": "text", "data": {"text": "Hello group"}}],
"alt_message": "Hello group",
"time": 1234567890
}
Notice Events
# Group member increase
{
"id": "event-id",
"type": "notice",
"onebot12_raw_type": "notice",
"detail_type": "group_member_increase",
"self": {"user_id": "bot-id"},
"group_id": "group-id",
"user_id": "user-id",
"operator_id": "operator-id",
"sub_type": "approve",
"time": 1234567890
}
# Group member decrease
{
"id": "event-id",
"type": "notice",
"onebot12_raw_type": "notice",
"detail_type": "group_member_decrease",
"self": {"user_id": "bot-id"},
"group_id": "group-id",
"user_id": "user-id",
"operator_id": "operator-id",
"sub_type": "leave",
"time": 1234567890
}
Request Events
# Friend request
{
"id": "event-id",
"type": "request",
"onebot12_raw_type": "request",
"detail_type": "friend",
"self": {"user_id": "bot-id"},
"user_id": "user-id",
"comment": "申请消息",
"flag": "request-flag",
"time": 1234567890
}
# Group invitation request
{
"id": "event-id",
"type": "request",
"onebot12_raw_type": "request",
"detail_type": "group",
"self": {"user_id": "bot-id"},
"group_id": "group-id",
"user_id": "user-id",
"comment": "申请消息",
"flag": "request-flag",
"sub_type": "invite",
"time": 1234567890
}
Meta Events
# Lifecycle event
{
"id": "event-id",
"type": "meta_event",
"onebot12_raw_type": "meta_event",
"detail_type": "lifecycle",
"self": {"user_id": "bot-id"},
"sub_type": "enable",
"time": 1234567890
}
# Heartbeat event
{
"id": "event-id",
"type": "meta_event",
"onebot12_raw_type": "meta_event",
"detail_type": "heartbeat",
"self": {"user_id": "bot-id"},
"interval": 5000,
"status": {"online": true},
"time": 1234567890
}
Configuration Options
Account Configuration
Each account has the following independent configuration options:
mode: The running mode of the account ("server" or "client")server_path: The WebSocket path for Server modeserver_token: The authentication token for Server mode (optional)client_url: The WebSocket address to connect to in Client modeclient_token: The authentication token for Client mode (optional)enabled: Whether to enable this accountplatform: The platform identifier, default is "onebot12"implementation: The implementation identifier, such as "go-cqhttp" (optional)
Configuration Example
[OneBotv12_Adapter.accounts.main]
mode = "server"
server_path = "/onebot12-main"
server_token = "main_token"
enabled = true
platform = "onebot12"
implementation = "go-cqhttp"
[OneBotv12_Adapter.accounts.backup]
mode = "client"
client_url = "ws://127.0.0.1:3002"
client_token = "backup_token"
enabled = true
platform = "onebot12"
implementation = "shinonome"
[OneBotv12_Adapter.accounts.test]
mode = "client"
client_url = "ws://127.0.0.1:3003"
enabled = false
Default Configuration
If no accounts are configured, the adapter will automatically create:
[OneBotv12_Adapter.accounts.default]
mode = "server"
server_path = "/onebot12"
enabled = true
platform = "onebot12"
Return Values of Send Methods
Message Sending Methods
All message sending methods (such as .Text(), .Image(), .Raw_ob12() etc.) return an asyncio.Task object, which can be awaited directly to obtain the sending result:
task = await onebot12.Send.To("group", 123456).Text("Hello")
Chained Modifier Methods
All chained modifier methods (such as .At(), .AtAll(), .Reply()) return self, supporting chained calls:
# Combining multiple modifier methods
await onebot12.Send.To("group", 123456).Reply("msg123").At(789).At(790).Text("Text")
API Response Standard
Adapters follow the ErisPulse standardized response specification (standards/api-response.md):
# Success Response
{
"status": "ok", # Required: execution status
"retcode": 0, # Required: return code (0 indicates success)
"data": { # Required: response data
"message_id": "123456",
"time": 1632847927.599013
},
"message_id": "123456", # Required: message ID (empty string if not present)
"message": "", # Required: error message (empty if successful)
"echo": "1234", # Optional: echo value from the request returned as-is
"onebot12_raw": {...} # Optional: raw response data
}
# Failure Response
{
"status": "failed", # Required: execution status
"retcode": 10003, # Required: return code (non-zero indicates failure)
"data": None, # Required: null for failures
"message_id": "", # Required: empty string for failures
"message": "Missing required parameters", # Required: error description
"echo": "1234", # Optional: echo value from the request returned as-is
"onebot12_raw": {...} # Optional: raw response data
}
Error Code Specification
Follows OneBot12 standard error codes:
- 0: Success
- 1xxxx: Action request error
- 2xxxx: Action processor error
- 3xxxx: Action execution error (33001 indicates network timeout)
Multi-Account Sending Syntax
# Account selection methods
await onebot12.Send.Using("main").To("group", 123456).Text("Main account message")
await onebot12.Send.Using("backup").To("group", 123456).Image("http://example.com/image.jpg")
# API call method
await onebot12.call_api("send_message", account_id="main",
detail_type="group", group_id=123456,
content=[{"type": "text", "data": {"text": "Hello"}}])
Asynchronous Processing Mechanism
The OneBot12 adapter adopts an asynchronous non-blocking design:
- Message sending does not block the event handling loop.
- Multiple concurrent sending operations can be performed simultaneously.
- API responses can be handled promptly.
- WebSocket connections remain active.
- Concurrent processing of multiple accounts, with each account running independently.
Error Handling
Adapters provide a comprehensive error handling mechanism:
- Automatic reconnection for network connection exceptions (supports independent reconnection for each account, with a 30-second interval)
- Handling API call timeouts (fixed 30-second timeout)
- Automatic retry for failed message sending (up to 3 retries)
- Calling unsupported methods will return a friendly text prompt
Event Handling Enhancement
In multi-account mode, all events will automatically have account information added:
{
"type": "message",
"onebot12_raw_type": "message", // Original event type
"detail_type": "private",
"self": {"user_id": "123456"}, // The account ID that sent the event (standard field)
"platform": "onebot12",
// ... other event fields
}
Management Interface
# Get all account information
accounts = onebot12.accounts
# Check account connection status
connection_status = {
account_id: connection is not None and not connection.closed
for account_id, connection in oneobot12.connections.items()
}
# Dynamically enable/disable account (adapter needs to be restarted)
onebot12.accounts["test"].enabled = False
OneBot12 Standard Features
Message Segment Standard
OneBot12 uses a standardized message segment format:
# Text message segment
{"type": "text", "data": {"text": "Hello"}}
# Image message segment
{"type": "image", "data": {"file_id": "image-id"}}
# Mention message segment
{"type": "mention", "data": {"user_id": "user-id", "user_name": "Username"}}
# Reply message segment
{"type": "reply", "data": {"message_id": "msg-id"}}
API Standard
Follows the OneBot12 standard API specification:
send_message: Send a messagedelete_message: Recall a messageedit_message: Edit a messageget_message: Retrieve a messageget_self_info: Get self informationget_user_info: Get user informationget_group_info: Get group information
Best Practices
- Configuration Management: It is recommended to use multi-account configurations to manage robots with different purposes separately.
- Error Handling: Always check the return status of API calls.
- Message Sending: Use appropriate message types to avoid sending unsupported messages.
- Connection Monitoring: Regularly check the connection status to ensure service availability.
- Performance Optimization: When sending in batches, use the Batch method to reduce network overhead.
- Method Calls: It is recommended to use standard PascalCase naming (e.g.,
.Text()), but lowercase forms are also supported for compatibility with different programming styles (this approach may be incompatible with older versions).