1. 引言
WorkBuddy 是一款面向个人和团队的工作流自动化工具,支持通过插件和 Webhook 与外部服务对接。将 WorkBuddy 接入 QQ,可以让机器人在群聊或私聊中自动响应指令、执行任务并返回结果,从而把日常沟通与自动化流程打通。本文将从账号准备、服务搭建、消息收发到工作流联动,完整演示接入过程,并提供可直接运行的代码示例。
2. 准备工作
在开始之前,需要准备以下环境和账号:
- 一个可用的 QQ 账号,用于登录机器人框架。
- 一台可联网的服务器或本地开发机,建议使用 Linux 或 macOS。
- Node.js 16 及以上版本,用于运行示例代码。
- WorkBuddy 账号,并创建一个空白工作流。
本文使用NapCatQQ作为 QQ 协议实现,通过 WebSocket 与本地服务通信。NapCatQQ 提供稳定的消息收发接口,适合个人开发者和中小团队使用。
3. 搭建 QQ 消息服务
首先安装 NapCatQQ 并启动服务。以下以 Docker 方式为例:
docker run -d \ --name napcat \ -p 3001:3001 \ -p 6099:6099 \ -e NAPCAT_UID=$(id -u) \ -e NAPCAT_GID=$(id -g) \ --network host \ mlikiowa/napcat-docker:latest启动后,在浏览器中访问http://localhost:6099/webui进入管理界面,使用 QQ 扫码登录。登录成功后,NapCatQQ 会监听3001端口提供 HTTP API,同时通过6099端口提供 WebSocket 事件推送。
接下来创建一个 Node.js 项目,并安装依赖:
mkdir workbuddy-qq-bot cd workbuddy-qq-bot npm init -y npm install ws axios4. 接收 QQ 消息
NapCatQQ 通过 WebSocket 推送消息事件。下面代码实现消息监听,并把收到的文本消息打印到控制台:
const WebSocket = require('ws'); const ws = new WebSocket('ws://localhost:3001'); ws.on('open', () => { console.log('已连接到 NapCatQQ WebSocket'); }); ws.on('message', (data) => { const event = JSON.parse(data.toString()); if (event.post_type === 'message') { const { message_type, user_id, group_id, raw_message } = event; const sender = message_type === 'group' ? `群 ${group_id}` : `用户 ${user_id}`; console.log(`[${sender}] ${raw_message}`); } }); ws.on('error', (err) => { console.error('WebSocket 错误:', err.message); });保存为listen.js并运行:
node listen.js此时在 QQ 中给机器人发送一条消息,控制台应能打印出对应内容。
5. 发送 QQ 消息
发送消息需要调用 NapCatQQ 的 HTTP API。下面封装一个发送函数,支持私聊和群聊:
const axios = require('axios'); const API_BASE = 'http://localhost:3001'; async function sendMessage(message_type, target_id, text) { const payload = { message_type, user_id: message_type === 'private' ? target_id : undefined, group_id: message_type === 'group' ? target_id : undefined, message: text }; const res = await axios.post(`${API_BASE}/send_msg`, payload); return res.data; } // 示例:发送私聊消息 sendMessage('private', 10001, '你好,我是 WorkBuddy 机器人') .then((data) => console.log('发送成功:', data)) .catch((err) => console.error('发送失败:', err.message));将上面的代码保存为send.js,把10001替换为真实的 QQ 号后运行,即可验证消息发送能力。
6. 接入 WorkBuddy 工作流
WorkBuddy 提供 Webhook 触发器和 HTTP 请求节点。下面演示如何把 QQ 消息转发到 WorkBuddy,并把返回结果回传给 QQ。
首先在 WorkBuddy 中创建一个工作流,添加一个Webhook 触发器,请求方式选择POST,请求体格式为 JSON。工作流内部可以串联任意节点,例如调用大模型、查询数据库或执行脚本。最后添加一个HTTP 响应节点,返回处理结果。
假设 WorkBuddy 的 Webhook 地址为https://api.workbuddy.cn/webhook/qq-bot,下面代码实现消息转发:
const WebSocket = require('ws'); const axios = require('axios'); const WS_URL = 'ws://localhost:3001'; const WORKBUDDY_WEBHOOK = 'https://api.workbuddy.cn/webhook/qq-bot'; const ws = new WebSocket(WS_URL); async function callWorkBuddy(text) { const res = await axios.post(WORKBUDDY_WEBHOOK, { text }); return res.data; } async function reply(message_type, target_id, text) { const payload = { message_type, user_id: message_type === 'private' ? target_id : undefined, group_id: message_type === 'group' ? target_id : undefined, message: text }; await axios.post('http://localhost:3001/send_msg', payload); } ws.on('message', async (data) => { const event = JSON.parse(data.toString()); if (event.post_type !== 'message') return; const { message_type, user_id, group_id, raw_message } = event; const target_id = message_type === 'group' ? group_id : user_id; try { const result = await callWorkBuddy(raw_message); const replyText = result.reply || '处理完成,但没有返回内容。'; await reply(message_type, target_id, replyText); } catch (err) { console.error('调用 WorkBuddy 失败:', err.message); await reply(message_type, target_id, '抱歉,处理消息时出现错误。'); } }); console.log('WorkBuddy QQ 机器人已启动');保存为bridge.js并运行,即可实现 QQ 消息到 WorkBuddy 工作流的完整闭环。
7. 完整示例:关键词指令机器人
下面给出一个更完整的示例,支持关键词匹配和简单对话。当用户发送/help时返回帮助信息,发送/time时返回当前时间,其他消息则转发给 WorkBuddy 处理:
const WebSocket = require('ws'); const axios = require('axios'); const WS_URL = 'ws://localhost:3001'; const WORKBUDDY_WEBHOOK = 'https://api.workbuddy.cn/webhook/qq-bot'; const ws = new WebSocket(WS_URL); function getHelpText() { return [ '可用指令:', '/help - 显示帮助', '/time - 获取当前时间', '其他消息将转发给 WorkBuddy 处理' ].join('\n'); } async function sendMessage(message_type, target_id, text) { const payload = { message_type, user_id: message_type === 'private' ? target_id : undefined, group_id: message_type === 'group' ? target_id : undefined, message: text }; await axios.post('http://localhost:3001/send_msg', payload); } async function handleMessage(event) { const { message_type, user_id, group_id, raw_message } = event; const target_id = message_type === 'group' ? group_id : user_id; const text = raw_message.trim(); if (text === '/help') { await sendMessage(message_type, target_id, getHelpText()); return; } if (text === '/time') { const now = new Date().toLocaleString('zh-CN'); await sendMessage(message_type, target_id, `当前时间:${now}`); return; } try { const res = await axios.post(WORKBUDDY_WEBHOOK, { text }); const replyText = res.data.reply || '处理完成。'; await sendMessage(message_type, target_id, replyText); } catch (err) { console.error('WorkBuddy 调用失败:', err.message); await sendMessage(message_type, target_id, '处理消息时出现错误,请稍后再试。'); } } ws.on('message', (data) => { const event = JSON.parse(data.toString()); if (event.post_type === 'message') { handleMessage(event).catch((err) => console.error('处理消息异常:', err)); } }); console.log('关键词指令机器人已启动');8. 部署与运维建议
本地调试通过后,建议将服务部署到云服务器,并使用进程管理工具保持运行。以下使用pm2管理 Node.js 进程:
npm install -g pm2 pm2 start bridge.js --name workbuddy-qq-bot pm2 save pm2 startup同时建议配置日志轮转,避免日志文件无限增长:
pm2 install pm2-logrotate pm2 set pm2-logrotate:max_size 10M pm2 set pm2-logrotate:retain 7安全方面,建议为 NapCatQQ 的 HTTP API 设置访问令牌,并在 WorkBuddy Webhook 中校验请求签名,防止未授权调用。
9. 常见问题排查
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| WebSocket 连接失败 | NapCatQQ 未启动或端口错误 | 检查容器状态,确认 3001 端口监听正常 |
| 收不到 QQ 消息 | 机器人未登录或事件未订阅 | 在 NapCatQQ 管理界面确认登录状态,检查事件订阅配置 |
| 发送消息报错 | 目标 QQ 号不存在或 API 地址错误 | 核对 QQ 号和 API 地址,查看返回的错误信息 |
| WorkBuddy 无响应 | Webhook 地址错误或工作流未发布 | 在 WorkBuddy 控制台测试 Webhook,确认工作流已发布 |
10. 总结
本文从零演示了 WorkBuddy 接入 QQ 的完整流程,包括 NapCatQQ 服务搭建、消息收发、Webhook 转发和关键词指令机器人实现。通过这套方案,可以把 QQ 群聊或私聊消息接入 WorkBuddy 工作流,实现自动问答、任务执行和数据查询等能力。后续可以根据业务需要扩展更多指令,或接入多个 QQ 群组,构建更复杂的自动化场景。