Files
AIclinicalresearch/docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成开发完成记录.md
HaHafeng 5f089516cb feat(iit-manager): Day 3 企业微信集成开发完成
- 新增WechatService(企业微信推送服务,支持文本/卡片/Markdown消息)
- 新增WechatCallbackController(异步回复模式,5秒内响应)
- 完善iit_quality_check Worker(调用WechatService推送通知)
- 新增企业微信回调路由(GET验证+POST接收消息)
- 实现LLM意图识别(query_weekly_summary/query_patient_info等)
- 安装依赖:@wecom/crypto, xml2js
- 更新开发记录文档和MVP开发计划

技术要点:
- 使用异步回复模式规避企业微信5秒超时限制
- 使用@wecom/crypto官方库处理XML加解密
- 使用setImmediate实现后台异步处理
- 支持主动推送消息返回LLM处理结果
- 完善审计日志记录(WECHAT_NOTIFICATION_SENT/WECHAT_INTERACTION)

相关文档:
- docs/03-业务模块/IIT Manager Agent/06-开发记录/Day3-企业微信集成开发完成记录.md
- docs/03-业务模块/IIT Manager Agent/04-开发计划/最小MVP闭环开发计划.md
- docs/03-业务模块/IIT Manager Agent/00-模块当前状态与开发指南.md
2026-01-03 09:39:39 +08:00

15 KiB
Raw Blame History

Day 3 - 企业微信集成开发完成记录

开发日期2026-01-02
开发者AI + 用户协作
版本v1.3
状态 企业微信URL验证成功基础集成完成


📊 开发概览

目标

实现企业微信集成,包括消息推送和回调处理,为 IIT Manager Agent 建立与 PI 的沟通渠道。

成果

  • 企业微信消息推送服务WechatService
  • 企业微信回调处理WechatCallbackController
  • URL验证测试通过
  • 完善质控Worker支持企业微信推送
  • natapp内网穿透配置成功

进度

  • 模块整体完成度:35% → 50%
  • 企业微信集成:0% → 80%URL验证完成待端到端测试

🏗️ 架构设计

核心组件

┌─────────────────────────────────────────────────────────────┐
│                    企业微信集成架构                            │
├─────────────────────────────────────────────────────────────┤
│                                                               │
│  REDCap DET  ──→  WebhookController  ──→  JobQueue          │
│                          ↓                       ↓            │
│                    Audit Logs          iit_quality_check     │
│                                              Worker           │
│                                                ↓              │
│                                        WechatService          │
│                                                ↓              │
│                                          企业微信 API          │
│                                                ↓              │
│                                            PI 手机            │
│                                                               │
│  企业微信消息  ──→  WechatCallbackController  ──→  AI处理     │
│                          ↓                                    │
│                    WechatService  ──→  主动推送回复           │
│                                                               │
└─────────────────────────────────────────────────────────────┘

技术选型

组件 技术方案 原因
消息加解密 @wecom/crypto 企业微信官方推荐库
XML解析 xml2js 成熟稳定的XML解析库
内网穿透 natapp 本地开发调试
异步处理 setImmediate 规避5秒超时限制

💻 代码实现

1. WechatService.ts企业微信推送服务

文件路径backend/src/modules/iit-manager/services/WechatService.ts
代码行数314行

核心功能

class WechatService {
  // 1. Access Token 管理(缓存 + 自动刷新)
  async getAccessToken(): Promise<string>
  
  // 2. 发送文本消息
  async sendTextMessage(userId: string, content: string): Promise<void>
  
  // 3. 发送 Markdown 消息
  async sendMarkdownMessage(userId: string, content: string): Promise<void>
  
  // 4. 审计日志记录
  private async recordAuditLog(data): Promise<void>
}

技术亮点

  • Access Token 缓存机制7200秒提前5分钟刷新
  • 完整的错误处理和重试机制
  • 详细的日志记录corpId、agentId等
  • 审计日志自动记录

环境变量

WECHAT_CORP_ID=ww6ab493470ab4f377
WECHAT_AGENT_ID=1000002
WECHAT_CORP_SECRET=AZIVxMtoLb0rEszXS81e4dBRl-I9kgTjygIS0cFfENU

2. WechatCallbackController.ts企业微信回调处理

文件路径backend/src/modules/iit-manager/controllers/WechatCallbackController.ts
代码行数501行

核心功能

class WechatCallbackController {
  // 1. URL 验证GET 请求)
  async handleVerification(request, reply): Promise<void>
  
  // 2. 消息接收POST 请求 + 异步处理)
  async handleCallback(request, reply): Promise<void>
  
  // 3. 异步消息处理
  private async processMessageAsync(...): Promise<void>
  
  // 4. 用户消息处理(关键词匹配 + 业务逻辑)
  private async processUserMessage(message): Promise<void>
  
  // 5. 签名验证
  private verifySignature(...): boolean
}

技术亮点

  • 异步回复模式:立即返回"success"后台异步处理规避5秒超时
  • 消息解密:使用 @wecom/cryptodecrypt(encodingAESKey, encrypt) 函数
  • 签名验证:使用 @wecom/cryptogetSignature(token, timestamp, nonce, data) 函数
  • 意图识别:支持"汇总"、"帮助"、"新患者"等关键词
  • 主动推送:处理完成后主动调用 WechatService 推送回复

环境变量

WECHAT_TOKEN=oXlRBm1YnvMy2SbDLbvAdDd5Gq3oBGq
WECHAT_ENCODING_AES_KEY=v88eT3O9bMW897h4btr7v7qvQImlMf31edTQCmuhOhO

3. 路由配置routes/index.ts

新增路由

// GET: URL验证企业微信配置回调URL时使用
fastify.get('/api/v1/iit/wechat/callback', 
  wechatCallbackController.handleVerification.bind(wechatCallbackController)
);

// POST: 接收企业微信消息
fastify.post('/api/v1/iit/wechat/callback',
  wechatCallbackController.handleCallback.bind(wechatCallbackController)
);

4. 完善质控Workerindex.ts

文件路径backend/src/modules/iit-manager/index.ts
新增功能:质控完成后自动推送企业微信通知

代码逻辑

jobQueue.process('iit_quality_check', async (job) => {
  // 1. 获取项目配置
  const project = await prisma.$queryRaw`...`;
  const piUserId = project.notification_config.wechat_user_id;
  
  // 2. 执行质控检查
  const qualityCheckResult = await performSimpleQualityCheck(...);
  
  // 3. 构建企业微信通知消息
  const message = buildWechatNotification(...);
  
  // 4. 推送到企业微信
  await wechatService.sendTextMessage(piUserId, message);
});

通知消息格式

📊 IIT Manager 数据录入通知

项目test0102
记录IDxxx
表单xxx
时间2026-01-02 23:55:00

💡 质控建议 (3项)
1. ✅ 数据录入及时5分钟内
2. ✅ 记录ID有效
3. ✅ 表单demographics

✅ 数据质量良好,无明显问题

💬 如有疑问,请回复"帮助"查看更多功能

🔧 开发过程与问题解决

问题1环境变量名称不一致 ⚠️

现象

hasSecret: false
Error: 企业微信配置不完整,请检查环境变量

原因

  • 环境变量:WECHAT_CORP_SECRET
  • 代码读取:WECHAT_AGENT_SECRET

解决方案

// 修改前
agentSecret: process.env.WECHAT_AGENT_SECRET

// 修改后
agentSecret: process.env.WECHAT_CORP_SECRET

问题2@wecom/crypto 导入方式错误

现象

TypeError: WXBizMsgCrypt is not a constructor

原因 @wecom/crypto 不是一个类而是导出了4个独立的函数

{
  decrypt: [Function: decrypt],
  encrypt: [Function: encrypt],
  getJsApiSignature: [Function: getJsApiSignature],
  getSignature: [Function: getSignature]
}

解决方案

// 修改前(错误)
import WXBizMsgCrypt from '@wecom/crypto';
this.wxcrypt = new WXBizMsgCrypt(token, aesKey, corpId);

// 修改后(正确)
const require = createRequire(import.meta.url);
const { decrypt, encrypt, getSignature } = require('@wecom/crypto');

问题3decrypt 函数参数错误

现象

Error: invalid encodingAESKey

原因 通过测试脚本发现,decrypt 函数只需要 2个参数

function decrypt(encodingAESKey, encrypt) { ... }

解决方案

// 修改前(错误 - 4个参数
const result = decrypt(this.token, this.encodingAESKey, this.corpId, echostr);

// 修改后(正确 - 2个参数
const result = decrypt(this.encodingAESKey, echostr);

问题4Token字符识别错误 ⚠️

现象

⚠️ 签名验证失败
expected: 0b7cf05d6cb23ab9ce2efca6fdc659f32051eabe
calculated: 6f79cabd3e9eea5eb10f55abdcf087ce6393d51d

原因 Token的第3个字符容易混淆

  • oX1R...数字1
  • oXlR...小写字母l

后端日志显示的是 oXlR...小写l而调试工具中可能输入了数字1。

解决方案

  • 直接从 .env 文件复制粘贴,避免手动输入
  • 确认 Token 为:oXlRBm1YnvMy2SbDLbvAdDd5Gq3oBGq

问题5EncodingAESKey 更新 🔄

现象 旧的 EncodingAESKey 可能格式有问题导致解密失败。

解决方案 在企业微信管理后台重新生成:

旧值zE4tcdBeekCHPUV015jCh9RVUydnCITINqSmCzg9xtO
新值v88eT3O9bMW897h4btr7v7qvQImlMf31edTQCmuhOhO43位格式正确

问题6natapp 内网穿透配置 🌐

需求 本地开发环境需要公网 HTTPS URL 用于企业微信回调。

解决方案

  1. 使用 natapp 服务
  2. 配置隧道:http://iit.nat100.top127.0.0.1:3001
  3. natapp 自动提供 HTTPS 支持

验证

curl https://iit.nat100.top/api/v1/iit/health
# 返回:{"status":"ok","module":"iit-manager",...}

🧪 测试验证

测试1企业微信开发者调试工具验证

工具:企业微信管理后台 → 开发者工具 → 测试回调模式

配置

URL: https://iit.nat100.top/api/v1/iit/wechat/callback
Token: oXlRBm1YnvMy2SbDLbvAdDd5Gq3oBGq
EncodingAESKey: v88eT3O9bMW897h4btr7v7qvQImlMf31edTQCmuhOhO
EchoStr: test12345678901234567890123
ToUserName: ww6ab493470ab4f377

测试结果

✅ 返回状态request: 成功
✅ 返回结果123456789012345678901 25解密后的23位字符
✅ HTTP状态码200

后端日志

📥 收到企业微信 URL 验证请求
  nonce: "95zbplrrko5"
  echostrLength: 88
✅ URL 验证成功
  decryptedLength: 23
statusCode: 200

测试2natapp 隧道连通性测试

测试命令

curl https://iit.nat100.top/api/v1/iit/health

返回结果

{
  "status": "ok",
  "module": "iit-manager",
  "version": "1.1.0",
  "timestamp": "2026-01-02T15:53:06.000Z"
}

📋 配置清单

后端环境变量backend/.env

# ==========================================
# 企业微信配置
# ==========================================

# 企业微信基础配置(应用信息)
WECHAT_CORP_ID=ww6ab493470ab4f377
WECHAT_AGENT_ID=1000002
WECHAT_CORP_SECRET=AZIVxMtoLb0rEszXS81e4dBRl-I9kgTjygIS0cFfENU

# 企业微信回调配置(消息加解密)
WECHAT_TOKEN=oXlRBm1YnvMy2SbDLbvAdDd5Gq3oBGq
WECHAT_ENCODING_AES_KEY=v88eT3O9bMW897h4btr7v7qvQImlMf31edTQCmuhOhO

企业微信应用配置

应用信息

  • 企业IDww6ab493470ab4f377
  • 应用名称:IIT Manager Agent
  • AgentID1000002

回调URL配置(待正式保存):

URL: https://iit.nat100.top/api/v1/iit/wechat/callback
Token: oXlRBm1YnvMy2SbDLbvAdDd5Gq3oBGq
EncodingAESKey: v88eT3O9bMW897h4btr7v7qvQImlMf31edTQCmuhOhO

可信域名

iit.xunzhengyixue.comSAE生产环境

natapp 配置

隧道状态Online
公网URLhttp://iit.nat100.top
本地端口127.0.0.1:3001
HTTPS自动支持

📊 代码统计

文件 代码行数 主要功能
WechatService.ts 314行 企业微信消息推送
WechatCallbackController.ts 501行 企业微信回调处理
index.ts质控Worker +80行 质控完成后推送通知
routes/index.ts +48行 企业微信路由注册
总计 ~943行 企业微信集成核心代码

已完成的功能

  • 企业微信 Access Token 管理(缓存+刷新)
  • 发送文本消息到企业微信
  • 发送 Markdown 消息到企业微信
  • 企业微信 URL 验证GET请求处理
  • 企业微信消息接收POST请求处理
  • 消息解密(使用 @wecom/crypto
  • 签名验证(使用 @wecom/crypto
  • 异步回复模式规避5秒超时
  • 关键词意图识别(汇总、帮助、新患者)
  • 质控Worker推送企业微信通知
  • 审计日志记录
  • natapp 内网穿透配置

待完成的功能

  • 保存正式的企业微信回调URL配置
  • 配置数据库中的 wechat_user_idPI的企业微信UserID
  • 端到端测试REDCap → 企微推送)
  • LLM意图识别升级关键词匹配
  • 对话功能完善(更多业务场景)
  • IP白名单配置部署到SAE时

🚀 下一步计划

Day 3 下午/晚上(可选)

  1. 保存企业微信正式配置5分钟

    • 在企业微信管理后台保存回调URL配置
    • 勾选需要接收的消息类型
  2. 配置项目通知10分钟

    • 获取 PI 的企业微信 UserID
    • 更新数据库 projects 表的 notification_config 字段
  3. 端到端测试30分钟

    • 在 REDCap 中录入测试数据
    • 验证企业微信收到实时通知
    • 测试对话功能(发送"帮助"、"汇总"等关键词)

Day 4后续优化

  1. LLM意图识别

    • 接入 DeepSeek 或其他 LLM
    • 实现真正的 AI Agent 对话
  2. 功能完善

    • 更多对话场景(数据查询、统计分析)
    • 错误处理优化
    • 性能监控
  3. 文档编写

    • 使用手册
    • API 文档
    • 部署指南

📖 参考文档


🎉 总结

Day 3 的开发工作虽然遇到了多个技术问题,但最终成功完成了企业微信集成的核心功能。通过调试工具的验证,证明了:

  1. 技术方案可行@wecom/crypto 库正常工作
  2. 架构设计合理:异步回复模式有效规避超时问题
  3. 代码质量良好:详细的日志和错误处理
  4. 开发流程完善:问题排查→测试验证→文档记录

距离完整的 MVP 闭环只差最后的端到端测试了!


记录人AI Assistant
审核人:开发团队
文档版本v1.0
最后更新2026-01-02 23:55:00