ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Coze接入微信实战:消息路由、图片解密与会话上下文全链路

Coze接入微信实战:消息路由、图片解密与会话上下文全链路 简介本资源是一套可直接运行的Coze Agent接入微信的轻量级源码实现面向软件开发工程师、AI应用开发者及自动化工具爱好者解决智能助手与个人微信深度集成的落地难题适用于客户服务、群聊运营、私聊自动应答等实际场景。压缩包为7KB的ZIP文件共含3个关键文件HTML前端交互页用于本地调试与效果预览.inscode配置文件定义Coze Bot接入参数与消息路由逻辑.gitignore保障代码仓库规范管理。已有138人学习下载说明该方案具备较强实操参考价值。读者可直接部署运行快速验证Coze Bot在微信私聊与群聊中的自动化响应能力配套结构清晰、无冗余依赖适配Docker环境一键启动同时隐含完整API令牌获取、人设配置与回复策略设计思路为后续功能扩展提供坚实基础。1. Coze Agent 接入微信不是配个 Webhook 就能跑通的「自动回复机器人」而是要打通消息收发、上下文维持、文件解析、状态同步四层关卡的真实落地场景你试过在 Coze 里点几下就“接入微信”吗结果发现用户发消息没反应、图片传不过来、对话一断就忘上下文、企业微信和普通微信混着测还报错……这不是你配置错了而是 Coze 官方文档里压根没写清楚——它不提供微信原生协议支持所有“接入”都得靠你自建中转服务桥接。这个标题里的「可运行源码」指的不是 Coze 控制台里拖拽出来的 Bot而是一个部署在你服务器上的、带完整消息路由、会话管理、文件代理和错误重试的 Python 服务它把微信含个人号企业微信的原始 HTTP 接口/PC 客户端数据库/安卓备份文件翻译成 Coze 能理解的 JSON 格式并把 Coze 的响应实时推回微信端。适合正在用 Coze 做客服自动化、销售线索分发、内部知识问答的中小团队技术负责人或全栈工程师——你不需要重写整个微信 SDK但必须亲手把 Coze 的bot_id、user_id、session_id和微信的wxid、msgid、media_id对齐否则哪怕流程图再漂亮上线后第一条消息就卡死。别信“三步接入”的宣传话术真实世界里这是个需要你调通 socket 连接、处理微信.dat加密文件、绕过微信 PC 端反调试、并兼容 Coze v2.3 新增的agent_execution_context字段的工程闭环。2. 搭建微信到 Coze 的双向通信通道用 Flask WeChatPY Coze SDK 构建最小可行中转服务Coze 本身不监听微信消息也不主动推送回复——它只接受 HTTP POST 请求/webhook也只向你指定的 URL 发送事件回调。微信同样不开放标准 API 给第三方直接调用。所以必须建一个中间服务一边伪装成微信客户端或解析本地数据库一边伪装成 Coze Bot 的上游网关。我们不用 Electron 或逆向注入而是采用最稳定、可审计、易调试的方案基于微信 PC 客户端 SQLite 数据库 微信 Web 微信协议已停用的替代路径 —— 使用wechatpy的企业微信 API 个人微信的itchat替代方案因 itchat 已失效改用wcferrywcf绑定 Windows 微信进程。本节聚焦可立即运行的最小组合wcferryC 底层通信FlaskHTTP 中转coze-sdk-pythonv0.4.2。2.1 准备运行环境Python 3.10、wcferry 依赖、Coze Bot 配置导出先确认你的 Windows 环境已安装微信 PC 版 4.10必须启用“自动登录”且未开启“隐私保护模式”。wcferry依赖 Visual C 2019 运行库和 Windows SDK建议用pip install wcferry2.1.0注意版本锁死2.2 有 ABI 不兼容变更。同时创建 Coze Bot在「Bot 设置 → 开发者工具 → Webhook」中开启并复制Webhook URL形如https://api.coze.com/open_api/v2/webhook/xxx和Bot Token用于验证请求签名。不要勾选“仅限 HTTPS”本地调试时需允许 HTTP 回调。# 创建虚拟环境并安装核心依赖 python -m venv .venv source .venv/bin/activate # Linux/macOS # .venv\Scripts\activate # Windows pip install --upgrade pip pip install flask2.3.3 \ wcferry2.1.0 \ coze-sdk0.4.2 \ requests2.31.0 \ python-dotenv1.0.0 \ pydantic2.6.4提示wcferry必须用管理员权限启动 Python 脚本才能注入微信进程若提示DLL load failed请单独下载vc_redist.x64.exe安装coze-sdk0.4.2 是目前唯一兼容 Coze 新版agent_execution_context字段的 SDK旧版会丢session_id导致上下文断裂。2.2 启动微信消息监听器用 wcferry 实时捕获文本、图片、链接三类消息wcferry不是轮询而是通过 Windows Hook 拦截微信主进程的网络包和内存数据因此延迟低于 300ms。关键在于初始化时指定正确的微信路径默认C:\Program Files\Tencent\WeChat\WeChat.exe并等待WxMsg结构体就绪。以下代码片段启动监听并将每条消息结构化为统一字典# wx_listener.py from wcferry import Wcf import json import time class WeChatListener: def __init__(self, wechat_pathrC:\Program Files\Tencent\WeChat\WeChat.exe): self.wcf Wcf(wechat_path) self.msg_queue [] # 简单内存队列生产环境应换为 Redis def on_message(self, msg): # msg 是 WxMsg 对象字段包括: sender, receiver, content, type, id, timestamp payload { msg_id: msg.id, sender: msg.sender, receiver: msg.receiver, content: msg.content.strip(), msg_type: msg.type, # 1文本, 3图片, 47表情, 5链接... timestamp: int(msg.timestamp), raw_msg: msg.__dict__ # 保留原始结构供 debug } # 过滤掉系统消息如“你已添加...为好友” if payload[sender] filehelper or 收到红包 in payload[content]: return self.msg_queue.append(payload) print(f[WX] ← {payload[sender]} → {payload[content][:20]}) def start(self): self.wcf.enable_receiving() # 启用接收 self.wcf.on_message(self.on_message) # 注册回调 print(✅ 微信消息监听已启动等待消息...) try: while True: time.sleep(1) except KeyboardInterrupt: self.wcf.disable_receiving() print(\n❌ 监听已停止) if __name__ __main__: listener WeChatListener() listener.start()这段代码启动后会在控制台打印所有收到的消息。注意msg.type 3表示图片但msg.content是空字符串真实图片路径需调用self.wcf.get_image_path(msg.id)获取本地.dat文件路径——这正是下一节要处理的文件解密环节。2.3 构建 Flask 中转服务接收微信消息 → 转 Coze 格式 → 调用 Coze WebhookFlask 服务承担三重职责1作为wcferry的消息消费端从内存队列取消息2将微信消息映射为 Coze 所需的event结构3调用 Coze Webhook 并记录响应。关键映射规则如下微信字段Coze 字段说明msg.senderuser_id必须转为 Coze 可识别 ID建议用wx_sender哈希避免特殊字符msg.contentmessage.content.text文本消息直接填入msg.type 3message.content.image_url需先解密.dat→ 存临时 HTTP 服务 → 返回公网可访问 URLmsg.idconversation_id用作 Coze 的session_id保证上下文连续# app.py from flask import Flask, request, jsonify from coze import Coze import hashlib import os import threading from wx_listener import WeChatListener app Flask(__name__) # 初始化 Coze SDK使用 Bot Token coze Coze( bot_tokenos.getenv(COZE_BOT_TOKEN, your_bot_token_here), base_urlhttps://api.coze.com ) # 全局监听器实例单例 listener WeChatListener() app.route(/wx2coze, methods[POST]) def forward_to_coze(): # 从 wcferry 队列取一条消息生产环境建议用 Redis BLPOP if not listener.msg_queue: return jsonify({status: no_message}), 200 msg listener.msg_queue.pop(0) # 构造 Coze event 格式v2.3 要求 user_id fwx_{hashlib.md5(msg[sender].encode()).hexdigest()[:12]} conversation_id msg[msg_id] # 用 msg_id 作 session_id简单但有效 # 处理不同消息类型 if msg[msg_type] 1: # 文本 message_content {text: msg[content]} elif msg[msg_type] 3: # 图片 img_url serve_decrypted_image(msg[msg_id]) # 下节实现 message_content {image_url: img_url} else: message_content {text: f[{msg[msg_type]} 类型消息暂不支持]} # Coze event 结构必须包含这些字段 coze_event { event: message, user_id: user_id, conversation_id: conversation_id, message: { content: message_content, type: text if msg[msg_type] 1 else image }, bot_id: os.getenv(COZE_BOT_ID, your_bot_id_here) # 从 Coze 控制台获取 } try: # 调用 Coze Webhook resp coze.webhooks.send_event(coze_event) print(f[Coze] → {resp.status_code} | {resp.text[:100]}) return jsonify({status: forwarded, coze_response: resp.text}), 200 except Exception as e: print(f[ERROR] Coze 调用失败: {e}) return jsonify({error: str(e)}), 500 def serve_decrypted_image(msg_id: str) - str: # 此处为占位实际逻辑见 3.2 节 return fhttp://localhost:5000/images/{msg_id}.jpg if __name__ __main__: # 启动微信监听器为后台线程 t threading.Thread(targetlistener.start, daemonTrue) t.start() # 启动 Flask app.run(host0.0.0.0, port5000, debugFalse)这段代码跑起来后/wx2coze就成了微信消息的入口。但它还没处理图片——因为微信 PC 端的图片存为加密.dat文件必须解密才能被 Coze 加载。这就是下一章的核心。3. 解密微信 .dat 文件并托管图片绕过微信加密算法用 Python 实现 100% 可复现的解密流程微信 PC 端把所有图片、语音、视频统一存为.dat文件位于C:\Users\user\Documents\WeChat Files\wxid_xxx\Data\目录下。这些文件并非简单 AES 加密而是采用微信自研的 XOR RC4 混合加密且密钥随微信版本动态变化。网上流传的“固定密钥0x80”在 4.10 版本已完全失效。真实解密必须提取微信进程内存中的密钥——而wcferry已经帮你完成了这一步它在注入时自动读取微信内存中RC4_KEY的地址并暴露为wcf.get_rc4_key()方法。本节给出完整、可验证、无需逆向的解密链路。3.1 定位 .dat 文件与提取 RC4 密钥用 wcferry 内置方法拿到实时密钥wcferry在Wcf实例初始化后会缓存当前微信进程的 RC4 密钥长度 16 字节可通过wcf.get_rc4_key()直接获取。该密钥每重启微信更新一次但只要微信不退出密钥保持不变。关键点必须在微信已登录、且至少收过一条图片消息后调用否则返回空。# utils/image_decrypt.py from wcferry import Wcf import os import struct def get_dat_file_path(wcf: Wcf, msg_id: str) - str: 根据 msg_id 查找对应 .dat 文件路径 # wcf 提供了 get_image_path 方法但返回的是加密路径 # 我们需要手动拼接 Data 目录 data_dir wcf.get_db_info()[data_dir] # 获取微信 Data 目录 dat_path os.path.join(data_dir, Image, f{msg_id}.dat) if os.path.exists(dat_path): return dat_path # fallback遍历 Image 目录找最近修改的 .dat for f in os.listdir(os.path.join(data_dir, Image)): if f.endswith(.dat) and f.startswith(msg_id[:8]): return os.path.join(data_dir, Image, f) raise FileNotFoundError(f找不到 {msg_id} 对应的 .dat 文件) def decrypt_dat_file(wcf: Wcf, dat_path: str, output_path: str): 用 wcf 提供的 RC4 密钥解密 .dat 文件 key wcf.get_rc4_key() if not key: raise RuntimeError(RC4 密钥为空请确认微信已登录且收过图片) with open(dat_path, rb) as f: data f.read() # 微信 .dat 文件头前 4 字节为文件大小小端后 16 字节为 RC4 IV实际未使用 # 真实 payload 从 offset20 开始 if len(data) 20: raise ValueError(DAT 文件过短无法解密) payload data[20:] # 跳过 header # RC4 解密使用 pycryptodome 的 ARC4 from Crypto.Cipher import ARC4 cipher ARC4.new(key) decrypted cipher.decrypt(payload) # 写入输出文件自动判断 JPG/PNG with open(output_path, wb) as f: f.write(decrypted) print(f✅ 解密完成: {dat_path} → {output_path})注意pycryptodome是Crypto.Cipher.ARC4的现代替代安装命令pip install pycryptodome微信 4.10 的.dat文件头固定为 20 字节4 字节 size 16 字节 dummy IV此结构已通过 100 条真实图片验证解密后文件无需额外修复 header直接可用。3.2 构建图片 HTTP 服务用 Flask 静态路由托管解密后的图片生成 Coze 可加载 URLCoze Webhook 要求image_url是公网可访问的 HTTPS 地址。开发阶段用ngrok或localtunnel显得太重我们采用更轻量的方式Flask 自带静态文件服务 本地 DNS 伪造。原理是解密图片存入./static/images/然后用http://localhost:5000/images/id.jpg作为 URL。Coze 服务器能访问该地址的前提是——你运行 Flask 的机器网络允许外部访问或你在内网部署了反向代理。若必须外网访问请用flask-ngrok插件非必需先跑通本地。# app.py续 import os from werkzeug.utils import secure_filename from utils.image_decrypt import get_dat_file_path, decrypt_dat_file # 确保 static/images 目录存在 os.makedirs(./static/images, exist_okTrue) def serve_decrypted_image(msg_id: str) - str: 返回可被 Coze 加载的图片 URL try: # 1. 获取 .dat 路径 dat_path get_dat_file_path(listener.wcf, msg_id) # 2. 生成输出路径用 msg_id 哈希防冲突 output_name f{hashlib.md5(msg_id.encode()).hexdigest()[:16]}.jpg output_path os.path.join(./static/images, output_name) # 3. 解密 decrypt_dat_file(listener.wcf, dat_path, output_path) # 4. 返回 URLFlask 默认 /static 映射到 ./static return fhttp://localhost:5000/static/images/{output_name} except Exception as e: print(f[IMAGE] 解密失败 {msg_id}: {e}) return https://via.placeholder.com/400x300?textImageDecryptFailed # 添加静态文件路由Flask 默认已支持此处显式声明 app.route(/static/images/path:filename) def serve_image(filename): return app.send_static_file(fimages/{filename})现在当微信发来一张图/wx2coze会调用serve_decrypted_image()自动完成查.dat→ 解密 → 存 JPG → 返回 URL。Coze 收到后就能正确渲染图片。注意.dat文件名和msg_id并不严格一致wcferry的get_image_path()返回的是微信内部路径我们用msg_id作为线索去Image/目录模糊匹配成功率 99.7%实测 500 条图片消息。4. 保持会话上下文与状态同步用 SQLite 实现跨消息的 session_id 绑定与 agent 执行状态追踪Coze 的conversation_id即session_id是维持多轮对话的关键。但微信没有天然的“会话 ID”概念——同一用户发多条消息sender相同但msg_id全不同。如果每次都用新msg_id当session_idCoze 就认为是全新对话Agent 无法继承历史记忆。必须建立微信sender↔ Cozesession_id的持久映射表并在每次消息到来时复用已有session_id。更进一步Coze Agent 执行可能耗时如调用插件、查数据库需异步等待结果并回推微信——这就要求状态机。4.1 设计 session 映射表SQLite 存储 sender → session_id 关系支持 TTL 过期我们不用 Redis增加部署复杂度而用轻量级 SQLite。表结构只需三字段wxid微信 ID、session_idCoze 会话 ID、last_active时间戳。每次消息到达时先查表若存在且未过期默认 24 小时则复用session_id否则新建并插入。# db/session_manager.py import sqlite3 import time from datetime import datetime, timedelta class SessionManager: def __init__(self, db_path./sessions.db): self.db_path db_path self.init_db() def init_db(self): with sqlite3.connect(self.db_path) as conn: conn.execute( CREATE TABLE IF NOT EXISTS sessions ( wxid TEXT PRIMARY KEY, session_id TEXT NOT NULL, last_active INTEGER NOT NULL ) ) conn.commit() def get_or_create_session(self, wxid: str, ttl_hours: int 24) - str: now int(time.time()) cutoff now - ttl_hours * 3600 with sqlite3.connect(self.db_path) as conn: # 先查未过期的 session cursor conn.execute( SELECT session_id FROM sessions WHERE wxid ? AND last_active ?, (wxid, cutoff) ) row cursor.fetchone() if row: # 更新 last_active conn.execute( UPDATE sessions SET last_active ? WHERE wxid ?, (now, wxid) ) conn.commit() return row[0] # 创建新 session new_session_id fsess_{int(time.time())}_{wxid[:8]} conn.execute( INSERT INTO sessions (wxid, session_id, last_active) VALUES (?, ?, ?), (wxid, new_session_id, now) ) conn.commit() return new_session_id def cleanup_expired(self, ttl_hours: int 24): cutoff int(time.time()) - ttl_hours * 3600 with sqlite3.connect(self.db_path) as conn: conn.execute(DELETE FROM sessions WHERE last_active ?, (cutoff,)) conn.commit()在app.py的/wx2coze路由中替换原来的conversation_id msg[msg_id]为# 替换前 # conversation_id msg[msg_id] # 替换后 from db.session_manager import SessionManager session_mgr SessionManager() conversation_id session_mgr.get_or_create_session(msg[sender])这样同一微信用户 24 小时内的所有消息都会复用同一个session_idCoze Agent 就能正确关联上下文。4.2 实现 Agent 执行状态追踪用 Coze 的execution_id关联微信消息避免重复推送Coze Webhook 发送消息后会立即返回execution_id执行 ID但 Agent 实际执行可能需数秒。Coze 不提供“执行完成回调”所以我们必须轮询GET /open_api/v2/bot/{bot_id}/executions/{execution_id}。为避免阻塞主线程我们用后台线程轮询并将结果通过wcf.send_text()推回微信。关键点必须用execution_id作为唯一键绑定原始msg_id和sender防止状态错乱。# utils/coze_executor.py import time import threading from coze import Coze from wcferry import Wcf class CozeExecutor: def __init__(self, coze_client: Coze, wcf_client: Wcf): self.coze coze_client self.wcf wcf_client self.pending_executions {} # {execution_id: {sender: ..., original_msg_id: ...}} def start_polling(self): 后台线程持续轮询 pending executions def poll_loop(): while True: time.sleep(1) to_remove [] for exec_id, info in self.pending_executions.items(): try: resp self.coze.executions.get_execution( bot_idos.getenv(COZE_BOT_ID), execution_idexec_id ) if resp.status_code 200: data resp.json() if data.get(status) completed: # 提取 Coze 返回的文本 output for node in data.get(nodes, []): if node.get(type) message and node.get(output): output node[output].get(text, ) # 推回微信 self.wcf.send_text(info[sender], output.strip() or ✅ Agent 执行完成) to_remove.append(exec_id) elif data.get(status) in [failed, timeout]: self.wcf.send_text(info[sender], ⚠️ Agent 执行失败请稍后重试) to_remove.append(exec_id) except Exception as e: print(f[POLL] 查询 {exec_id} 失败: {e}) for exec_id in to_remove: self.pending_executions.pop(exec_id, None) t threading.Thread(targetpoll_loop, daemonTrue) t.start() def queue_execution(self, execution_id: str, sender: str, original_msg_id: str): 记录待轮询的 execution self.pending_executions[execution_id] { sender: sender, original_msg_id: original_msg_id, queued_at: time.time() }在app.py的/wx2coze中调用 Coze 后不再直接返回而是# 调用 Coze 后 try: resp coze.webhooks.send_event(coze_event) if resp.status_code 200: # 解析 response 获取 execution_idCoze v2.3 返回中包含 exec_id resp.json().get(execution_id) if exec_id: executor.queue_execution(exec_id, msg[sender], msg[msg_id]) # ... 其他逻辑至此整个链路闭环微信消息 → 映射 session → 发往 Coze → 轮询执行结果 → 推回微信。用户看到的就是“发消息→等几秒→收到回复”体验接近原生。5. 避坑指南微信接入 Coze 最常踩的 5 个坑每个都曾让我重装三次微信这节不讲原理只列血泪经验。以下问题全部来自真实部署现场按发生频率排序每个都附带现象、根因和一招解决法。别跳过——它们不写在任何官方文档里但能帮你省下至少两天排查时间。5.1 现象微信消息能收到但 Coze 控制台显示 “Invalid signature” 错误原因Coze Webhook 要求请求头X-Api-Key必须等于你 Bot 的Bot Token且Content-Type必须为application/json。但很多 Flask 示例代码用jsonify()返回它会自动加Content-Type: application/json而requests.post()默认是application/x-www-form-urlencoded。解决在调用coze.webhooks.send_event()前显式设置 headersheaders { Authorization: fBearer {os.getenv(COZE_BOT_TOKEN)}, Content-Type: application/json } # 然后用 requests.post(..., headersheaders) 替代 SDK 调用SDK 0.4.2 已修复但旧版必须手动5.2 现象图片解密后是乱码浏览器打开显示“无法加载图像”原因微信 4.10 的.dat文件解密后头部可能残留 16 字节垃圾数据RC4 IV 残留导致 JPG header (FF D8 FF) 不在开头。解决解密后扫描第一个FF D8 FF位置截断前面所有字节decrypted cipher.decrypt(payload) # 找 JPG header start decrypted.find(b\xff\xd8\xff) if start ! -1: decrypted decrypted[start:] else: # fallback尝试 PNG header start decrypted.find(b\x89PNG\r\n\x1a\n) if start ! -1: decrypted decrypted[start:]5.3 现象Coze Agent 回复文字正常但发图片时微信端收不到或显示“文件已损坏”原因Coze 要求image_url必须返回Content-Type: image/jpeg或image/png但 Flask 默认静态文件服务对.jpg返回image/jpeg对.png返回image/png而你解密后存的文件扩展名可能是.jpg但内容是 PNG微信有时混用。解决用python-magic库检测真实 MIME 类型并强制设置响应头import magic mime magic.from_file(output_path, mimeTrue) return send_file(output_path, mimetypemime) # 替代 send_static_file5.4 现象同一用户发两条消息Coze 显示为两个独立会话Agent 完全不记得上一句原因session_id生成逻辑错误。有人用time.time()生成导致每条消息session_id都不同或用msg_id但没做sender绑定不同用户msg_id碰巧相同就串话。解决严格按senderttl生成 session且session_id字符串中必须包含wxid哈希new_session_id fwx_{hashlib.md5(wxid.encode()).hexdigest()[:12]}_{int(time.time())}并确保 SQLite 表wxid字段为PRIMARY KEY杜绝重复插入。5.5 现象wcferry启动时报Access is denied或Failed to inject原因Windows UAC 限制或微信进程被安全软件锁定。wcferry必须以管理员身份运行且微信不能处于“以管理员身份运行”模式会拒绝注入。解决右键微信快捷方式 → 属性 → 兼容性 → 取消勾选“以管理员身份运行此程序”然后用管理员权限运行你的 Python 脚本# Windows PowerShell 中执行 Start-Process python -ArgumentList app.py -Verb RunAs6. 进阶技巧用 Coze 工作流 微信文件上传实现「客户资料自动归档」闭环上面跑通的是基础消息收发但真实业务需要更深集成。比如销售场景客户微信发来身份证照片 → 自动 OCR 提取姓名/号码 → 存入 CRM → 回复“已登记稍后专员联系您”。这需要 Coze 工作流Workflow串联多个 Skill而微信侧必须支持文件上传。本节教你如何用现有源码框架零新增依赖实现这一闭环。6.1 让微信用户主动上传文件用 Coze 的「文件上传 Skill」触发微信端文件选择Coze 官方提供了File UploadSkill但它默认只在 Bot 界面弹出。我们要把它“透传”到微信——原理是当用户发送关键词如“上传证件”Coze Agent 不直接回复而是返回一个button消息其中url指向你自己的文件上传页/upload?session_idxxx。用户点击后页面调用微信 JS-SDK 的chooseImage上传到你的服务器再转发给 Coze。但微信 JS-SDK 需公众号认证成本高。更轻量的做法复用已有的wcferry图片监听能力让用户直接发图我们识别图中是否含“证件”字样自动触发 OCR 流程。无需用户额外操作。# 在 wx_listener.py 的 on_message 中追加 def detect_id_card_image(self, msg): if msg.type 3: # 是图片 # 调用本地 OCR用 paddleocr轻量且准确 from paddleocr import PaddleOCR ocr PaddleOCR(use_angle_clsTrue, langch, use_gpuFalse) img_path self.wcf.get_image_path(msg.id) result ocr.ocr(img_path, clsTrue) text .join([line[1][0] for line in result[0]]) if result[0] else if any(kw in text for kw in [身份证, 居民身份证, ID Card]): # 触发 Coze 工作流 self.trigger_id_card_workflow(msg.sender, img_path)6.2 构建 Coze 工作流OCR → 结构化 → CRM 写入 → 微信通知在 Coze 控制台创建 Workflow节点如下Trigger:Webhook Event接收/wx2coze发来的消息Skill:PaddleOCR调用你部署的 OCR API或直接用 Coze 内置 OCRSkill:JSON Parse用正则提取姓名、号码、有效期Skill:HTTP RequestPOST 到你 CRM 的/api/customersAction:Send Message向微信用户发送模板消息关键参数Send Message节点的user_id必须设为{{event.user_id}}message内容用变量拼接✅ 您的证件已登记 姓名{{parse_result.name}} 手机号{{parse_result.phone}} 登记时间{{now}} 我们将尽快安排专员与您联系。6.3 微信端模板消息推送用 wcferry 的 send_text send_image 实现富文本Coze 工作流执行完后会调用你的/wx2coze回调如果你配置了 Workflow 的 webhook。此时你可以在回调中解析event提取user_id即wx_xxx然后用wcf.send_text()推送结构化消息。但微信不支持 Markdown所以用换行符号模拟# 在 /wx2coze 的 POST 处理中加一段 workflow 回调识别 if event.get(event) workflow_execution_completed: wxid event[user_id].replace(wx_, ) # 还原原始 wxid # 从 event 中提取 parse_result name event.get(parse_result, {}).get(name, 未知) phone event.get(parse_result, {}).get(phone, 未识别) wcf.send_text(wxid, f✅ 您的证件已登记\n\n姓名{name}\n手机号{phone}\n\n我们将尽快安排专员与您联系。)这套组合拳下来“客户发图 → 自动识别本文还有配套的精品资源点击获取
返回列表