OneBot 11 协议完整调用文档
本文档详细介绍 OneBot 11 标准协议的所有 API 接口、事件类型、消息段格式及完整示例。
适用于:NapCatQQ、go-cqhttp、OpenShamrock 等 OneBot 11 实现
目录
1. 协议概述
OneBot 11 是一个聊天机器人应用接口标准,定义了:
- 统一的 API 调用格式
- 统一的事件上报格式
- 统一的消息段(Message Segment)格式
1.1 请求格式
HTTP API 请求格式:
POST /api_endpoint
Content-Type: application/json
{
"param1": "value1",
"param2": "value2"
}WebSocket API 请求格式:
{
"action": "api_name",
"params": {
"param1": "value1",
"param2": "value2"
},
"echo": "optional_identifier"
}1.2 响应格式
标准响应结构:
{
"status": "ok", // 状态: ok/failed/async
"retcode": 0, // 返回码: 0=成功, 其他=失败
"data": {}, // 响应数据
"message": "", // 错误信息(失败时)
"wording": "", // 用户友好的错误信息
"echo": "identifier" // 请求时的echo字段
}2. 通信方式
2.1 HTTP 通信
HTTP POST (调用 API)
curl -X POST http://127.0.0.1:5700/send_private_msg \
-H "Content-Type: application/json" \
-d '{"user_id": 123456, "message": "你好"}'HTTP POST (接收事件)
需要在 OneBot 配置中设置上报地址,OneBot 会将事件 POST 到指定 URL。
2.2 WebSocket 通信
正向 WebSocket (客户端连接到 OneBot)
const ws = new WebSocket('ws://127.0.0.1:6700');
// 发送API请求
ws.send(JSON.stringify({
action: "send_private_msg",
params: {
user_id: 123456,
message: "你好"
},
echo: "request_1"
}));
// 接收响应和事件
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(data);
};反向 WebSocket (OneBot 连接到服务器)
在 OneBot 配置中设置反向 WebSocket 地址,OneBot 会主动连接。
3. API 接口
3.1 消息发送
3.1.1 发送私聊消息
接口: send_private_msg
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| user_id | int64 | 是 | 对方 QQ 号 |
| message | message | 是 | 要发送的内容 |
| auto_escape | boolean | 否 | 消息内容是否作为纯文本发送(不解析CQ码) |
请求示例:
{
"user_id": 123456789,
"message": "你好,这是一条私聊消息"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"message_id": 123456
}
}消息段示例:
{
"user_id": 123456789,
"message": [
{
"type": "text",
"data": {
"text": "你好,"
}
},
{
"type": "face",
"data": {
"id": "123"
}
}
]
}3.1.2 发送群消息
接口: send_group_msg
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| message | message | 是 | 要发送的内容 |
| auto_escape | boolean | 否 | 消息内容是否作为纯文本发送 |
请求示例:
{
"group_id": 987654321,
"message": "大家好!"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"message_id": 654321
}
}3.1.3 发送消息(统一接口)
接口: send_msg
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| message_type | string | 否 | 消息类型: private/group |
| user_id | int64 | 否 | 对方 QQ 号(私聊时必填) |
| group_id | int64 | 否 | 群号(群聊时必填) |
| message | message | 是 | 要发送的内容 |
| auto_escape | boolean | 否 | 是否作为纯文本 |
请求示例:
{
"message_type": "group",
"group_id": 987654321,
"message": "统一发送接口测试"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"message_id": 789012
}
}3.1.4 发送合并转发(群聊)
接口: send_group_forward_msg
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| messages | array | 是 | 自定义转发消息 |
请求示例:
{
"group_id": 987654321,
"messages": [
{
"type": "node",
"data": {
"name": "消息发送者A",
"uin": "10001000",
"content": "第一条消息内容"
}
},
{
"type": "node",
"data": {
"name": "消息发送者B",
"uin": "10002000",
"content": "第二条消息内容"
}
}
]
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"message_id": 111222,
"forward_id": "abcd1234"
}
}3.1.5 发送合并转发(好友)
接口: send_private_forward_msg
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| user_id | int64 | 是 | 对方 QQ 号 |
| messages | array | 是 | 自定义转发消息 |
请求示例:
{
"user_id": 123456789,
"messages": [
{
"type": "node",
"data": {
"name": "发送者",
"uin": "10001000",
"content": "转发消息内容"
}
}
]
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"message_id": 333444,
"forward_id": "xyz789"
}
}3.2 消息操作
3.2.1 撤回消息
接口: delete_msg
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| message_id | int32 | 是 | 消息 ID |
请求示例:
{
"message_id": 123456
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.2.2 获取消息
接口: get_msg
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| message_id | int32 | 是 | 消息 ID |
请求示例:
{
"message_id": 123456
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"time": 1234567890,
"message_type": "group",
"message_id": 123456,
"real_id": 789012,
"sender": {
"user_id": 987654321,
"nickname": "发送者昵称",
"card": "群名片",
"sex": "male",
"age": 20,
"area": "中国",
"level": "10",
"role": "member",
"title": "群头衔"
},
"message": [
{
"type": "text",
"data": {
"text": "消息内容"
}
}
]
}
}3.2.3 获取合并转发内容
接口: get_forward_msg
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string | 是 | 合并转发 ID |
请求示例:
{
"id": "abcd1234efgh5678"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"messages": [
{
"time": 1234567890,
"message_type": "group",
"message_id": 111,
"real_id": 222,
"sender": {
"user_id": 123456,
"nickname": "发送者A"
},
"message": [
{
"type": "text",
"data": {
"text": "第一条消息"
}
}
]
},
{
"time": 1234567891,
"message_type": "group",
"message_id": 333,
"real_id": 444,
"sender": {
"user_id": 654321,
"nickname": "发送者B"
},
"message": [
{
"type": "text",
"data": {
"text": "第二条消息"
}
}
]
}
]
}
}3.2.4 标记消息已读
接口: mark_msg_as_read
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| message_id | int32 | 是 | 消息 ID |
请求示例:
{
"message_id": 123456
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.3 群组管理
3.3.1 设置群名
接口: set_group_name
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| group_name | string | 是 | 新群名 |
请求示例:
{
"group_id": 987654321,
"group_name": "新的群名称"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.3.2 设置群头像
接口: set_group_portrait
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| file | string | 是 | 图片文件路径或URL |
| cache | int | 否 | 是否使用缓存,0不使用,1使用 |
请求示例:
{
"group_id": 987654321,
"file": "file:///C:/Users/Admin/avatar.jpg",
"cache": 0
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.3.3 设置群管理员
接口: set_group_admin
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| user_id | int64 | 是 | 要设置的 QQ 号 |
| enable | boolean | 是 | true 为设置,false 为取消 |
请求示例:
{
"group_id": 987654321,
"user_id": 123456789,
"enable": true
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.3.4 设置群名片
接口: set_group_card
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| user_id | int64 | 是 | 要设置的 QQ 号 |
| card | string | 否 | 群名片内容,不填或空字符串表示删除 |
请求示例:
{
"group_id": 987654321,
"user_id": 123456789,
"card": "新的群名片"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.3.5 设置群专属头衔
接口: set_group_special_title
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| user_id | int64 | 是 | 要设置的 QQ 号 |
| special_title | string | 否 | 专属头衔,不填或空字符串表示删除 |
| duration | int64 | 否 | 专属头衔有效期,单位秒,-1 表示永久 |
请求示例:
{
"group_id": 987654321,
"user_id": 123456789,
"special_title": "群大佬",
"duration": -1
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.3.6 退出群组
接口: set_group_leave
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| is_dismiss | boolean | 否 | 是否解散,仅在是群主时有效 |
请求示例:
{
"group_id": 987654321,
"is_dismiss": false
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.3.7 全员禁言
接口: set_group_whole_ban
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| enable | boolean | 是 | 是否禁言 |
请求示例:
{
"group_id": 987654321,
"enable": true
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.4 群成员管理
3.4.1 群单人禁言
接口: set_group_ban
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| user_id | int64 | 是 | 要禁言的 QQ 号 |
| duration | int64 | 否 | 禁言时长,单位秒,0 表示取消禁言 |
请求示例:
{
"group_id": 987654321,
"user_id": 123456789,
"duration": 600
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.4.2 群匿名用户禁言
接口: set_group_anonymous_ban
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| anonymous | object | 否 | 匿名用户对象(来自上报) |
| anonymous_flag | string | 否 | 匿名用户标识(来自上报) |
| duration | int64 | 否 | 禁言时长,单位秒 |
请求示例:
{
"group_id": 987654321,
"anonymous_flag": "xxxx_anonymous_flag",
"duration": 600
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.4.3 群组踢人
接口: set_group_kick
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| user_id | int64 | 是 | 要踢的 QQ 号 |
| reject_add_request | boolean | 否 | 拒绝此人的加群请求 |
请求示例:
{
"group_id": 987654321,
"user_id": 123456789,
"reject_add_request": false
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.5 好友管理
3.5.1 删除好友
接口: delete_friend
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| user_id | int64 | 是 | 好友 QQ 号 |
请求示例:
{
"user_id": 123456789
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.6 文件操作
3.6.1 上传群文件
接口: upload_group_file
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| file | string | 是 | 本地文件路径 |
| name | string | 是 | 储存名称 |
| folder | string | 否 | 父目录ID |
请求示例:
{
"group_id": 987654321,
"file": "file:///C:/Users/Admin/document.pdf",
"name": "重要文档.pdf"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.6.2 获取群文件系统信息
接口: get_group_file_system_info
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
请求示例:
{
"group_id": 987654321
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"file_count": 123,
"limit_count": 1000,
"used_space": 1234567890,
"total_space": 10737418240
}
}3.6.3 获取群根目录文件列表
接口: get_group_root_files
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
请求示例:
{
"group_id": 987654321
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"files": [
{
"file_id": "abcd1234",
"file_name": "文件名.txt",
"busid": 102,
"file_size": 12345,
"upload_time": 1234567890,
"dead_time": 0,
"modify_time": 1234567890,
"download_times": 5,
"uploader": 123456,
"uploader_name": "上传者昵称"
}
],
"folders": [
{
"folder_id": "xyz789",
"folder_name": "文件夹名",
"create_time": 1234567890,
"creator": 123456,
"creator_name": "创建者昵称",
"total_file_count": 10
}
]
}
}3.6.4 获取群子目录文件列表
接口: get_group_files_by_folder
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| folder_id | string | 是 | 文件夹 ID |
请求示例:
{
"group_id": 987654321,
"folder_id": "xyz789"
}响应数据: 同 get_group_root_files
3.6.5 获取群文件资源链接
接口: get_group_file_url
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| file_id | string | 是 | 文件 ID |
| busid | int32 | 是 | 文件类型 |
请求示例:
{
"group_id": 987654321,
"file_id": "abcd1234",
"busid": 102
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"url": "https://download.example.com/file?token=xxxxx"
}
}3.7 信息获取
3.7.1 获取登录号信息
接口: get_login_info
请求参数: 无
请求示例:
{}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"user_id": 1001000,
"nickname": "机器人昵称"
}
}3.7.2 获取陌生人信息
接口: get_stranger_info
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| user_id | int64 | 是 | QQ 号 |
| no_cache | boolean | 否 | 是否不使用缓存 |
请求示例:
{
"user_id": 123456789,
"no_cache": false
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"user_id": 123456789,
"nickname": "用户昵称",
"sex": "male",
"age": 20,
"qid": "abc123",
"level": 10,
"login_days": 365
}
}3.7.3 获取好友列表
接口: get_friend_list
请求参数: 无
请求示例:
{}响应数据:
{
"status": "ok",
"retcode": 0,
"data": [
{
"user_id": 123456789,
"nickname": "好友昵称1",
"remark": "备注名1"
},
{
"user_id": 987654321,
"nickname": "好友昵称2",
"remark": "备注名2"
}
]
}3.7.4 获取群信息
接口: get_group_info
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| no_cache | boolean | 否 | 是否不使用缓存 |
请求示例:
{
"group_id": 987654321,
"no_cache": false
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"group_id": 987654321,
"group_name": "群名称",
"group_memo": "群公告",
"group_create_time": 1234567890,
"group_level": 5,
"member_count": 100,
"max_member_count": 500
}
}3.7.5 获取群列表
接口: get_group_list
请求参数: 无
请求示例:
{}响应数据:
{
"status": "ok",
"retcode": 0,
"data": [
{
"group_id": 987654321,
"group_name": "群名称1",
"member_count": 100,
"max_member_count": 500
},
{
"group_id": 123456789,
"group_name": "群名称2",
"member_count": 50,
"max_member_count": 200
}
]
}3.7.6 获取群成员信息
接口: get_group_member_info
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| user_id | int64 | 是 | QQ 号 |
| no_cache | boolean | 否 | 是否不使用缓存 |
请求示例:
{
"group_id": 987654321,
"user_id": 123456789,
"no_cache": false
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"group_id": 987654321,
"user_id": 123456789,
"nickname": "用户昵称",
"card": "群名片",
"sex": "male",
"age": 20,
"area": "中国",
"join_time": 1234567890,
"last_sent_time": 1234567890,
"level": "10",
"role": "member",
"unfriendly": false,
"title": "专属头衔",
"title_expire_time": 1234567890,
"card_changeable": true,
"shut_up_timestamp": 0
}
}role 说明:
owner: 群主admin: 管理员member: 普通成员
3.7.7 获取群成员列表
接口: get_group_member_list
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| no_cache | boolean | 否 | 是否不使用缓存 |
请求示例:
{
"group_id": 987654321,
"no_cache": false
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": [
{
"group_id": 987654321,
"user_id": 123456789,
"nickname": "成员1",
"card": "群名片1",
"sex": "male",
"age": 20,
"area": "中国",
"join_time": 1234567890,
"last_sent_time": 1234567890,
"level": "10",
"role": "owner",
"unfriendly": false,
"title": "",
"title_expire_time": 0,
"card_changeable": false,
"shut_up_timestamp": 0
},
{
"group_id": 987654321,
"user_id": 987654321,
"nickname": "成员2",
"card": "群名片2",
"sex": "female",
"age": 18,
"area": "中国",
"join_time": 1234567890,
"last_sent_time": 1234567890,
"level": "5",
"role": "member",
"unfriendly": false,
"title": "",
"title_expire_time": 0,
"card_changeable": true,
"shut_up_timestamp": 0
}
]
}3.7.8 获取群荣誉信息
接口: get_group_honor_info
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group_id | int64 | 是 | 群号 |
| type | string | 是 | 要获取的荣誉类型 |
type 可选值:
talkative: 龙王performer: 群聊之火legend: 群聊炽焰strong_newbie: 冒尖小春笋emotion: 快乐源泉all: 所有荣誉
请求示例:
{
"group_id": 987654321,
"type": "all"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"group_id": 987654321,
"current_talkative": {
"user_id": 123456789,
"nickname": "龙王昵称",
"avatar": "https://q.qlogo.cn/...",
"day_count": 5
},
"talkative_list": [
{
"user_id": 123456789,
"nickname": "历史龙王1",
"avatar": "https://q.qlogo.cn/...",
"description": "连续3天"
}
],
"performer_list": [],
"legend_list": [],
"strong_newbie_list": [],
"emotion_list": []
}
}3.7.9 检查是否可以发送图片
接口: can_send_image
请求参数: 无
请求示例:
{}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"yes": true
}
}3.7.10 检查是否可以发送语音
接口: can_send_record
请求参数: 无
请求示例:
{}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"yes": true
}
}3.7.11 获取运行状态
接口: get_status
请求参数: 无
请求示例:
{}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"online": true,
"good": true,
"stat": {
"packet_received": 1234,
"packet_sent": 5678,
"packet_lost": 0,
"message_received": 100,
"message_sent": 50,
"disconnect_times": 0,
"lost_times": 0,
"last_message_time": 1234567890
}
}
}3.7.12 获取版本信息
接口: get_version_info
请求参数: 无
请求示例:
{}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"app_name": "NapCatQQ",
"app_version": "2.0.0",
"app_full_name": "NapCatQQ v2.0.0",
"protocol_version": "v11",
"coolq_edition": "pro",
"coolq_directory": "/path/to/napcat",
"go-cqhttp": false,
"plugin_version": "1.0.0",
"plugin_build_number": 100,
"plugin_build_configuration": "release",
"runtime_version": "node v18.0.0",
"runtime_os": "Windows 10"
}
}3.8 其他操作
3.8.1 处理加好友请求
接口: set_friend_add_request
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| flag | string | 是 | 请求标识(从上报中获取) |
| approve | boolean | 是 | 是否同意请求 |
| remark | string | 否 | 添加后的好友备注 |
请求示例:
{
"flag": "request_flag_xxx",
"approve": true,
"remark": "新朋友"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.8.2 处理加群请求/邀请
接口: set_group_add_request
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| flag | string | 是 | 请求标识(从上报中获取) |
| sub_type | string | 是 | add 或 invite,请求类型 |
| approve | boolean | 是 | 是否同意请求/邀请 |
| reason | string | 否 | 拒绝理由(拒绝时) |
请求示例:
{
"flag": "request_flag_xxx",
"sub_type": "add",
"approve": true
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.8.3 获取图片信息
接口: get_image
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | string | 是 | 图片缓存文件名 |
请求示例:
{
"file": "xxxx.image"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"size": 123456,
"filename": "xxxx.image",
"url": "https://gchat.qpic.cn/..."
}
}3.8.4 获取语音
接口: get_record
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | string | 是 | 语音文件名 |
| out_format | string | 是 | 要转换到的格式 |
请求示例:
{
"file": "xxxx.record",
"out_format": "mp3"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"file": "file:///path/to/record.mp3"
}
}3.8.5 OCR 图片识别
接口: ocr_image
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| image | string | 是 | 图片ID |
请求示例:
{
"image": "xxxx.image"
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": {
"texts": [
{
"text": "识别的文字内容1",
"confidence": 95,
"coordinates": [100, 100, 200, 150]
},
{
"text": "识别的文字内容2",
"confidence": 90,
"coordinates": [100, 160, 200, 210]
}
],
"language": "zh-CN"
}
}3.8.6 清理缓存
接口: clean_cache
请求参数: 无
请求示例:
{}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}3.8.7 重启 OneBot 实现
接口: set_restart
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| delay | int64 | 否 | 延迟重启时间(毫秒) |
请求示例:
{
"delay": 1000
}响应数据:
{
"status": "ok",
"retcode": 0,
"data": null
}4. 事件上报
OneBot 会将各种事件通过配置的方式上报给应用程序。
4.1 消息事件
4.1.1 私聊消息
post_type: message
message_type: private
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "message",
"message_type": "private",
"sub_type": "friend",
"message_id": 123456,
"user_id": 123456789,
"message": [
{
"type": "text",
"data": {
"text": "你好"
}
}
],
"raw_message": "你好",
"font": 0,
"sender": {
"user_id": 123456789,
"nickname": "发送者昵称",
"sex": "male",
"age": 20
}
}sub_type 说明:
friend: 好友消息group: 群临时会话other: 其他
4.1.2 群消息
post_type: message
message_type: group
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "message",
"message_type": "group",
"sub_type": "normal",
"message_id": 654321,
"group_id": 987654321,
"user_id": 123456789,
"anonymous": null,
"message": [
{
"type": "text",
"data": {
"text": "大家好"
}
}
],
"raw_message": "大家好",
"font": 0,
"sender": {
"user_id": 123456789,
"nickname": "发送者昵称",
"card": "群名片",
"sex": "male",
"age": 20,
"area": "中国",
"level": "10",
"role": "member",
"title": ""
}
}sub_type 说明:
normal: 正常消息anonymous: 匿名消息notice: 系统提示(如「管理员已同意...」)
sender.role 说明:
owner: 群主admin: 管理员member: 普通成员
4.2 通知事件
4.2.1 群成员增加
post_type: notice
notice_type: group_increase
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "group_increase",
"sub_type": "approve",
"group_id": 987654321,
"operator_id": 111111,
"user_id": 123456789
}sub_type 说明:
approve: 管理员同意入群invite: 管理员邀请入群
4.2.2 群成员减少
post_type: notice
notice_type: group_decrease
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "group_decrease",
"sub_type": "leave",
"group_id": 987654321,
"operator_id": 123456789,
"user_id": 123456789
}sub_type 说明:
leave: 主动退群kick: 成员被踢kick_me: 登录号(机器人)被踢
4.2.3 群管理员变动
post_type: notice
notice_type: group_admin
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "group_admin",
"sub_type": "set",
"group_id": 987654321,
"user_id": 123456789
}sub_type 说明:
set: 设置管理员unset: 取消管理员
4.2.4 群文件上传
post_type: notice
notice_type: group_upload
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "group_upload",
"group_id": 987654321,
"user_id": 123456789,
"file": {
"id": "file_id_xxx",
"name": "上传的文件.txt",
"size": 12345,
"busid": 102
}
}4.2.5 群禁言
post_type: notice
notice_type: group_ban
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "group_ban",
"sub_type": "ban",
"group_id": 987654321,
"operator_id": 111111,
"user_id": 123456789,
"duration": 600
}sub_type 说明:
ban: 禁言lift_ban: 解除禁言
特殊情况:
duration为 0 表示解除禁言user_id为 0 表示全员禁言
4.2.6 好友添加
post_type: notice
notice_type: friend_add
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "friend_add",
"user_id": 123456789
}4.2.7 群消息撤回
post_type: notice
notice_type: group_recall
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "group_recall",
"group_id": 987654321,
"user_id": 123456789,
"operator_id": 111111,
"message_id": 654321
}说明:
user_id: 消息发送者operator_id: 操作者(撤回消息的人)- 若操作者是消息发送者本人,则
user_id==operator_id
4.2.8 好友消息撤回
post_type: notice
notice_type: friend_recall
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "friend_recall",
"user_id": 123456789,
"message_id": 123456
}4.2.9 群内戳一戳
post_type: notice
notice_type: notify
sub_type: poke
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "notify",
"sub_type": "poke",
"group_id": 987654321,
"user_id": 123456789,
"target_id": 111111
}说明:
user_id: 发送者target_id: 被戳者
4.2.10 群红包运气王
post_type: notice
notice_type: notify
sub_type: lucky_king
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "notify",
"sub_type": "lucky_king",
"group_id": 987654321,
"user_id": 123456789,
"target_id": 111111
}说明:
user_id: 红包发送者target_id: 运气王
4.2.11 群荣誉变更
post_type: notice
notice_type: notify
sub_type: honor
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "notify",
"sub_type": "honor",
"group_id": 987654321,
"user_id": 123456789,
"honor_type": "talkative"
}honor_type 说明:
talkative: 龙王performer: 群聊之火emotion: 快乐源泉
4.2.12 群成员名片更新
post_type: notice
notice_type: group_card
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "group_card",
"group_id": 987654321,
"user_id": 123456789,
"card_new": "新名片",
"card_old": "旧名片"
}4.2.13 离线文件
post_type: notice
notice_type: offline_file
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "offline_file",
"user_id": 123456789,
"file": {
"name": "文件名.txt",
"size": 12345,
"url": "https://download.example.com/file"
}
}4.2.14 客户端状态变更
post_type: notice
notice_type: client_status
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "client_status",
"client": {
"app_id": 123456,
"device_name": "设备名称",
"device_kind": "手机"
},
"online": true
}4.2.15 精华消息
post_type: notice
notice_type: essence
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "notice",
"notice_type": "essence",
"sub_type": "add",
"group_id": 987654321,
"sender_id": 123456789,
"operator_id": 111111,
"message_id": 654321
}sub_type 说明:
add: 添加delete: 移出
4.3 请求事件
4.3.1 加好友请求
post_type: request
request_type: friend
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "request",
"request_type": "friend",
"user_id": 123456789,
"comment": "我是XXX",
"flag": "request_flag_xxx"
}说明:
comment: 验证信息flag: 请求标识,用于处理请求时的标识
处理方式: 使用 set_friend_add_request API
4.3.2 加群请求/邀请
post_type: request
request_type: group
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "request",
"request_type": "group",
"sub_type": "add",
"group_id": 987654321,
"user_id": 123456789,
"comment": "请让我加入",
"flag": "request_flag_xxx"
}sub_type 说明:
add: 加群请求invite: 邀请登录号入群
处理方式: 使用 set_group_add_request API
4.4 元事件
4.4.1 生命周期
post_type: meta_event
meta_event_type: lifecycle
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "meta_event",
"meta_event_type": "lifecycle",
"sub_type": "enable"
}sub_type 说明:
enable: OneBot 启用disable: OneBot 停用connect: WebSocket 连接成功
4.4.2 心跳
post_type: meta_event
meta_event_type: heartbeat
上报数据:
{
"time": 1234567890,
"self_id": 1001000,
"post_type": "meta_event",
"meta_event_type": "heartbeat",
"status": {
"online": true,
"good": true
},
"interval": 5000
}说明:
interval: 心跳间隔(毫秒)status: 运行状态
5. 消息段(CQ码)
消息段用于在消息中插入特殊内容,如图片、表情、@某人等。
5.1 纯文本
类型: text
数组格式:
{
"type": "text",
"data": {
"text": "纯文本内容"
}
}CQ码格式:
纯文本内容5.2 QQ表情
类型: face
数组格式:
{
"type": "face",
"data": {
"id": "123"
}
}CQ码格式:
[CQ:face,id=123]说明: id 为 QQ 表情 ID,范围 0-221
5.3 图片
类型: image
数组格式:
{
"type": "image",
"data": {
"file": "file:///C:/image.jpg",
"type": "flash",
"url": "https://example.com/image.jpg",
"cache": 1,
"proxy": 1,
"timeout": 5
}
}CQ码格式:
[CQ:image,file=file:///C:/image.jpg,type=flash]参数说明:
file: 图片文件路径/URL/base64- 本地文件:
file:///C:/image.jpg - 网络图片:
https://example.com/image.jpg - Base64:
base64://iVBORw0KGgo...
- 本地文件:
type: 图片类型- 不填: 普通图片
flash: 闪照show: 秀图
url: 图片URL(发送时可用file代替)cache: 是否使用缓存,0否1是proxy: 是否通过代理下载,0否1是timeout: 下载超时时间(秒)
5.4 语音
类型: record
数组格式:
{
"type": "record",
"data": {
"file": "file:///C:/record.amr",
"magic": 0,
"url": "https://example.com/record.amr",
"cache": 1,
"proxy": 1,
"timeout": 5
}
}CQ码格式:
[CQ:record,file=file:///C:/record.amr]参数说明:
file: 语音文件路径/URL/base64magic: 是否变声,0否1是- 其他参数同图片
支持的格式: amr, silk, mp3, wav
5.5 视频
类型: video
数组格式:
{
"type": "video",
"data": {
"file": "file:///C:/video.mp4",
"url": "https://example.com/video.mp4",
"cache": 1,
"proxy": 1,
"timeout": 5
}
}CQ码格式:
[CQ:video,file=file:///C:/video.mp4]支持的格式: mp4, avi, mov
5.6 at某人
类型: at
数组格式:
{
"type": "at",
"data": {
"qq": "123456789"
}
}CQ码格式:
[CQ:at,qq=123456789]说明:
qq: QQ号,all表示@全体成员
5.7 猜拳
类型: rps
数组格式:
{
"type": "rps"
}CQ码格式:
[CQ:rps]5.8 掷骰子
类型: dice
数组格式:
{
"type": "dice"
}CQ码格式:
[CQ:dice]5.9 窗口抖动(戳一戳)
类型: shake
数组格式:
{
"type": "shake"
}CQ码格式:
[CQ:shake]说明: 仅支持好友消息
5.10 戳一戳(群聊)
类型: poke
数组格式:
{
"type": "poke",
"data": {
"type": "1",
"id": "1"
}
}CQ码格式:
[CQ:poke,type=1,id=1]常用type和id组合:
| type | id | 说明 |
|---|---|---|
| 1 | 1 | 戳一戳 |
| 2 | 2 | 比心 |
| 3 | 3 | 点赞 |
| 4 | 4 | 心碎 |
| 5 | 5 | 666 |
| 6 | 6 | 放大招 |
5.11 匿名发消息
类型: anonymous
数组格式:
{
"type": "anonymous",
"data": {
"ignore": 0
}
}CQ码格式:
[CQ:anonymous,ignore=0]说明:
ignore: 可选,表示无法匿名时是否继续发送- 必须放在消息开头
5.12 链接分享
类型: share
数组格式:
{
"type": "share",
"data": {
"url": "https://example.com",
"title": "标题",
"content": "内容描述",
"image": "https://example.com/image.jpg"
}
}CQ码格式:
[CQ:share,url=https://example.com,title=标题,content=内容描述,image=https://example.com/image.jpg]5.13 推荐好友/群
类型: contact
数组格式:
{
"type": "contact",
"data": {
"type": "qq",
"id": "123456789"
}
}CQ码格式:
[CQ:contact,type=qq,id=123456789]type 说明:
qq: 推荐好友group: 推荐群
5.14 位置
类型: location
数组格式:
{
"type": "location",
"data": {
"lat": "39.9042",
"lon": "116.4074",
"title": "位置名称",
"content": "详细地址"
}
}CQ码格式:
[CQ:location,lat=39.9042,lon=116.4074,title=位置名称,content=详细地址]5.15 音乐分享
类型: music
数组格式:
{
"type": "music",
"data": {
"type": "qq",
"id": "123456"
}
}CQ码格式:
[CQ:music,type=qq,id=123456]type 说明:
qq: QQ音乐163: 网易云音乐xm: 虾米音乐custom: 自定义音乐卡片
自定义音乐卡片:
{
"type": "music",
"data": {
"type": "custom",
"url": "https://music.example.com/song.mp3",
"audio": "https://music.example.com/song.mp3",
"title": "歌曲标题",
"content": "歌手名",
"image": "https://music.example.com/cover.jpg"
}
}5.16 回复
类型: reply
数组格式:
{
"type": "reply",
"data": {
"id": "123456"
}
}CQ码格式:
[CQ:reply,id=123456]说明:
id: 回复的消息ID- 必须放在消息开头
5.17 合并转发节点
类型: node
数组格式:
{
"type": "node",
"data": {
"id": "123456"
}
}或自定义节点:
{
"type": "node",
"data": {
"name": "发送者名称",
"uin": "123456789",
"content": [
{
"type": "text",
"data": {
"text": "消息内容"
}
}
]
}
}说明:
- 引用消息: 使用
id字段 - 自定义消息: 使用
name、uin、content字段
5.18 XML消息
类型: xml
数组格式:
{
"type": "xml",
"data": {
"data": "<?xml version='1.0' encoding='UTF-8'?>...",
"resid": 123
}
}CQ码格式:
[CQ:xml,data=<?xml version='1.0' encoding='UTF-8'?>...]5.19 JSON消息
类型: json
数组格式:
{
"type": "json",
"data": {
"data": "{\"app\":\"com.tencent.structmsg\",...}",
"resid": 123
}
}CQ码格式:
[CQ:json,data={"app":"com.tencent.structmsg",...}]5.20 一种xml的图片消息(棉花)
类型: cardimage
数组格式:
{
"type": "cardimage",
"data": {
"file": "https://example.com/image.jpg",
"minwidth": "200",
"minheight": "200",
"maxwidth": "500",
"maxheight": "500",
"source": "来源",
"icon": "https://example.com/icon.jpg"
}
}5.21 文本转语音
类型: tts
数组格式:
{
"type": "tts",
"data": {
"text": "要转换的文本内容"
}
}CQ码格式:
[CQ:tts,text=要转换的文本内容]6. 错误码
| retcode | 说明 |
|---|---|
| 0 | 成功 |
| 1 | 已提交异步处理 |
| 100 | 参数缺失或参数无效 |
| 101 | 插件无法处理请求 |
| 102 | 插件无法处理请求或未启用 |
| 103 | 操作失败 |
| 104 | 未授权 |
| 200 | 操作失败,一般为资源不存在 |
| 201 | 操作失败,返回的数据为空 |
| 1400 | 无效的请求 |
| 1401 | 无效的令牌 |
| 1403 | 禁止访问 |
| 1404 | API 不存在 |
常见错误处理:
// JavaScript 示例
async function callAPI(action, params) {
const response = await fetch('http://127.0.0.1:5700/' + action, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params)
});
const result = await response.json();
if (result.retcode !== 0) {
console.error(`API调用失败: ${result.message || result.wording}`);
throw new Error(result.message);
}
return result.data;
}7. 完整示例
7.1 Python 完整示例
import requests
from flask import Flask, request, jsonify
app = Flask(__name__)
# OneBot API 配置
ONEBOT_HTTP_API = "http://127.0.0.1:5700"
# ========== API 调用示例 ==========
def send_private_msg(user_id, message):
"""发送私聊消息"""
url = f"{ONEBOT_HTTP_API}/send_private_msg"
data = {
"user_id": user_id,
"message": message
}
response = requests.post(url, json=data)
return response.json()
def send_group_msg(group_id, message):
"""发送群消息"""
url = f"{ONEBOT_HTTP_API}/send_group_msg"
data = {
"group_id": group_id,
"message": message
}
response = requests.post(url, json=data)
return response.json()
def send_image(group_id, image_path):
"""发送图片"""
message = [
{
"type": "text",
"data": {"text": "这是一张图片:"}
},
{
"type": "image",
"data": {"file": f"file:///{image_path}"}
}
]
return send_group_msg(group_id, message)
def get_group_member_list(group_id):
"""获取群成员列表"""
url = f"{ONEBOT_HTTP_API}/get_group_member_list"
data = {"group_id": group_id}
response = requests.post(url, json=data)
return response.json()
# ========== 事件接收示例 ==========
@app.route('/onebot', methods=['POST'])
def handle_event():
"""处理OneBot上报的事件"""
event = request.json
# 获取事件类型
post_type = event.get('post_type')
if post_type == 'message':
# 消息事件
handle_message(event)
elif post_type == 'notice':
# 通知事件
handle_notice(event)
elif post_type == 'request':
# 请求事件
handle_request(event)
elif post_type == 'meta_event':
# 元事件
handle_meta_event(event)
return jsonify({})
def handle_message(event):
"""处理消息事件"""
message_type = event.get('message_type')
user_id = event.get('user_id')
raw_message = event.get('raw_message')
print(f"收到{message_type}消息: {raw_message}")
if message_type == 'private':
# 私聊消息
if raw_message == 'hello':
send_private_msg(user_id, "你好!")
elif message_type == 'group':
# 群消息
group_id = event.get('group_id')
if raw_message == '菜单':
menu = """
可用命令:
1. hello - 打招呼
2. 群信息 - 查看群信息
3. 成员列表 - 查看群成员
"""
send_group_msg(group_id, menu)
elif raw_message == '群信息':
# 获取群信息
url = f"{ONEBOT_HTTP_API}/get_group_info"
resp = requests.post(url, json={"group_id": group_id})
info = resp.json()['data']
msg = f"""
群号: {info['group_id']}
群名: {info['group_name']}
成员数: {info['member_count']}/{info['max_member_count']}
"""
send_group_msg(group_id, msg)
elif raw_message == '成员列表':
# 获取群成员列表
result = get_group_member_list(group_id)
members = result['data']
msg = f"群成员总数: {len(members)}\n"
for member in members[:10]: # 只显示前10个
msg += f"- {member['nickname']} ({member['user_id']})\n"
send_group_msg(group_id, msg)
def handle_notice(event):
"""处理通知事件"""
notice_type = event.get('notice_type')
if notice_type == 'group_increase':
# 群成员增加
group_id = event.get('group_id')
user_id = event.get('user_id')
welcome = [
{"type": "at", "data": {"qq": str(user_id)}},
{"type": "text", "data": {"text": " 欢迎加入本群!"}}
]
send_group_msg(group_id, welcome)
elif notice_type == 'group_decrease':
# 群成员减少
group_id = event.get('group_id')
user_id = event.get('user_id')
sub_type = event.get('sub_type')
if sub_type == 'leave':
msg = f"用户 {user_id} 离开了本群"
elif sub_type == 'kick':
operator_id = event.get('operator_id')
msg = f"用户 {user_id} 被 {operator_id} 踢出了本群"
send_group_msg(group_id, msg)
def handle_request(event):
"""处理请求事件"""
request_type = event.get('request_type')
if request_type == 'friend':
# 加好友请求
flag = event.get('flag')
user_id = event.get('user_id')
comment = event.get('comment')
print(f"收到加好友请求: {user_id}, 验证消息: {comment}")
# 自动同意
url = f"{ONEBOT_HTTP_API}/set_friend_add_request"
requests.post(url, json={
"flag": flag,
"approve": True,
"remark": "新朋友"
})
elif request_type == 'group':
# 加群请求
sub_type = event.get('sub_type')
flag = event.get('flag')
group_id = event.get('group_id')
user_id = event.get('user_id')
if sub_type == 'add':
print(f"收到加群请求: {user_id} 请求加入 {group_id}")
# 自动同意
url = f"{ONEBOT_HTTP_API}/set_group_add_request"
requests.post(url, json={
"flag": flag,
"sub_type": "add",
"approve": True
})
def handle_meta_event(event):
"""处理元事件"""
meta_event_type = event.get('meta_event_type')
if meta_event_type == 'lifecycle':
sub_type = event.get('sub_type')
print(f"生命周期事件: {sub_type}")
elif meta_event_type == 'heartbeat':
# 心跳事件,可以不处理
pass
# ========== 高级功能示例 ==========
def send_forward_msg(group_id):
"""发送合并转发消息"""
messages = [
{
"type": "node",
"data": {
"name": "发送者A",
"uin": "10001",
"content": "这是第一条消息"
}
},
{
"type": "node",
"data": {
"name": "发送者B",
"uin": "10002",
"content": [
{"type": "text", "data": {"text": "这是第二条消息,包含图片"}},
{"type": "image", "data": {"file": "https://example.com/image.jpg"}}
]
}
}
]
url = f"{ONEBOT_HTTP_API}/send_group_forward_msg"
response = requests.post(url, json={
"group_id": group_id,
"messages": messages
})
return response.json()
def send_at_message(group_id, user_id, text):
"""发送@消息"""
message = [
{"type": "at", "data": {"qq": str(user_id)}},
{"type": "text", "data": {"text": f" {text}"}}
]
return send_group_msg(group_id, message)
def ban_group_member(group_id, user_id, duration):
"""禁言群成员"""
url = f"{ONEBOT_HTTP_API}/set_group_ban"
response = requests.post(url, json={
"group_id": group_id,
"user_id": user_id,
"duration": duration
})
return response.json()
# ========== 启动Flask服务 ==========
if __name__ == '__main__':
# 在OneBot配置中设置HTTP上报地址为: http://your-ip:5000/onebot
app.run(host='0.0.0.0', port=5000, debug=True)7.2 Node.js WebSocket 示例
const WebSocket = require('ws');
// OneBot WebSocket 地址
const ONEBOT_WS = 'ws://127.0.0.1:6700';
// 连接到 OneBot
const ws = new WebSocket(ONEBOT_WS);
// 请求ID计数器
let echoId = 0;
// ========== WebSocket 连接处理 ==========
ws.on('open', () => {
console.log('已连接到 OneBot');
// 发送测试消息
sendGroupMsg(987654321, '机器人已上线!');
});
ws.on('message', (data) => {
const msg = JSON.parse(data);
// 判断是事件上报还是API响应
if (msg.post_type) {
// 事件上报
handleEvent(msg);
} else if (msg.echo) {
// API响应
handleApiResponse(msg);
}
});
ws.on('close', () => {
console.log('WebSocket 连接已关闭');
});
ws.on('error', (error) => {
console.error('WebSocket 错误:', error);
});
// ========== API 调用函数 ==========
function callAPI(action, params = {}) {
const echo = `req_${++echoId}`;
const request = {
action: action,
params: params,
echo: echo
};
ws.send(JSON.stringify(request));
return echo;
}
function sendPrivateMsg(userId, message) {
return callAPI('send_private_msg', {
user_id: userId,
message: message
});
}
function sendGroupMsg(groupId, message) {
return callAPI('send_group_msg', {
group_id: groupId,
message: message
});
}
function getGroupInfo(groupId) {
return callAPI('get_group_info', {
group_id: groupId
});
}
// ========== 事件处理 ==========
function handleEvent(event) {
const postType = event.post_type;
if (postType === 'message') {
handleMessage(event);
} else if (postType === 'notice') {
handleNotice(event);
} else if (postType === 'request') {
handleRequest(event);
} else if (postType === 'meta_event') {
handleMetaEvent(event);
}
}
function handleMessage(event) {
const messageType = event.message_type;
const rawMessage = event.raw_message;
const userId = event.user_id;
console.log(`收到${messageType}消息:`, rawMessage);
if (messageType === 'private') {
// 私聊消息处理
if (rawMessage === 'ping') {
sendPrivateMsg(userId, 'pong');
}
} else if (messageType === 'group') {
// 群消息处理
const groupId = event.group_id;
if (rawMessage === '!help') {
const help = `
可用命令:
- !help: 显示帮助
- !info: 群信息
- !echo <文本>: 复读
`.trim();
sendGroupMsg(groupId, help);
} else if (rawMessage === '!info') {
getGroupInfo(groupId);
} else if (rawMessage.startsWith('!echo ')) {
const text = rawMessage.substring(6);
sendGroupMsg(groupId, text);
}
}
}
function handleNotice(event) {
const noticeType = event.notice_type;
if (noticeType === 'group_increase') {
// 欢迎新成员
const groupId = event.group_id;
const userId = event.user_id;
const welcomeMsg = [
{ type: 'at', data: { qq: userId.toString() } },
{ type: 'text', data: { text: ' 欢迎加入本群!' } }
];
sendGroupMsg(groupId, welcomeMsg);
}
}
function handleRequest(event) {
const requestType = event.request_type;
if (requestType === 'friend') {
// 自动同意好友请求
callAPI('set_friend_add_request', {
flag: event.flag,
approve: true
});
} else if (requestType === 'group') {
// 自动同意加群请求
if (event.sub_type === 'add') {
callAPI('set_group_add_request', {
flag: event.flag,
sub_type: 'add',
approve: true
});
}
}
}
function handleMetaEvent(event) {
if (event.meta_event_type === 'heartbeat') {
// 心跳事件
console.log('心跳:', event.status);
}
}
// ========== API 响应处理 ==========
function handleApiResponse(response) {
console.log('API响应:', response);
if (response.status === 'ok') {
// 成功
if (response.data) {
console.log('返回数据:', response.data);
}
} else {
// 失败
console.error('API调用失败:', response.message);
}
}附录
A. 常用消息段组合示例
A.1 发送图文消息
{
"group_id": 987654321,
"message": [
{
"type": "text",
"data": {"text": "看看这张图片:"}
},
{
"type": "image",
"data": {"file": "https://example.com/image.jpg"}
},
{
"type": "text",
"data": {"text": "\n怎么样?"}
}
]
}A.2 @某人并回复
{
"group_id": 987654321,
"message": [
{
"type": "reply",
"data": {"id": "123456"}
},
{
"type": "at",
"data": {"qq": "123456789"}
},
{
"type": "text",
"data": {"text": " 收到!"}
}
]
}A.3 发送表情包组合
{
"group_id": 987654321,
"message": [
{
"type": "face",
"data": {"id": "178"}
},
{
"type": "text",
"data": {"text": "早上好!"}
},
{
"type": "face",
"data": {"id": "179"}
}
]
}B. NapCatQQ 配置示例
# OneBot 配置
http:
enable: true
host: 0.0.0.0
port: 5700
secret: ""
enableHeart: true
enablePost: true
postUrls:
- "http://your-server:5000/onebot"
ws:
enable: true
host: 0.0.0.0
port: 6700
wsReverse:
enable: true
urls:
- "ws://your-server:8080/ws"结语
本文档涵盖了 OneBot 11 协议的所有主要接口和事件类型。在实际使用中:
- 优先使用 WebSocket:实时性更好,双向通信更方便
- 合理处理错误:检查
retcode,记录错误日志 - 注意限流:避免频繁调用 API 导致被限制
- 消息段灵活组合:充分利用各种消息段类型
- 事件及时处理:避免阻塞事件处理流程
如有疑问,请参考:
- OneBot 11 标准: https://github.com/botuniverse/onebot-11
- NapCatQQ 文档: https://napneko.github.io
- go-cqhttp 文档: https://docs.go-cqhttp.org
祝你开发愉快! 🎉