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

38 KiB
Raw Blame History

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. 总体架构(逻辑图)

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. 任务状态机(逻辑图)

stateDiagram-v2
    [*] --> 草稿
    草稿 --> 待审核: 运营提交
    待审核 --> 已排期: 审核通过
    待审核 --> 草稿: 驳回
    已排期 --> 队列中: 到点入队
    队列中 --> 执行中: Agent认领
    执行中 --> 已发布: 平台回执成功
    执行中 --> 失败重试: 可重试错误
    失败重试 --> 队列中: 指数退避重入
    执行中 --> 失败终态: 超过重试上限
    失败终态 --> [*]
    已发布 --> [*]

5. 任务执行时序(逻辑图)

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 风控方案(逻辑图 + 策略)

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 全链路时序(用户→端→平台→用户 + 重试/挑战)

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 重试与降级状态机

stateDiagram-v2
    [*] --> 队列中
    队列中 --> 执行中: Agent认领
    执行中 --> 已发布: 平台回执成功
    执行中 --> 网络重试: 网络/超时错误
    网络重试 --> 执行中: 退避1m/5m/15m/1h
    网络重试 --> 失败终态: 超上限N次
    执行中 --> 挑战中: 需扫码/验证码
    挑战中 --> 执行中: 用户完成挑战
    挑战中 --> 挂起: 挑战超时
    挂起 --> 执行中: 用户稍后处理
    执行中 --> 账号冷却: 风控拦截
    账号冷却 --> 执行中: 冷却结束+人工确认
    账号冷却 --> 失败终态: 人工放弃
    失败终态 --> 队列中: 人工一键重发
    已发布 --> [*]
    失败终态 --> [*]

21.3 二次验证挑战兜底流程

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。

附录:参考链接