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_idint64对方 QQ 号
messagemessage要发送的内容
auto_escapeboolean消息内容是否作为纯文本发送(不解析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_idint64群号
messagemessage要发送的内容
auto_escapeboolean消息内容是否作为纯文本发送

请求示例:

{
  "group_id": 987654321,
  "message": "大家好!"
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": {
    "message_id": 654321
  }
}

3.1.3 发送消息(统一接口)

接口: send_msg

请求参数:

字段类型必填说明
message_typestring消息类型: private/group
user_idint64对方 QQ 号(私聊时必填)
group_idint64群号(群聊时必填)
messagemessage要发送的内容
auto_escapeboolean是否作为纯文本

请求示例:

{
  "message_type": "group",
  "group_id": 987654321,
  "message": "统一发送接口测试"
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": {
    "message_id": 789012
  }
}

3.1.4 发送合并转发(群聊)

接口: send_group_forward_msg

请求参数:

字段类型必填说明
group_idint64群号
messagesarray自定义转发消息

请求示例:

{
  "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_idint64对方 QQ 号
messagesarray自定义转发消息

请求示例:

{
  "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_idint32消息 ID

请求示例:

{
  "message_id": 123456
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.2.2 获取消息

接口: get_msg

请求参数:

字段类型必填说明
message_idint32消息 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

请求参数:

字段类型必填说明
idstring合并转发 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_idint32消息 ID

请求示例:

{
  "message_id": 123456
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.3 群组管理

3.3.1 设置群名

接口: set_group_name

请求参数:

字段类型必填说明
group_idint64群号
group_namestring新群名

请求示例:

{
  "group_id": 987654321,
  "group_name": "新的群名称"
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.3.2 设置群头像

接口: set_group_portrait

请求参数:

字段类型必填说明
group_idint64群号
filestring图片文件路径或URL
cacheint是否使用缓存,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_idint64群号
user_idint64要设置的 QQ 号
enablebooleantrue 为设置,false 为取消

请求示例:

{
  "group_id": 987654321,
  "user_id": 123456789,
  "enable": true
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.3.4 设置群名片

接口: set_group_card

请求参数:

字段类型必填说明
group_idint64群号
user_idint64要设置的 QQ 号
cardstring群名片内容,不填或空字符串表示删除

请求示例:

{
  "group_id": 987654321,
  "user_id": 123456789,
  "card": "新的群名片"
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.3.5 设置群专属头衔

接口: set_group_special_title

请求参数:

字段类型必填说明
group_idint64群号
user_idint64要设置的 QQ 号
special_titlestring专属头衔,不填或空字符串表示删除
durationint64专属头衔有效期,单位秒,-1 表示永久

请求示例:

{
  "group_id": 987654321,
  "user_id": 123456789,
  "special_title": "群大佬",
  "duration": -1
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.3.6 退出群组

接口: set_group_leave

请求参数:

字段类型必填说明
group_idint64群号
is_dismissboolean是否解散,仅在是群主时有效

请求示例:

{
  "group_id": 987654321,
  "is_dismiss": false
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.3.7 全员禁言

接口: set_group_whole_ban

请求参数:

字段类型必填说明
group_idint64群号
enableboolean是否禁言

请求示例:

{
  "group_id": 987654321,
  "enable": true
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.4 群成员管理

3.4.1 群单人禁言

接口: set_group_ban

请求参数:

字段类型必填说明
group_idint64群号
user_idint64要禁言的 QQ 号
durationint64禁言时长,单位秒,0 表示取消禁言

请求示例:

{
  "group_id": 987654321,
  "user_id": 123456789,
  "duration": 600
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.4.2 群匿名用户禁言

接口: set_group_anonymous_ban

请求参数:

字段类型必填说明
group_idint64群号
anonymousobject匿名用户对象(来自上报)
anonymous_flagstring匿名用户标识(来自上报)
durationint64禁言时长,单位秒

请求示例:

{
  "group_id": 987654321,
  "anonymous_flag": "xxxx_anonymous_flag",
  "duration": 600
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.4.3 群组踢人

接口: set_group_kick

请求参数:

字段类型必填说明
group_idint64群号
user_idint64要踢的 QQ 号
reject_add_requestboolean拒绝此人的加群请求

请求示例:

{
  "group_id": 987654321,
  "user_id": 123456789,
  "reject_add_request": false
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.5 好友管理

3.5.1 删除好友

接口: delete_friend

请求参数:

字段类型必填说明
user_idint64好友 QQ 号

请求示例:

{
  "user_id": 123456789
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.6 文件操作

3.6.1 上传群文件

接口: upload_group_file

请求参数:

字段类型必填说明
group_idint64群号
filestring本地文件路径
namestring储存名称
folderstring父目录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_idint64群号

请求示例:

{
  "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_idint64群号

请求示例:

{
  "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_idint64群号
folder_idstring文件夹 ID

请求示例:

{
  "group_id": 987654321,
  "folder_id": "xyz789"
}

响应数据: 同 get_group_root_files

3.6.5 获取群文件资源链接

接口: get_group_file_url

请求参数:

字段类型必填说明
group_idint64群号
file_idstring文件 ID
busidint32文件类型

请求示例:

{
  "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_idint64QQ 号
no_cacheboolean是否不使用缓存

请求示例:

{
  "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_idint64群号
no_cacheboolean是否不使用缓存

请求示例:

{
  "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_idint64群号
user_idint64QQ 号
no_cacheboolean是否不使用缓存

请求示例:

{
  "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_idint64群号
no_cacheboolean是否不使用缓存

请求示例:

{
  "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_idint64群号
typestring要获取的荣誉类型

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

请求参数:

字段类型必填说明
flagstring请求标识(从上报中获取)
approveboolean是否同意请求
remarkstring添加后的好友备注

请求示例:

{
  "flag": "request_flag_xxx",
  "approve": true,
  "remark": "新朋友"
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.8.2 处理加群请求/邀请

接口: set_group_add_request

请求参数:

字段类型必填说明
flagstring请求标识(从上报中获取)
sub_typestringadd 或 invite,请求类型
approveboolean是否同意请求/邀请
reasonstring拒绝理由(拒绝时)

请求示例:

{
  "flag": "request_flag_xxx",
  "sub_type": "add",
  "approve": true
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": null
}

3.8.3 获取图片信息

接口: get_image

请求参数:

字段类型必填说明
filestring图片缓存文件名

请求示例:

{
  "file": "xxxx.image"
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": {
    "size": 123456,
    "filename": "xxxx.image",
    "url": "https://gchat.qpic.cn/..."
  }
}

3.8.4 获取语音

接口: get_record

请求参数:

字段类型必填说明
filestring语音文件名
out_formatstring要转换到的格式

请求示例:

{
  "file": "xxxx.record",
  "out_format": "mp3"
}

响应数据:

{
  "status": "ok",
  "retcode": 0,
  "data": {
    "file": "file:///path/to/record.mp3"
  }
}

3.8.5 OCR 图片识别

接口: ocr_image

请求参数:

字段类型必填说明
imagestring图片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

请求参数:

字段类型必填说明
delayint64延迟重启时间(毫秒)

请求示例:

{
  "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/base64
  • magic: 是否变声,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组合:

typeid说明
11戳一戳
22比心
33点赞
44心碎
55666
66放大招

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 字段
  • 自定义消息: 使用 nameuincontent 字段

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禁止访问
1404API 不存在

常见错误处理:

// 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 协议的所有主要接口和事件类型。在实际使用中:

  1. 优先使用 WebSocket:实时性更好,双向通信更方便
  2. 合理处理错误:检查 retcode,记录错误日志
  3. 注意限流:避免频繁调用 API 导致被限制
  4. 消息段灵活组合:充分利用各种消息段类型
  5. 事件及时处理:避免阻塞事件处理流程

如有疑问,请参考:

祝你开发愉快! 🎉

最后修改:2026 年 01 月 11 日
如果觉得我的文章对你有用,请随意赞赏