第七章:企业微信消息解密与完整回调链路打通
这一章是从“能收到请求”到“能理解消息”的关键跃迁。
上一章我们已经做到:
企业微信消息可以进入 FastAPI
但目前系统仍然是:
✔ 收到了请求
❌ 看不懂内容
❌ 没有解密
❌ 没有业务分发
这一章结束后,你的系统会变成:
企业微信 → 解析 → 解密 → 识别消息 → 分发处理
7.1 企业微信加密消息的真实结构
企业微信 POST 请求的核心内容如下:
<xml>
<ToUserName><![CDATA[wwxxxxx]]></ToUserName>
<Encrypt><![CDATA[encrypted_message]]></Encrypt>
</xml>
同时 HTTP 参数还有:
msg_signature=xxx
timestamp=xxx
nonce=xxx
📌 本质结构
HTTP层参数(签名)
↓
XML外壳
↓
Encrypt(真正消息体)
↓
AES解密
↓
明文XML
7.2 完整处理流程设计
本章完成后的标准链路:
POST /wecom/callback
↓
1. 解析XML
↓
2. 提取 Encrypt
↓
3. 校验 msg_signature
↓
4. AES解密
↓
5. 得到明文XML
↓
6. 解析消息内容
↓
7. 进入Dispatcher
7.3 更新 wecom_crypto(核心升级)
📌 crypto.py(完整实现)
from wechatpy.crypto import WeChatCrypto
import os
class WeComCrypto:
def __init__(self):
self.token = os.getenv("WECOM_TOKEN")
self.aes_key = os.getenv("WECOM_AES_KEY")
self.corp_id = os.getenv("WECOM_CORP_ID")
self.crypto = WeChatCrypto(
self.token,
self.aes_key,
self.corp_id
)
def verify_signature(self, msg_signature, timestamp, nonce, data):
"""
校验签名
"""
return self.crypto.check_signature(
msg_signature,
timestamp,
nonce,
data
)
def decrypt_message(self, msg_signature, timestamp, nonce, xml):
"""
解密企业微信消息
"""
return self.crypto.decrypt_message(
xml,
msg_signature,
timestamp,
nonce
)
7.4 XML解析增强
📌 parser.py(升级版)
import xml.etree.ElementTree as ET
def parse_encrypt_xml(xml_str: str):
"""
解析外层XML(带Encrypt)
"""
root = ET.fromstring(xml_str)
data = {}
for child in root:
data[child.tag] = child.text
return data
def parse_plain_xml(xml_str: str):
"""
解析解密后的XML
"""
root = ET.fromstring(xml_str)
data = {}
for child in root:
data[child.tag] = child.text
return data
7.5 callback.py(完整版本)
📌 POST入口升级
from fastapi import APIRouter, Request
from app.wecom.crypto import WeComCrypto
from app.wecom.parser import parse_encrypt_xml, parse_plain_xml
router = APIRouter()
crypto = WeComCrypto()
@router.post("/callback")
async def callback(request: Request):
"""
企业微信消息入口
"""
# 1️⃣ 获取URL参数
params = dict(request.query_params)
msg_signature = params.get("msg_signature")
timestamp = params.get("timestamp")
nonce = params.get("nonce")
# 2️⃣ 读取XML
body = await request.body()
xml_str = body.decode("utf-8")
# 3️⃣ 解析外层XML
outer = parse_encrypt_xml(xml_str)
encrypt = outer.get("Encrypt")
print("收到Encrypt:", encrypt)
# 4️⃣ 校验签名
crypto.verify_signature(
msg_signature,
timestamp,
nonce,
encrypt
)
# 5️⃣ 解密消息
plain_xml = crypto.decrypt_message(
msg_signature,
timestamp,
nonce,
xml_str
)
print("解密后XML:", plain_xml)
# 6️⃣ 解析明文
message = parse_plain_xml(plain_xml)
print("结构化消息:", message)
return "success"
7.6 明文消息结构
解密后通常是:
<xml>
<ToUserName>wwxxx</ToUserName>
<FromUserName>user123</FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType>text</MsgType>
<Content>你好</Content>
<MsgId>123456</MsgId>
</xml>
📌 转换后的结构
{
"ToUserName": "wwxxx",
"FromUserName": "user123",
"MsgType": "text",
"Content": "你好",
"MsgId": "123456"
}
7.7 消息类型识别(第一版)
在 callback 中加入:
msg_type = message.get("MsgType")
if msg_type == "text":
print("文本消息:", message.get("Content"))
elif msg_type == "event":
print("事件消息")
else:
print("其他类型:", msg_type)
7.8 当前系统状态
✅ 已完成
✔ FastAPI回调入口
✔ XML解析(外层+内层)
✔ msg_signature校验
✔ AES解密
✔ 明文结构化
✔ 消息类型识别
🚧 当前系统能力
企业微信 → 你的系统
✔ 已能进入
✔ 已能解密
✔ 已能识别内容
但还没有:
❌ Redis队列
❌ AI处理
❌ 回复消息
7.9 本章核心成果
这一章完成后,你的系统已经具备:
👉 “理解用户消息”的能力
不再是HTTP服务,而是:
👉 企业微信消息处理系统
🚀 下一章预告(第八章)
第八章:消息分发与Dispatcher设计
下一章我们将完成:
消息路由
│
├── text → AI处理
├── event → 事件处理
├── image → 图片处理
└── file → 文件处理
并引入:
- Dispatcher模式
- Handler拆分
- 可扩展消息架构
👉 到这一章结束:
系统将开始具备“业务处理能力”,真正进入AI链路入口。