feat: 任务发布到企微客户群(企业群发)与资源库单条新增

- 任务中心新增「发布到企微群」:同步客户群清单(wecom_group_chats)、
  按群主分组创建企业群发任务(add_msg_template)、发送记录落库
  wecom_group_pushes,迁移 mysql/0009;lib/wecom-client.ts 补
  listCustomerGroupChats/createGroupMsgTemplate
- KOC 资源库支持单条新增:app/api/resources-insert + lib/resource-write,
  拆出资源写入公共逻辑供导入复用;0008 补合作方外部联系人字段
- 环境变量示例补企微凭证与 SEED_DEMO_DATA;next.config 增加
  allowedDevOrigins;CLAUDE.md 补充项目说明
- .gitignore 排除 .codegraph/ 与 .ipynb_checkpoints/
This commit is contained in:
ABAPPLO
2026-08-20 15:16:18 +08:00
parent 8f7ea0558d
commit 9697b5890d
22 changed files with 3695 additions and 449 deletions

View File

@@ -54,6 +54,12 @@ cp .env.self-hosted.example .env.self-hosted
| `FEISHU_APP_ID` / `FEISHU_APP_SECRET` | 读取飞书内容表和配图 |
| `AI_TOOL_CENTER_MCP_URL` / `AI_TOOL_CENTER_MCP_KEY` | 小红书公开数据采集服务 |
| `ENABLE_SCHEDULER` | 是否启用每天 09:00 自动采集,生产保持 `true` |
| `WECOM_CORP_ID` / `WECOM_AGENT_ID` / `WECOM_SECRET` | 企业微信自建应用,用于临期催办的应用消息推送;三项需同时填写,全部留空则只走群机器人 |
| `WECOM_ROBOT_WEBHOOK` | 企业微信群机器人 webhook用于当日催办汇总 |
| `WECOM_NOTIFY_DUE_DAYS` | 临期阈值,默认 3超过则不在催办可填 130 |
| `WECOM_NOTIFY_ENABLED` | 企业微信通知总开关,默认 `true`;临时关闭设为 `false` |
企业微信变量全部选填:不填则临期催办与汇总都跳过,不影响其他功能。所有变量都可以在「合作方」页面顶部「企业微信连通性」面板查看就绪状态,并用「测试群机器人」「测试发送」按钮验证。
密钥必须由密码管理器生成,禁止提交到 Git、聊天、部署日志或 URL。三个业务密钥 `ADMIN_INTERNAL_TOKEN``KOC_MCP_API_KEY``AI_TOOL_CENTER_MCP_KEY` 不得复用。
@@ -206,3 +212,57 @@ docker compose --env-file .env.self-hosted \
| 飞书读取失败 | 检查应用权限、文档授权和服务器到飞书 OpenAPI 的网络 |
生产日志不得打印数据库密码、飞书 Secret、MCP key 或完整带 key 的采集服务 URL。
## 11. 企业微信自建应用与群机器人配置
KOC LOOP 的企业微信通知是**单向外发**:每天 09:00 与定时采集一同触发,给合作方绑定的外部联系人推送临期催办,再向群机器人发送当日汇总。不需要 OAuth 回调,也不需要拉通讯录。
### 11.1 群机器人(用于当日催办汇总)
1. 在企业微信里建立一个用于催办的群;
2. 群设置 → 群机器人 → 添加机器人 → 复制 webhook 地址,形如 `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=...`
3. 把整个 webhook 写入 `WECOM_ROBOT_WEBHOOK`
只要这一项就绪,每天 09:00 的催办汇总就会推到该群。
### 11.2 自建应用(用于给单个合作方发应用消息)
1. 登录企业微信管理后台 → 应用管理 → 自建 → 创建应用,名称建议 `KOC LOOP 催办`
2. 应用详情页记下 `AgentId`,填入 `WECOM_AGENT_ID`
3. 我的企业 → 企业信息 → 企业 ID填入 `WECOM_CORP_ID`
4. 应用详情页 → Secret → 发送 Secret 到管理端,填入 `WECOM_SECRET`
5. 应用「可见范围」必须包含合作方对应的企业微信成员,否则推送时会返回 `invaliduser`
### 11.3 绑定外部联系人
企业微信应用消息推送需要 `external_userid`(外部联系人 IDKOC LOOP 不自动拉取,需要手动绑定:
1. 在企业微信「客户联系 → 外部联系人」里找到合作方对应的客户;
2. 复制其 external_userid形如 `woxxxxxx`
3. 在 KOC LOOP 后台「合作方」页面,找到对应合作方行,点「绑定」粘贴 ID → 「保存」;
4. 点「测试发送」验证;如果返回 `应用消息发送失败`,多半是应用可见范围未包含该外部联系人,或 external_userid 复制错了。
外部联系人 ID 不入库后不会自动同步企业微信端的变更;如果合作方的外部联系人在企业微信里被删除或转移,需要回来更新这一列。
### 11.4 验证
部署后到后台「合作方」页面,顶部「企业微信连通性」面板应显示三项就绪状态:群机器人、自建应用消息、临期阈值。逐项点「测试」:
- 「测试群机器人」:群内收到 `[KOC LOOP 测试] 群机器人连通性正常,时间 ...` 即配置成功;
- 合作方行的「测试发送」:对应外部联系人收到同样格式的测试消息即绑定正确。
如果面板显示「未配置」但已填环境变量,先确认容器加载了新的 `.env.self-hosted`(重启服务),再回到该页面点「刷新状态」。
### 11.5 任务发布到企微客户群(企业群发)
平台支持把任务以「企业群发」方式推送到多个外部客户群。**企业微信不允许外部群添加群机器人 webhook**,官方路径是半自动群发:平台创建群发任务 → 各群的群主在企业微信客户端「群发助手」里点击发送 → 消息才送达客户群。依赖 11.2 的同一个自建应用,无需新增环境变量;数据库表 `wecom_group_chats` / `wecom_group_pushes` 由迁移 `mysql/0009_wecom_group_push.sql` 创建(`npm run db:migrate` 自动执行)。
使用前需在企业微信管理后台完成三项配置:
1. **客户联系 → 配置 → 可调用应用**:把该自建应用加入可调用列表,否则客户群相关接口会报权限错误;
2. **应用可见范围**:必须包含所有目标群的群主(群主是群发任务的确认人);
3. **应用可信 IP**(应用详情页 → 开发者接口 → 企业可信 IP必须包含服务器出口 IP否则接口返回 `60020 not allow to access from your ip`
使用流程:后台「任务中心」→ 任务行「发布到企微群」→ 弹窗内「同步群列表」(拉取客户联系下的正常状态客户群)→ 勾选目标群、确认文案 → 「创建群发」。创建成功后平台返回 msgid 并落库 `wecom_group_pushes`,各群主在企微客户端收到群发助手提醒,**点击发送后**消息(含 KOC 领取链接)才出现在群里。
限制与注意:每个客户群每月最多接收「当月天数」条企业群发;群主使用的企业微信客户端需 ≥4.1.10 才能免选群直接发送;无效的 chat_id 会进入失败列表但不影响其他群。