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

OneBot11 平台特性文件

OneBot11Adapter 是基於 OneBot V11 協議所建構的適配器。


docs/zh-TW/quick-start.md

文件資訊

基本資訊

v5 範式更新(4.3.0)

本適配器已完成 v5 範式對齊(增量升級,API 兼容):

已有能力(4.2.0 起支援):多帳號、Api DSL 標準動作映射(get_self_info→get_login_info 等)、Request DSL(好友/群請求審批:event.approve() / event.reject())、EventMixin、i18n。

標準 Api 動作(Api DSL)

適配器將 OneBot12 標準動作名自動映射到 OB11 動作名,模組可跨平台統一呼叫:

OB12 標準動作 OB11 動作 說明
get_self_info get_login_info 欄位標準化 user_id/user_name/user_displayname
get_user_info get_stranger_info 欄位標準化
delete_message delete_msg 撤回訊息
leave_group set_group_leave 退出群
get_friend_list get_friend_list 動作名一致,預設透傳
get_group_info get_group_info 動作名一致,預設透傳
upload_file upload_group_file / upload_private_file 擴展 group_id/user_id 可選參數,filetype 自動偵測類型路由

基本用法

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

# 獲取機器人資訊
result = await onebot.Api.get_self_info()
print(result["data"]["user_id"], result["data"]["user_name"])

# 撤回訊息
await onebot.Api.delete_message(message_id=123456)

# 上傳群檔案(filetype 自動偵測類型路由到 upload_group_file)
result = await onebot.Api.upload_file(group_id=123456, file="/path/to/file.zip")

# 指定帳戶(多帳戶)
result = await onebot.Api.Using("main").get_self_info()

# 未映射的 OB11 動作透過 call() 逃生艙呼叫(NapCat/Lagrange 等擴展通用)
result = await onebot.Api.call("send_poke", group_id=123, user_id=456)

支援的消息發送類型

所有發送方法均透過鏈式語法實現,例如:

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

# 使用預設帳戶發送
await onebot.Send.To("group", group_id).Text("Hello World!")

# 指定特定帳戶發送
await onebot.Send.Using("main").To("group", group_id).Text("來自主帳戶的消息")

# 鏈式修飾:@使用者 + 回覆
await onebot.Send.To("group", group_id).At(123456).Reply(msg_id).Text("回覆訊息")

# @全體成員
await onebot.Send.To("group", group_id).AtAll().Text("公告訊息")

基礎發送方法

群操作方法

以下方法需透過 To("group", group_id) 指定目標群,使用群上下文執行操作:

查詢方法

好友操作方法

鏈式修飾方法(可組合使用)

鏈式修飾方法返回 self,支援鏈式呼叫,必須在最終發送方法前呼叫:

鏈式呼叫示例

# 基礎發送
await onebot.Send.To("group", 123456).Text("Hello")

# @單個使用者
await onebot.Send.To("group", 123456).At(789012).Text("你好")

# @多個使用者
await onebot.Send.To("group", 123456).At(111).At(222).At(333).Text("大家好")

# 發送 OneBot12 格式訊息
ob12_msg = [{"type": "text", "data": {"text": "Hello"}}]
await onebot.Send.To("group", 123456).Raw_ob12(ob12_msg)

# 點讚
await onebot.Send.Like(123456, times=10)

# 禁言群成員
await onebot.Send.To("group", 123456).Ban(789012, duration=3600)

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

# 踢人
await onebot.Send.To("group", 123456).Kick(789012)

# 設定群管理員
await onebot.Send.To("group", 123456).SetAdmin(789012)

# 修改群名
await onebot.Send.To("group", 123456).SetGroupName("新群名")

# 獲取群資訊
result = await onebot.Send.To("group", 123456).GetGroupInfo()

# 指定帳戶操作
await onebot.Send.Using("main").To("group", 123456).Ban(789012)

不支援的類型處理

如果呼叫未定義的發送方法,適配器會回傳文字提示:

# 呼叫不存在的方法
await onebot.Send.To("group", 123456).SomeUnsupportedMethod(arg1, arg2)
# 實際發送: "[不支援的發送類型] 方法名: SomeUnsupportedMethod, 參數: [...]"

請求操作(Request DSL)

適配器提供請求操作 DSL,用於處理好友請求和群請求(加群/邀請)的同意/拒絕操作。

Event 快捷方法

請求事件支援 event.approve() 和 event.reject() 快捷方法,內部自動呼叫 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()

手動呼叫 Request DSL

# 同意請求
await onebot.Request("flag_string").accept()

# 拒絕請求
await onebot.Request("flag_string").reject()

# 指定帳戶操作
await onebot.Request("flag_string").Using("main").accept()

完整範例

from ErisPulse.Core.Event import request

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

    # 方法一:使用 Event 快捷方法
    if comment == "passphrase":
        await event.approve()
    else:
        await event.reject()

    # 方法二:使用 Request DSL
    flag = event.get("flag")
    if comment == "passphrase":
        await onebot.Request(flag).accept()
    else:
        await onebot.Request(flag).reject()

請求操作回傳值

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

事件類型映射

標準 OB12 映射

OB11 原始類型 轉換後 detail_type 說明
message_type: private private 私聊消息
message_type: group group 群聊消息
request_type: friend friend 好友請求
request_type: group group 群請求
meta_event_type: heartbeat heartbeat 心跳
notice_type: group_upload group_file_upload 群文件上傳
notice_type: group_admin group_admin_change 群管理員變動
notice_type: group_increase group_member_increase 群成員增加
notice_type: group_decrease group_member_decrease 群成員減少
notice_type: group_ban group_ban 群禁言
notice_type: friend_add friend_increase 好友添加
notice_type: friend_delete friend_decrease 好友刪除
notice_type: group_recall / friend_recall message_recall 消息撤回

平台特有事件(onebot11_ 前綴)

OB11 原始類型 轉換後 detail_type 說明
meta_event_type: lifecycle onebot11_lifecycle OneBot 實現生命週期
notify + sub_type: honor onebot11_honor 群榮譽變更
notify + sub_type: poke onebot11_poke 戳一戳
notify + sub_type: lucky_king onebot11_lucky_king 群紅包運氣王
CQ 碼未知類型 消息段 onebot11_{type} 未識別的 CQ 碼

事件示例

// 好友請求
{
  "type": "request",
  "detail_type": "friend",
  "user_id": "789012",
  "comment": "請加好友",
  "request_id": "flag_abc123",
  "flag": "flag_abc123"
}

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

// 生命週期(平台特有)
{
  "type": "meta_event",
  "detail_type": "onebot11_lifecycle",
  "sub_type": "enable"
}

// 戳一戳(平台特有)
{
  "type": "notice",
  "detail_type": "onebot11_poke",
  "group_id": "123456",
  "user_id": "789012",
  "target_id": "345678"
}

// 群紅包運氣王(平台特有)
{
  "type": "notice",
  "detail_type": "onebot11_lucky_king",
  "group_id": "123456",
  "user_id": "789012",
  "target_id": "345678"
}

// 榮譽變更(平台特有)
{
  "type": "notice",
  "detail_type": "onebot11_honor",
  "group_id": "123456",
  "user_id": "789012",
  "honor_type": "talkative"
}

// CQ 碼擴展消息段
{
  "type": "message",
  "message": [
    {"type": "onebot11_shake", "data": {}}
  ]
}

擴展欄位說明

事件擴展方法

OneBot11 适配器為事件物件註冊了以下平台專有方法,可在事件處理器中直接調用:

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()

方法列表

方法 回傳類型 說明
get_raw_event() dict 取得 OneBot11 完整原始事件資料
get_raw_self_id() str 取得原始 self_id(Bot 的 QQ 號)
get_sender_info() dict 取得完整的發送者資訊(包含 nickname、role、level 等)
get_sender_role() str 取得發送者在群內的角色(owner/admin/member)
get_sender_level() int 取得發送者等級
get_sender_title() str 取得發送者群頭銜
is_system_message() bool 判斷是否為系統訊息(sub_type == "system")

使用範例

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("管理員好!")

    title = event.get_sender_title()
    if title:
        await event.reply(f"你的頭銜是: {title}")

@command("whoami")
async def whoami(event):
    info = event.get_sender_info()
    nickname = info.get("nickname", "未知")
    level = event.get_sender_level()
    await event.reply(f"暱稱: {nickname}, 等級: {level}")

配置選項

OneBot11 适配器采用多账户架構,每個帳戶獨立配置。配置鍵名為 OneBotAdapter。

帳戶配置字段

字段 類型 必填 默認值 說明
bot_id str 是 "" 機器人 QQ 號,用於標識帳戶
mode str 否 "server" 運行模式:"server"(被動監聽)或 "client"(主動連接)
url str 否 "ws://127.0.0.1:3001" Client 模式的 WebSocket 位址
token str 否 "" 認證 Token(Client 模式連接 Token / Server 模式驗證 Token)
server_path str 否 "/" Server 模式的 WebSocket 路徑
enabled bool 否 true 是否啟用該帳戶
name str 否 "" 帳戶備註名稱

內建預設值

配置示例

[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

預設配置

如果未配置任何帳戶,適配器會自動創建:

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

發送方法返回值

所有發送方法均返回一個 Task 對象,可以直接 await 獲取發送結果。返回結果遵循 ErisPulse 适配器标准化返回规范:

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

多賬戶發送語法

# 賬戶選擇方法
await onebot.Send.Using("main").To("group", 123456).Text("主賬戶消息")
await onebot.Send.Using("backup").To("group", 123456).Image("http://example.com/image.jpg")

# 通過 bot_id 選擇賬戶
await onebot.Send.Using("123456789").To("group", 123456).Text("通過QQ號選擇")

# API調用方式
await onebot.call_api("send_msg", account_id="main", group_id=123456, message="Hello")

賬戶解析優先級

call_api 和 Using() 中 account_id 參數的解析優先級:

  1. 精確匹配賬戶名稱
  2. 匹配 bot_id 字段
  3. 匹配賬戶的任意 str 類型字段
  4. 回退到第一個已啟用的賬戶

異步處理機制

OneBot11 適配器採用異步非阻塞設計,確保:

  1. 消息發送不會阻塞事件處理循環
  2. 多個併發發送操作可以同時進行
  3. API 回應能夠即時處理
  4. WebSocket 連接保持活躍狀態
  5. 多帳號併發處理,每個帳號獨立運行

錯誤處理

適配器提供完善的錯誤處理機制:

  1. 網路連接異常自動重連(支援每個帳戶獨立重連,間隔30秒)
  2. API 呼叫超時處理(固定30秒超時)
  3. 連接失敗時自動按間隔重試

事件處理增強

多賬戶模式下,所有事件都會自動添加賬戶資訊:

{
    "type": "message",
    "detail_type": "private",
    "self": {"user_id": "123456789", "platform": "onebot11"},
    "platform": "onebot11",
    // ... 其他事件欄位
}

適配器自動維護 self_id → account_name 映射,event.reply() 無需手動指定賬戶即可正確路由到來源賬戶。

管理介面

# 獲取所有帳戶資訊
accounts = onebot.accounts

# 檢查帳戶連接狀態
connection_status = {
    account_id: connection is not None and not connection.closed
    for account_id, connection in onebot.connections.items()
}

# 動態啟用/停用帳戶(需要重新啟動適配器)
onebot.accounts["test"].enabled = False

self_id 自動映射

適配器會自動建立 OneBot self_id(QQ號)到 account_name 的映射關係,用於事件回傳路由:

# 適配器內部自動完成
# 當收到事件時,self.user_id 欄位填入為 bot_id
# 適配器自動記錄: self_id("123456789") → account_name("main")

# 因此 event.reply() 可以自動找到正確的帳戶發送訊息
@message.on_message()
async def handler(event):
    await event.reply("自動路由到正確的帳戶")