从 0 到自己跑通一条已审消息的全流程:环境搭建 + 日常 SOP + 故障排查 + 红线。预计 1.5 小时。
akke-wda-dm-playbook.md,把它喂给你 Mac 上的 Claude Code,AI 会带你逐步执行命令,遇到必须人做的环节会停下问你。推荐做法:先扫一遍本页心里有数 → 再开 Claude Code 喂 .md 实际操作。
Akke 的 DM 发送是一条"先审后发"的流水线,你的工作发生在最后两环:
抓评论 → AI 评分 → AI 起草 DM
↓
你在 Akke 后台审核(通过 / 编辑 / 拒绝) ← 你做这一步
↓
被通过的 DM 落入 Supabase message_queue 表(状态 approved)
↓
你 Mac 上跑 dm_send_v3.py 拉取 approved 行 ← 你做这一步
↓
脚本通过 WebDriverAgent 操控你的 iPhone 抖音 App 发送
↓
回写 sent / failed 状态
关键认知:
动手装环境前先把这些账号开好。所有邀请都找现任项目 Owner(在 Lark "Akke 智能获客系统群" 里 @ 一下即可)。
| 平台 | 等级 | 用途 | 邀请方做什么 |
|---|---|---|---|
Akke 应用账号akke.upio.ai |
必备 | 登录 dashboard 审核 DM 草稿、看 message_queue 状态 | Owner 进 /team 邀请你的邮箱,给 Operator 角色 |
| worker .env (凭据文件) |
必备 | 本地 dm_send_v3 脚本访问 Supabase 取 approved 行需要这些密钥 | Owner 通过 1Password / Lark 私密会话把 SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY / FLY_WORKER_SECRET 给你。不要发到群里。 |
GitHub 仓库akke |
必备 | clone 项目代码(dm_send_v3.py 等脚本在这里) | Owner 在仓库 Settings → Collaborators 加你的 GitHub 账号 |
Supabase 项目app.supabase.com |
强烈建议 | 出问题时直接查 SQL(如 message_queue 卡了哪条、conversations 状态机为啥不动) | Owner 进 Project Settings → Team 邀请你的邮箱 |
Vercel 团队vercel.com |
可选 | 看前端构建日志、Cron 执行历史。日常发 DM 用不到。 | 邀请 + 关键一步见下方警告框 |
vercel.com/account/login-connections,把你的 GitHub 账号绑定进去。否则你 push 后 Vercel 会拒绝部署,errorLink 是 team-configuration。
akke.upio.ai| 项 | 要求 | 说明 |
|---|---|---|
| Mac | macOS 14+,建议 16GB 内存 | 跑 Xcode 编译 + Python WDA 客户端 + Akke worker。Intel / Apple Silicon 都行 |
| iPhone | iPhone 12 及以上,iOS 17+ | 抖音 App 跑 WDA 自动化的真机。建议专门一台用于工作,不要混你日常生活用的 |
| 数据线 | 原装或 MFi 认证 | USB 连接 Mac↔iPhone 全程要插着,不能拔 |
| Apple ID | 你自己的 Apple ID(任何区都行) | 用来在 Xcode 里登录 Personal Team(免费个人开发者)。不要用公司共享 ID |
| 抖音账号 | 已登录 iPhone 抖音 App | Owner 给你分配一个工作号;自己日常号不要用来跑 Akke |
下面 10 步是第一次开搞前要走一遍的,预计 1-1.5 小时(Xcode 下载占大头)。每步独立,做完一步打 ✓ 再下一步。
Mac App Store 搜索 "Xcode" → 下载(约 12 GB,需要 1-2 小时网速看人)→ 装好后必须打开一次接受协议。
然后终端执行:
xcode-select --install
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcode-select -p # 输出 /Applications/Xcode.app/... 即就绪
Xcode → Settings → Accounts → 点 "+" 加你的 Apple ID查 Team ID 的快捷方式:
security find-certificate -a -p ~/Library/Keychains/login.keychain-db \
| openssl x509 -noout -subject 2>/dev/null \
| grep -o 'OU=[A-Z0-9]\{10\}' | head -1
# 输出:OU=NQC9WL9445 ← Team ID 是 NQC9WL9445
cd ~
git clone https://github.com/appium/WebDriverAgent.git
cd WebDriverAgent
# 把 Facebook 默认 bundle ID 改成你自己的(用你名字的拼音/缩写)
sed -i '' 's/com.facebook.WebDriverAgentRunner/com.<你名>.WebDriverAgentRunner/g' \
WebDriverAgent.xcodeproj/project.pbxproj
把 <你名> 替换成英文小写名字(例:com.kara.WebDriverAgentRunner)。Personal Team 不能用别人占过的 bundle ID,必须改。
cd ~/WebDriverAgent
xcodebuild build-for-testing \
-project WebDriverAgent.xcodeproj \
-scheme WebDriverAgentRunner \
-destination 'generic/platform=iOS' \
CODE_SIGNING_ALLOWED=NO
编译结果会在 ~/Library/Developer/Xcode/DerivedData/WebDriverAgent-* 下。
构建后 xctestrun 文件里的 bundle ID 也要改一次:
sed -i '' 's/com.facebook.WebDriverAgentRunner/com.<你名>.WebDriverAgentRunner/g' \
~/Library/Developer/Xcode/DerivedData/WebDriverAgent-*/Build/Products/*.xctestrun
新 iOS 上常见。不影响编译,只要你加了 CODE_SIGNING_ALLOWED=NO 和 generic/platform=iOS 就能跳过 platform 检查继续。
用数据线连上 iPhone(信任电脑),先取你的 UDID:
system_profiler SPUSBDataType | grep -A 4 "iPhone" | grep "Serial Number"
把 UDID 记下来(40 位字符),然后:
UDID=00008110-001A44421447801E # 换成你的
# 找编译产物
APP=$(find ~/Library/Developer/Xcode/DerivedData/WebDriverAgent-* \
-name "WebDriverAgentRunner-Runner.app" | head -1)
# 安装
xcrun devicectl device install app --device $UDID "$APP"
iPhone 第一次跑 WDA 会弹 "Untrusted Developer",必须手动信任:
iPhone → 设置 → 显示与亮度 → 自动锁定 → 永不。
iOS 17+ 必须用 pymobiledevice3(旧的 tidevice 已经不能用了):
pip3 install --user 'pymobiledevice3>=9.12.0'
pymobiledevice3 --version # 验证装好
cd ~
git clone git@github.com:<Akke 仓库地址> Akke
cd Akke/worker
pip3 install -r requirements.txt
playwright install chromium # 备用,目前 DM 不走 playwright 但其他工具会用
把现任 Owner 通过 1Password 给你的 worker .env 内容,保存到:
~/Akke/worker/.env
内容应该至少包含:
SUPABASE_URL=https://<xxx>.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJ...
FLY_WORKER_SECRET=<长字符串>
SUPABASE_SERVICE_ROLE_KEY 能绕过所有租户隔离访问全库数据。不要 commit、不要发群、不要截图分享。每天开始发 DM 之前跑下面 7 步,全程 5 分钟。
开终端 1,跑:
sudo pymobiledevice3 remote tunneld -d
这条命令需要前台保持运行,不要关。让它一直跑。
新开终端 2:
curl -s http://127.0.0.1:49151/ | python3 -c "
import sys, json
d = json.load(sys.stdin)
v = list(d.values())[0]
print(v['rsd_address'], v['rsd_port'])
"
会输出类似 fd68:295b:b075::1 55320(IPv6 地址 + 端口),抄下来。
终端 2 继续跑(替换上一步抄的地址 + 你自己的 bundle ID):
pymobiledevice3 developer dvt xcuitest \
--rsd fd68:295b:b075::1 55320 \
com.<你名>.WebDriverAgentRunner.xctrunner
注意:bundle ID 末尾 .xctrunner 是固定后缀,不能省。这个终端也要保持前台。
新开终端 3:
pymobiledevice3 usbmux forward 8100 8100
这条会把 iPhone 的 WDA 端口映射到 Mac 的 localhost:8100。
新开终端 4:
curl http://localhost:8100/status
返回 JSON 含 "sessionId" 字段就 OK。如果 timeout 或 connection refused 跳第 6 节"故障排查"。
终端 4:
cd ~/Akke/worker
python3 dm_send_v3.py --max 5
--max 5 是本批最多发 5 条。新人头几次跑建议 --max 3 摸熟手感。
终端会打印每条候选的进度,类似:
[1/5] 候选: 榴莲 (sec_uid: MS4w...) intent=95
→ 暖场 OK
→ 跳转 profile OK
→ 点击私信 OK
→ 输入文案 OK
→ 发送 SENT ✓
间隔 120s(随机 90-180s)
[2/5] ...
跑完后回各个终端按 Ctrl+C:终端 1 (tunneld) → 终端 2 (xcuitest) → 终端 3 (forward)。或者一把杀干净:
sudo pkill -f "remote tunneld"
pkill -f xcuitest
pkill -f "usbmux forward"
下面 8 类是已知坑。按症状对照修法。
curl localhost:8100/status timeout 或 connection refused三步链有一环挂了。按顺序检查:
多半是 iPhone 屏幕黑了。Personal Team 没有解锁权限,屏幕一锁所有 XCTest 命令会立即挂起。
修法:
xcodebuild test runner 跑超过 ~1h 会被 testmanagerd 主动断连(与证书无关,是苹果内部超时)。
修法:单批 ≤ 8 条 DM,超过拆成多次跑,每次重启 xcuitest 终端。
抖音 iOS App 的输入框(Draft.js)把每个换行符当 Enter(=立即发送)。如果 prompt 写出多段文案,send_keys 会触发风控且永久消耗对方配额。
修法:用最新的 dm_send_v3.py(已加 \n 折叠安全网)。不要回退到 v1 / v2 版本。
对方关闭了陌生人私信。这是正常拦截,不是你的问题。脚本会自动 mark_failed,跳下一条。
账号触发风控(22102 是观察期,7911 是速率软封)。
修法:
抖音偶尔抽查。脚本会等待,你手动滑一下完成验证,然后回到终端按回车继续。验证码本身不计风险分,正常通过即可。
Personal Team 签名只有 7 天有效期。每周二(或者你自己定的时间)跑一次重签:
大约 5 分钟。
dm_send_v3.py 加了 \n 折叠安全网兜底,但别故意去试# 终端 1
sudo pymobiledevice3 remote tunneld -d
# 终端 2 — 取 RSD 地址
curl -s http://127.0.0.1:49151/ | python3 -c "import sys,json;d=json.load(sys.stdin);v=list(d.values())[0];print(v['rsd_address'],v['rsd_port'])"
# 终端 2 — 启 xctest(用上面输出的地址)
pymobiledevice3 developer dvt xcuitest \
--rsd <ip> <port> com.<你名>.WebDriverAgentRunner.xctrunner
# 终端 3
pymobiledevice3 usbmux forward 8100 8100
# 终端 4 — 验活
curl http://localhost:8100/status
# iPhone:解锁 → 抖音 App → 切「我」 → 回首页停 30s
# 终端 4 — 发
cd ~/Akke/worker && python3 dm_send_v3.py --max 5
# 收工
sudo pkill -f "remote tunneld"; pkill -f xcuitest; pkill -f "usbmux forward"
7173 | 对方关私信,正常拦截,跳下一条 |
7462 | 同一对象已发过、对方未回复,配额用完 |
7911 | 账号速率软封,停用 24h |
22102 | 账号观察期,停用 24-72h,换号 |
| curl 8100 timeout | 三步链断了一环,按"故障排查 1"重启 |
| 所有命令 timeout | iPhone 屏幕黑了,立即解锁 |
| connection invalidated | WDA 跑超 1h,单批 ≤ 8 条 + 重启 |