tags: [企业微信, 集成, 配置]
| 参数 | 值 |
|---|---|
| 企业 ID (CorpID) | wwa979fc0ebcce602a |
| 应用 ID (AgentID) | 1000008 |
| 应用 Secret | 3QIxJQfqFgACBBcybmyc_I-mOoFvicH-Y6hdQ09ldLk |
| Token(回调验证) | dc56c68beba4c06984ce17c6342cacb1 |
| EncodingAESKey(回调加密) | WngnBCzsdXlPcdNBVG6l7auYMokMvuM94jMunTdSEHM |
| 回调 URL | http://api.zilanlife.com/wecom/callback |
| 服务端 IP | 59.51.140.250 |
| 可信域名 | api.zilanlife.com |
| DeepSeek API Key | sk-8a62671966e1470bb1a6b223a9a549fa |
| 回调服务端口 | 18790(仅 127.0.0.1) |
登录 work.weixin.qq.com → 应用管理 → 创建应用
DNS(用户操作):A 记录 api.zilanlife.com → 47.109.158.218
⚠️ api.zilanlife.com 走 Nginx 80 端口(HTTP),不需要额外开放端口。/wecom/callback 路径反代到内网 127.0.0.1:18790。
Nginx(Hermes 在 aliyun2 执行):
cat > /www/server/panel/vhost/nginx/api.zilanlife.com.conf << 'EOF'
server {
listen 80;
server_name api.zilanlife.com;
root /www/wwwroot/api.zilanlife.com;
index index.html;
location /wecom/callback {
proxy_pass http://127.0.0.1:18790;
proxy_set_header Host $host;
proxy_read_timeout 60s;
}
}
EOF
mkdir -p /www/wwwroot/api.zilanlife.com
nginx -t && nginx -s reload
api.zilanlife.comWW_verify_j5y70gNGnVqhnH4d.txt上传到服务器:
echo 'j5y70gNGnVqhnH4d' > /www/wwwroot/api.zilanlife.com/WW_verify_j5y70gNGnVqhnH4d.txt
确认 http://api.zilanlife.com/WW_verify_j5y70gNGnVqhnH4d.txt 可访问
点击验证通过
应用详情页 → 企业可信 IP → 添加 59.51.140.250
⚠️ 必须先完成域名验证才能操作。
应用详情页 → 接收消息 → 设置API接收:
| 字段 | 值 |
|---|---|
| URL | http://api.zilanlife.com/wecom/callback |
| Token | dc56c68beba4c06984ce17c6342cacb1 |
| EncodingAESKey | WngnBCzsdXlPcdNBVG6l7auYMokMvuM94jMunTdSEHM |
消息事件勾选:用户发送的普通消息
Python 脚本路径:/data/wecom_callback.py(aliyun2)
依赖安装:
pip3 install pycryptodome
启动命令:
nohup python3 /data/wecom_callback.py > /data/wecom_callback.log 2>&1 &
重启命令:
pkill -f wecom_callback.py
nohup python3 /data/wecom_callback.py > /data/wecom_callback.log 2>&1 &
员工在企微发消息
↓
企微 POST 加密 XML → api.zilanlife.com/wecom/callback
↓
Nginx 反代 → 127.0.0.1:18790(Python 服务)
↓
1. URL 验证(GET):解密 echostr → 返回明文
2. 接收消息(POST):解密消息体 → DeepSeek AI → 加密回复
echostr 参数并返回明文(企业微信首次配置时调用)16字节随机串 + 4字节消息长度(big-endian) + 消息内容 + CorpidPOST https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={TOKEN}
{
"touser": "WuXingdeYeKong",
"msgtype": "text",
"agentid": 1000008,
"text": {"content": "消息内容"}
}
GET https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token={TOKEN}&department_id=1&fetch_child=1
userid 如 WuXingdeYeKong,不一定是姓名拼音WuXingdeYeKongGET /cgi-bin/gettoken?corpid=...&corpsecret=...http://47.109.158.218:1279/api/v1/poems/randomhttp://47.109.158.218:1279/api/v1/poems/search?q=关键词| 坑 | 现象 | 解决 |
|---|---|---|
| 未配可信域名 | IP 白名单无法添加 | 先验证域名,再配 IP |
| IP 未加白 | 通讯录/user API 返回 60020 | 应用详情 → 企业可信 IP |
userIds 参数无效 |
user/list 返回所有人 | 拉全量客户端建映射 |
| 回调 Key 不一致 | URL 验证失败 | Token/EncodingAESKey 需与后台严格一致 |
| DeepSeek Key 错误 | 401 Authorization Required | 使用正确的 sk-xxx key |
| 搜索按内容不按作者 | 搜"李白"返回马致远 | random 抽到命中为止 |
数据来源:销帮帮 formId=7539701,2026年,模板创建(text_12=ef4570ef...),排除关联客户已删除的记录
业务术语:
模板创建 = 销帮帮 text_12 值为模板创建 UUID卡片格式(手机端适配,分割线不超过 5 个 ━):
📊 {设计师名} — 2026年签单前复盘表
━━━━━
📝 未填写 {N} 条
━━━━━
请在规定范围时间内登录销帮帮填写完毕!
示例:
📊 陈叶婷 — 2026年签单前复盘表
━━━━━
📝 未填写 5 条
━━━━━
请在规定范围时间内登录销帮帮填写完毕!
流程:
API 调取条件:
{
"corpid": "xbb8abca6c277b846dab5e0c8a52fe9506e",
"formId": 7539701,
"conditions": [
{"attr": "text_12", "value": ["ef4570ef-5460-7b62-b888-b3295f475e51"], "symbol": "equal"}
],
"pageSize": 100, "page": 1
}
然后客户端过滤 addTime >= 2026-01-01,再逐条 customer/detail 排除 code=100404。
发送规则:
姓名映射:
| 销帮帮 | 企业微信 | userid |
|---|---|---|
| 胡华玉 | 胡玉 | WeiXiaoXiangYang |
| 陈明先 | 陈想 | ChenXiang |
| 王飞 | 王习僧 | b5ed7c2b00 |
| 赵耀 | ❌ 不存在 | — |
工作流名称:企微AI回复
| 参数 | 值 |
|---|---|
| API Key | app-6ax5fzZvsOuQvSDiQ0bcCgwa |
| 端点 | http://47.109.158.218:8088/v1/workflows/run |
| 输入 | query(文本) |
| 输出 | text(文本) |
节点结构:
query 输入{{#start.query#}},关掉 Thinkingtext回调路径:api.zilanlife.com/wecom/callback → Nginx → 127.0.0.1:18790
流程:
员工发消息 → 企微加密 POST → 回调服务解密 → Dify API 发送 query → LLM 处理 → 返回 text → 加密回复 → 员工收到
代码要点:
body = {"inputs": {"query": user_msg}, "response_mode": "blocking", "user": "wecom"}
req = Request(DIFY_API_URL, data=json.dumps(body).encode(),
headers={"Authorization": f"Bearer {DIFY_API_KEY}"})
# 返回 text = data["data"]["outputs"]["text"]
| 版本 | 后端 | 模式 | 状态 |
|---|---|---|---|
| v1 | DeepSeek API 直连 | 同步 | ❌ Key 泄露风险 |
| v2 | Key 注释 | 同步 | ❌ 不可用 |
| v3 | Dify 工作流 | 同步 | ❌ 超时断连 (BrokenPipe) |
| v4 | Dify 工作流 | 异步 | ✅ 当前 |
问题:同步模式下 Dify 处理 15-30 秒,企微 5 秒超时断连 → BrokenPipeError
方案:
收到消息 → 立即 200(不等 Dify)→ 后台线程处理 → send_msg 主动推送
代码:
def do_POST(self):
# 先返回 200
self.send_response(200); self.end_headers()
# 后台处理
threading.Thread(target=lambda: send_msg(user_id, ai_reply(msg))).start()
| 保护 | 机制 | 效果 |
|---|---|---|
| 超时兜底 | Dify 15s 无响应 → 先发「正在处理」→ 继续等 45s | 不丢消息,用户有反馈 |
| 发送重试 | send_msg 失败自动重试 3 次,间隔 1s | 网络抖动不丢 |
| systemd | Restart=always,崩溃 5s 自动复活 |
进程挂了秒恢复 |
并发能力:
systemd 配置:
[Service]
ExecStart=/usr/bin/python3 -u /data/wecom_callback.py
Restart=always
RestartSec=5
# 服务器重启后自动拉起 → systemctl enable
| 项目 | 内容 |
|---|---|
| 任务 ID | 82990ab2bd98 |
| 触发 | 每天 5:00 |
| 执行 | 本机 wecom_xbb_push.sh → SSH aliyun2 → Python 脚本 |
| 监控 | deliver: origin,结果推回 Hermes |
为什么迁到 aliyun2:
脚本路径:
~/.hermes/scripts/wecom_xbb_push.sh(SSH 跳板)/opt/scripts/wecom_xbb_push.py(实际执行)| 坑 | 现象 | 解决 |
|---|---|---|
| IP 变动 | 本地出网 IP 从 59.51→1.204,企微 60020 | 脚本迁 aliyun2,用固定 IP |
systemctl stop 卡死 |
服务持续 deactivating,超时 | prod.js SIGTERM 处理有 bug,手动 kill 进程 |
| WAL 删除致数据丢失 | 部署时删 WAL 文件 → 未刷盘数据永久丢失 | 先用 wal_checkpoint 强制刷盘,再停服 |
| Dify LLM Thinking 输出 | 回复含 <think> 标签 |
关掉 LLM 节点的 Thinking 模式 |
| Dify 变量引用错误 | #sys.query# not found |
改为 #start.query# |
| Cron 本地跑不通 | no_agent 脚本依赖本地 IP 白名单 |
改 shell 脚本 SSH 远端执行 |