把 AI 小助手接入企业微信:用一个回调接口做群聊机器人实战篇

你也许已经有了一个「看起来还挺像样」的 AI 小助手服务,比如:

  • 有 HTTP 接口 /v1/chat
  • 能识别不同 Skill(待办、日报、FAQ 等);
  • 甚至已经有网页版前端。

但现实是:同事们每天真正打开的是企业微信,很少会专门去打开一个新网页跟机器人聊天。

这篇文章就做一件很实用的小事:

在不动你现有 AI 服务核心逻辑的前提下,
用一个企业微信“回调接口”
把它变成「群聊里的 @ 机器人」。

一、整体思路:后端不重写,只加一层「翻译器」

假设你现在的 AI 服务长这样:

  • 接口:POST /v1/chat

返回:

{ "answer": "上午开会,下午写代码……", "skill": "daily_plan", "duration_ms": 1234 }

请求体:

{ "question": "今天帮我规划下工作", "session_id": "xxx", "user_id": "u_123", "user_level": "normal" }

我们要做的只是:

  1. 在企业微信后台配置一个消息回调 URL(比如 /wechat/callback);
  2. 在后端写一个超薄适配层
    • 收到企业微信推来的加密 XML;
    • 解密 → 提取出「用户 ID + 文本内容」;
    • 把「文本内容」转成 question,连同 user_id 一起转发给 /v1/chat
    • 拿到 answer,再按照企业微信要求的格式加密返回。

可以简单理解为:

企业微信:提供 UI 和消息推送
你的 AI 小助手:负责“想答案”
中间这个回调接口:负责「翻译 + 转发 + 回填」

二、企业微信端:你必须准备的 3 个关键参数

在写代码前,先在企业微信后台把几个关键信息准备好。

2.1 创建自建应用 / 机器人

  1. 管理员登录企业微信后台;
  2. 进入【应用管理】 →【自建】→【创建应用】;
  3. 按提示填写名称、图标即可。

创建完成后,记下:

  • CorpID(企业 ID)
  • AgentID(应用 ID)
  • Secret(应用密钥)
其中 CorpID 稍后会和 Token、EncodingAESKey 一起用于解密;
Secret 一般用于你「主动调用企业微信接口」,本篇只做回调,不用到。

2.2 配置消息回调

在刚刚创建的自建应用里,找到:

  • 「接收消息」或「回调配置」模块

配置三项:

  1. URL:你后端可公网访问的地址,比如
    https://your-domain.com/wechat/callback
  2. Token:自己随便写一个,比如 my_wechat_token_2024
  3. EncodingAESKey:企业微信自动生成的一串 43 位字符串

这三项记下来,对应到代码里的环境变量:

环境变量名对应企业微信配置
WECHAT_TOKENToken
WECHAT_ENCODING_AES_KEYEncodingAESKey
WECHAT_CORP_ID企业 CorpID

三、项目结构:只新增一个 wechat_adapter.py

假设你当前项目结构:

project/ ├── app/ │ ├── server.py # 已有:包含 /v1/chat │ ├── ... ├── docker-compose.yml └── Dockerfile

现在只需要:

  • app/ 下加一个 wechat_adapter.py,做企业微信适配;
  • server.py 里把这个 router 挂起来。

四、后端实现:FastAPI + wechatpy

这里用 FastAPI 举例(Flask 思路完全一样),并使用 wechatpy 来处理消息加解密,避免自己手写 AES。

4.1 安装依赖

pip install fastapi uvicorn wechatpy httpx

(如果你已经有 FastAPI,只需加 wechatpyhttpx 即可。)

4.2 编写 wechat_adapter.py

# app/wechat_adapter.py import os from fastapi import APIRouter, Request from fastapi.responses import PlainTextResponse from wechatpy.enterprise.crypto import WeChatCrypto from wechatpy.enterprise import parse_message, create_reply import httpx # 从环境变量读取配置 WECHAT_TOKEN = os.getenv("WECHAT_TOKEN") WECHAT_ENCODING_AES_KEY = os.getenv("WECHAT_ENCODING_AES_KEY") WECHAT_CORP_ID = os.getenv("WECHAT_CORP_ID") # 你自己的 AI 服务接口 AGENT_BACKEND_URL = os.getenv("AGENT_BACKEND_URL", "http://localhost:8000/v1/chat") router = APIRouter() @router.get("/callback") async def wechat_verify( msg_signature: str, timestamp: str, nonce: str, echostr: str ): """ 企业微信在配置回调 URL 时,会发一个 GET 请求校验。 要做的就是:用 WeChatCrypto 解密 echostr,然后原样返回。 """ crypto = WeChatCrypto(WECHAT_TOKEN, WECHAT_ENCODING_AES_KEY, WECHAT_CORP_ID) try: echostr_decoded = crypto.decrypt_message(echostr, msg_signature, timestamp, nonce) return PlainTextResponse(content=echostr_decoded) except Exception: # 验签失败就返回空,企业微信会认为不通过 return PlainTextResponse(content="") @router.post("/callback") async def wechat_callback(request: Request): """ 真正收消息的入口。 1. 解密 XML 2. 解析文本内容 3. 调用内部 AI 服务 4. 构造并加密回复 """ query = request.query_params msg_signature = query.get("msg_signature") timestamp = query.get("timestamp") nonce = query.get("nonce") raw_xml = await request.body() crypto = WeChatCrypto(WECHAT_TOKEN, WECHAT_ENCODING_AES_KEY, WECHAT_CORP_ID) try: msg_xml = crypto.decrypt_message( raw_xml, msg_signature, timestamp, nonce ) except Exception: return PlainTextResponse(content="") # 解析企业微信 XML msg = parse_message(msg_xml) # 只处理文本消息 if msg.type != "text": reply = create_reply("暂时只支持文本消息哦~", msg) encrypted = crypto.encrypt_message(reply.render(), nonce, timestamp) return PlainTextResponse(content=encrypted) # 用户ID(企业微信里的 userid) user_id = msg.source content = msg.content.strip() # [可选] 去掉前面的 @机器人 文本,只保留真正问题 # 例如:"@AI小助手 帮我写日报" → "帮我写日报" if content.startswith("@"): idx = content.find(" ") if idx != -1: content = content[idx + 1 :].strip() # 调用你自己的 AI 接口 async with httpx.AsyncClient(timeout=30) as client: try: resp = await client.post( AGENT_BACKEND_URL, json={ "question": content, "session_id": f"wx_{user_id}", "user_id": f"wx_{user_id}", "user_level": "normal", } ) data = resp.json() answer = data.get("answer", "后端没有返回 answer 字段,请检查。") except Exception as e: answer = f"后端服务异常:{e}" # 构造回复 XML 并加密 reply = create_reply(answer, msg) encrypted = crypto.encrypt_message(reply.render(), nonce, timestamp) return PlainTextResponse(content=encrypted)

4.3 在 server.py 中挂载 router

# app/server.py from fastapi import FastAPI from app.wechat_adapter import router as wechat_router app = FastAPI(title="My AI Agent Service") # 原有 /v1/chat 等接口 # @app.post("/v1/chat") # async def chat(...): # ... # 新增企业微信路由 app.include_router(wechat_router, prefix="/wechat")

本地启动(开发阶段):

uvicorn app.server:app --host 0.0.0.0 --port 8000 --reload

现在,你有了如下几个接口:

  • POST /v1/chat:原来的 AI 接口
  • GET /wechat/callback:用于企业微信验证 URL
  • POST /wechat/callback:用于接收真实消息并回复

五、让企业微信找到你的服务:Nginx / 域名配置

企业微信需要访问你服务器的公网地址,所以一般会放在 Nginx 之后。

假设你有一个域名 https://bot.example.com,Nginx 配置大致如下(核心是 /wechat/ 这段):

server { listen 80; server_name bot.example.com; location / { proxy_pass http://app:8000/; } # 专门给企业微信回调用 location /wechat/ { proxy_pass http://app:8000/wechat/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

重载 Nginx:

nginx -s reload

然后在企业微信后台把回调 URL 填写为:

https://bot.example.com/wechat/callback

保存时,企业微信会向这个 URL 发一个 GET 请求进行签名验证。只要你代码和配置写对,后台就会提示「验证通过」。


六、Docker Compose 中增加环境变量(如在容器里跑)

如果你是用 docker-compose 启动 FastAPI 应用,在 docker-compose.yml 里为 app 服务增加环境变量:

services: app: build: . environment: - OPENAI_API_KEY=sk-xxxx - WECHAT_TOKEN=my_wechat_token_2024 - WECHAT_ENCODING_AES_KEY=你的43位AESKey - WECHAT_CORP_ID=你的企业CorpID - AGENT_BACKEND_URL=http://app:8000/v1/chat ports: - "8000:8000"

重新构建并启动:

docker-compose up -d --build

七、在企业微信群里真实体验一把

  1. 确保:
    • 你的 app 服务已启动;
    • Nginx 反向代理配置正确;
    • 企业微信后台的回调验证已经通过。
  2. 在企业微信中:
    • 找到你刚刚创建的自建应用 / 机器人;
    • 将它添加到某个测试群
  3. 对同事来说,这就是一个普通的群聊机器人
    • 不需要任何技术知识;
    • 会记住对话上下文(取决于你 /v1/chat 的实现);
    • 会调用你现有的多技能 / RAG / 缓存逻辑。

在群里直接 @ 它,例如:

张三:@AI小助手 帮我写一份今天的工作计划: 上午要开会,下午写代码,晚上看两篇技术文章。 AI小助手: 好的,这是你今天的简要工作计划: 1. 上午:准备和参加会议,记录行动项…… 2. 下午:根据会议结论编写代码…… 3. 晚上:选择两篇和当前项目相关的技术文章……

八、简单故障排查 Checklist

1. 企业微信后台提示「URL 验证失败」

重点检查:

  • WECHAT_TOKENEncodingAESKeyCorpID 是否和后台一致;
  • URL 是否和你代码里的路由匹配(是否带 /wechat/callback 前缀);
  • Nginx 是否正确转发到你的 app:8000/wechat/

可以在回调接口里先打印日志,确认 GET 请求有没有到后端。

2. 群里 @ 机器人没反应

可能原因:

  1. /wechat/callback 配置的是内网地址,企业微信访问不到;
  2. 你的 AI 服务 /v1/chat 报错,导致 answer 为空或超时;
  3. 机器人没有被拉进当前群。

排查方法:

  • 先在后端打印收到的 msg.content,确保消息已经到达你服务;
  • 再单独用 curl 或 Postman 测试 /v1/chat 是否工作正常。

3. 机器人一直回复「只支持文本」

说明你发送的是图片、文件等非文本类型,而代码里只接受 msg.type == "text"。可以根据实际需要扩展对其他类型的支持。


九、进阶扩展思路(可选)

当基础版本跑通后,你可以逐步加一些“工程化”功能:

  1. 按用户配额控制用量
    • user_id = msg.source 传给 /v1/chat
    • 在 AI 服务侧按人统计 Token 消耗,设置每日上限。
  2. 按部门开放不同 Skill
    • 若能从企业微信接口拿到部门信息,可在内部配置文件中,为不同部门开放不同功能。
  3. 对接钉钉 / 飞书
    • 保持 /v1/chat 不变;
    • 新增 dingtalk_adapter.pyfeishu_adapter.py,用同样的“回调 → 转发”模式接入。

十、总结

  • 不动核心,只加一层适配
    企业微信只是换了一个入口,你的 AI 逻辑仍只暴露 /v1/chat
  • 成本低,上手快
    一份 wechat_adapter.py + 一点 Nginx / Docker 配置,就能把你的 AI 小助手真正「塞进」日常企业工作流。
  • 具备可扩展空间
    后续可以按配额、权限、统计、管理后台等方向继续进化,而这一层群聊回调接口几乎无须改变。

Read more

Flutter 组件 spry 适配鸿蒙 HarmonyOS 实战:轻量化 Web 框架,构建高性能端侧微服务与 Middleware 治理架构

Flutter 组件 spry 适配鸿蒙 HarmonyOS 实战:轻量化 Web 框架,构建高性能端侧微服务与 Middleware 治理架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 spry 适配鸿蒙 HarmonyOS 实战:轻量化 Web 框架,构建高性能端侧微服务与 Middleware 治理架构 前言 在鸿蒙(OpenHarmony)生态迈向全场景分布式协同、涉及设备端侧 API 暴露、轻量化资源服务镜像及严苛的跨端 RPC 通信背景下,如何实现一套既能保持极低内存足迹(Footprint)、又能提供类似后端(Node.js/Koa)般丝滑开发体验且具备全异步处理能力的“端侧 Web 基座”,已成为决定应用分布式自治能力与全栈同构效率的关键。在鸿蒙设备这类强调 AOT 极致效能与背景任务严格限制的环境下,如果应用依然采用重量级的 HTTP 服务端,由于由于进程级的上下文切换开销,极易由于由于“算力溢出”导致鸿蒙应用在作为服务端响应时发生明显的电量损耗。 我们需要一种能够解耦路由逻辑、支持

VibeThinker-1.5B-WEBUI使用秘籍:提升推理效率的7个技巧

VibeThinker-1.5B-WEBUI使用秘籍:提升推理效率的7个技巧 1. 背景与核心价值 随着大模型在数学推理和代码生成任务中的广泛应用,如何在控制成本的前提下实现高效推理成为工程实践中的关键挑战。微博开源的 VibeThinker-1.5B 模型以仅15亿参数规模,在数学与编程类任务中展现出超越更大模型的性能表现,为低成本、高效率的AI推理提供了新的可能性。 该模型总训练成本仅为7,800美元,却在AIME24、AIME25等权威数学基准测试中超过DeepSeek R1(参数量超其400倍),同时在LiveCodeBench v6上得分达51.1,优于Magistral Medium。这表明其在竞争性编程与复杂逻辑推理场景中具备显著优势。 本文将围绕 VibeThinker-1.5B-WEBUI 的实际应用,系统介绍7个提升推理效率的关键技巧,帮助开发者最大化利用这一轻量级高性能模型。 2. 理解模型定位与适用边界 2.1 小参数但强推理的设计哲学 VibeThinker-1.5B 属于典型的“小模型、大能力”范式。它并非通用对话模型,而是专注于结构化推理

Claude Code源码泄露!重磅解读51万行代码,AI圈直接起飞

Claude Code源码泄露!重磅解读51万行代码,AI圈直接起飞

大家好,我是查老师。 什么?Anthropic 旗下的编程工具Claude Code 源码被“泄漏”了。 01 发生了什么? AI巨头Anthropic遭遇重大安全事故,其核心AI编程工具Claude Code的完整源代码意外泄露,规模达51.2万行TypeScript代码、超1900个文件,此事引发全球AI行业震动,被业内称为AI界的“核泄漏”事件。 更让人大跌眼镜的是,此次泄露并非黑客攻击所致,而是一场低级的发布打包失误,据悉,Web3安全公司实习研究员未正确排除调试文件(.npm文件),导致一个57MB的源映射文件被公开发布。 该文件包含完整的源码映射信息,开发者只需简单脚本即可还原1900多个TypeScript原始文件,涵盖Claude Code的内部架构、核心算法和工具调用机制,包括代码执行沙箱安全机制、多模态上下文理解模块等多项未发布功能。 02 为什么这件事这么“魔幻” 错得很“低级”:source map是开发调试用的文件,绝对不该出现在给用户的发布包里。这是一个从Web开发时代就有的常识性错误。更讽刺的是,Claude C

Web Access:一个Skill,拉满Agent联网和浏览器能力

Web Access:一个Skill,拉满Agent联网和浏览器能力

Web Access:一个Skill,拉满Agent联网和浏览器能力 摘要:本文深度解析Web Access Skill如何彻底解决Claude Code、OpenClaw等Agent框架的联网痛点,通过CDP浏览器直连、Sub-Agent并行分治、站点经验沉淀三大核心技术,实现一次性并发操作100个网页的极致体验。包含完整安装配置指南与实战案例。 关键词:Web Access Skill, Agent联网, Claude Code, OpenClaw, CDP浏览器自动化, Sub-Agent并行, 站点经验沉淀, AI浏览器控制 一、为什么现有Agent联网方案总是"差点意思"? 如果你用过Claude Code或OpenClaw的默认联网功能,一定遇到过这些抓狂时刻: * 搜索引擎钻牛角尖:让Agent"调研小红书上关于AI工具的风评",它拿着Web Search工具换各种关键词在搜索引擎里翻,就是不肯直接打开小红书 * 动态页面直接歇菜:Web Fetch去抓小红书、微信公众号,返回的不是空白就是登录提示,跟瞎子摸象似的 * 并发能力约等于零: