# 多平台发布部署与实现说明（抖音 / 微信视频号 / B站 / 小红书）

## 1. 目标

本文件用于集中说明以下内容：

- 平台登录（扫码）如何实现
- 自动化发布链路如何实现
- 部署时必须具备的运行环境与配置
- 常见故障如何快速定位

适用代码范围：`backend/app/modules/publish`、`backend/app/services/publish_service.py`、`backend/app/services/qr_login_service.py`、`backend/app/services/uploader/*`。

---

## 2. 总体架构

### 2.1 API 入口

- `POST /api/publish`：执行发布
- `POST /api/publish/login/{platform}`：获取二维码并启动登录会话
- `GET /api/publish/login/status/{platform}`：轮询扫码状态
- `POST /api/publish/logout/{platform}`：注销并删除对应 Cookie
- `POST /api/publish/cookies/save/{platform}`：手动保存浏览器 `document.cookie`
- `GET /api/publish/accounts`：查询各平台是否已登录
- `GET /api/publish/screenshot/{filename}`：读取发布成功截图（需登录）

核心路由文件：`backend/app/modules/publish/router.py`。

### 2.2 服务分层

- `PublishService`：平台路由、账号隔离、视频路径处理、调用具体 uploader
- `QRLoginService`：Playwright 获取二维码、监控扫码结果、保存 Cookie
- `*Uploader`：平台发布自动化（抖音/微信/小红书基于 Playwright，B站基于 biliup）

---

## 3. Cookie 与账号隔离

### 3.1 存储路径

- 用户隔离路径：`backend/user_data/{user_uuid}/cookies/{platform}_cookies.json`
- 兼容旧版路径：`backend/app/cookies/{platform}_cookies.json`

路径管理文件：`backend/app/core/paths.py`。

### 3.2 Cookie 格式

- `bilibili`：简化字典格式（`SESSDATA` / `bili_jct` / `DedeUserID` / `DedeUserID__ckMd5`）
- `douyin` / `weixin` / `xiaohongshu`：Playwright `storage_state` 格式（`cookies + origins`）

对应逻辑：`backend/app/services/publish_service.py` 与 `backend/app/services/qr_login_service.py`。

---

## 4. 运行与部署要求

### 4.1 系统依赖

- Python 3.10+
- Node.js 18+
- Playwright Chromium（`playwright install chromium`）
- 系统 Chrome（建议）
- Xvfb（建议，尤其抖音/微信 headful）

### 4.2 启动建议

- 推荐使用根目录脚本启动后端：`./run_backend.sh`
- 脚本内置 `xvfb-run`，适合无物理桌面服务器场景

脚本：`run_backend.sh`。

### 4.3 环境变量（核心）

统一在 `backend/.env` 配置，配置定义见 `backend/app/core/config.py`。

- 抖音：`DOUYIN_HEADLESS_MODE`、`DOUYIN_CHROME_PATH`、`DOUYIN_USER_AGENT`、`DOUYIN_LOCALE`、`DOUYIN_TIMEZONE_ID`
- 微信：`WEIXIN_HEADLESS_MODE`、`WEIXIN_CHROME_PATH`、`WEIXIN_USER_AGENT`、`WEIXIN_LOCALE`、`WEIXIN_TIMEZONE_ID`、`WEIXIN_TRANSCODE_MODE`
- 小红书：`XIAOHONGSHU_HEADLESS_MODE`、`XIAOHONGSHU_CHROME_PATH`、`XIAOHONGSHU_USER_AGENT`、`XIAOHONGSHU_LOCALE`、`XIAOHONGSHU_TIMEZONE_ID`
- 发布截图目录：`PUBLISH_SCREENSHOT_DIR`

说明：小红书这些配置当前用于发布 uploader；扫码登录服务里抖音/微信使用独立配置，B站/小红书登录走通用默认浏览器参数。

---

## 5. 登录实现（扫码）

统一由 `QRLoginService` 处理：

1. 打开平台登录页并提取二维码（CSS/Text 多策略）
2. 前端展示二维码给用户扫码
3. 后台监控 URL + Session Cookie 变化
4. 登录成功后保存 Cookie 文件

关键文件：`backend/app/services/qr_login_service.py`。

### 5.1 抖音

- 登录页：`https://creator.douyin.com/`
- 额外能力：监听 `check_qrconnect` 接口，支持识别 `redirect_url`
- 特殊场景：若触发刷脸验证，会提取验证二维码 `face_verify_qr` 返回前端

### 5.2 微信视频号

- 登录页：`https://channels.weixin.qq.com/platform/`
- 二维码提取支持 `img/canvas/svg` 等兜底选择器

### 5.3 小红书

- 登录页：`https://creator.xiaohongshu.com/`
- 关键修复：默认可能落在短信登录页，先自动切换到扫码模式再提取二维码
- 成功判定支持 `/new/home`，避免仅依赖旧 `success_indicator`

### 5.4 B站

- 登录页：`https://passport.bilibili.com/login`
- 扫码成功后保存 B站所需核心 Cookie 字段

---

## 6. 自动化发布实现

### 6.1 抖音（Playwright）

文件：`backend/app/services/uploader/douyin_uploader.py`

- 使用 `storage_state` 打开浏览器上下文
- 自动进入上传页，触发 file chooser 上传
- 上传完成后填写标题/简介/话题，必要时处理封面
- 发布成功判定：页面跳转、接口信号、管理页核验
- 成功后回写 Cookie，并保存发布成功截图

### 6.2 微信视频号（Playwright）

文件：`backend/app/services/uploader/weixin_uploader.py`

- 进入视频号创作平台，自动定位上传入口
- 标题/描述/标签按当前产品规则统一写入“视频描述”字段
- 发布成功判定：`post_create` API 或页面离开创建页
- 成功后回写 Cookie，并保存发布成功截图

### 6.3 小红书（Playwright）

文件：`backend/app/services/uploader/xiaohongshu_uploader.py`

- 自动进入发布页并触发上传
- 上传阶段增强：
  - `UPLOAD_SIGNAL_TIMEOUT` 启动探测窗口
  - 无后缀视频文件自动准备带后缀临时文件（`hardlink/copy`）
  - 文件名后缀一致性校验
  - `UPLOAD_IDLE_TIMEOUT` 空转超时保护，避免长时间“假卡住”
- 发布成功判定：URL 跳转 + 成功文案 + 发布 API 信号
- 成功后回写 Cookie，并返回成功截图 URL

### 6.4 B站（biliup）

文件：`backend/app/services/uploader/bilibili_uploader.py`

- 使用 biliup SDK，不依赖 Playwright 发布流程
- 读取 B站 Cookie，调用 biliup 上传并提交
- 返回 `bvid/aid` 对应链接（若 API 返回）

---

## 7. 调试与排障

### 7.1 后端日志

- PM2 输出日志：`~/.pm2/logs/vigent2-backend-out.log`
- PM2 错误日志：`~/.pm2/logs/vigent2-backend-error.log`

### 7.2 常见问题

- 现象：登录二维码拿不到
  - 优先检查平台登录页是否改版（selector 失效）
  - 小红书需确认是否仍停留短信登录视图

- 现象：发布看起来卡住
  - 检查是否长期停留“等待上传状态/等待发布结果”
  - 小红书优先检查上传文件名后缀与 MIME 识别

- 现象：突然要求重新登录
  - 通常为 Cookie 失效或平台风控，需要重新扫码

### 7.3 调试产物

- 开启对应 `*_DEBUG_ARTIFACTS` 可输出调试截图/网络日志
- 成功截图通过 `/api/publish/screenshot/{filename}` 回传前端

---

## 8. 建议的验收流程（每次部署后）

1. 健康检查：`curl http://127.0.0.1:8006/health`
2. 登录检查：分别触发 4 个平台扫码登录并确认状态轮询可达成功
3. 发布检查：四个平台各发 1 条测试视频（或最少覆盖当日变更平台）
4. 截图检查：确认成功截图可通过 `/api/publish/screenshot/{filename}` 拉取
5. 日志检查：确认无持续重试、无长时间空转、无明显 selector 失败风暴

---

## 9. 关联文档

- 总部署文档：`Docs/DEPLOY_MANUAL.md`
- 后端说明：`Docs/BACKEND_README.md`
- 当日变更记录：`Docs/DevLogs/Day31.md`
