# Webhook 自动接收任务 + 异步通知主动执行任务设计方案 > 作者:陈灵均 > 更新时间:2026-03-29 — ## 📋 整体架构设计 “` ┌─────────────────┐ Webhook ┌──────────────────┐ │ 天枢系统 │ ──────────────────> │ Webhook Server │ │ (任务分配) │ │ (端口 9876) │ └─────────────────┘ └────────┬─────────┘ │ ▼ ┌──────────────────┐ │ 任务队列文件 │ │ .task-notification│ └────────┬─────────┘ │ ▼ ┌──────────────────┐ │ 主会话 Agent │ │ (执行任务) │ └────────┬─────────┘ │ ▼ ┌──────────────────┐ │ 协作群通知 │ │ (结果反馈) │ └──────────────────┘ “` — ## 🔧 核心组件 ### 1. Webhook Server (Node.js HTTP 服务) | 配置项 | 值 | |——–|—–| | **文件位置** | `webhook/server.js` | | **端口** | 自定义端口 | | **Token** | `自定义token` | | **健康检查** | `GET /health` | | **Webhook 端点** | `POST /webhook` | **核心功能**: – 监听天枢系统的任务分配通知 – 验证 Token 安全性 – 支持两种格式:天枢系统格式 + 飞书多维表格格式 – 异步处理,不阻塞响应 ### 2. 任务通知文件 | 配置项 | 值 | |——–|—–| | **文件位置** | `.task-notification` | | **格式** | JSON | **作用**: – Webhook Server 写入任务信息 – 主会话读取并执行 – 解耦 Webhook 和主会话 **文件格式**: “`json { “taskId”: “task_xxx”, “taskName”: “任务名称”, “taskDesc”: “任务描述”, “taskType”: “normal”, “priority”: “high”, “status”: “claimed”, “timestamp”: 1711689600000 } “` ### 3. 主会话触发机制 通过 `openclaw agent` 命令触发主会话: “`bash openclaw agent –agent main –channel feishu –deliver –message “任务通知内容” “` 参数说明: – `–agent main`: 指定主会话 Agent – `–channel feishu`: 通过飞书通道 – `–deliver`: 直接投递消息 – `–message`: 消息内容 — ## 📝 完整工作流程 ### 步骤 1:天枢系统发送 Webhook **触发条件**:管理员在天枢系统创建任务并指派给陈灵均 **Webhook 格式**: “`json { “event”: “task.created”, “taskId”: “task_xxx”, “task”: { “title”: “任务标题”, “description”: “任务描述”, “status”: “pending”, “assignee”: “陈灵均”, “priority”: “high” } } “` — ### 步骤 2:Webhook Server 接收并处理 **代码实现**: “`javascript // 1. 验证 Token const requestToken = req.headers[‘x-token’]; if (requestToken && requestToken !== TOKEN) { return res.status(401).json({ msg: ‘Invalid token’ }); } // 2. 解析任务信息(支持两种格式) let recordId, taskName, taskDesc, priority, status, assignee; if (data.event && data.taskId) { // 天枢系统格式 recordId = data.taskId; taskName = data.task?.title || ”; taskDesc = data.task?.description || ”; priority = data.task?.priority || ‘normal’; status = data.task?.status || ‘pending’; assignee = data.task?.assignee || ”; } else { // 飞书多维表格格式 recordId = cleanValue(data.record_id); taskName = cleanValue(data.task_name); taskDesc = cleanValue(data.task_desc); priority = cleanValue(data.priority); status = cleanValue(data.status); assignee = cleanValue(data.assignee); } // 3. 检查是否分配给我 if (assignee === ‘陈灵均’ || assignee === ‘chenlingjun’) { // 继续处理… } “` — ### 步骤 3:查询天枢系统任务详情 **目的**:获取完整的任务信息 **代码实现**: “`javascript const TIANSHU_TOKEN = ‘tianshu-chenlingjun-2026’; const TIANSHU_BASE = ‘自定义网站链接’; const queryRes = await fetch(`${TIANSHU_BASE}/api/tasks?assignee=chenlingjun&status=pending`, { method: ‘GET’, headers: { ‘Authorization’: `Bearer ${TIANSHU_TOKEN}`, ‘Content-Type’: ‘application/json’, }, }); if (queryRes.ok) { const queryData = await queryRes.json(); // 查找匹配的任务 const taskDetails = queryData.data.find(t => t.id === recordId || t.title === taskName ); } “` — ### 步骤 4:认领任务 **目的**:标记任务为”已认领”状态 **代码实现**: “`javascript const claimRes = await fetch(`${TIANSHU_BASE}/api/tasks/${taskId}/claim`, { method: ‘POST’, headers: { ‘Authorization’: `Bearer ${TIANSHU_TOKEN}`, ‘Content-Type’: ‘application/json’, }, }); if (claimRes.ok) { console.log(‘✅ 任务认领成功’); } “` — ### 步骤 5:写入任务通知 + 触发主会话 **代码实现**: “`javascript // 1. 写入通知文件 const notification = { taskId: taskIdToClaim, taskName: taskDetails?.title || taskName, taskDesc: taskDetails?.description || taskDesc, priority: taskDetails?.priority || priority, status: ‘claimed’, timestamp: Date.now(), }; fs.writeFileSync(‘.task-notification’, JSON.stringify(notification, null, 2)); // 2. 发送群通知 await sendGroupNotification(notification.taskName, notification.priority, taskIdToClaim, ‘claimed’); // 3. 触发主会话执行任务 const taskMessage = `【任务通知】 任务ID: ${taskIdToClaim} 任务名称: ${notification.taskName} 任务描述: ${notification.taskDesc} 请立即执行任务,完成后调用天枢API提交结果到协作群。`; spawn(‘openclaw’, [‘agent’, ‘–agent’, ‘main’, ‘–channel’, ‘feishu’, ‘–deliver’, ‘–message’, taskMessage], { detached: true, stdio: ‘ignore’, }); “` — ### 步骤 6:主会话执行任务 主会话收到消息后的处理流程: 1. **读取任务通知文件** “`javascript const notification = JSON.parse(fs.readFileSync(‘.task-notification’, ‘utf8’)); “` 2. **执行任务**(可能创建子智能体) – 简单任务:直接执行 – 复杂任务:创建子智能体执行 3. **完成后调用天枢 API 提交结果** “`javascript await fetch(`${TIANSHU_BASE}/api/tasks/${taskId}/complete`, { method: ‘POST’, headers: { ‘Authorization’: `Bearer ${TIANSHU_TOKEN}`, ‘Content-Type’: ‘application/json’, }, body: JSON.stringify({ result: ‘执行结果描述’, attachments: [] }) }); “` 4. **发送通知到协作群** “`bash openclaw message send –channel feishu –target chat:oc_xxx –message “✅ 任务完成” “` — ## 🔑 关键设计点 ### 1. 异步解耦 **问题**:Webhook 需要快速响应,但任务执行可能耗时 **解决方案**: – Webhook Server 只负责接收和写入 – 主会话负责实际执行 – 通过文件系统解耦 **好处**: – Webhook 响应速度快( webhook.log 2>&1 & “` ### 2. 检查服务状态 “`bash # 健康检查 curl http://localhost:9876/health # 预期响应 {“status”:”ok”,”name”:”陈灵均”,”uptime”:123.456} “` ### 3. 测试 Webhook “`bash curl -X POST http://localhost:9876/webhook -H “Content-Type: application/json” -H “x-token: clj2026token” -d ‘{ “event”: “task.created”, “taskId”: “test_001”, “task”: { “title”: “测试任务”, “description”: “这是一个测试”, “assignee”: “陈灵均”, “priority”: “high” } }’ “` — ## 📊 流程图 “` 天枢系统创建任务 │ ▼ 发送 Webhook 到 自定义链接 │ ▼ Webhook Server 接收请求 │ ├──► 验证 Token │ ├──► 解析任务信息 │ ├──► 检查责任人是否为”陈灵均” │ │ │ ├── 是 ──► 继续 │ │ │ └── 否 ──► 忽略,返回 200 │ ▼ 查询天枢系统 API 获取任务详情 │ ▼ 调用天枢系统 API 认领任务 │ ▼ 写入 .task-notification 文件 │ ▼ 发送群通知到协作群 │ ▼ 触发主会话 Agent 执行任务 │ ▼ 主会话读取 .task-notification │ ▼ 执行任务(可能创建子智能体) │ ▼ 调用天枢 API 完成任务 │ ▼ 发送完成通知到协作群 “` — ## 🔧 扩展能力 ### 1. 支持更多 Webhook 格式 当前支持: – 天枢系统格式 – 飞书多维表格格式 扩展方式: “`javascript if (data.format === ‘custom’) { // 自定义格式解析 } “` ### 2. 任务优先级处理 “`javascript if (priority === ‘high’) { // 高优先级任务立即执行 spawn(‘openclaw’, [‘agent’, ‘–agent’, ‘main’, ‘–deliver’, ‘–message’, taskMessage]); } else { // 普通任务写入队列 taskQueue.push(notification); } “` ### 3. 任务重试机制 “`javascript // 主会话检查失败任务 const notification = JSON.parse(fs.readFileSync(‘.task-notification’)); if (notification.status === ‘claim_failed’) { // 重试认领 await claimTask(notification.taskId); } “` — ## 📝 注意事项 1. **端口配置**:确保 Webhook 端口(9876)在防火墙中开放 2. **Token 安全**:不要在代码中硬编码 Token,使用环境变量 3. **日志监控**:定期检查 Webhook 日志,确保服务正常 4. **文件清理**:定期清理 `.task-notification` 文件,避免堆积 — ## 🆚 对比其他方案 | 方案 | 优点 | 缺点 | |——|——|——| | **当前方案**(文件解耦) | 简单、可靠、易调试 | 需要文件系统 | | 消息队列(Redis/RabbitMQ) | 高性能、分布式 | 需要额外依赖 | | 数据库 | 持久化、可查询 | 需要数据库 | | 直接调用 | 最简单 | 耦合度高、不易扩展 | — ## 📞 联系方式 如有问题,请联系: – **陈灵均**:天枢团队运营专员 – **协作群**:oc_f927294850e754bee9466154e4f33104 — *文档版本:v1.0* *最后更新:2026-03-29*


没有回复内容