Files
wecom-ai-assistant/docs/deploy-cloud-minimal.md
2026-02-05 16:36:32 +08:00

10 KiB
Raw Blame History

云端最小回调壳部署方案

一、目标

阶段目标:在备案域名上部署最小可用回调壳,使企业微信能完成 URL 校验与回调联调。

最小功能范围

  • /api/wecom/callback GET 校验(兼容 signature/msg_signature
  • /api/wecom/callback POST 密文消息回调验签、解密、echo 回复)
  • 结构化日志 + trace_id
  • Nginx 反代 + HTTPSLet's Encrypt
  • ⏸️ 数据库(可先不启用,但接口与配置要预留)
  • ⏸️ Admin 后台(可先占位)

二、架构

企业微信 → HTTPS (443) → Nginx → Backend (8000)
                              ↓
                          PostgreSQL (可选)

服务清单

  • backend: Python 3.12 + FastAPI + Uvicorn最小回调壳
  • nginx: 反代 + HTTPSLet'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

# JWTadmin 登录,可选)
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

# SSLLet'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 前置条件

  1. 备案域名:已备案且主体关联的域名(例如:api.yourdomain.com
  2. 服务器LinuxUbuntu 20.04+ / CentOS 7+),公网 IP开放 80/443 端口
  3. Docker:已安装 Docker 和 docker-compose
  4. 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使用 CertbotLet'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&timestamp=123&nonce=abc&echostr=xxx"

5.2 本地测试 POST 回调

# 使用企业微信官方测试工具生成测试请求
# 或使用 curl 模拟(需要正确的签名和加密)
curl -X POST "http://localhost:8000/api/wecom/callback?msg_signature=xxx&timestamp=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 企业微信后台配置

  1. 登录企业微信管理后台https://work.weixin.qq.com
  2. 进入应用设置:应用管理 → 自建应用 → 选择你的应用
  3. 配置回调 URL
    • 接收消息服务器 URLhttps://your-domain.com/api/wecom/callback
    • Token.env 中的 WECOM_TOKEN 完全一致
    • EncodingAESKey.env 中的 WECOM_ENCODING_AES_KEY 完全一致
    • 消息加解密方式:安全模式
  4. 点击保存

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 回调

  1. 在企业微信中发送测试消息

    • 打开企业微信客户端
    • 找到你配置的应用
    • 发送文本消息:你好,测试一下
  2. 观察后端日志

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": "已收到:你好,测试一下"
}
  1. 检查企业微信客户端:应收到回复:已收到:你好,测试一下

七、常见问题

7.1 GET 校验失败

原因

  • Token 不一致
  • EncodingAESKey 不一致
  • 签名算法错误

解决

  1. 检查 .env 中的 WECOM_TOKENWECOM_ENCODING_AES_KEY
  2. 确保与企微后台配置完全一致(包括大小写、空格)
  3. 重启后端:docker-compose restart backend

7.2 POST 回调失败

原因

  • 签名验证失败
  • 解密失败
  • XML 解析失败

解决

  1. 检查日志中的错误信息
  2. 确认 EncodingAESKey 正确
  3. 确认消息加解密方式为安全模式

7.3 HTTPS 证书问题

原因

  • Let's Encrypt 证书未正确配置
  • 证书过期

解决

  1. 检查证书:sudo certbot certificates
  2. 续期证书:sudo certbot renew
  3. 重启 Nginxdocker-compose restart nginx

7.4 域名无法访问

原因

  • DNS 未解析
  • 防火墙未开放 80/443 端口
  • Nginx 配置错误

解决

  1. 检查 DNSnslookup your-domain.com
  2. 检查端口:netstat -tlnp | grep -E '80|443'
  3. 检查 Nginx 日志:docker-compose logs nginx

八、下一步

完成最小回调壳部署后,按以下顺序逐步接入:

  1. 最小回调壳(当前阶段)
  2. ⏭️ 数据库接入(会话与消息入库)
  3. ⏭️ Admin 后台(会话列表、工单、知识库)
  4. ⏭️ FAQ/RAG(智能回复)

九、参考文档