# 部署指南 --- ## 前置条件 - Node.js >= 18 - PostgreSQL 数据库(已运行 Parse Server,或独立部署) - QiWe 开放平台账号(已获取 Token 和 GUID) --- ## 1. 环境配置 复制环境变量模板并填入真实配置: ```bash cp .env.example .env ``` 编辑 `.env`: ```env # 运行环境 NODE_ENV=production PORT=3101 # Parse SDK (PostgreSQL) PARSE_APP_ID=lami-ai PARSE_MASTER_KEY=你的masterKey PARSE_SERVER_URL=https://你的服务器地址/parse # QiWe 开放平台 QIWE_API_BASE=https://manager.qiweapi.com/qiwe QIWE_TOKEN=你的qiwe-token QIWE_GUID=你的qiwe-guid QIWE_USER_ID=你的qiwe-user-id ``` 配置说明: | 变量 | 获取方式 | |------|---------| | `PARSE_MASTER_KEY` | Parse Server 的 masterKey | | `PARSE_SERVER_URL` | Parse Server 地址 | | `QIWE_TOKEN` | QiWe 控制台 → 应用凭证 → TokenId | | `QIWE_GUID` | QiWe 控制台 → 实例管理 → 点开详情获取 | | `QIWE_USER_ID` | QiWe API `getPersonalInfo` 返回的 userId | --- ## 2. 安装依赖 ```bash npm install ``` --- ## 3. 初始化数据库 运行独立的数据库初始化脚本,创建所有表结构: ```bash npm run init-db ``` 脚本会: 1. 验证 Parse 连接 2. 创建 6 张表(GroupChat, GroupMember, Message, MessageSyncCursor, Contact, WebhookLog) 3. 设置每张表的字段和 CLP 权限 4. 输出建议的 PostgreSQL 索引 SQL **注意:** 索引 SQL 需要手动在 PostgreSQL 中执行以优化查询性能。可以在数据库管理工具(如 pgAdmin、DBeaver)中执行脚本输出的 SQL。 **幂等性:** 该脚本可重复执行,已存在的字段会自动跳过,不会报错。 --- ## 4. 配置 Webhook 回调地址 在 QiWe 控制台 → 应用凭证 → 配置回调地址中填入: ``` https://你的服务器地址/api/qiwe/webhook ``` 配置后 QiWe 会立即发送验证消息,服务日志中会看到 `[Webhook]` 相关输出。 --- ## 5. 启动服务 ### 开发模式(热重载) ```bash npm run dev ``` ### 生产模式(编译后运行) ```bash npm run build npm start ``` ### PM2 生产部署 ```bash # 安装 PM2 npm install -g pm2 # 启动 pm2 start ecosystem.config.cjs # 查看状态 pm2 status # 查看日志 pm2 logs lami-qiwe # 设置开机自启 pm2 save pm2 startup ``` --- ## 6. 首次全量同步 服务启动 30 秒后会自动开始首次同步。也可以手动触发: ```bash # 群同步 curl -X POST http://localhost:3101/api/qiwe/sync-groups # 消息同步 curl -X POST "http://localhost:3101/api/qiwe/sync-messages?maxPages=20&limit=200" # 联系人同步 curl -X POST http://localhost:3101/api/qiwe/sync-contacts # 查看状态 curl http://localhost:3101/api/qiwe/status ``` 建议顺序:**群同步 → 消息同步 → 联系人同步** --- ## 7. 验证部署 ```bash # 健康检查 curl http://localhost:3101/api/health # 状态查询 curl http://localhost:3101/api/qiwe/status ``` --- ## 8. 定时任务说明 服务启动后自动运行以下定时任务: | 周期 | 任务 | |------|------| | 每 3 分钟 | 增量消息同步(补漏 Webhook 可能丢失的消息) | | 每 1 小时 | 全量群同步 + 群详情补全 + ownerName 回填 + senderName 回填 | | 每 6 小时 | 全量联系人同步 | --- ## 9. 常见问题 ### Q: 脚本 npm run init-db 报连接失败 检查 `.env` 中 `PARSE_SERVER_URL` 和 `PARSE_MASTER_KEY` 是否正确,确保服务器可以从当前网络访问。 ### Q: Webhook 验证失败 确保服务器在公网可访问,端口未被防火墙拦截。测试环境可使用 ngrok 等内网穿透工具。 ### Q: 消息同步有遗漏 Webhook 可能因网络问题丢失少量消息,增量消息同步(每 3 分钟)会自动补漏。如仍有大量遗漏,增加 `maxPages` 参数手动触发一次同步。 ### Q: 群成员昵称/群主名称为什么是空的 - `batchGetRoomDetail` API **明确不返回成员昵称**。昵称的唯一可靠来源是消息中的 `senderName`。 - 未发言的企微成员和微信用户无法获取昵称,此类成员的 `nickname` 将保持为空。 - 群主名称 (`ownerName`) 通过 Webhook 群创建事件和定时 `backfillOwnerNames` 任务回填,该任务依赖群主曾经在消息中出现过。