Warning
用之前先想清楚(风险自担)
- 这个插件会把你自己的抖音登录凭证(Cookie)交给本机脚本,替你调用抖音的接口。这不是抖音官方功能 —— 属于个人学习性质的自动化,可能违反抖音的用户协议,账号风险由你自己承担。
- Cookie 等同于登录态:只存在本机(
$DSH_HOME/douyin-duty/,不进仓库、不上传任何服务器 —— 代码全是本地的,可自行审阅)。但请你别把 Cookie 贴给任何人,也别在公共电脑上用。 - 自动发送(私信 / 卡片 / 评论)默认关闭,且每一道都有
confirm闸 —— 请在了解每一项开关做什么之后再打开;在别人视频下发评论是公开行为。 - 推荐流的筛选是启发式(互动比值 + 评论文本),不是内容理解 —— 它会误判,见「已知局限」。
- 仅供个人学习研究,请勿用于商业用途或大规模账号操作。
先看五行
- 它替你刷一轮抖音,把值得看的挑出来,写一份 Markdown 日报。
- 不看画面:不截图、不 OCR、不做图像识别、不做 ASR。判断只用文案 / 标签 / 作者 / 时长 / 互动数 / 高赞评论——全是 JSON 字段。
- 采集只要一份 Cookie:走不签名的只读接口(
tab/feed+hot/search),不需要浏览器。- 读评论 / 读通知要签名只读;发私信 / 发卡片 / 发评论才用无头 Chrome(屏幕上不出现窗口)。
- 默认不发任何评论。自动评论是可选功能,默认关,且「@ 自己」是否成立未经验证。
| ✅ 做 | ❌ 不做 |
|---|---|
| 用只读推荐流接口取候选(3 页 feed + 热榜) | 不看视频画面(无截图 / OCR / 视觉模型) |
| 代码层硬筛:没文案、时长 <12 秒、文案太短且评论少 → 直接跳过 | 不做语音识别(不装 Whisper) |
| 拉高赞评论作为判断依据(前 5 条) | 不下载视频(只取元数据) |
| 用「文案 + 标签 + 互动比值 + 高赞评论」判断值不值得点开 | 不做关键词搜索(抖音 web 没有可用搜索接口) |
写 Markdown 日报到 out/<日期>.md |
不做私信自动投递(没有稳定接口;发信走工具,且要你点头) |
| 可选:Windows 通知 / webhook | 不代你登录、不上传任何凭证 |
可选:私信、分享卡片、回评论(默认全关,且都要 confirm) |
不保证判断准确(见下面「已知局限」) |
| 干什么 | 怎么走 | 需要登录? |
|---|---|---|
| 取候选 / 出清单 | 不签名的只读接口 tab/feed + hot/search |
要(Cookie) |
| 读评论 / 读通知(含「评论区 @ 我」) | 签名只读(tools/dy-signer.mjs 出 a_bogus) |
要 |
| 发私信 / 发卡片 / 发评论 | 无头 Chrome 里跑抖音自己的前端 | 要 |
⚠️ 可见浏览器只在扫码登录时用一次;其余全是无头 Chrome 或纯 HTTP。⚠️ 扫码 / 私信 / 卡片 / 评论这几个脚本只找chrome.exe(不找 Edge)。 没装 Chrome 不影响「取候选 + 写日报」,但上面这几个动作会失败。⚠️ 发任何东西前必须先问使用者(confirm: true闸,不传只回草稿)。
抖音没有字幕轨可白拿(B站 有),所以不能"读原文",只能读观众反应:
第 0 层 硬过滤(纯代码,0 token)
没文案 ⇒ 跳过|时长 <12 秒 ⇒ 跳过|文案太短 且 评论少 ⇒ 跳过
(两个阈值在设置页可调,默认 12 字 / 3 条;两个条件同时成立才丢)
⚠️ 太旧、带货、标题党 **没有自动筛**,交给模型逐条判断
第 1 层 互动结构打分(纯数值,0 token)
关键不是点赞绝对值,而是比值:
收藏/点赞 高 ⇒ 有保存价值(教程/攻略/美食)
转发/点赞 高 ⇒ 想转给别人(好笑/共鸣)
评论/点赞 高 ⇒ 引发讨论
⚠️ 播放量对别人的视频经常是 0 ⇒ 完全不参与计算
第 2 层 语义判断(模型)
输入是**压缩过的证据包**,不是原始 JSON:
文案 / 作者 / 时长 / 发布时间 / 互动四件套 / 三个比值 / 高赞评论 top5
模型必须**引用具体证据**(哪条评论、哪个比值),禁止"感觉有趣"
第 3 层 不确定就不推
证据不够 ⇒ 进「判断不了」区,**不出现在推荐里**
能区分的几类(各自判据不同):😂好笑 · 🛠有实用 · 💡涨知识 · 💗共鸣 · 🐱萌。 会主动降权:评论出现「被骗了/标题党」· 文案模板化 · 昵称带「测评/推荐」· 纯颜值 BGM(点赞高但评论空洞)。
⚠️ 诚实说:这套比 B站 版弱一档。B站 读字幕全文,抖音只能读观众反应。 它做不到"条条精准",但能做到"扫一眼报告,大部分值得点开"。策略是宽松召回 + 严格推荐: 点错成本很低(划过去就行),漏掉才是真损失。
# 先跑预检(不用装 DSH;克隆下来后在本目录跑)
git clone https://github.com/NEWJO123/dsh-douyin-scroll.git
cd dsh-douyin-scroll
node selfcheck.mjs # 全部通过再装
# 安装(本地目录链接,开发/自用)
dsh plugin --profile web add link:<本目录>cd dsh-douyin-scroll
git pull # 拉最新
node selfcheck.mjs # 确认预检全过
dsh plugin --profile web add link:<本目录绝对路径> # 重新指一次(幂等)然后重启一次 dsh,设置页里「关于」那行版本号变了就是升上了。 配置和聊天记忆都放在插件家目录(不随仓库走),升级不动它们。
0.3.x 各版本的变化看 CHANGELOG.md。
设置页点「装主依赖」。它会在插件家目录建一个独立 venv、装 curl_cffi + httpx(走国内镜像,通常 30 秒)。
进度看 install.log,不卡页面。
两条路,任选一条:
# A. 扫码(唯一会开可见浏览器的场景)
node tools/qr-login.mjs startB. 设置页 → 抖音 Cookie / 登录 → 把浏览器里已登录抖音的 Cookie 请求头粘进去
Cookie 只落在本机 <家目录>/douyin_cookie.txt(Windows 上 ACL 收不紧,但目录在你自己 profile 下),
不进日志、不进报告、不上传。日志里只出现脱敏后的 key 名。
- 关注关键词:一行一个,例如
搞笑、美食、猫 - 推荐流分类:例如
游戏、游戏解说 - 指定作者:作者主页链接或
sec_uid(可选) - 每天最多挑几条(默认 5)、每次最多筛选几个(默认 12)
然后点「现在跑一轮」。
写到 <DSH_HOME>/douyin-duty/out/<日期>.md:
# 刷抖音 · 2026-10-21
> 本轮:证据包 10 条 → 逐条看过 10 条 → 推荐 4 条 · 顺带一提 4 条 · 判断不了 2 条
> 因「没文案」跳过 2 条,因「时长<12 秒」跳过 2 条
> ⚠️ 太旧、带货、标题党这些没有自动筛,靠逐条判断
## 值得看
### 7401234567890123401
**加班到凌晨三点回家,猫以为我死了** · @两只猫的铲屎官 · 12 秒 · 8 小时前
🔗 https://www.douyin.com/video/7401234567890123401
📊 赞 12.8万 · 评 8600 · 藏 9000 · 转 2.1万
**为什么值得**:高赞评论 3 条都在说"笑死/绷不住",转发/点赞 0.16 明显偏高 ⇒ 是那种会想转给朋友看的段子。
**一句话**:养猫的人看了会心一笑。
## 顺带一提(证据不够,没算进推荐)
- 7401234567890123456 · 某个美食教程 · 收藏比不错但评论太少,先记着
## 没把握 / 判断不了
- 7401234567890123457 · 文案只有「嗯」,评论 1 条 —— **没有判断依据,不硬猜**### <纯数字视频ID> 这一行是宿主数配额用的 —— 这一行数 = 今天挑了几条。
「顺带一提」「判断不了」里不要加这种标题,加了会吃掉当天额度。
| 项 | 必须? | 怎么给 |
|---|---|---|
| 抖音 Cookie | 必须 | 设置页粘贴,或 node tools/qr-login.mjs start 扫码(不上传) |
| 关键词 / 分类 | 建议填 | 设置页,一行一个(只当报告标注,不参与采集) |
| 运行时间 | 可选 | 开「峰谷时段自动刷」→ 午间 12:00–14:00 / 夜间 18:00–09:00 |
| 每天几条 | 可选 | 默认 5,填 0 = 不自动刷(仍可手动跑) |
| 通知方式 | 可选,默认 Windows 通知 | 默认就会弹;想换群/机器人就 notifyMode=webhook + 你的 webhook 地址 |
| 要 @ 谁 | 只在开评论时需要 | 设置页填抖音昵称;留空 = 不发评论 |
你不需要提供:任何 API key、账号密码、抖音开发者资质、bb-browser、Playwright。
# ① 不装 DSH 就能跑的判断层自检
python tools/smoke.py
# → 会打印"硬筛原因 + 证据包 + 粗分类",你能直接看出它怎么判断的
# ② 全套本地预检(不联网、不起浏览器)
node selfcheck.mjs
# ③ 装进 DSH 后
# 设置页「测一下」= 查会话 + 试取一次候选 → 回答"能不能用"| 项 | 默认 | 说明 |
|---|---|---|
| 每天最多挑几条 | 5 | 全天总量;0 = 不自动刷 |
| 每次最多筛选几个 | 12 | 证据包上限(传给 forward-pick.py --limit,最多 30) |
| 中午谷时 / 晚上谷时 | 开 / 开 | 12:00–14:00 / 18:00–次日 09:00 |
| 自定义时段 | 空 | 想加几个加几个(09:00–11:00、跨零点的 23:00–02:00 都行);跟上面两个叠加,任意一个命中就跑,每个时段每天一次 |
| 关键词 / 分类 / 作者 | 空 | 一行一个;采集侧不按词搜(没有可用搜索接口)。关键词命中文案/话题的候选排序靠前(软偏好 ×1.35),不命中也不丢 |
| 文案太短阈值 / 评论少阈值 | 12 / 3 | 两个条件同时成立才跳过 |
| 自动评论并 @ | 关 | 危险,默认关 |
| 每轮 / 每天最多评论 | 1 / 0 | commentPerDay=0 ⇒ 一条都不会发 |
| 通知方式 | toast | toast / file / webhook / both |
| 日报写多细 | full | full / brief(薄)/ off(不写) |
| pythonPath / dshBin | 自动 | 一般不用改 |
| 发私信给谁(昵称 / 稳定 ID) | 空 | dmTo 只显示;dmToId 才决定发给谁 |
更新地址 updateUrl |
空 | 留空 = 自动查 npm / GitHub;填了就只查这一个 |
2026-10-21 删掉了「采集来源」和「工作区」两项:前者只剩一条路(只读推荐流), 后者是"读外部 AGENTS.md 当人设"的口子,已封死 —— 人设只读插件自带的
prompts/persona.md。
一轮跑完,结果要真的推到你面前,不能只是躺在文件夹里。默认走 Windows 通知,零配置:
| 方式 | 行为 | 要准备什么 |
|---|---|---|
toast(默认) |
屏幕右下角弹一条:挑到几条 + 前两条值不值得看;留在通知中心(Win+N) | 什么都不用 |
file |
不额外提醒,报告落在 out/<日期>.md |
— |
webhook |
推到企业微信 / 飞书 / 钉钉群,或任意 URL(custom) |
一个机器人 webhook 地址 |
both |
弹通知 + 推 webhook | 同上 |
设置页「通知 → 发一条测试消息」点一下就知道通不通 —— 通了会当场弹到你屏幕上。
为什么不做「抖音私信发给我」:发私信要签名和登录态,且风险高;插件里虽然有
douyin_dm/douyin_share_card,但它们只在会话里由模型调用,且必须你点头, 不会自动把日报私信给你。
- 设置里「自动评论」关着(默认)→ 工具层直接拒绝
- 评论执行器 =
off(默认)→ 即使开关开着也不会发 - 「要 @ 谁」留空 → 不会发(评论的意义就是那一下 @)
| 执行器 | 行为 | 状态 |
|---|---|---|
off |
不发(默认) | ✅ |
builtin |
走抖音评论提交接口 | ❌ 不可用(要验签票据)——调用会如实报错 |
browser |
在真实页面上填评论,但不点发送 | |
http |
转发给你自己部署的服务 | ✅ 你有自己通道时用 |
🔴 风险(必须知道):
- 抖音评论区**「@ 自己」是否成立未经验证**;
- 评论以你本人账号名义发出;
- 频繁评论会触发风控/限流,可能影响你正常刷抖音。
- 🔴 两个工具(
douyin_dm/douyin_share_card)都必须传confirm: true,否则只回草稿。 - 🔴 先卡片,后文字:既要发卡片又要发文字时,永远先卡片、隔几秒再文字。
douyin_share_card给了reason会自动按这个顺序办(卡片 → 回读 → 隔 N 秒 → 理由), 不要再补一次douyin_dm。 ⚠️ 纯文本网址在抖音里点不开,只有分享卡片能点 —— 所以用卡片,不要拼文本链接。⚠️ 回读能证明「发出去了」,证明不了「对方已读」。
- 判断准确率低于 B站 版 —— 没有字幕,只能读观众反应。
- 「文案极简 + 评论少」的视频一定会漏 —— 这是刻意的:没依据就不硬猜。
- 播放量不可用 —— 对非作者的视频经常返回 0,所以判据里完全不用它。
- 关键词搜索不可用 —— 抖音 web 的
general/search被 2483 挡住;只有推荐流。 所以「关键词」只能给命中的候选加排序分,不能保证推荐的都是你关心的(#3 的误会就出在这)。 - 推荐流每轮不一样 —— 同一时间跑两次可能拿到不同候选;报告里会标注每个采集源新增了几条。
- 评论可能拉不到 —— 签名失效 / 风控 / 接口变更都会让某几条没有评论区证据;报告会如实写。
| 现象 | 看哪里 |
|---|---|
| 设置页不出现「刷抖音」 | 重启 dsh;看日志有没有 1 entry did not activate |
| 拿不到候选 | health.json / duty.log / forward-pick.json 的 meta(每个源的 new 和 status) |
| 报告是空的 | 宿主会补一份「占位报告」并贴日志尾部;完整日志在 duty.log |
| 判断太保守/太激进 | 调「文案太短阈值 / 评论少阈值」和「每次最多筛选几个」 |
| 一轮跑太久 | 降证据包条数(前 5 条才拉评论,拉评论是最慢的一步) |
| 昨天挑的今天还算配额 | 不会:配额按 out/<今天>.md 里的 ### ID 数,跨天自然归零 |
「现在跑一轮」立刻失败,duty.log 里写着 profile "headless" does not exist |
桌面版只有 desktop(Electron 独占),headless 得自己建一次:dsh plugin --profile headless add link:<插件目录>。插件会在日志里提前提示这一行 |
| 发私信 / 分享卡片报「profile 被残留进程占着」 | 之前扫码登录留下的浏览器进程还攥着 chrome-profile。按报错里那条 Get-CimInstance 命令查 PID,确认是残留的再结束,然后重试(别删 profile —— 登录态在里面) |
| webhook 报「地址指向本机」 | 回环 / 169.254 这类地址默认拦掉(防 SSRF)。真要把报告推到本机或内网服务,设 DOUYIN_WEBHOOK_ALLOW_LOCAL=1 |
数据都在:<DSH_HOME>/douyin-duty/(config.json / collector.json / forward-pick.json /
round-evidence.json / duty.md / out/ / inbox/ / duty.log / health.json)。
dsh-douyin-scroll/
├── package.json / cordis.patch.yml # 插件声明(entry id 必须 = douyin-scroll)
├── index.js # 宿主半端:配置/工具/定时器/证据包/headless 跑一轮/HTTP
├── client.js # 设置页(非 ESM 自注册脚本)
├── AI-USAGE.md # ⭐ 给别的 AI 看的使用说明(MCP 接入 + 安全红线)
├── selfcheck.mjs # 本地预检(110 项)
├── tools/
│ ├── mcp-server.mjs # ⭐ 标准 MCP server(stdio,零依赖)—— 别的 agent 工具接进来
│ ├── panel-render-check.mjs # ⭐ 设置页真渲染一遍(抓白屏,语法检查查不出)
│ ├── doctor.mjs # ⭐ 环境体检(纯 Node,不依赖 Python)
│ ├── forward-pick.py # ⭐ 取候选 + 硬筛 + 打分 + dropped 计数
│ ├── forward-run.mjs # 命令行一键:拉候选 + 弹通知
│ ├── api-comments.py # 签名拉评论
│ ├── notice-read.py # 签名读通知(含 @ 我)
│ ├── api-reply.py # 签名回评论(只读先通才写)
│ ├── comment-api.mjs # 无头页面里发评论/回复
│ ├── comment-mention-ui.mjs # 真 @ 提及(只有 UI 点选才算数)
│ ├── comment-delete.mjs # 删自己的评论(页面里 POST /comment/delete/)
│ ├── comment-reply.mjs # 真实 UI 回某条评论(保守方案)
│ ├── comment-read-dom.mjs # 从评论区 DOM 读(绕开"只翻前 80 条"的接口盲区)
│ ├── card-share.mjs # 分享卡片(无头页面点「分享给朋友」)
│ ├── im-send.mjs # 私信发送 + 回读(头像左右判发送方)
│ ├── mk-msg.mjs # 把清单拼成私信正文
│ ├── qr-login.mjs # 扫码登录(唯一可见浏览器)
│ ├── cdp.mjs # CDP 小工具
│ ├── dy-signer.mjs # 抖音 web 签名器(纯 Node + jsdom)
│ ├── session-guard.py # 会话保险丝(坏签名别打写接口)
│ └── smoke.py # 判断层自检(离线)
├── lib/
│ ├── hostdeps.mjs # 三级兜底取宿主依赖
│ ├── paths.mjs # ⭐ 家目录/插件目录的唯一来源(不写死盘符)
│ ├── chrome.mjs # 无头浏览器(找不到 Chrome 就找 Edge/Chromium)
│ ├── state.mjs # 家目录 / 谷时窗口 / 章程记账 / Cookie 脱敏
│ ├── credential.mjs # Cookie 存取
│ ├── notify.mjs # webhook + 报告摘要 + URL 脱敏
│ ├── toast.mjs # Windows 通知(默认)
│ └── uvfetch.mjs # 机器上没有 uv/python 时自动下一份
├── prompts/
│ ├── duty.md # 一轮的章程(判据 + 红线 + 报告格式)
│ ├── persona.default.md # 中性默认人设(随包发布)
│ └── sample-candidates.json # 内置示例(离线演示用)
└── requirements.txt # 只有 curl_cffi + httpx
插件自带一个标准 MCP server(tools/mcp-server.mjs,stdio,零依赖)。
Claude Code / Cursor / Cline / 另一个 DSH 都能接:
{
"mcpServers": {
"douyin": {
"command": "node",
"args": ["<插件目录>/tools/mcp-server.mjs"],
"env": { "DOUYIN_HOME": "<插件家目录>" }
}
}
}设置页「给别的 AI 用 → 看接入方式」里有一键复制(路径按你这台机器算好)。
完整说明见 AI-USAGE.md,或者直接让那个 AI 调 douyin_guide。
为什么不做成"任何 AI 都能直接装":MCP 是各家通用的接口,但它只解决"能调工具"。 「按点刷一轮 → 写日报」那条值班链路仍然在 DSH 里(要 headless 会话 + 定时器)。 两件事分开:能力走 MCP,值班走 DSH 插件。
MIT