# hl-douyin-plugin **Repository Path**: fox-glaze/hl-douyin-plugin ## Basic Information - **Project Name**: hl-douyin-plugin - **Description**: trss-yunzai的douyin自动续火插件 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-31 - **Last Updated**: 2026-09-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

hl-douyin-plugin

hl-douyin-plugin

node yunzai license

TRSS-Yunzai 抖音自动续火插件。定时给抖音好友发消息保住火花,跑完把结果推到群里,配套一个带临时验证码鉴权的 Web 面板做可视化管理。 移植自 `douyin-auto-spark`(Playwright / TypeScript),改写为 Yunzai 插件:浏览器自动化换成仓库里已有的 puppeteer,定时改成可热更新的 cron,账号按机器人隔离,Cookie 加密落盘。 > **如遇到问题,请查看 [问题解决.md](问题解决.md)** —— 常见问题排查、安全说明、目录结构、以及每处设计的取舍理由都在那里。 ## 功能 - **定时续火** — 6 位 cron(秒在最前),锅巴或指令改完立即生效,不用重启 - **配置热重载** — 锅巴 / 面板 / 指令保存即时生效;直接手改 `config/config.yaml` 也会自动重新读盘(监听文件),改 `debug` 这类开关不用重启 - **跳过今日已续火** — 抖音火花一天只认一次,已成功的账号定时任务直接跳过,可开关 - **好友改名不断火** — 续火目标存 `主名 + 别名 + 备注`,主名搜不到自动试别名,命中后把新名提为主名 - **结果推送** — 跑完自动发群 / 私聊 / 两者,支持多群、跨机器人、详细/简要两种模式、仅失败时推送 - **Web 可视化面板** — 账号管理、给指定好友手动发信、拉取会话列表、扫码登录、改配置、看状态与审计 - **私信聊天** — 面板里点一个账号就进它的抖音私信,像 IM 一样收发;聊天记录存本机 sqlite,**不过期** - **远程过验证** — 抖音追加身份验证时私信一个临时链接,在里面看着那台浏览器的画面直接点/拖/打字过掉 - **自动过短信验证** — 插件自己点「发送验证码」,只跟你要短信里那几位数字,全程不发链接 - **三种登录方式** — 扫码自动抓 Cookie、私聊粘贴、发 txt 文件(QQ 输入框会截断超长 Cookie) - **Cookie 刷新** — 凭证「半失效」(sessionid 未作废、只是短命字段陈旧)时 `#抖音刷新ck` 换回新 Cookie,免重扫 - **多机器人隔离** — 账号按 botId 分文件存储,面板会话只能进入「你是主人」的那些机器人 - **锅巴配置** — 全部配置项都在锅巴面板里可视化编辑,账号与 Cookie 也在里面增删 - **文本出图** — 帮助 / 设置 / 状态渲染成图片,渲染失败自动降级成文字 - **访问频次控制** — 拦截图片/字体/埋点请求、缓存 Cookie 检查结论,减少对抖音的请求量 - **退出自动收尾** — `#重启` 与进程退出前先关浏览器、聊天页、扫码页、数据库,不留孤儿 Chromium - **插件更新** — `#抖音更新` 拉取新代码并自动重启,更新前备份 `config/` 与 `data/` ## 安装 在 Yunzai 根目录执行,然后重启。三个源内容一致,选一个即可: ``` bash # Gitee(主仓库,更新最快) git clone --depth 1 https://gitee.com/fox-glaze/hl-douyin-plugin ./plugins/hl-douyin-plugin # GitCode(国内直连,同步自 Gitee,可能滞后一会儿) git clone --depth 1 https://gitcode.com/sujier/hl-douyin-plugin ./plugins/hl-douyin-plugin # GitHub git clone --depth 1 https://github.com/HL-z7/hl-douyin-plugin ./plugins/hl-douyin-plugin ``` 无需 `npm install`:依赖全部复用 Yunzai 自带的 puppeteer / express / node-schedule / yaml / lodash。聊天记录用 Node 内置的 `node:sqlite`,也不算新依赖,但它要 **Node ≥ 22.5**;低于这个版本聊天功能照样能用,只是不落盘(看不到本地历史),其余功能不受影响。 装好后 `#抖音更新` 就能拉新代码并自动重启,不必再手动 `git pull` —— 它拉的是你 clone 时用的那个源。 首次启动自动生成: | 路径 | 说明 | | --- | --- | | `config/config.yaml` | 只存你改过的项,默认值在代码里,插件升级后新字段自动补齐 | | `data/secret.key` | AES-256-GCM 主密钥(0600),**丢了等于所有 Cookie 作废,备份时别漏** | | `data/accounts/<机器人QQ>.json` | 加密后的账号数据 | | `data/chat.db` | 聊天记录(sqlite,WAL),第一次进聊天界面时才建 | | `data/audit.json` | 操作审计 | 整个 `data/` 已在 `.gitignore` 里。 ## 指令 | 指令 | 权限 | 说明 | | --- | --- | --- | | `#抖音web` | 主人 | **私信**发一条点开即进的面板链接,群里只回一句「已发送」 | | `#抖音web下线` | 主人 | 立刻作废自己的验证码、面板会话与远程验证链接,并终止进行中的登录会话 | | `#抖音登录 [账号名]` | 主人 | 扫码登录,二维码以图片发回,成功后自动存 Cookie | | `#抖音自动登录 [账号名]` | 主人 | 同上,且抖音要短信验证时插件自己点「发送验证码」,只跟你要那几位数字 | | `#抖音手动登录 账号名 Cookie` | 主人 | 只能私聊;在群里发会尝试撤回并拒收 | | `#抖音文件登录 账号名` | 主人 | 只能私聊;随后发一个装着 Cookie 的 txt | | `#抖音检查cookie` | 主人 | 逐个打开抖音验证凭证是否还有效(结果按 TTL 缓存) | | `#抖音刷新ck [账号名]` | 主人 | 带旧凭证访问一次抖音,换回站点重新下发的整套 Cookie 并落盘;不带账号名则逐个刷全部账号。sessionid 还有效时免重扫,已作废时救不回来(见 [Cookie 刷新](#cookie-刷新)) | | `#抖音续火` | 主人 | 立即为当前机器人的所有启用账号跑一次 | | `#抖音续火 跳过` | 主人 | 同上,但今天已成功的账号跳过,用于补跑定时任务 | | `#抖音加好友 账号名 昵称` | 主人 | 支持 `昵称(备注)` 与 `新名=旧名` 写法 | | `#抖音删好友 账号名 昵称` | 主人 | 主名或别名都能删掉整条目标 | | `#抖音备注 账号名 昵称 备注` | 主人 | 备注留空则清除 | | `#抖音账号` | 主人 | 账号列表、绑定的好友、上次结果 | | `#抖音删除账号 账号名` | 主人 | 连 Cookie 一起删 | | `#抖音状态` | 所有人 | 状态面板,默认出图 | | `#抖音设置` | 主人 | 查看当前配置与可改项,默认出图 | | `#抖音重载` | 主人 | 重新读 `config/config.yaml` 并让改动生效(手改文件通常自动生效,这条用来确认) | | `#抖音帮助` | 所有人 | 指令一览,默认出图 | | `#抖音更新` / `#抖音强制更新` | 主人 | git pull 拉新代码,按配置自动重启 | `抖音` 均可替换为 `dy`,`#` 可省略。 `#抖音设置` 支持的直改项(复杂配置走面板或锅巴): ```text #抖音设置 定时 开/关 #抖音设置 cron 0 20 8 * * * # 无效表达式会自动还原 #抖音设置 跳过 开/关 # 跳过今天已续过火的账号 #抖音设置 推送 开/关 #抖音设置 推送范围 群/私聊/两者 #抖音设置 推送模式 详细/简要 #抖音设置 渲染 开/关 # 关掉则帮助/设置/状态都发纯文字 #抖音设置 聊天 开/关 # 面板里的私信聊天入口;关掉会立刻收掉已开的会话(记录不删) #抖音设置 打码 开/关 # 群内回复面板链接时是否隐去主机(公网 IP 强烈建议开) #抖音设置 自动短信 开/关 # 让 #抖音登录 也自动接管短信验证 #抖音设置 调试 开/关 # 每一步都记日志,卡住时先开它再跑一次 #抖音设置 快照 开/关 # 调试态下额外把截图与页面原文存到 data/debug/ #抖音设置 加群 [群号] # 不填用当前群 #抖音设置 删群 [群号] #抖音设置 加好友 [QQ号] # 不填用自己 #抖音设置 删好友 [QQ号] #抖音设置 解封IP # 清空被限流拉黑的 IP #抖音设置 会话 # 查看活跃的面板会话与远程验证链接 #抖音重载 # 手改 config.yaml 后重新读盘(通常自动生效) ``` ## 怎么用 ### 加账号 三条路,任选一条: 1. **`#抖音登录 账号名`** — 扫码,Cookie 自动抓。要求短信验证的号改用 `#抖音自动登录`,插件会自己点按钮,只私信跟你要短信里那几位数字 2. **`#抖音web`** → 面板里粘 Cookie / 扫码 / 配好友,一处搞定 3. **`#抖音文件登录 账号名`** + 发一个 txt — Cookie 太长时用,QQ 输入框会截断超长文本 ### Cookie 刷新 续火开始报错、面板显示凭证异常时,先别急着重扫,试一下 **`#抖音刷新ck`**(账号多可以带账号名只刷一个)。 原理:带着旧 Cookie 开一次浏览器访问抖音,把站点这次重新下发的整套 Cookie 收回来、加密落盘,好友名单、备注等账号数据原样保留。因此它能不能救回来,取决于 `sessionid` 是否仍被抖音认可—— - **能救**:多数「ck 过期」其实是 `ttwid` / `msToken` 这类短命字段陈旧触发了风控,`sessionid` 本身还在有效期,刷新一次就续上了 - **救不了**:`sessionid` 已被服务端作废(长期未用、异地被顶号)。插件会进不了登录态,此时如实回复要求重新扫码,不会假装刷新成功 刷新与续火、聊天窗共用同一把账号锁:账号正在续火或聊天窗开着时,该项会提示稍后再试,其余账号不受影响。刷完后可用 `#抖音检查cookie` 复核。 ### 配续火好友 好友改名是断火最常见的原因,所以续火目标不是一个裸昵称,而是 `{ 主名, 别名[], 备注 }`:主名搜不到会按顺序试别名,命中别名后自动把它提为主名,下次直接用新名搜。 指令、面板、锅巴三处用同一套文本语法: ```text 张三 # 只有主名 张三(表妹) # 带备注,全角括号与 | 也认 张三三=张三 # 主名「张三三」,别名「张三」 张三三=张三=小三(表妹) # 多别名 + 备注 ``` 用 `#抖音加好友 账号名 张三三=张三` 添加,或在面板/锅巴里填同样的字符串。备注只用于展示,不参与搜索。 ### 设定时 ```text #抖音设置 cron 0 20 8 * * * # 每天 08:20:00,秒在最前 ``` 改完立即生效,不用重启。`#抖音状态` 里的「下次执行」就是当前生效值。 ### 进私信聊天 `#抖音web` → 面板「账号与发信」→ 点一个账号的「进入聊天」。左边会话列表、右边气泡流、下面输入框。聊天记录存 `data/chat.db`,**只增不减、没有过期清理**,三个月没联系的人仍然在列表里。 空闲 180 秒(`chat.idleCloseSec`)自动收掉聊天页;一个账号同一时刻只能干一件事,续火与聊天抢同一把锁。 ### 消息模板 留空 = 随机发一言(自带离线数据,无需联网)。 占位符:`{{account}}` `{{friend}}` `{{yiyan}}` `{{from}}` `{{date}}` `{{time}}` `{{weekday}}` ```text {{friend}} 早上好,今天是 {{date}} {{weekday}} ``` 写错的占位符在保存时就被拒绝,不会原样发给好友。yaml 里不方便换行可以写字面 `\n`。日期时间固定按 Asia/Shanghai 算,服务器在国外也不差一天。账号可以单独设模板,覆盖全局那份。 ## 配置 `config/config.yaml`,也可在锅巴或面板里改。 三条路都是改完立即生效,**不用重启**: - **锅巴 / Web 面板 / `#抖音设置`** — 保存时直接改进程里那份配置,本来就是即时的 - **直接编辑 `config/config.yaml`** — 插件监听这个文件,保存后自动重新读盘:cron 会重新排表, `chat.enable` 关掉会顺手收掉已开的聊天会话,日志里会记一行「配置已热重载」和改了哪几项 - **`#抖音重载`** — 手动触发一次上面的流程。手改文件时通常用不上(自动的), 它的用处是确认「到底生效了没有」——Docker 挂载目录等环境收不到文件事件时它也是唯一的路 例外只有三个:`web.enable`、`web.base`、`web.port`。路由与监听端口在插件加载时就定死了, 改这三项仍要 `#重启`(热重载会在日志与 `#抖音重载` 的回复里点名提醒)。 配置文件允许只写你要改的字段,缺的由代码里的默认值补齐;文件写坏(语法错误,或写到一半的 残片)时热重载会整个放弃并把原因写进日志,**不会**把正在生效的配置换成默认值。 | 键 | 默认 | 说明 | | --- | --- | --- | | `spark.enable` | `true` | 定时续火总开关 | | `spark.cron` | `0 20 8 * * *` | 每天 08:20:00 | | `spark.skipIfDone` | `true` | 定时任务跳过今天已成功的账号(手动续火不受限) | | `spark.messageTemplate` | `""` | 全局模板,空则发一言 | | `spark.yiyanIncludeSource` | `true` | 一言末尾附带 ——「出处」 | | `spark.minGapMs` / `maxGapMs` | `2500` / `6000` | 好友之间的随机间隔,太快容易被风控 | | `spark.searchRetry` | `3` | 搜不到好友的重试次数(全部候选名都搜不到才算丢) | | `spark.accountTimeoutMs` | `300000` | 单账号超时兜底 | | `spark.headless` | `true` | 关掉可看浏览器,调选择器时用 | | `spark.browserPath` | `""` | 空则用 Yunzai 的 `chromium_path` | | `spark.screenshotOnFail` | `true` | 失败时整页截图存 `data/screenshots` | | `spark.blockResources` | `true` | 拦截图片/字体/媒体请求(样式表不拦,否则元素塌成 0×0) | | `spark.blockTracking` | `true` | 额外拦掉 app_log、slardar、推荐流等接口 | | `spark.cookieCheckTTL` | `30` | Cookie 检查结论缓存分钟数,0 = 不缓存 | | `spark.friendsCacheTTL` | `240` | 会话(好友)列表缓存分钟数,面板上可绕过。0 = 每次都真拉 | | `spark.browserIdleClose` | `60` | 页面全关完后多久收掉浏览器实例(秒),释放 200~400MB。0 = 一直留着 | | `push.enable` | `true` | 跑完是否推送结果 | | `push.target` | `both` | `group` 只推群 / `friend` 只私聊 / `both` 两边都推 | | `push.mode` | `detail` | `detail` 逐条列出 / `summary` 只报数量 | | `push.onlyOnFail` | `false` | 开启后一切正常时保持静默 | | `push.groups` / `friends` | `[]` | `{botId, groupId}` / `{botId, userId}`,botId 留空 = 用执行续火的那台 | | `web.enable` | `true` | 面板总开关(改动需重启) | | `web.base` | `/douyin` | 挂载路径(改动需重启) | | `web.port` | `0` | 0 = 复用 Yunzai 端口(改动需重启) | | `web.url` | `""` | 对外地址,反代时填 | | `web.codeTTL` / `sessionTTL` | `300` / `1800` | 验证码 / 会话有效期(秒) | | `web.rateWindow` / `rateGeneral` / `rateAuth` | `60` / `300` / `8` | 限流窗口与两个桶的配额 | | `web.banAfter` | `12` | 鉴权失败几次后拉黑 IP | | `web.auditKeep` | `500` | 审计日志保留条数 | | `web.maskLinkInGroup` | `true` | 群里回复面板地址时给主机与端口打码。用公网 IP 直连的务必开启 | | `chat.enable` | `true` | 私信聊天总开关。关掉则面板无入口、接口 403,已开会话立刻收掉(记录不删) | | `chat.idleCloseSec` | `180` | 多久没人轮询就自动关掉聊天页(秒) | | `chat.pollMs` | `3000` | 前端拉新消息的间隔(毫秒)。只读本地页面,不向抖音发请求 | | `chat.historyLimit` | `60` | 进会话时一次给多少条历史;往上翻页每次再给 40 条 | | `chat.maxLength` | `500` | 单条消息字数上限 | | `security.allowManualCookie` | `true` | 关掉则只能扫码登录 | | `security.maskCookie` | `true` | 接口返回里的 Cookie 打码 | | `security.qrLoginTimeout` | `180` | 扫码等待上限(秒),从二维码真正发出那一刻起算 | | `security.deleteCookieFile` | `true` | 解析完立刻删掉收到的 Cookie txt | | `security.remoteVerify` | `true` | 抖音要验证时私信一个远程操作页面,关掉则退回替代方案 | | `security.autoSms` | `false` | 让 `#抖音登录` 也自动接管短信验证(会真发一条短信) | | `security.verifyTimeout` | `600` | 进入验证态后的等待上限(秒) | | `security.verifyBindIp` | `true` | 验证链接绑定首次访问的 IP | | `render.image` | `true` | 帮助/设置/状态是否出图 | | `render.scale` | `1` | 渲染倍率(在 900px 版面 ×1.4 的基准上再乘) | | `update.autoRestart` | `true` | `#抖音更新` 成功后自动重启 | | `update.logLimit` | `20` | 更新日志展示的 commit 上限 | | `debug.enable` | `false` | 调试日志:登录与续火每一步记一行,Cookie 值不进日志 | | `debug.snapshot` | `false` | 现场快照:截图、纯文本、完整 HTML 存 `data/debug/`,需先开 `debug.enable` | | `debug.keep` | `200` | `data/debug/` 最多保留的文件数,0 = 不清理 | ## 安全要点 - Cookie 以 AES-256-GCM 加密存储,密钥在 `data/secret.key`;接口与日志里的 Cookie 一律打码 - 面板仅主人可开,验证码一次性、5 分钟过期、只授权「你是主人」的那些机器人 - 面板链接与远程验证链接**只私信**发,群里默认给主机与端口打码 - 验证码走 URL 的 hash 而非 query —— hash 不发给服务端,不进 access log、不随 Referer 外泄 - 远程验证页与主面板是两套权限,只能操作那一次登录的页面,没有执行任意脚本的入口 - 账号按机器人分文件,跨机器人读、删、跑都会失败 - 验证码、会话、IP 封禁全在内存里,重启即全部失效 完整说明见 [问题解决.md 的「安全说明」](问题解决.md#安全说明)。 ## 遇到问题 先看 **[问题解决.md](问题解决.md)**,里面按现象分好了条目:搜不到好友、Cookie 频繁失效、二维码不出、扫码确认了没反应、远程验证页点不动、聊天看不到历史、重启后多一个 Chromium…… 想知道到底停在哪一步:`#抖音设置 调试 开` 再跑一次,Yunzai 日志里每一步都有一行 `[调试]` 前缀的记录。查完记得关掉。 ## License [MIT](LICENSE)