@windtrace/qq-group-bot
v1.0.36
Published
qq机器人开发SDK,自用改版
Readme
qq-group-bot
一个基于 QQ 开放平台官方 API 的 Node.js 机器人 SDK,支持群聊、私聊(C2C)、频道(频道/服务器)、频道私信四大场景。
- 开箱即用:一条
bot.on(...)订阅消息事件,e.reply(...)直接回复 - 简单易读:基于官方 API 的纯手写封装,无编译产物,无冗余
- 覆盖全面:60+ 常用接口,覆盖消息、群管理、频道、子频道、日程、帖子、面板、互动
- 双模块支持:CommonJS 与 ESM 均可导入
安装
npm i @windtrace/qq-group-bot快速开始
CommonJS
const { Bot } = require('@windtrace/qq-group-bot')
const bot = new Bot({
appid: '', // 必填,QQ机器人的appID
secret: '', // 必填,QQ机器人的secret
sandbox: true, // 是否沙箱环境,默认 false
removeAt: true, // 移除消息开头的@提及,默认 false
logLevel: 'info', // 日志等级,默认 info
maxRetry: 10, // 最大重连次数,默认 10
intents: [ // 必填,订阅事件,无对应权限请注释
'GROUP_AT_MESSAGE_CREATE', // 群聊@消息事件
'C2C_MESSAGE_CREATE', // 私聊事件
'GUILD_MESSAGES', // 私域机器人频道消息事件,公域机器人请注释
'PUBLIC_GUILD_MESSAGES', // 公域机器人频道消息事件,私域机器人请注释
'DIRECT_MESSAGE', // 频道私信事件
'GUILD_MESSAGE_REACTIONS', // 频道消息表态事件
'GUILDS', // 频道变更事件
'GUILD_MEMBERS', // 频道成员变更事件
],
})
bot.start()ESM
import { Bot } from '@windtrace/qq-group-bot'
const bot = new Bot({ appid: '', secret: '', intents: ['GROUP_AT_MESSAGE_CREATE'] })
bot.start()也可以使用 createBot 快捷创建:
import { createBot, defineConfig } from '@windtrace/qq-group-bot'
const bot = createBot(defineConfig({
appid: '',
secret: '',
intents: ['GROUP_AT_MESSAGE_CREATE'],
}))配置项
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| appid | string | ✅ | - | QQ 机器人的 appID |
| secret | string | ✅ | - | QQ 机器人的 secret |
| intents | string[] | ✅ | - | 订阅事件,见下方枚举 |
| sandbox | boolean | | false | 是否使用沙箱环境 |
| removeAt | boolean | | false | 移除消息开头的@提及 |
| logLevel | string | | info | 日志等级:trace/debug/info/warn/error/fatal/mark |
| maxRetry | number | | 10 | 最大重连次数 |
| timeout | number | | 5000 | 请求超时(ms) |
| newapi | boolean | | false | 使用新域名 api.bot.qq.com |
事件订阅
消息事件
| 事件名 | 触发时机 |
|---|---|
| message.guild | 频道收到消息(AT_MESSAGE_CREATE / MESSAGE_CREATE) |
| message.group | 群聊收到消息(GROUP_AT_MESSAGE_CREATE / GROUP_MESSAGE_CREATE) |
| message.private.friend | 好友私聊消息(C2C_MESSAGE_CREATE) |
| message.private.direct | 频道私信消息(DIRECT_MESSAGE_CREATE) |
通知事件
| 事件名 | 触发时机 |
|---|---|
| notice.guild.increase/update/decrease | 频道创建/更新/删除 |
| notice.channel.increase/update/decrease | 子频道创建/更新/删除 |
| notice.channel.enter/exit | 音频/直播子频道成员进入/退出 |
| notice.guild.member.increase/update/decrease | 频道成员增加/更新/移除 |
| notice.group.add/del | 机器人被拉入/移出群 |
| notice.group.increase/decrease | 群成员增加/减少 |
| notice.group.request | 入群申请 |
| notice.group.receive_open/receive_close | 群消息接收/拒绝 |
| notice.friend.increase/decrease | 好友添加/删除 |
| notice.friend.receive_open/receive_close | 私聊消息接收/拒绝 |
| notice | 互动事件(按钮回调 INTERACTION_CREATE),按场景细分:notice.friend.action / notice.group.action / notice.guild.action |
| notice.audit | 消息审核通过/拒绝 |
| notice.forum.thread.create/update/delete | 频道帖子主题创建/更新/删除 |
| notice.forum.post.create/delete | 频道帖子创建/删除 |
| notice.forum.reply.create/delete | 频道帖子回复创建/删除 |
| notice.forum.audit | 频道帖子审核结果 |
订阅对应的通知事件需在
intents中声明,例如频道/子频道变更需GUILDS,成员变更需GUILD_MEMBERS。
发送消息
被动回复(推荐)
bot.start().then(() => {
// 频道消息
bot.on('message.guild', (e) => {
e.reply('hello world')
})
// 群聊消息
bot.on('message.group', (e) => {
e.reply('hello world')
})
// 好友私聊
bot.on('message.private.friend', (e) => {
e.reply('hello world')
})
// 频道私信
bot.on('message.private.direct', (e) => {
e.reply('hello world')
})
})消息事件对象 e 上还提供以下快捷方法:
| 方法 | 说明 |
|---|---|
| e.reply(message) | 回复消息 |
| e.recall() / e.recall(hidetip) | 撤回消息(频道消息支持 hidetip 隐藏提示) |
| e.pin() | 置顶消息(仅频道) |
| e.asAnnounce() | 将消息设置为公告(仅频道) |
| e.reaction(type, id) | 消息表态(仅频道) |
| e.deleteReaction(type, id) | 删除表态(仅频道) |
| e.getReactionMembers(type, id) | 获取表态用户列表(仅频道) |
主动发送
bot.start().then(() => {
// 发送频道消息
bot.sendGuildMessage(channel_id, 'hello')
// 发送群消息
bot.sendGroupMessage(group_id, 'hello')
// 发送私聊消息
bot.sendPrivateMessage(user_id, 'hello')
// 发送频道私信,需先创建私信会话
bot.createDirectSession(guild_id, user_id).then(({ guild_id }) => {
bot.sendDirectMessage(guild_id, 'hello')
})
})消息段(segments)
消息参数支持消息段对象数组(也兼容字符串模板),可组合文本、@、表情、图片、Markdown、按钮等。
// @所有人 + 文本
bot.sendGroupMessage(group_id, [
{ type: 'at', user_id: 'all' },
{ type: 'text', text: ' 大家好' },
])
// @指定用户 + 表情 + 文本
bot.sendGroupMessage(group_id, [
{ type: 'at', user_id: '用户openid' },
{ type: 'face', id: '123' },
{ type: 'text', text: ' 你好' },
])
// 发送本地/网络图片
bot.sendGroupMessage(group_id, [{ type: 'image', file: './a.png' }])
bot.sendGroupMessage(group_id, [{ type: 'image', file: 'https://xxx.com/a.png' }])
// 发送 Markdown(模板ID)
bot.sendGroupMessage(group_id, [{ type: 'markdown', custom_template_id: 'xxx' }])
// 消息引用回复
bot.sendGroupMessage(group_id, [{ type: 'reply', id: '消息id' }, { type: 'text', text: '引用回复' }])支持的消息段类型:
| 类型 | 说明 |
|---|---|
| text | 纯文本 |
| at | @某人(user_id 传 all 表示@全体) |
| face | 表情(id) |
| reply | 引用回复(id 为消息id,或 event_id) |
| image / video / audio / file | 媒体文件(file 支持本地路径/URL/base64:///Buffer) |
| markdown | Markdown(content 或 custom_template_id) |
| keyboard | 按钮键盘 |
| embed / ark / card | 富媒体卡片 |
流式消息
// 流式发送长文本(自动分片)
bot.sendPrivateStreamMessage(user_id, '这是一段很长的文本...', null, {
chunkSize: 100, // 每片字符数,默认 总长/2
delay: 100, // 分片间隔(ms),默认 100
})API 参考
好友
| 方法 | 说明 |
|---|---|
| getSelfInfo() | 获取机器人信息 |
| getFriendList() | 获取好友列表(暂未支持) |
| getFriendInfo(friend_id) | 获取好友信息(暂未支持) |
| sendFriendInputNotify(user_id, input_type, input_second, msg_id) | 设置私聊输入状态 |
群管理
| 方法 | 说明 |
|---|---|
| getGroupInfo(group_id) | 获取群信息 |
| getGroupList() | 获取群列表 |
| getGroupBotInfo(group_id) | 获取群内 bot 状态 |
| getGroupMemberList(group_id) | 获取群成员列表 |
| getGroupMemberInfo(group_id, member_id) | 获取群成员信息 |
| kickGroupMember(group_id, member_id) | 踢出群成员 |
| muteGroupMember(group_id, op, memberlist, end_time) | 禁言群成员(op: add/update/del) |
| getGroupmuteState(group_id) | 获取群内禁言状态 |
| approvalGroupRequest(group_id, member_id, op, join_request_id, reject_reason, add_to_member_blacklist) | 入群申请审批 |
| getGroupRequestList(group_id) | 入群申请列表 |
| getAutoApproveList() | 获取自动审批策略列表 |
| createAutoApprove(group_openids, group_ids, is_enable, expire_at, remark) | 创建自动审批策略 |
| changeAutoApprove(strategy_id, is_enable, expire_at, group_action, remark) | 修改自动审批策略 |
| deleteAutoApprove(strategy_id) | 删除自动审批策略 |
| execAutoApprove(strategy_id) | 执行自动审批策略 |
| changeWhitelistOfAutoApprove(strategy_id, op, whitelist_users) | 修改自动审批策略白名单 |
频道(服务器)
| 方法 | 说明 |
|---|---|
| getGuildList() | 获取频道列表 |
| getGuildInfo(guild_id) | 获取频道信息 |
| getGuildMemberList(guild_id) | 获取频道成员列表 |
| getGuildMemberInfo(guild_id, member_id) | 获取频道成员信息 |
| kickGuildMember(guild_id, member_id, clean, blacklist) | 踢出频道成员 |
| muteGuild(guild_id, seconds, end_time) / unMuteGuild(guild_id) | 频道禁言 / 取消禁言 |
| muteGuildMember(guild_id, member_id, seconds, end_time) / unMuteGuildMember(guild_id, member_id) | 禁言频道成员 / 取消禁言 |
| muteGuildMembers(guild_id, member_ids, seconds, end_time) / unMuteGuildMembers(guild_id, member_ids) | 批量禁言 / 取消禁言 |
| getGuildRoles(guild_id) | 获取频道角色列表 |
| creatGuildRole(guild_id, role) | 创建频道角色 |
| updateGuildRole(guild_id, role_id, updateInfo) | 修改频道角色 |
| deleteGuildRole(role_id) | 删除频道角色 |
| addGuildMemberRoles(guild_id, channel_id, member_id, role_id) | 添加频道成员角色 |
| removeGuildMemberRoles(guild_id, channel_id, member_id, role_id) | 移除频道成员角色 |
| getChannelPermissionOfRole(channel_id, role_id) | 获取角色频道权限 |
| updateChannelPermissionOfRole(channel_id, role_id, permission) | 更新角色频道权限 |
| getChannelMemberPermission(channel_id, member_id) | 获取用户频道权限 |
| updateChannelMemberPermission(channel_id, member_id, permission) | 更新用户频道权限 |
| getChannelPins(channel_id) | 获取置顶消息列表 |
| pinChannelMessage(channel_id, message_id) / unPinChannelMessage(channel_id, message_id) | 置顶 / 取消置顶消息 |
| setChannelAnnounce(guild_id, channel_id, message_id) | 设置频道公告 |
| getGuildAccessApis(guild_id) | 获取频道可访问 API 类别 |
| applyGuildAccess(guild_id, channel_id, apiInfo, desc) | 申请频道 API 权限 |
子频道
| 方法 | 说明 |
|---|---|
| createChannel(guild_id, channelInfo) | 创建子频道 |
| updateChannel(channel_id, updateInfo) | 修改子频道 |
| deleteChannel(channel_id) | 删除子频道 |
| getChannelList(guild_id) | 获取子频道列表 |
| getChannelInfo(channel_id) | 获取子频道信息 |
| reactionGuildMessage(channel_id, message_id, type, id) | 对消息表态 |
| deleteGuildMessageReaction(channel_id, message_id, type, id) | 删除消息表态 |
| getGuildMessageReactionMembers(channel_id, message_id, type, id) | 获取表态用户列表 |
| getChannelSchedules(channel_id, since) | 获取频道日程 |
| getChannelScheduleInfo(channel_id, schedule_id) | 获取日程详情 |
| createChannelSchedule(channel_id, schedule) | 创建日程 |
| updateChannelSchedule(channel_id, schedule_id, schedule) | 修改日程 |
| deleteChannelSchedule(channel_id, schedule_id) | 删除日程 |
| controlChannelAudio(channel_id, audio_control) | 音频控制 |
| setOnlineMic(channel_id) / setOfflineMic(channel_id) | 上麦 / 下麦 |
| getChannelThreads(channel_id) | 获取频道帖子列表 |
| getChannelThreadInfo(channel_id, thread_id) | 获取帖子详情 |
| publishThread(channel_id, title, content, format) | 发布帖子 |
| deleteThread(channel_id, thread_id) | 删除帖子 |
消息(私聊/群/频道/频道私信)
| 方法 | 说明 |
|---|---|
| sendPrivateMessage(user_id, message, source, options) | 发送私聊消息(options.stream 为 true 时自动流式发送) |
| sendPrivateStreamMessage(user_id, message, source, options) | 流式发送私聊消息 |
| recallPrivateMessage(user_id, message_id) | 撤回私聊消息 |
| sendGroupMessage(group_id, message, source) | 发送群消息 |
| recallGroupMessage(group_id, message_id) | 撤回群消息 |
| sendGuildMessage(channel_id, message, source) | 发送频道消息 |
| recallGuildMessage(channel_id, message_id, hidetip) | 撤回频道消息 |
| getGuildMessage(channel_id, message_id) | 获取频道消息 |
| sendDirectMessage(guild_id, message, source) | 发送频道私信 |
| getDirectMessage(guild_id, message_id) | 获取频道私信 |
| recallDirectMessage(guild_id, message_id, hidetip) | 撤回频道私信 |
自定义菜单 / 指令面板
| 方法 | 说明 |
|---|---|
| getMenu() | 获取全局自定义菜单 |
| changeMenu(menu) | 修改全局自定义菜单 |
| getPanels(scope) | 获取指令面板列表(scope: c2c/group/channel/dm) |
| createPanels(scope, target_type, user_openids, group_openids, panel) | 创建指令面板 |
| getPanel(panel_id) | 获取指令面板详情 |
| changePanel(panel_id, panel) | 修改指令面板 |
| deletePanel(panel_id) | 删除指令面板 |
| changePanelTarget(panel_id, op, useropenids, groupopenids) | 修改指令面板关联对象 |
互动
| 方法 | 说明 |
|---|---|
| replyAction(action_id, code, opt) | 回应互动操作(按钮回调) |
| createDirectSession(guild_id, user_id) | 创建私信会话 |
| getGenerateUrl(callback_data) | 获取机器人分享链接 |
工具函数
| 函数 | 说明 |
|---|---|
| getFileBase64(file) | 文件转 base64(支持本地路径/URL/base64:///Buffer) |
| getBase64FromLocal(filepath) | 本地文件转 base64 |
| getBase64FromWeb(url) | 网络资源转 base64 |
| md5(data) | 计算 md5 哈希 |
| deepClone(obj) | 深拷贝 |
| isEmpty(data) | 判断是否为空对象 |
| remove(list, item) | 从数组移除元素 |
| toObject(data) | 解析为对象 |
| trimQuote(str) | 去除首尾引号 |
| findLastIndex(list, predicate) | 查找最后一个满足条件的元素下标 |
const { getFileBase64 } = require('@windtrace/qq-group-bot')
// 图片统一用消息段(segments),base64 加 base64:// 前缀(群/私聊/频道通用)
bot.sendGroupMessage(group_id, [{ type: 'image', file: `base64://${await getFileBase64('./a.png')}` }])
// 本地路径/URL 直接作为 file
bot.sendGroupMessage(group_id, [{ type: 'image', file: './a.png' }])
bot.sendGroupMessage(group_id, [{ type: 'image', file: 'https://xxx.com/a.png' }])注意:base64 数据含
=填充符,不能内联进字符串模板(会被解析截断),需使用消息段对象数组;file也可直接传 Buffer。
注意事项
- 私聊、群聊场景的
user_id/group_id/member_id均为 openid,需通过消息事件或getGroupMemberList等接口获取 - 沙箱环境与正式环境的数据不互通,切换环境需重新申请相关权限
- 频道私信发送前必须先调用
createDirectSession创建会话 - 群聊@事件、私聊事件需机器人具备对应权限,否则请从
intents中注释掉
