forked from wangziqi/gongxue-base
3.3 KiB
3.3 KiB
CRM Webhook Worker
更新时间:2026-06-29
apps/worker 是后端异步任务进程,当前首个落地任务是 CRM 客资 webhook 推送。API 只负责在客资首绑时写入 crm_webhook_queue;worker 负责消费到期任务、签名、发送、失败重试和写入 crm_webhook_log。
运行命令
本地单次消费一批任务:
npm --workspace @tiku-saas/worker run crm:once
或使用根脚本测试:
npm run test:worker:crm
生产常驻:
npm --workspace @tiku-saas/worker run start
建议 API 和 worker 作为两个独立进程部署,共用同一个 DATABASE_URL。
配置
环境变量:
WORKER_CRM_BATCH_SIZE=20
WORKER_CRM_POLL_INTERVAL_MS=10000
WORKER_CRM_MAX_ATTEMPTS=5
WORKER_CRM_BACKOFF_SECONDS=5,30,120,600,1800
WORKER_CRM_REQUEST_TIMEOUT_MS=10000
WORKER_CRM_ALLOW_INSECURE_LOCALHOST=false
租户后台配置仍走:
PUT /api/crm/config
GET /api/crm/config
GET /api/crm/queue
密钥必须写入 app_private.tenant_secrets,公共表 crm_config.secret_ref 只保留引用,例如:
app_private.tenant_secrets:crm:webhook
Provider
worker 根据队列 payload 的 provider 或 webhook URL 自动判断:
| provider | URL 特征 | 行为 |
|---|---|---|
generic |
默认 | POST { event: "lead.created", data: ... } |
dingtalk |
dingtalk.com |
markdown 消息;按钉钉自定义机器人安全设置做 timestamp/sign |
feishu |
feishu.cn / larksuite.com |
interactive card;按飞书自定义机器人签名做 timestamp/sign |
wecom |
qyapi.weixin.qq.com / work.weixin.qq.com |
企业微信群机器人 markdown 消息 |
官方参考:
- 钉钉开放平台:自定义机器人安全设置,
timestamp + "\n" + secret做 HMAC-SHA256 后 Base64。 - 飞书开放平台:自定义机器人签名校验,使用 timestamp 和 secret 生成签名。
- 企业微信开发者文档:群机器人配置说明,群机器人 webhook 使用
msgtype消息体。
队列状态
crm_webhook_queue.status:
pending -> processing -> sent
pending -> processing -> retrying -> processing -> sent
pending -> processing -> retrying -> failed
pending -> discarded
说明:
pending/retrying:等待 worker 消费。processing:worker 已抢占任务。sent:目标 webhook 返回 2xx。failed:超过最大重试次数。discarded:租户 CRM 未启用或 URL 缺失,任务不会继续重试。
每次尝试都会写入 crm_webhook_log,日志只记录 provider、目标 host、请求体和响应摘要,不写入 webhook secret。
安全边界
- 前端不能直接写
crm_webhook_queue。 - 前端不能持有 CRM webhook secret。
- 生产环境 webhook 必须使用 HTTPS。
WORKER_CRM_ALLOW_INSECURE_LOCALHOST=true只用于本地 fake webhook 测试。- worker 使用数据库服务端连接读取
app_private.tenant_secrets,不要把 secret 复制到公共表。
后续增强
- 轮询/定向分配销售。
- 钉钉/飞书/企微富卡片模板。
- 失败告警和死信运营后台。
- 批量 CRM 推送、跟进效果统计。