10 KiB
10 KiB
云端最小回调壳部署方案
一、目标
阶段目标:在备案域名上部署最小可用回调壳,使企业微信能完成 URL 校验与回调联调。
最小功能范围:
- ✅
/api/wecom/callbackGET 校验(兼容signature/msg_signature) - ✅
/api/wecom/callbackPOST 密文消息回调(验签、解密、echo 回复) - ✅ 结构化日志 + trace_id
- ✅ Nginx 反代 + HTTPS(Let's Encrypt)
- ⏸️ 数据库(可先不启用,但接口与配置要预留)
- ⏸️ Admin 后台(可先占位)
二、架构
企业微信 → HTTPS (443) → Nginx → Backend (8000)
↓
PostgreSQL (可选)
服务清单:
backend: Python 3.12 + FastAPI + Uvicorn(最小回调壳)nginx: 反代 + HTTPS(Let's Encrypt)db: PostgreSQL 16(可选,先不启用)
三、环境变量配置
3.1 必需变量(.env)
# ============ Backend ============
API_HOST=0.0.0.0
API_PORT=8000
# Database(可选,先不启用)
DATABASE_URL=postgresql+asyncpg://wecom:wecom_secret@db:5432/wecom_ai
DATABASE_URL_SYNC=postgresql://wecom:wecom_secret@db:5432/wecom_ai
# JWT(admin 登录,可选)
JWT_SECRET=your-jwt-secret-change-in-production
JWT_ALGORITHM=HS256
JWT_EXPIRE_MINUTES=60
# WeCom Callback(必须,从企业微信管理后台获取)
WECOM_CORP_ID=你的企业ID
WECOM_AGENT_ID=你的应用AgentId
WECOM_SECRET=你的应用Secret(可选,用于主动发送消息)
WECOM_TOKEN=你的Token(必须与企微后台一致)
WECOM_ENCODING_AES_KEY=你的43位密钥(必须与企微后台一致)
# WeCom API
WECOM_API_BASE=https://qyapi.weixin.qq.com
WECOM_API_TIMEOUT=10
WECOM_API_RETRIES=2
# Log
LOG_LEVEL=INFO
LOG_JSON=true
# ============ Nginx ============
# 域名(必须,备案域名)
DOMAIN=your-domain.com
# SSL(Let's Encrypt)
SSL_EMAIL=your-email@example.com
3.2 关键变量说明
| 变量 | 说明 | 来源 |
|---|---|---|
WECOM_TOKEN |
企业微信回调 Token | 企微后台 → 应用 → 接收消息 → Token |
WECOM_ENCODING_AES_KEY |
43 位 Base64 编码密钥 | 企微后台 → 应用 → 接收消息 → EncodingAESKey |
WECOM_CORP_ID |
企业 ID | 企微后台 → 我的企业 → 企业信息 |
WECOM_AGENT_ID |
应用 AgentId | 企微后台 → 应用管理 → 自建应用 → 应用详情 |
DOMAIN |
备案域名 | 你的域名服务商 |
四、部署步骤
4.1 前置条件
- 备案域名:已备案且主体关联的域名(例如:
api.yourdomain.com) - 服务器:Linux(Ubuntu 20.04+ / CentOS 7+),公网 IP,开放 80/443 端口
- Docker:已安装 Docker 和 docker-compose
- GitHub:代码已推送到 GitHub(用于 CI/CD)
4.2 服务器初始化
# 1. 安装 Docker 和 docker-compose
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 2. 克隆项目(或通过 CI/CD 部署)
git clone https://github.com/your-org/wecom-ai-assistant.git
cd wecom-ai-assistant
# 3. 创建 .env 文件
cp .env.example .env
# 编辑 .env,填入上述必需变量
4.3 配置 Nginx + HTTPS
方案 A:使用 Certbot(Let's Encrypt)
# 1. 安装 Certbot
sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx
# 2. 先启动 HTTP 服务(用于验证)
docker-compose up -d backend
# 3. 配置 Nginx(临时 HTTP 配置)
# 编辑 deploy/nginx.conf,添加 server_name
# 然后运行:docker-compose up -d nginx
# 4. 获取 SSL 证书
sudo certbot --nginx -d your-domain.com -d www.your-domain.com --email your-email@example.com --agree-tos --non-interactive
# 5. 更新 nginx.conf,使用 Certbot 生成的配置
# Certbot 会自动修改 /etc/nginx/sites-available/default
# 将配置复制到 deploy/nginx.conf,或使用 volume 挂载
方案 B:手动配置 Nginx + Let's Encrypt
创建 deploy/nginx-ssl.conf:
events { worker_connections 1024; }
http {
upstream backend {
server backend:8000;
}
# HTTP → HTTPS 重定向
server {
listen 80;
server_name your-domain.com www.your-domain.com;
return 301 https://$server_name$request_uri;
}
# HTTPS
server {
listen 443 ssl http2;
server_name your-domain.com www.your-domain.com;
# SSL 证书(Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# /api -> backend
location /api/ {
proxy_pass http://backend;
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;
proxy_read_timeout 30s;
}
# 健康检查
location /health {
proxy_pass http://backend/health;
access_log off;
}
}
}
更新 docker-compose.yml:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./deploy/nginx-ssl.conf:/etc/nginx/nginx.conf:ro
- /etc/letsencrypt:/etc/letsencrypt:ro # SSL 证书
depends_on:
- backend
4.4 启动服务
# 1. 构建镜像
docker-compose build backend
# 2. 启动服务(最小回调壳:只启动 backend + nginx)
docker-compose up -d backend nginx
# 3. 检查日志
docker-compose logs -f backend
4.5 验证服务
# 1. 检查服务状态
docker-compose ps
# 2. 检查健康检查
curl https://your-domain.com/health
# 3. 检查回调接口(应返回 400,因为缺少参数)
curl https://your-domain.com/api/wecom/callback
五、本地验证
5.1 本地启动最小回调壳
# 1. 启动后端(不启动 db/admin)
docker-compose up -d backend
# 2. 检查日志
docker-compose logs backend
# 3. 测试 GET 校验(模拟企业微信)
# 注意:需要正确的 signature/timestamp/nonce/echostr
curl "http://localhost:8000/api/wecom/callback?signature=xxx×tamp=123&nonce=abc&echostr=xxx"
5.2 本地测试 POST 回调
# 使用企业微信官方测试工具生成测试请求
# 或使用 curl 模拟(需要正确的签名和加密)
curl -X POST "http://localhost:8000/api/wecom/callback?msg_signature=xxx×tamp=123&nonce=abc" \
-H "Content-Type: application/xml" \
-d '<xml><Encrypt><![CDATA[加密内容]]></Encrypt></xml>'
5.3 验证日志格式
检查日志输出是否符合结构化日志格式:
{
"timestamp": "2025-02-05T10:00:00Z",
"level": "INFO",
"message": "wecom verify success",
"trace_id": "abc123",
"echostr_length": 43
}
六、线上验证
6.1 企业微信后台配置
- 登录企业微信管理后台:https://work.weixin.qq.com
- 进入应用设置:应用管理 → 自建应用 → 选择你的应用
- 配置回调 URL:
- 接收消息服务器 URL:
https://your-domain.com/api/wecom/callback - Token:与
.env中的WECOM_TOKEN完全一致 - EncodingAESKey:与
.env中的WECOM_ENCODING_AES_KEY完全一致 - 消息加解密方式:安全模式
- 接收消息服务器 URL:
- 点击保存
6.2 验证 GET 校验
保存后,企业微信会立即发送 GET 请求验证。观察后端日志:
docker-compose logs -f backend
成功日志:
INFO: wecom verify success {"trace_id": "...", "echostr_length": 43}
失败日志:
WARNING: wecom verify failed {"trace_id": "...", "timestamp": "...", "nonce": "..."}
如果验证失败,检查:
- Token 是否一致
- EncodingAESKey 是否一致
- 域名是否可访问(
curl https://your-domain.com/api/wecom/callback)
6.3 验证 POST 回调
-
在企业微信中发送测试消息:
- 打开企业微信客户端
- 找到你配置的应用
- 发送文本消息:
你好,测试一下
-
观察后端日志:
docker-compose logs -f backend
成功日志:
{
"timestamp": "2025-02-05T10:00:00Z",
"level": "INFO",
"message": "wecom message received",
"trace_id": "abc123",
"external_userid": "external_userid_xxx",
"msgid": "123456",
"msg_type": "text",
"content_summary": "你好,测试一下"
}
{
"timestamp": "2025-02-05T10:00:01Z",
"level": "INFO",
"message": "wecom reply sent",
"trace_id": "abc123",
"external_userid": "external_userid_xxx",
"msgid": "123456",
"reply_summary": "已收到:你好,测试一下"
}
- 检查企业微信客户端:应收到回复:
已收到:你好,测试一下
七、常见问题
7.1 GET 校验失败
原因:
- Token 不一致
- EncodingAESKey 不一致
- 签名算法错误
解决:
- 检查
.env中的WECOM_TOKEN和WECOM_ENCODING_AES_KEY - 确保与企微后台配置完全一致(包括大小写、空格)
- 重启后端:
docker-compose restart backend
7.2 POST 回调失败
原因:
- 签名验证失败
- 解密失败
- XML 解析失败
解决:
- 检查日志中的错误信息
- 确认 EncodingAESKey 正确
- 确认消息加解密方式为安全模式
7.3 HTTPS 证书问题
原因:
- Let's Encrypt 证书未正确配置
- 证书过期
解决:
- 检查证书:
sudo certbot certificates - 续期证书:
sudo certbot renew - 重启 Nginx:
docker-compose restart nginx
7.4 域名无法访问
原因:
- DNS 未解析
- 防火墙未开放 80/443 端口
- Nginx 配置错误
解决:
- 检查 DNS:
nslookup your-domain.com - 检查端口:
netstat -tlnp | grep -E '80|443' - 检查 Nginx 日志:
docker-compose logs nginx
八、下一步
完成最小回调壳部署后,按以下顺序逐步接入:
- ✅ 最小回调壳(当前阶段)
- ⏭️ 数据库接入(会话与消息入库)
- ⏭️ Admin 后台(会话列表、工单、知识库)
- ⏭️ FAQ/RAG(智能回复)