ecd-5qfbmvz3yvpvbiog0 上,三个抖音号在同一台云电脑并行跑。
accounts 表,三个号心跳当时全部新鲜(<5min)。| 运营 / 号 | account_id | 通道 | 日限 | 心跳 | 部署目录(机上) |
|---|---|---|---|---|---|
| 小文(野荞) 目标机,保持不动 |
81cc9678-9b53-413b-9f40-7964341f4af1 |
cloud_pc | 30 | 正常 | C:\akke-wuying\wuying-dm |
| 饭粒(一筑·全屋定制) 待迁入 |
c5d236e1-fd80-4cff-b349-506dfd09699b |
cloud_pc | 30 | 正常 | C:\akke-wuying\wuying-dm(自己那台) |
| 零星(小星=夏夏) 待迁入 |
8af08f10-6db5-4d83-8942-b908349efbda |
cloud_pc | 30 | 正常 | C:\akke-wuying\wuying-dm(自己那台) |
accounts 表里有两条:8af08f10…(cloud_pc,就是云电脑这条)
和 d7ac1384…(manual,已 archived)。按 name 取 row[0] 会绑到错的那条,
结果就是「按 A 号 claim、却在 B 号前台发」。云电脑永远指 8af08f10。
| 号 | DM 腿(首触 + 回复捕获) | route-B 腿(二次触达) | 开机自启 |
|---|---|---|---|
| 饭粒 | 浏览器 DOMdouyin_dm_web_send_dom.py + douyin_dm_web_capture_dom.py |
DOM(07-08 切)douyin_touch_web_dom.py,独立 start-routeb.bat 两窗 |
AkkeDomDmStart(30s) + AkkeRouteBStart(120s) |
| 零星 | 浏览器 DOM(同上) | DOM(07-08 切),route-B tail 焊在 akke-start.ps1 里 |
AkkeDomDmStart + AkkeRouteBStart |
| 野荞 | 现场确认项 手上资料只记录了 07-03 给饭粒 + 零星切 DOM,没有野荞那台切 DOM 的记录,它可能还在跑抖音 PC 客户端 GUI 版 douyin_dm_grounded.py。开工第一步先在野荞机上跑确认命令(见 Step 1)。 | ||
9222 写死在代码里,没有 env 开关三个号必须各开一个独立 Edge(各登一个抖音号),端口只能错开成 9222 / 9223 / 9224。但现在这几处全是硬编码常量:
| 文件 | 行 | 现在的值 |
|---|---|---|
douyin_dm_web_send_dom.py | 43 | CDP = "http://127.0.0.1:9222" |
douyin_dm_web_capture_dom.py | 39 | CDP = "http://127.0.0.1:9222" |
douyin_touch_web_dom.py | 45 | CDP = "http://127.0.0.1:9222" |
start-edge-debug.bat | 22-23 | set PORT=9222 / set PROFILE=C:\akke-edge-debug |
watchdog-dm-routeb.ps1 | 42-43, 101 | profile 与 9222 均写死 |
.env(account_id 是对的、领的单也是对的),
但发送时全部连到 127.0.0.1:9222 这一个浏览器 —— 也就是三个号领的单,全部从同一个抖音账号发出去。
DB 里会记成三个号各自发了,实际只有一个号在发。这是最坏的一类故障:日志全绿、数据全假。
改法(三个 .py 各一行,.bat / .ps1 收参数):
# 三个 .py 统一改成读 env、默认仍是 9222(老机器零行为变化) CDP = "http://127.0.0.1:" + os.environ.get("AKKE_CDP_PORT", "9222") # start-edge-debug.bat 收 env,未设时退回原值 if "%AKKE_CDP_PORT%"=="" (set PORT=9222) else (set PORT=%AKKE_CDP_PORT%) if "%AKKE_EDGE_PROFILE%"=="" (set PROFILE=C:\akke-edge-debug) else (set PROFILE=%AKKE_EDGE_PROFILE%)
worker/scripts/wuying-dm/,不在高危路径清单里,但建议走 PR(这条链上任何一处漏改都会导致上面那个静默发错号)。
合 main 后由 sync-wuying-scripts.yml 同步到公共镜像,云电脑才拉得到。
只推镜像不合 main 是无效的 —— 下次任何 wuying 改动合 main 会拿旧版把镜像覆盖回去,修复静默还原。
.env,三个号不能共用一个目录# wuying_poll_agent.py:47,57
WORK_DIR = Path(__file__).resolve().parent
load_dotenv(WORK_DIR / '.env')
脚本从自己所在目录读 .env,AKKE_ACCOUNT_ID 是 1:1 绑死的。
所以一机三号 = 三份完整独立的部署目录,不能共用一个 C:\akke-wuying\wuying-dm。
目录规划见第 ③ 节。
sent_log_YYYYMMDD.csv、agent.log、templates\ 也都是按目录走的,三套各自独立,
不要为了省事做符号链接指到同一份 —— sent_log 一旦被三个进程同时 append,
会触发「无表头 → csv.DictReader 把首行数据当表头 → 全标 failed 但其实真发了」那个老坑。
这一条没有代码能绕开,只能靠调节奏压住。两次实证:
%APPDATA%\douyin、
%LOCALAPPDATA%\douyin、注册表 HKCU\Software\ByteDance)被一起复制 →
抖音判定「同一台设备挂 3 个号、从 3 个 IP 活动」→ 三台搜人集体软封(搜索结果为空,但联想下拉有结果、浏览器能搜)。缓解措施(合并当天就要做,不是出事再做):
accounts.daily_limit 从 各 30 下调到各 15,先跑一周看,别一上来就 90/天堆一台机。reset-douyin-fingerprint.ps1 还得跑。accounts.dispatch_paused_until(见第 ⑤ 节,这个字段一改就同时停派单和静音心跳告警)。
换机器对「搜人量过载」无效,别把停发误当成机器问题去重装。合并后这台机要同时跑:3 × 调试版 Edge(各带独立 user-data-dir,实测每个约 0.8–1.5G) + 3 × poll agent + route-B 的 watch / consume 进程。6 核 12G 是原本按单号配的。
没有实测数据,不敢拍「够」或「不够」。Step 8 里安排了一步内存实测;如果吃紧, 要么升配(企业办公型可扩),要么这个合并方案只能放两个号。
| 号 | account_id | 部署目录 | Edge profile | CDP 端口 | 开机任务 |
|---|---|---|---|---|---|
| 小文(野荞) | 81cc9678…4f1 |
C:\akke-wuying\wuying-dm保持原样 |
C:\akke-edge-debug |
9222 | AkkeDomDmStart |
| 饭粒(一筑) | c5d236e1…69b |
C:\akke-wuying\wuying-dm-yizhu |
C:\akke-edge-debug-yizhu |
9223 | AkkeDomDmStart-Yizhu |
| 零星(小星) | 8af08f10…bda |
C:\akke-wuying\wuying-dm-xiaoxing |
C:\akke-edge-debug-xiaoxing |
9224 | AkkeDomDmStart-Xiaoxing |
.env 隔离)② 一个号一个 Edge profile(登录态 + 指纹隔离)
③ 一个号一个端口(发送不串号)。任何一条打破,都会退化成「三个号发同一个号」或「A 号的单发到 B 号」。
PS C:\Users\admin>) ·
🗄️ DB = Supabase 改字段
就是第 ② 节的阻断项 A。改 5 个文件 → PR → 合 main → 等 sync-wuying-scripts.yml 把脚本同步到公共镜像。
这一步没做完,后面全部白做。
验证同步到位:浏览器打开
https://raw.githubusercontent.com/upioai/wiki/main/public/akke/wuying-dm/douyin_dm_web_send_dom.py,
搜 AKKE_CDP_PORT 能搜到即镜像已更新。
cd C:\akke-wuying\wuying-dm Select-String .\.env -Pattern AKKE_DM_SCRIPT Get-ScheduledTask *akke* | Select TaskName,State Get-Content .\akke-start.ps1 -TotalCount 5
AKKE_DM_SCRIPT=douyin_dm_web_send_dom.py → 已是 DOM 版,继续下一步。给饭粒和零星的 accounts.dispatch_paused_until 设一个未来时刻(迁移窗口 + 缓冲)。
paused_skip 不派单;
② wuying-heartbeat-watch cron 看到它在未来就跳过、不会报「无影 agent 没在轮询」。
所以停机迁移期间不用另外关告警,改这一个字段就够。
迁完记得清空,否则新机器起来了也一条不派 —— 06-14 野荞被自己静音一整天、06-29 零星把人为静音误读成「软封自愈冷却」,都是栽在忘了清这个字段。
.env(这是整个迁移最关键的一份资产)🖥️ 饭粒机 / 零星机每台各跑一遍,把 base64 结果回传:
cd C:\akke-wuying\wuying-dm
[Convert]::ToBase64String([IO.File]::ReadAllBytes(".\.env"))
curl.exe + paste.rs 或 base64,不要用 Invoke-WebRequest(会转码把文件搞坏)。
paste.rs 实测阈值已降到 <96KB(旧记的 384KB 别信)。base64 别贴回 PowerShell 提示符,写进文件再解。
# 以饭粒为例,零星把 -yizhu 换成 -xiaoxing mkdir C:\akke-wuying\wuying-dm-yizhu cd C:\akke-wuying\wuying-dm-yizhu # ① 先单独拉一次 update.bat 本身(它不在自己的下载列表里,机器上那份可能停在几个月前) curl.exe -fsSL -o update.bat "https://raw.githubusercontent.com/upioai/wiki/main/public/akke/wuying-dm/update.bat" .\update.bat
update.bat 跑完 [2/3] 段打出的 OK 行数,
应该等于仓里 $files 的长度(当前 12)。只打 1-2 行 = 机器上是远古版更新器,
它自己不更新自己,会让整台机静默停在旧代码上 —— 07-19 饭粒机就是这么让捕获腿挂了很久没人发现的
(douyin_dm_grounded.py 是几个月前的截断版,IndentationError 把整条 import 链炸掉,
但 DM 发送腿照常工作,所以没人察觉)。
update.bat 的下载列表里没有任何 douyin_dm_web_*.py(只有 6 个 PC 客户端脚本)。
DOM 通道的发送 / 捕获脚本必须单文件 curl 补拉:
curl.exe -fS "https://raw.githubusercontent.com/upioai/wiki/main/public/akke/wuying-dm/<file>.py" -o <file>.py
_leave_thread(发完离开会话让对方回复产生红点,红点捕获全靠它),
差点把「回复漏读」bug 带上生产机。部署后按字节数 + 关键函数命中数双校验。
.env🖥️ 野荞机把 Step 3 备份的原 .env 解出来放进对应目录,然后用 Add-Content 追加下面这段到文件末尾
(dotenv 后者覆盖前者,所以追加即生效;别手改文件中间 —— 这些 .env 里常有重复行,手改中间那行会被后面的覆盖掉):
# 饭粒目录 wuying-dm-yizhu\.env 追加 AKKE_CDP_PORT=9223 AKKE_EDGE_PROFILE=C:\akke-edge-debug-yizhu # 零星目录 wuying-dm-xiaoxing\.env 追加 AKKE_CDP_PORT=9224 AKKE_EDGE_PROFILE=C:\akke-edge-debug-xiaoxing
AKKE_ACCOUNT_ID 用备份里的原值,不要新填。三份对照一遍:
| 目录 | AKKE_ACCOUNT_ID 应为 |
|---|---|
wuying-dm | 81cc9678-9b53-413b-9f40-7964341f4af1 |
wuying-dm-yizhu | c5d236e1-fd80-4cff-b349-506dfd09699b |
wuying-dm-xiaoxing | 8af08f10-6db5-4d83-8942-b908349efbda |
AKKE_SECOND_TOUCH_ENABLED=0 —— 留 =1 会和 consume 同时驱动、把同一批人二触两遍。
起来后看 agent banner 的 second_touch=on/off 就是验证点。
# 饭粒(9223) start msedge --remote-debugging-port=9223 --user-data-dir="C:\akke-edge-debug-yizhu" https://www.douyin.com # 零星(9224) start msedge --remote-debugging-port=9224 --user-data-dir="C:\akke-edge-debug-xiaoxing" https://www.douyin.com
C:\akke-edge-debug 目录再改名 ——
复制 profile = 连浏览器指纹和登录态一起复制,就是 06-23 那个「克隆镜像共用设备指纹 → 集体软封」的坑换了个皮。
每个 profile 第一次启动时自己生成,才拿得到独立指纹。
C:\akke-edge-debug 存在的原因)。
验证端口通:浏览器开 http://127.0.0.1:9223/json/version,返回 Edge 版本 JSON 即 OK。
akke-start.ps1 + 三个开机任务🖥️ 野荞机每个目录一份 akke-start.ps1,内容就是原来那套(kill 残留 → 拉 Edge → 轮询等 CDP 通 → 暖机 → 起 poll agent),
只是把端口 / profile / 目录换成本号的。注册成三个登录触发任务,错开延时避免同时抢资源:
| 任务名 | 延时 | 拉起 |
|---|---|---|
AkkeDomDmStart(野荞,已有) | 30s | wuying-dm\akke-start.ps1 |
AkkeDomDmStart-Yizhu | 90s | wuying-dm-yizhu\akke-start.ps1 |
AkkeDomDmStart-Xiaoxing | 150s | wuying-dm-xiaoxing\akke-start.ps1 |
conversation-item=0(面板没开/DOM变了)。
判别:by_name N>0 但 conversation-item=0 = 面板没加载好(时序问题),不是登录过期
(真过期是连 by_name 都读不到)。无害但污染日志,Start-Sleep 15 + 先跑一次 capture 暖机即可。
akke-start.ps1 里那段自更新(起 poll agent 前先从镜像拉最新 wuying_poll_agent.py,带 >20KB 体积校验防截断)
要三份都保留。少了它,机器会永远跑缓存的旧版 —— 症状是「改动明明合了 main 和镜像,云电脑行为却不变」。
另外:给云电脑加任何自动化前,先跑诊断确认真实启动入口
(列启动文件夹 + Get-ScheduledTask *akke* + 看 akke-start.ps1 内容),
别默认是 start.bat —— 07-26 就把自更新焊进了 start.bat,而 DOM 机开机根本不过它,白干一轮。
| # | 检查项 | 怎么看 | 合格标准 |
|---|---|---|---|
| 1 | 三个端口各自活着 | 浏览器开 127.0.0.1:9222/9223/9224/json/version |
三个都返回 Edge 版本 JSON |
| 2 | 三个 agent 各绑对号 | 看每个 agent banner 的 v= / account= / second_touch= / rc= |
account 值与第 ③ 节表格逐一对上 |
| 3 | 交叉验证:agent 的号 = 它那个 Edge 里登的号 | 逐台把 banner 里的 account 和对应 Edge 窗口里抖音登录的账号肉眼对一遍 | 三对三一致 这是 wrong-account 事故唯一测得出来的地方 |
| 4 | 捕获腿真的活着 | 各目录跑 py douyin_dm_web_capture_dom.py |
出 web capture[DOM] + conversation-item N>0 + COMMIT 写回,无报错 |
| 5 | DB 侧心跳 | 查三个号的 accounts.last_poll_at |
三个都在 5 分钟内刷新(超过就判离线、零派单) |
| 6 | 肉眼核私信气泡 | 三个号各发一条真单后,人工翻抖音私信列表 | 对方会话里真有气泡 |
sent 只代表「点了发送」,
抖音的陌生人私信限流(status_code 7911,约 24h 冷却)是静默丢弃的 —— HTTP 200、success:true、
日志一片绿,消息根本没送到。迁移后的第一批必须人工核气泡。
dispatch_paused_until
+ 在旧机上重新拉起 agent,即刻回到原状(旧机的部署目录和 .env 原封没动)。dispatch_paused_until 设未来,
单独停它一个(另外两个不受影响),同时心跳告警自动静音。dm_panel_failed、之前全 sent」= Edge 窗口卡死,不是号出问题。
判别依据:dm_panel_failed 不罚账号,所以账号仍 active、consecutive_failures=0、无 ban/cooling ——
看到失败但账号计数没涨,八成就是窗口卡死。修法 = 重跑该号的 akke-start.ps1。
别在卡死的 Edge 里手动点私信或导航离开抖音(是常见诱因)。claimed 的行必然没发出去,可以直接 REST PATCH 回
status=pending, claimed_at=null 让新机重领,不会重复骚扰。