Files
EveryPublish/docs/multi-platform-publish-plan.md
T

601 lines
38 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# EveryPublish 多平台聚合发布方案(调研与架构设计)
> 调研日期:2026-08-20 | 数据来源:GitHub API 实测(星标/许可/活跃度)+ 官方文档抽查 + 工程实践估计。
> 说明:本会话 web_search 不可用,个别官方接口细节(X 定价、国内开放平台审核范围)以官方最新文档为准,文中已标注置信度。
## 0. TL;DR 结论速览
1. **你的方向是对的**:「网站控制端 + 客户侧安装的执行端」是覆盖国内平台且支持多人协作的唯一高效解。行业成熟商业产品(易媒助手、融媒宝、蚁小二等)均采用同构方案,开源侧 `social-auto-upload` 的 Web-UI 衍生版也是该形态。
2. **但不要一刀切,用双通道混合架构**:国际平台(X/IG/YouTube/TikTok)走**官方 API**,服务器直连、无需 Agent、完全合规;国内平台(抖音/快手/小红书/视频号/B站)走 **Agent 浏览器自动化**。合规面最大、Agent 复杂度最小。
3. **唯一硬骨头是视频号**:微信官方无内容发布 API,只有「视频号助手」网页自动化一条路,会话短(小时级)、风控极高且牵连微信账号——建议单独迭代、默认关闭、客户主动开通并书面确认。
4. **IP 风控的核心是一账号一固定 IP**:国内账号绑国内住宅 IP,国外账号绑国外住宅 IP,在 Agent 的浏览器 Context 级注入,永不跨区、永不轮换。
5. **现成可复用**:`dreammis/social-auto-upload`(MIT,14.4k★,覆盖抖音/快手/小红书/视频号/微博/B站/TikTok/YouTube)是国内通道的最佳地基;`inovector/mixpost`(MIT)可整体消化国际侧;`postiz-app`(AGPL)只宜自托管参考。
6. **最快验证路径**:第 1 周自托管 Mixpost 跑通国际平台并开始验证客户价值,同时并行开发 Agent 通道。
## 1. 需求与约束拆解
| 客户诉求 | 技术含义 |
|---|---|
| 越简单越好 | 客户三步上手:装 Agent → 扫码绑定 → 网站排期,零配置 |
| 发布越快 | WSS 任务推送到执行 <1s;跨平台并行;失败自动重试 |
| 账号越稳 | 登录态单点持有 + 固定设备指纹 + 固定 IP + 人级频率 |
| 覆盖全部发布功能 | 图文/视频/定时/多平台/多账号,统一任务模型 |
| 不违反官方规则 | 官方 API 优先;自动化部分明确告知灰色性质并分级开通 |
| 多运营协作一个官方账号 | 控制台角色权限 + 审核流;账号凭据不落运营手中 |
| IP 风控 | 账号-IP 绑定路由,按归属地分流(见 §8) |
## 2. 三种实现形态对比
| 维度 | Web控制端+桌面Agent(推荐) | 浏览器插件 | 纯云端官方API SaaS |
|---|---|---|---|
| 多用户协作单账号 | **优**:凭据单点持有,角色审批,全程审计 | 差:多人登录同一账号易触发平台多设备风控 | 优:但仅覆盖有 API 的平台 |
| 账号凭据安全 | 优:客户本地加密,服务器零凭据 | 差:凭据散落各浏览器 | 优:OAuth,无密码 |
| IP 控制 | 优:Agent 按账号绑定代理 | 优:用户真实 IP(最自然) | 中:API 对 IP 不敏感 |
| 7×24 无人值守 | 优 | 差:需客户电脑开机 + 浏览器常驻 | 优 |
| 平台覆盖率 | **最广**:自动化兜底全部平台 | 中:受插件权限限制 | 仅覆盖有官方 API 的平台(抖音/快手/小红书/视频号内容发布均无公开 API) |
| 合规度 | 灰+白混合(分级开通) | 灰 | 白 |
| 开发成本 | 中高(可大幅复用开源) | 低 | 低(现成开源) |
**结论**:主架构 = Web 控制端 + Agent;国际平台叠加官方 API 通道;浏览器插件仅作扫码辅助或单人轻量版。
## 3. 总体架构(逻辑图)
```mermaid
flowchart TB
subgraph WEB["① 控制端 Web(多租户 SaaS)"]
U["运营 / 审核 / 管理员"]
W["任务编排 · 素材库OSS · 账号台账 · 审计"]
U --- W
end
subgraph CORE["② 调度中心(服务器)"]
Q["任务队列 Redis · 状态机 · 排期器"]
API["通道A 官方API执行器(OAuth直连)"]
AGW["通道B Agent网关(WSS注册/心跳/路由)"]
end
subgraph AGENT["③ 执行端 Agent(客户侧安装)"]
WS["WSS长连接 · 主动出网回连"]
VAULT["凭据保险库(cookie本地加密)"]
ROUTER["代理路由器(一账号一IP)"]
PA["Playwright 执行器(每账号独立档案)"]
QR["扫码登录面板(本地页面/托盘)"]
end
WEB -->|"任务下发"| Q
Q -->|"通道A 官方API"| API
Q -->|"通道B 自动化"| AGW
AGW --> WS --> ROUTER --> PA
VAULT --- PA
QR --- VAULT
API --> INT["国际:X / IG / YouTube / TikTok"]
PA --> DOM["国内:抖音/快手/小红书/视频号/B站/微博"]
PA --> INT
```
**要点**:
- 控制端:角色(管理员/审核/运营)、素材库(OSS+CDN)、账号台账、审计日志、通知(企微/钉钉/邮件)。
- Agent:轻量常驻进程(早期草案为 Tauri/Electron 壳;最终定版:WinUI 3 壳 + Go 核心,见 docs/tech-stack.md)。四大组件:WSS 客户端(主动出网,免内网穿透)、凭据保险库(SQLCipher,服务器零凭据)、代理路由器、Playwright 执行器。
- 素材流:控制端预签名直传 OSS → Agent 按任务拉取 → 发布后回调。
- 响应速度:WSS 下发 <1s;总耗时 ≈ 平台上传+审核,架构不构成瓶颈。
- **控制面/数据面分离**:我方服务器只处理任务元数据,全部平台流量从客户侧 Agent 发出,我方 IP 不接触平台(详见 §3.1)。
## 3.1 控制面 / 数据面分离(关键澄清:我方服务器不会被封)
你提出的这一点是方案成立的前提,明确写入设计原则:
- **控制面(我方 SaaS 服务器)**:只流转任务元数据——队列、排期、审核、审计、素材 OSS 中转、通知。**从不直接访问任何平台**,平台看不到我方任何基础设施,因而不存在「我方服务器 IP 被封」的可能。
- **数据面(客户侧 Agent)**:登录态、代理路由、浏览器自动化、上传与发布,全部从客户自己的机器发出,使用客户自己的 IP(企业宽带/住宅)或客户绑定的住宅代理。**客户与客户之间天然隔离**,杜绝「大量用户共用同一 IP」的矩阵风控问题。
- **素材中转**:素材存我方 OSS,但上传动作由客户 Agent 发起,平台只看到 Agent 的 IP,我方 OSS 不暴露给平台。
- **唯一例外——官方 API 通道**:X/IG/YouTube/TikTok 走客户自己的应用凭据 + OAuth,平台识别的是客户的应用与账号,IP 不敏感,可安全地放在我方服务器执行;如客户仍希望「数据不出我方」,也可整体下沉到 Agent。
**Agent 部署三形态**:
| 形态 | 7×24 | IP 真实度 | 成本 | 适用 |
|---|---|---|---|---|
| 客户办公电脑(默认) | 需常开 | 企业真实 IP,最优 | 零 | 默认形态,符合「越简单越好」 |
| 客户自有 VPS + 住宅代理 | ✅ | 住宅代理,较好 | 代理月费 | 需要深夜定时发布/无人值守的客户 |
| 我方托管 Agent(增值) | ✅ | 独享住宅代理 + 独享设备档案 | 高(我方承担风险与运维) | 大客户定制,绝不与其他客户共享 IP |
多人协作逻辑不变:控制面照常支撑多运营/审核/排期,数据面由客户 Agent 单点执行——一个官方账号始终只在一台机器、一个 IP、一个设备档案上登录。
## 4. 任务状态机(逻辑图)
```mermaid
stateDiagram-v2
[*] --> 草稿
草稿 --> 待审核: 运营提交
待审核 --> 已排期: 审核通过
待审核 --> 草稿: 驳回
已排期 --> 队列中: 到点入队
队列中 --> 执行中: Agent认领
执行中 --> 已发布: 平台回执成功
执行中 --> 失败重试: 可重试错误
失败重试 --> 队列中: 指数退避重入
执行中 --> 失败终态: 超过重试上限
失败终态 --> [*]
已发布 --> [*]
```
## 5. 任务执行时序(逻辑图)
```mermaid
sequenceDiagram
participant OP as 运营(Web)
participant S as 服务器
participant A as Agent(客户机器)
participant P as 目标平台
A->>S: WSS注册(设备+账号清单)
OP->>S: 提交任务(素材/标题/平台/时间)
S->>S: 校验 → 审核 → 排期
S->>A: 推送任务(加密载荷)
A->>S: ACK 认领(幂等)
A->>A: 选账号 → 注入代理 → 校验登录态
A->>P: 上传素材 + 提交发布
P-->>A: 发布回执
A->>S: 回传结果 + 截图留证
S-->>OP: 实时状态 + 失败通知
```
## 6. 通信与安全设计
- **WSS 长连接**:Agent → Server 出站连接(天然穿透 NAT/防火墙),心跳 30s,断线指数退避重连;任务带 ID + ACK 幂等,防重复执行。
- **加密**:任务载荷 AES-256-GCM,密钥经 KMS 信封加密;素材下载 URL 短时效签名。
- **凭据**:cookie/token 仅存 Agent 本地(SQLCipher),服务器只存「账号是否在线、最后活跃」等元信息。
- **审计**:谁在何时提交/审核/执行了哪个账号的什么内容,全链路留痕。
## 7. 平台接入矩阵
| 平台 | 官方发布API | 推荐通道 | 登录方式 | 会话稳定性 | 难度 | 合规 | 风控敏感度 |
|---|---|---|---|---|---|---|---|
| 抖音 | 开放平台有(企业审核) | 自动化(默认)/API(客户有资质时) | 扫码 | 中(约1-4周) | ★★★ | 灰/白 | 高 |
| 快手 | 开放平台有(需审核) | 自动化 | 扫码 | 中 | ★★★ | 灰/白 | 中高 |
| 小红书 | 专业号API(以电商为主) | 自动化 | 扫码 | 中短 | ★★★ | 灰/白 | 高 |
| 视频号 | **无**(仅视频号助手) | 自动化(唯一路径) | 微信扫码 | **短(小时级)** | ★★★★★ | 灰 | **极高(牵连微信)** |
| B站 | 投稿协议成熟(biliup) | 协议库直连(非浏览器) | 扫码/cookie | 长(月级) | ★★ | 半白 | 低 |
| 微博 | 开放平台(需审核) | API / 自动化 | 扫码 | 中 | ★★ | 白 | 低 |
| X | v2官方API(付费) | 服务器直连 API | OAuth | 长 | ★★ | 白 | 低 |
| Instagram | Graph API(仅商业号) | 服务器直连 API | OAuth | 长 | ★★ | 白 | 低 |
| YouTube | Data API v3 | 服务器直连 API | OAuth | 长 | ★★ | 白 | 低 |
| TikTok | Content Posting API(需审核) | 服务器直连 API | OAuth | 长 | ★★★ | 白 | 低 |
| WhatsApp | Cloud API(模板消息) | Cloud API(通知)/私协议(群发,灰) | 扫码/凭证 | 中 | ★★★ | 白/灰 | 中高 |
> 注:自动化目标站点——抖音 `creator.douyin.com`、快手 `cp.kuaishou.com`、小红书 `creator.xiaohongshu.com`、视频号 `channels.weixin.qq.com`、B站 `member.bilibili.com`。
> WhatsApp 特殊性:无信息流「发布」概念;Cloud API 走模板消息(适合通知/营销,需审核模板),状态/群发属私协议灰区。
> 置信度说明:抖音/快手/小红书开放平台能力存在但审核门槛与覆盖范围需以官方文档核实(中置信);视频号无公开 API 为高置信(官方仅有视频号助手)。
## 8. IP 风控方案(逻辑图 + 策略)
```mermaid
flowchart LR
ACC["账号台账"] --> REG{"账号归属地?"}
REG -->|国内平台| POOL1["国内住宅IP池<br/>芝麻/快代理/922S5等"]
REG -->|国外平台| POOL2["海外住宅IP池<br/>BrightData/IPRoyal等"]
POOL1 --> BIND["一账号绑定一IP<br/>长期固定不轮换"]
POOL2 --> BIND
BIND --> CTX["浏览器Context级注入<br/>(非全局TUN,防串账号)"]
CTX --> EXEC["执行发布"]
```
**策略**:
- 一账号一 IP,长期固定;**严禁轮换**(轮换=异地登录信号,触发风控)。
- 住宅 IP 优先,IDC 机房 IP 风险最高;新 IP 先「养」再发。
- 官方 API 通道不依赖 IP 属地(服务器任选);但 YouTube 自动化必须显式代理(`social-auto-upload` 的 `YT_PROXY` 已实证此坑:Chromium 不吃系统代理)。
- 代理池定时健康检查(可用性 + 归属地),异常自动摘除;同平台多账号放不同 IP + 不同设备档案。
## 9. 账号稳定策略
- **每账号独立持久化浏览器档案**(user_data_dir):固定 UA/分辨率/时区/字体,不跨机器迁移。
- **登录一律官方扫码**(APP 扫码天然绑定设备),禁止代登密码。
- **Cookie 保鲜**:每日低频心跳访问 + 失效检测,失效即推送「重新扫码」到控制台与企业微信。
- **发布节奏**:单账号人级频率上限,失败指数退避,避开平台风控高峰(大促/晚高峰更敏感)。
- **视频指纹**:ffmpeg 重编码去除元数据,多平台分发避免同文件哈希直传(防搬运识别关联)。
- 平台风控核心信号是「设备+IP+行为」三要素,三者全固定最稳——这也是 Agent 方案优于插件方案的根本原因。
## 10. 开源项目聚合与复用建议
| 项目 | 星标 | 许可 | 覆盖平台 | 复用方式 |
|---|---|---|---|---|
| dreammis/social-auto-upload | 14.4k | MIT | 抖音/快手/小红书/视频号/微博/B站/百家号/支付宝生活号/虎扑/TikTok/YouTube | **国内通道地基**:fork 后把本地脚本改造成 Agent 服务,uploader 层几乎不动 |
| inovector/mixpost | 3.5k | MIT | X/FB/IG/LinkedIn/Mastodon/Pinterest/TikTok/YouTube | MIT 可商用,国际侧可直接魔改 |
| gitroomhq/postiz-app | 34.9k | AGPL-3.0 | X/IG/TikTok/YouTube/Threads/Bluesky/Pinterest/LinkedIn/Reddit 等 | 自托管可用;闭源 SaaS 注意 AGPL 传染,仅作参考 |
| biliup/biliup | 5.4k | MIT | B站 | 投稿库 `bili_webup` 直接集成 |
| DevilJie/social-auto-upload-web-ui | 210 | MIT | 同上(Web 化) | Web+本地服务分层先例,前端可参考 |
| dorisoy/ShortVideo.AutoPublisher | 167 | MIT | 抖音/视频号/小红书/百家号/头条 | 视频号实现参考(.NET+Playwright),桌面 Agent 先例 |
| ddean2009/MoneyPrinterPlus | 6.8k | GPL-3.0 | 抖音/快手/小红书/视频号 | 视频号上传流程参考;GPL 注意 |
| white0dew/XiaohongshuSkills | 3.3k | MIT | 小红书 | 小红书发布流程参考(Agent 生态) |
| NanmiCoder/MediaCrawler | 63.1k | 自定义 | 小红书/抖音/快手/B站/微博(爬) | 登录态/签名逆向参考;发布在付费 Pro 版 |
| ReaJason/xhs | 2.2k | MIT | 小红书 | Web 协议封装,发布能力有限需自研上传 |
| tweepy | 11.2k | MIT | X | X 官方 API 客户端 |
| WhiskeySockets/Baileys | 10.8k | MIT | WhatsApp(私协议) | 备用;优先 Cloud API |
| davidteather/TikTok-Api | 6.6k | MIT | TikTok(私协议) | 备用;优先官方 API |
| subzeroid/instagrapi | 6.7k | 自定义 | IG(私协议) | 不推荐主线(封号风险高) |
| lich0821/WeChatFerry | 6.8k | MIT | 微信(已归档) | 仅参考 |
**复用策略**:国内地基 `social-auto-upload`(MIT)→ 国际侧 Mixpost(MIT)→ B站 biliup → 视频号参考 tencent_uploader + ShortVideo.AutoPublisher。私协议库(instagrapi/Baileys/TikTok-Api)不作主线,仅官方 API 未覆盖时的知情备选。
## 11. 实现难度与可信度评估
| 模块 | 难度 | 可信度 | 说明 |
|---|---|---|---|
| Web 控制台 + 任务队列 | ★★ | ★★★★★ | 成熟技术栈,无风险 |
| 官方 API 通道(国际) | ★★ | ★★★★★ | OAuth + 官方 SDK,完全合规 |
| Agent 框架(WSS+凭据+代理) | ★★★ | ★★★★ | 工程量大但完全可控 |
| 抖音/快手/小红书自动化 | ★★★ | ★★★☆ | 有 MIT 开源可 fork;持续风控适配 |
| B站投稿 | ★★ | ★★★★★ | biliup 协议成熟稳定 |
| **视频号** | ★★★★★ | ★★ | 无 API、会话短、牵连微信,唯一硬骨头 |
| WhatsApp 群发/状态 | ★★★★ | ★★☆ | Cloud API 限模板;私协议有封号风险 |
| IP 代理管理 | ★★★ | ★★★★ | 采购 + 绑定 + 健康检查 |
| 多租户/权限/审计 | ★★★ | ★★★★★ | 常规业务功能 |
**总评**:MVP(官方 API 通道 + 抖音/快手/小红书/B站)2-3 人 × 4-6 周;全量(含视频号)3-4 人 × 2-3 个月 + 持续风控维护(平台前端改版适配是长期成本,每周巡检)。
## 12. 分阶段实施路线
| 阶段 | 内容 | 周期 | 产出 |
|---|---|---|---|
| P0 验证 | 自托管 Mixpost 跑通 X/IG/YouTube | 1 周 | 验证国际侧价值与合规通道 |
| P1 MVP | 控制台 + 任务队列 + Agent 框架 + 抖音/快手/小红书/B站 | 3-4 周 | 可交付的第一版 |
| P2 协作 | 角色权限/审核流/审计/通知 | 1-2 周 | 多人协作闭环 |
| P3 攻坚 | 视频号(独立迭代)+ 微博/百家号 | 2-3 周 | 全平台覆盖 |
| P4 白通道 | 抖音开放平台/小红书专业号 API 接入(客户有资质时) | 并行 | 合规面扩大 |
| P5 商业化 | 多租户/计费/渠道 | 持续 | SaaS 化 |
## 13. 合规边界(务必读)
- **官方 API = 完全合规**(平台授权);**浏览器自动化 = 技术上违反多数平台「禁止自动化访问」条款**,实际执行风险是限流/封号。产品必须对客户**知情告知**,不可隐瞒。
- **分级开通**:白名单通道(官方 API 平台)默认开启;灰通道(自动化)客户主动开通 + 签署风险告知书。
- **红线不碰**:大规模矩阵养号、搬运去重绕过、刷量、私信轰炸——触碰即封号且可能产生法律风险。
- **内容合规前置**:平台内容审核由平台执行,我方提供发布前自检提示,不代替审核。
- **数据合规**:凭据加密最小化,素材仅在客户授权空间流转(个保法/数安法)。
- **视频号特别告知**:微信账号是客户核心资产,封禁损失远大于其他平台——默认关闭、独立审批开通、建议专用微信号。
## 14. 风险清单与缓解
| 风险 | 影响 | 缓解 |
|---|---|---|
| 平台前端改版/选择器失效 | 自动化断链 | 模块化选择器 + 灰度监控 + 每周巡检(最大持续成本) |
| 登录态失效 | 发布失败 | 保鲜心跳 + 失效推送 + 一键重扫 |
| 账号风控 | 限流/封号 | 固定设备+IP+人级频率+养号策略 |
| 代理失效 | 整批失败 | 池健康检查 + 同区域自动切换 |
| API 涨价/收紧 | 成本/断供 | X 从 Basic 起步,预留自动化兜底 |
| 视频号牵连微信 | 重大损失 | 默认关闭 + 专用微信号 + 客户书面确认 |
| AGPL 传染 | 法律/商业 | 商用选 MIT 项目或自托管,律师审阅 |
## 15. 「越简单越好」的产品体验设计
- **客户三步**:装 Agent(一条命令/安装包)→ 打开本地扫码面板绑定各平台 → 网站排期一键发布。
- **控制台极简视图**:今天要发什么 / 发了没 / 失败原因 / 一键重试。
- **发布回执**:每平台截图 + 链接留证,运营可查可复核。
- **登录过期**:红点 + 企微提醒 + 扫码面板自动弹出。
- **单人版与团队版同一套**:单人 = 跳过审核流,零学习成本。
## 16. 用户端 / 管理端体验走查(Q&A 补充)
### 16.1 三种形态的「安装」真相
同一套 Agent 软件,只差运行地点:
| 形态 | 装什么 | 谁来装 | 怎么装 | 扫码在哪出现 |
|---|---|---|---|---|
| 客户办公电脑(默认) | 桌面应用(系统托盘) | 客户 IT / 账号负责人 | 下载安装包,双击即用 | 应用窗口 / 托盘弹窗 |
| 客户自有 VPS | Docker 容器(无界面) | 客户 IT | 一条命令 / 一键脚本 | 控制台统一弹码(经 WSS 回传二维码图片,推荐) |
| 我方托管(增值) | **无需安装** | 我方 | 我方部署 | 客户控制台页面直接弹码 |
- 无论哪种形态,客户要做的「账号动作」**只有扫码登录**(官方 APP 扫码,天然绑定设备);账号密码/验证码永不经过我方系统。
- 住宅代理:办公电脑走企业宽带时**零配置**;VPS / 托管形态需购买住宅代理并粘贴代理账号密码(托管形态可由我方代采购)。
### 16.2 用户端体验(装 Agent 的那一端)
- **首次 5 分钟**:装好 → 打开 → 登录企业工作区 → 输入配对码绑定控制台 → 逐个平台点「绑定」弹码 → 手机扫码 → 绿色对勾。此后常驻托盘,无感运行。
- **日常几乎零操作**:托盘显示在线状态与待发任务数;登录过期时弹窗 + 企微/短信提醒「请重新扫码」;部分平台约每周需扫一次码。
- **关键分工**:装机的人是企业 IT 或账号负责人,不是日常运营——运营全程只碰网站。
### 16.3 管理端体验(Web 控制台)
- **运营**:素材库上传 → 编辑标题/话题 → 勾选平台与账号 → 排期日历选时间 → 提交。发布中实时进度(上传中/审核中/已发布 + 链接截图);失败显示原因 + 一键重试。
- **审核**:待审列表 → 分平台预览 → 通过/驳回(附批注)。
- **管理员**:账号台账(绑定状态/最后活跃/代理绑定)、成员与角色、审计日志、通知渠道(企微/钉钉/邮件)。
- **单人版**:同一套界面自动隐藏审核流,运营即管理员,零学习成本。
### 16.4 平台方管理端(我方 SaaS 后台)
- 租户/计费、Agent 在线监控与版本推送、渠道适配器健康巡检(平台改版监控)、代理池与风控事件台账(托管形态)、客户支持。
## 17. 工程实施:技术栈、联调环境与排期(Q&A 补充)
### 17.1 可行性结论
- **能实现**。先例:dreammis/social-auto-upload(MIT)已跑通国内全平台上传流程,我们只把它从「本地脚本」改为「Agent 服务 + 控制台」;商业产品(易媒/融媒宝)同构。真正的不确定性只在平台风控对抗,不在架构。
- 「软件与网站连接很慢,即使本地调用也很慢」是**工程问题**:按 17.2 对照排查 + 17.3 分段计时,通常 5 分钟可定位。
### 17.2 连接慢的十大嫌疑
| 症状 | 根因与修复 |
|---|---|
| 每条消息都有固定 100-500ms 延迟 | 每次请求重新鉴权(bcrypt 重算)→ 改会话 Token/JWT 校验 |
| 本机访问 localhost 也慢几秒/偶发超时 | IPv6 陷阱:Node17+ 把 localhost 解析到 ::1,服务端只监听 127.0.0.1 → 显式用 127.0.0.1、--dns-result-order=ipv4first,或双栈监听 |
| 开了代理软件后本地调用变慢 | HTTP(S)_PROXY 环境变量劫持 localhost → NO_PROXY 加入 localhost,127.0.0.1 |
| 客户端执行发布时心跳/消息全卡住 | 单线程串行:Playwright 等重活阻塞消息循环 → 执行器独立 worker,消息与执行分离 |
| 状态更新「慢半拍」 | HTTP 轮询代替长连接 → 改 WebSocket/SSE 推送 |
| 每次任务重新建连 | 连接未复用 / TLS 每次握手 → 持久连接 + 会话复用 |
| 局域网跨机慢 | 路由器 AP 隔离 / mDNS 主机名解析慢 → 用 IP 直连、关 AP 隔离 |
| Windows 上整体偏慢 | Defender 实时扫描客户端进程(Go core/浏览器引擎)→ 加排除项,先用裸 curl 测基线 |
### 17.3 分段计时定位法(本仓库 `tools/diag-connection.mjs`)
| 环节 | 局域网正常值 | 偏大指向 |
|---|---|---|
| TCP connect | <2ms | 防火墙 / IPv6 / 代理 |
| WS 握手 open | <10ms | 服务端 WS 框架 / 鉴权 |
| 首条消息 RTT | <20ms | 串行往返过多 / 服务端处理 |
| 心跳间隔抖动 | 稳定 ±1s | 客户端单线程阻塞 |
| 服务端处理耗时 | 与接口总延迟之差=网络 | DB 慢查询 / N+1 / 同步 IO |
### 17.4 技术栈
> 2026-08-20 注:本节为早期 JS 栈草案,已被定版取代——技术栈以 docs/tech-stack.md 与 docs/delivery-plan.md 为准(MySQL + 前后端 Go 统一,页面层 React+TDesign)。
| 模块 | 选型 | 理由 |
|---|---|---|
| 仓库组织 | pnpm monorepo + Turborepo | apps/web、apps/agent-core、apps/agent-desktop 共享协议包 |
| 网站 | Next.js 15 + TS + Tailwind + shadcn/ui | 全栈一体,API Routes 即后端 |
| 数据 | PostgreSQL + Drizzle + Redis + BullMQ | 任务队列与排期靠 Redis |
| 实时 | Socket.IO(WebSocket) | 心跳/幂等/重连开箱即用 |
| 客户端核心 | Node + Playwright + ws + better-sqlite3 | 凭据本地加密存储;执行器独立子进程 |
| 客户端壳 | Electron + electron-builder | 托盘 + 扫码窗口;CI 出 Windows 包 |
| 素材 | 一期:服务器本地盘(StorageDriver 抽象);二期:MinIO/OSS | 直链下载(带短时效签名 token) |
| 测试 | vitest + Playwright + MockUploader 假执行器 | 先打通链路再上真实平台 |
### 17.5 内网联调环境(Mac=服务端,Windows=客户端)
完全可行,标准做法:
1. Mac:web 与 WS 服务绑定 0.0.0.0(`next dev -H 0.0.0.0`);查 Mac 局域网 IP:`ipconfig getifaddr en0`。
2. Windows:Agent 配置 `EP_WS=ws://<Mac局域网IP>:<端口>`(用 IP,不用主机名)。
3. 防火墙:macOS 放行 node 入站;Windows 出站默认放行。
4. 路由器:关闭 AP 隔离(访客网络常见坑)。
5. 先用 curl/wscat 从 Windows 测通 Mac 端口,再启动 Agent。
6. 公司网络隔离时:ZeroTier / Tailscale 组虚拟局域网。
7. 内网阶段用 ws:// 即可;生产才上 wss:// + 证书。
### 17.6 开发顺序与周期
| 阶段 | 内容 | 周期 |
|---|---|---|
| 0 协议定版+骨架 | WS 协议 JSON Schema、假执行器打通全链路、延迟基线 <300ms | 1 周 |
| 1 网站功能 | 租户/角色/账号台账/素材/排期/审核/通知 | 2-3 周 |
| 2 Agent 真实平台 | 抖音/快手/小红书/B站 uploader(参考 social-auto-upload) | 3-4 周 |
| 3 联调测试 | 异常注入:断网/掉线/登录过期/重复任务 | 1-2 周 |
| 4 视频号攻坚 | 独立迭代,默认关闭 | 2 周 |
| 5 打包分发 | Windows 安装包 + 自动更新 | 1 周 |
- **单人 10-13 周,双人并行 6-8 周**。
- 管理预期:网站 CRUD 与客户端框架确实不长(各 2-3 周),但**时间黑洞是平台 uploader 的适配与风控对抗**,不是网站也不是客户端框架;此后每周约 0.5-1 天持续维护。
## 18. 协议层考证:局域网慢的根因与实测基线
### 18.1 实测基线(2026-08 本机实测,Apple Silicon)
| 环节 | 实测 | 结论 |
|---|---|---|
| TCP 连接 127.0.0.1 x100 | avg 0.14ms(p99 1.17ms) | 协议开销可忽略 |
| TCP 连接 localhost(走 IPv6 解析) | avg 0.49ms(p99 4.33ms) | **IPv6 路径慢 3.5 倍**;若防火墙丢弃 ::1 包将变成秒级 |
| WS 握手(新建连接)x30 | avg 0.58ms | 建连便宜,但别每条消息都建 |
| 单连接消息 RTT x2000 | **avg 0.07ms(p99 0.14ms)** | 协议真实下界:亚毫秒 |
| 每消息新建连接 x30 | avg 0.75ms | 是复用连接的 **10 倍** |
| 单次 bcrypt 级哈希(pbkdf2 100k) | 15.9ms | 每次请求重算鉴权 = 每条消息 +16ms(Windows 更慢 50-150ms) |
| 串行 10 次往返 | 0.91ms | 本机便宜;跨机时 = 10×RTT + 处理 |
**考证结论**:协议层(TCP+WS 复用连接)本机只有 0.07ms。局域网环境「慢」必然是下列上层之一叠加:
### 18.2 局域网环境下慢的候选层(延迟预算表)
| 层 | 典型增量 | 判断方法 |
|---|---|---|
| 协议 RTT(复用连接) | <1ms | 基准 |
| WiFi 抖动 / 客户端节能 | +1~20ms | 换有线对比 |
| 丢包重传(TCP RTO) | **+200ms 起/包** | ping 查丢包率 |
| 每请求重算鉴权(bcrypt 级) | +16~150ms | 与免鉴权接口对比压测 |
| 每消息新建连接 / TLS 握手 | 本地 +0.5ms,跨机 +数 RTT | 对比复用与不复用 |
| IPv6 陷阱 | 本地 +0.35ms,丢包场景秒级 | 对比 127.0.0.1 与 localhost |
| HTTP 轮询 | 秒级(等于轮询间隔) | 协议审计 |
| Socket.IO 降级为长轮询 | 秒级 | 检查实际 transport |
| 服务端阻塞 / 慢 DB / N+1 | 不定 | 全链路埋点 |
### 18.3 协议层五条铁律(让「慢」结构上不可能发生)
1. **一条 WSS 连接用到底**:Agent→Server 单连接复用,不每任务建连;开启 TCP_NODELAY。
2. **鉴权只做一次**:连接建立时 auth 一次,后续走连接态 + 消息级 HMAC 校验(微秒级),杜绝每请求重算密码哈希。
3. **执行与消息分离**:Playwright/上传放独立 worker 进程,绝不阻塞消息循环(心跳卡死是「假慢」主因)。
4. **消息合并与节流**:ack 合并、进度回报节流 1 次/s,避免 chatty 串行往返。
5. **全链路埋点**:每条消息带 ts、ack 带 ackTs,服务端聚合各段 delay 指标并告警——「慢在哪」永远用数据说话,不再靠猜。
## 19. 浏览器调用最小化与指纹模拟
### 19.1 浏览器调用清单(原则:协议能办的事绝不开浏览器)
| 操作 | 触发浏览器? | 替代方案 |
|---|---|---|
| 登录取码 | 否 | 平台二维码 API(**仅视频号必须在浏览器内取码**) |
| 登录态校验 / 保鲜 | 否 | 轻量 HTTP API 心跳(首页/用户信息接口),空闲时浏览器保持关闭 |
| B站上传发布 | 否 | 投稿协议纯 HTTP(参考 biliup / bili_webup) |
| 抖音/快手/小红书上传 | **是(仅此一步)** | 冷启动 → 会话复用 → 用完即关 |
| 定时发布设置 | 部分可 API | 能用 API 就不开浏览器 |
| 视频号全流程 | 是 | 无替代(唯一通道) |
| 二次验证 | 视类型 | QR/短信/APP确认推送人工;滑块低风控平台本地尝试 |
### 19.2 浏览器生命周期
- **空闲**:浏览器保持关闭,登录态靠协议心跳保鲜 → 心跳与消息零浏览器开销。
- **执行**:仅「上传发布」阶段冷启动;同平台同账号任务排队复用同一实例(会话复用)。
- **结束**:任务完成即关,释放内存与句柄。
### 19.3 指纹模拟要点
- **用客户机器上真实 Chrome**(playwright channel:`chrome`),不用捆绑 Chromium——JA3/UA/指纹与真实浏览器的差异本身就是风控信号。
- 每账号独立 user_data_dir:固定 UA/分辨率/时区/语言/字体/hardwareConcurrency/deviceMemory。
- playwright-extra + stealth 插件;抹除 navigator.webdriver 与 CDP 自动化特征。
- 网络层:固定代理、WebRTC 防泄漏、时区与代理归属地一致。
- 行为层:可选「先浏览主页再发布」养号动作,操作间隔随机化(人级)。
- **铁律:一档案 = 一平台一账号一IP,永不交叉复用。**
## 20. 二次验证场景与兜底设计
### 20.1 统一挑战模型(Challenge)
- 消息:challenge.push(Agent→Server:类型+凭证+平台+账号)/ challenge.resolve(Server→Agent:用户输入结果)。
- 类型:qr(二维码)/ confirm(APP确认)/ sms(验证码)/ captcha(滑块点选)/ pending(人工处理)。
- 状态:挑战中 → 已解决 / 超时挂起 / 放弃。
### 20.2 五类挑战与兜底
| 类型 | 常见平台 | 检测 | 兜底流程 | 超时处理 |
|---|---|---|---|---|
| 二维码登录 | 抖音/快手/小红书/B站常态 | 登录页出现 QR | 推控制台+企微,码过期自动刷新 | 5min → 任务挂起 |
| APP确认「是本人」 | 抖音/小红书异地登录 | 页面提示确认 | 推送手机确认,Agent 轮询登录态 | 5min → 挂起 |
| 短信/邮箱验证码 | 各平台敏感操作 | 输入框出现 | 控制台弹输入框(带尾号提示)→ 回填,错可重输 2 次 | 3min → 挂起 |
| 滑块/点选 | 上传前风控 | 验证组件出现 | 默认截图推人工拖拽;低风控平台本地自动尝试,失败转人工 | 3min → 挂起 |
| 人机识别失败 | TikTok 等国际平台 | 登录被拒 | 推送人工登录指引 | 转人工队列 |
### 20.3 原则
- **账号稳优先**:验证码类挑战人工兜底为主、Agent 硬解为辅,绝不为速度牺牲账号。
- 挑战走控制面通道(不与平台流量混在一起)。
- 挂起任务可一键重发/放弃;所有挑战过程留审计。
## 21. 详细端到端逻辑图(重绘)
### 21.1 全链路时序(用户→端→平台→用户 + 重试/挑战)
```mermaid
sequenceDiagram
participant OP as 运营
participant S as 服务器
participant A as Agent
participant PL as 平台
participant IT as 账号负责人
Note over A,S: 单条WSS长连接复用(实测RTT 0.07ms)
OP->>S: 提交任务(素材/平台/排期)
S->>S: 校验→审核→入队→排期触发
S->>A: task.push(taskId,加密载荷)
A-->>S: ack(taskId) 幂等确认
A->>A: 选账号→注入代理→协议级登录态校验(不启浏览器)
alt 登录态正常
A->>PL: 冷启动浏览器→上传素材→提交发布
PL-->>A: 发布回执+截图
A->>S: task.result(success)
S-->>OP: 实时状态+链接
else 平台触发二次验证
PL-->>A: 挑战(扫码/短信/APP确认/滑块)
A->>S: challenge.push(类型,凭证)
S-->>IT: 控制台+企微提醒
IT->>S: 扫码或输入验证码
S->>A: challenge.resolve(结果)
A->>PL: 继续发布流程
else 网络类失败
A->>A: 指数退避 1m/5m/15m/1h
A->>PL: 自动重试上传
else 登录态失效
A->>S: challenge.push(qr)
S-->>IT: 推送扫码提醒
IT->>S: 扫码成功
S->>A: challenge.resolve
A->>PL: 恢复执行
else 风控拦截
A->>S: task.result(fail,原因)
S->>S: 账号冷却+人工队列
S-->>OP: 告警通知
end
```
### 21.2 重试与降级状态机
```mermaid
stateDiagram-v2
[*] --> 队列中
队列中 --> 执行中: Agent认领
执行中 --> 已发布: 平台回执成功
执行中 --> 网络重试: 网络/超时错误
网络重试 --> 执行中: 退避1m/5m/15m/1h
网络重试 --> 失败终态: 超上限N次
执行中 --> 挑战中: 需扫码/验证码
挑战中 --> 执行中: 用户完成挑战
挑战中 --> 挂起: 挑战超时
挂起 --> 执行中: 用户稍后处理
执行中 --> 账号冷却: 风控拦截
账号冷却 --> 执行中: 冷却结束+人工确认
账号冷却 --> 失败终态: 人工放弃
失败终态 --> 队列中: 人工一键重发
已发布 --> [*]
失败终态 --> [*]
```
### 21.3 二次验证挑战兜底流程
```mermaid
flowchart TB
TR["平台触发二次验证"] --> DET{"Agent检测挑战类型"}
DET -->|二维码登录| QR["取码→推控制台+企微<br/>码过期自动刷新"]
DET -->|APP确认| CF["推送手机确认提醒<br/>Agent轮询登录态"]
DET -->|短信/邮箱| SMS["控制台弹输入框<br/>用户输入→回传回填<br/>错可重输2次"]
DET -->|滑块/点选| CAP["默认截图推人工<br/>低风控平台本地尝试"]
QR --> OK{"完成?"}
CF --> OK
SMS --> OK
CAP --> OK
OK -->|是| CONT["Agent继续发布流程"]
OK -->|否/超时| PEND["任务挂起→人工队列<br/>一键重发/放弃"]
PEND --> CONT
```
## 22. 登录链路优化:把 10 秒级登录压到 2 秒级
### 22.1 拆解:登录到底慢在哪
朴素实现(浏览器全流程)逐环节耗时:启动浏览器 → 加载登录页 → 找/截二维码 → 传图 → 等扫码 → 轮询检测 → 换取登录态。其中「浏览器 + 页面 + 轮询」是机器耗时大头,人的扫码时间(3-10s)无法压缩但可以重叠。
| 环节 | 朴素实现 | 优化后 | 手段 |
|---|---|---|---|
| 启动浏览器 | 1-3s(冷启动) | **0s** | API 取码免浏览器(B站已验证,biliup 直接出 qrcode.png);视频号用常驻温实例 |
| 页面加载渲染 | 2-5s | ~1s(仅视频号) | 直达登录页 + 路由拦截广告/统计/字体资源 |
| 抽取二维码 | 0.5-2s(截图/找元素) | **<0.1s** | DOM 取二维码图片 URL 或 API 直接返回 token(开源项目 utils/login_qrcode 即此模式) |
| 码跨层传递 | 0.2-1s(传截图) | **<50ms** | 只传 token/图片URL,控制台本地重渲染——更快且**更清晰**(截图压缩会降低扫码成功率) |
| 检测扫码成功 | 轮询 1-3s/次 | 0.3-0.5s | 短轮询 300-500ms;或拦截页面自身状态 XHR 即时检测 |
| 换取登录态 | 1-2s(页面跳转等待) | 0.2-0.5s | API 换取 cookie/token |
| **机器合计** | **约 10-16s** | **约 1-2s**(视频号场景 3-4s) | 用户扫码 3-10s 不变,但成为唯一等待 |
### 22.2 五条铁律
1. **让登录少发生**:cookie 保鲜 + refresh 接口 + 过期预测(登录是低频事件,最好的登录优化是「不登录」)。
2. **能 API 不浏览器**:B站纯 API 已验证;抖音/小红书/快手优先尝试其 Web 登录 API,失败再回退浏览器。
3. **只传 token 不传截图**:所有层传递二维码内容/图片 URL,渲染端本地重绘。
4. **检测即时化**:300-500ms 短轮询 + 页面网络钩子双通道。
5. **等待重叠**:多平台并行取码、预计过期前预热、控制台+企微+托盘同时推送。
### 22.3 视频号例外(唯一必须浏览器的登录)
- 温浏览器常驻:登录需求出现前预启动,不冷启动。
- 直达登录页 + 资源拦截:只加载必要资源,页面 5s→1s。
- 取码:DOM 抓二维码图片 URL,不截图。
- 检测:注入 MutationObserver 监听登录态跳转 + 拦截页面状态 XHR。
- 提示:抖音/快手现可选用 patchright(补丁版 Playwright,开源项目已采用),指纹绕过更稳。
## 23. 系统设计文档(网页端 + 客户端 App)
完整系统设计(两端功能清单、连接方案评估、四层鉴权、REST/WS 协议、配对与登录流程、边界问题)见独立文档:docs/system-design.md。
## 附录:参考链接
- https://github.com/dreammis/social-auto-upload
- https://github.com/DevilJie/social-auto-upload-web-ui
- https://github.com/dorisoy/ShortVideo.AutoPublisher
- https://github.com/gitroomhq/postiz-app
- https://github.com/inovector/mixpost
- https://github.com/biliup/biliup
- https://github.com/SocialSisterYi/bilibili-API-collect (已归档)
- https://github.com/NanmiCoder/MediaCrawler
- https://github.com/ReaJason/xhs
- https://github.com/tweepy/tweepy
- https://github.com/WhiskeySockets/Baileys
- https://github.com/davidteather/TikTok-Api
- https://github.com/subzeroid/instagrapi
- 官方文档:developers.facebook.com(IG)、developers.google.com/youtube、developers.tiktok.com、developer.x.com、open.kuaishou.com、developer.open-douyin.com、open.xiaohongshu.com、channels.weixin.qq.com