🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

抖音私信桥 pcmxiao/dsh-douyin-bridge

DeepSeek 客户端
pcmxiao8 天前有提交已提供中文文档扫描:含敏感能力兼容 / 相关生态

把抖音私信接入会话,让智能体收发消息并刷视频

30.4/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/30 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/pcmxiao/dsh-douyin-bridge.git

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么[目录]—
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
暂无时间戳·判据 →
装得上吗[实装验证]—
本站尚未做安装检查
暂无时间戳·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/03·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 8 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 75 处,展示前 64 条)
  • 读取本地文件
    index.js:51
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true })
  • 写入本地文件
    index.js:51
    if (!existsSync(dir)) mkdirSync(dir, { recursive: true })
  • 读取本地文件
    index.js:54
    try { prev = JSON.parse(readFileSync(file, 'utf8')) } catch { }
  • 写入本地文件
    index.js:55
    writeFileSync(file, JSON.stringify({ ...prev, ...data, at: new Date().toISOString() }, null, 2))
  • 读取本地文件
    index.js:182
    if (existsSync(p)) {
  • 读取本地文件
    index.js:183
    const t = readFileSync(p, 'utf8')
  • 读取本地文件
    index.js:646
    if (!existsSync(file)) return { ok: false, error: `图片不存在:${file}` }
  • 写入本地文件
    index.js:666
    try { mkdirSync(dir, { recursive: true }) } catch { }
  • 写入本地文件
    index.js:669
    writeFileSync(out, buf)
  • 发起网络请求
    client.js:46
    const jget = async (p) => asJson(await fetch(API + p, { credentials: 'same-origin' }))
  • 发起网络请求
    client.js:47
    const jpost = async (p, body) => asJson(await fetch(API + p, {
  • 读取本地文件
    lib/douyin.mjs:2192
    if (!existsSync(path)) return { ok: false, error: `图片不存在:${path}` }
  • 读取本地文件
    lib/stickers.mjs:41
    if (!existsSync(STICKER_DIR)) mkdirSync(STICKER_DIR, { recursive: true })
  • 写入本地文件
    lib/stickers.mjs:41
    if (!existsSync(STICKER_DIR)) mkdirSync(STICKER_DIR, { recursive: true })
  • 读取本地文件
    lib/stickers.mjs:50
    const raw = readFileSync(INDEX, 'utf8')
  • 写入本地文件
    lib/stickers.mjs:61
    writeFileSync(INDEX, JSON.stringify(arr, null, 2))
  • 发起网络请求
    lib/stickers.mjs:119
    const res = await fetch(src, { headers: { 'user-agent': UA } })
  • 写入本地文件
    lib/stickers.mjs:162
    writeFileSync(abs, buf)
  • 读取本地文件
    lib/stickers.mjs:250
    return existsSync(p) ? p : ''
  • 读取本地文件
    lib/stickers.mjs:264
    if (existsSync(p)) unlinkSync(p)
  • 删除本地文件
    lib/stickers.mjs:264
    if (existsSync(p)) unlinkSync(p)
  • 读取本地文件
    lib/stickers.mjs:277
    if (existsSync(p)) bytes += statSync(p).size
  • 读取本地文件
    lib/stickers.mjs:277
    if (existsSync(p)) bytes += statSync(p).size
  • 写入本地文件
    lib/state.mjs:82
    try { mkdirSync(d, { recursive: true }) } catch { }
  • 读取本地文件
    lib/state.mjs:91
    if (existsSync(paths.config)) raw = JSON.parse(readFileSync(paths.config, 'utf8')) || {}
  • 读取本地文件
    lib/state.mjs:91
    if (existsSync(paths.config)) raw = JSON.parse(readFileSync(paths.config, 'utf8')) || {}
  • 写入本地文件
    lib/state.mjs:105
    writeFileSync(tmp, JSON.stringify(cfg, null, 2), 'utf8')
  • 写入本地文件
    lib/state.mjs:106
    renameSync(tmp, paths.config)
  • 读取本地文件
    lib/state.mjs:118
    if (!existsSync(paths.sessions)) return emptyMap()
  • 读取本地文件
    lib/state.mjs:119
    const raw = JSON.parse(readFileSync(paths.sessions, 'utf8'))
  • 写入本地文件
    lib/state.mjs:132
    writeFileSync(tmp, JSON.stringify(map, null, 2), 'utf8')
  • 写入本地文件
    lib/state.mjs:133
    renameSync(tmp, paths.sessions)
  • 读取本地文件
    lib/state.mjs:207
    const prev = existsSync(paths.log) ? readFileSync(paths.log, 'utf8') : ''
  • 读取本地文件
    lib/state.mjs:207
    const prev = existsSync(paths.log) ? readFileSync(paths.log, 'utf8') : ''
  • 写入本地文件
    lib/state.mjs:218
    writeFileSync(paths.log, lines.join('\n') + '\n', 'utf8')
  • 读取本地文件
    lib/browser.mjs:53
    if (explicit && existsSync(explicit)) return explicit
  • 读取本地文件
    lib/browser.mjs:55
    if (existsSync(p)) return p
  • 读取本地文件
    lib/browser.mjs:62
    if (existsSync(f)) return f
  • 执行外部命令固定命令
    lib/browser.mjs:98
    execFile('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', script], {
  • 写入本地文件
    lib/browser.mjs:239
    mkdirSync(this.userDataDir, { recursive: true })
  • 执行外部命令来自配置/变量
    lib/browser.mjs:241
    this.proc = spawn(this.exe, [
  • 发起网络请求
    lib/browser.mjs:290
    const r = await fetch(`${this.base}/json/version`, { signal: AbortSignal.timeout(2000) })
  • 发起网络请求
    lib/browser.mjs:304
    const r = await fetch(`${this.base}/json/version`, { signal: AbortSignal.timeout(2000) })
  • 读取本地文件
    lib/browser.mjs:679
    for (const f of readdirSync(dir)) {
  • 删除本地文件
    lib/browser.mjs:681
    try { rmSync(join(dir, f), { force: true }) } catch { }
  • 读取本地文件
    lib/douyin-api.mjs:375
    const raw = readFileSync(cacheFile, 'utf8')
  • 写入本地文件
    lib/douyin-api.mjs:388
    writeFileSync(cacheFile, JSON.stringify(obj), 'utf8')
  • 读取本地文件
    lib/session-history.mjs:78
    if (!existsSync(root)) return ''
  • 读取本地文件
    lib/session-history.mjs:80
    for (const ws of readdirSync(root)) {
  • 读取本地文件
    lib/session-history.mjs:82
    if (existsSync(d)) return d
  • 读取本地文件
    lib/session-history.mjs:99
    if (!existsSync(file)) return { ok: false, events: [], error: `没有 ${file}` }
  • 读取本地文件
    lib/session-history.mjs:103
    const raw = readFileSync(file)
  • 读取本地文件
    lib/session-history.mjs:219
    if (!existsSync(root)) return []
  • 读取本地文件
    lib/hostdeps.mjs:66
    for (const n of readdirSync(join(npm, '@deepseek-ai'))) {
  • 读取本地文件
    lib/hostdeps.mjs:79
    for (const p of readdirSync(join(dshHome, 'profiles'))) {
  • 读取本地文件
    lib/hostdeps.mjs:94
    if (!existsSync(pkgFile)) return null
  • 读取本地文件
    lib/hostdeps.mjs:95
    const pkg = JSON.parse(readFileSync(pkgFile, 'utf8'))
  • 读取本地文件
    lib/hostdeps.mjs:102
    return existsSync(file) ? pathToFileURL(file).href : null
  • 读取本地文件
    selfcheck.mjs:43
    if (!existsSync(p)) bad(`缺 ${f}`)
  • 读取本地文件
    selfcheck.mjs:44
    else if (statSync(p).size === 0) bad(`${f} 是空的`)
  • 读取本地文件
    selfcheck.mjs:55
    if (!existsSync(p)) continue
  • 读取本地文件
    selfcheck.mjs:59
    const src = readFileSync(p, 'utf8')
  • 读取本地文件
    selfcheck.mjs:81
    pkg = JSON.parse(readFileSync(join(ROOT, 'package.json'), 'utf8'))
  • 读取本地文件
    selfcheck.mjs:100
    const yml = readFileSync(join(ROOT, 'cordis.patch.yml'), 'utf8')
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DSH 插件:把抖音私信接进 DSH —— 私信进 DSH 会话,AI 用工具刷视频、分享、聊天(含图片/表情收发)。仅供学习研究。

README

由 DeepSeek 最新模型翻译生成
dsh-douyin-bridge(刷抖音) 把抖音私信接进 DSH。 好友在抖音给你发消息 → 消息进 DSH 会话 → 智能体拿到上下文 → 智能体用工具反过来刷视频、分享、把话回过去。 抖音私信 DSH ┌───────────────┐ ┌──────────────────────┐ │ 好友的消息 │──── 读 ─────────────▶│ 注入 → 会话 → LLM │ │ │ │ │ │ 视频卡片 │◀─── 分享 / 回话 ──────│ douyin_* 工具 │ └───────────────┘ └──────────────────────┘ ▲ 会话数据全在这里 它解决的是什么问题 qq-bridge 那套是:QQ 客户端 → SnowLuma(OneBot 网关)→ DSH → LLM,会话数据全在 DSH 里。 抖音没有这种现成的网关。
展开完整文档(README 剩余 1 节)
dsh-douyin-bridge(刷抖音)

把抖音私信接进 DSH。

好友在抖音给你发消息 → 消息进 DSH 会话 → 智能体拿到上下文 → 智能体用工具反过来刷视频、分享、把话回过去。

抖音私信 DSH ┌───────────────┐ ┌──────────────────────┐ │ 好友的消息 │──── 读 ─────────────▶│ 注入 → 会话 → LLM │ │ │ │ │ │ 视频卡片 │◀─── 分享 / 回话 ──────│ douyin_* 工具 │ └───────────────┘ └──────────────────────┘ ▲ 会话数据全在这里

它解决的是什么问题

qq-bridge 那套是:QQ 客户端 → SnowLuma(OneBot 网关)→ DSH → LLM,会话数据全在 DSH 里。

抖音没有这种现成的网关。这个项目做的就是那一层:

| | QQ 那套 | 这个项目 |
| IM 侧网关 | SnowLuma(现成) | 本插件自带(浏览器 DOM 操作) |
| 桥接形态 | MCP server + 桥接进程 | DSH 插件(宿主半 + 浏览器半) |
| 消息进 DSH | session/prompt | 注入 DSH 会话(agent/inbox/spliced + user/message) |
| 会话数据在哪 | DSH | DSH(本插件只留映射和去重指纹) |
| LLM 侧动作 | mcp__snowluma__ 工具 | douyin_ 工具 |

也就是说:这个插件扮演的是 SnowLuma 的角色,只不过桥的是抖音私信而不是 QQ,而且它直接长在 DSH 里,所以会话数据天然落在 DSH 的 session 日志中。

装

本地开发
dsh plugin --profile desktop add link:<这个目录>

或从 npm
dsh plugin --profile desktop add dsh-douyin-bridge

装完重启一次 DSH(bundle 层要重启才组装)。

然后:

1. 打开 设置 → 刷抖音
2. 点 「打开浏览器登录」 —— 会弹出一个抖音网页版的 Edge/Chrome 窗口
3. 在那个窗口里扫码登录(用你要跟人聊的那个号)
4. 别关那个窗口(登录态靠它)

之后它自己就开始轮询了。

💡 窗口关掉了不会再自己弹回来。
你要是手动把浏览器关了,桥会停下来(不会每隔几秒弹一个窗口骚扰你),日志里会写「浏览器窗口被关掉了 —— 桥接暂停」。
想让它回来:再点一次 「打开浏览器登录」,或者 POST /dsh-douyin-bridge/start。
浏览器自己崩了的话会自动重连(30 秒一次,最多 3 次)。

⚠️ 桌面版(Electron)的配置档只能由应用自己管。
dsh plugin --profile desktop … 会直接报
profile "desktop" is managed exclusively by the Electron application。
桌面版请在 设置 → 插件 里装,或者用 tools/dsh-rpc.mjs 调 pluginManager/installBundle(见 tools/README.md)。

排障:装上了但没反应

① 插件真的激活了吗(看 fiberPhase 是不是 active)
node tools/dsh-rpc.mjs pluginManager/listPlugins "{}" | grep -A2 douyin

② 桥接活着吗
node tools/dsh-rpc.mjs GET /dsh-douyin-bridge/status

③ 浏览器登录了没、会话列表读得到吗
node tools/dsh-rpc.mjs POST /dsh-douyin-bridge/stop
node tools/probe.mjs

如果 fiberPhase 是 failed,最常见的原因是读了没声明 inject 的服务: cordis 对 ctx.agents 这种没声明过的服务是抛异常(不是返回 undefined),插件直接不激活,而且这条错误不进任何日志文件。改完代码先跑:

node tools/_load-test.mjs # 用假 ctx 复现 cordis 的 Proxy 陷阱

配置

真正的配置在 $DSH_HOME/douyin-bridge/config.json(不在插件目录里,升级重装不会丢)。设置页能改的:

| 项 | 默认 | 意思 |
| mode | simulation | simulation = AI 自己决定要不要回;mirror = AI 的每条回复自动发回抖音;off = 只给工具,不自动注入 |
| peers | [] | 好友白名单。空 = 所有会话都进 DSH(自己发的消息永不回灌) |
| sharePeers | [] | 允许把视频分享给谁。空 = 跟随 peers |
| pollIntervalMs | 20000 | 轮询间隔。别调太短(见下面的风控提示) |
| maxInjectChars | 4000 | 单条注入消息的字符上限 |
| autoReply | true | 收到新消息时自动唤醒智能体 |
| browserPort | 47881 | CDP 端口 |
| userDataDir | <家目录>/profile | 浏览器配置档(登录态在这里) |
peers 建议填上。 留空 = 所有会话都进 DSH,等于把你整个私信列表喂给模型。

工具(LLM 侧)

| 工具 | 干什么 |
| douyin_search | 搜视频 |
| douyin_detail | 读视频详情(完整文案正文、作者、时长、统计、话题) |
| douyin_share | 分享视频到私信(可捎一句话 note) |
| douyin_comment_list | 列出某个视频下的评论(挑要处理的那一条) |
| douyin_comment_post | 在视频下发评论 |
| douyin_comment_share | 把某条评论分享给某个好友(对方收到评论卡片) |
| douyin_dm_list | 列出会话 |
| douyin_dm_read | 读某个好友的私信(图片/表情/语音/位置/视频/分享卡片都会标出类型) |
| douyin_dm_send | 发私信(纯文本) |
| douyin_dm_send_image | 发图片(本机文件,或 base64) |
| douyin_dm_send_emoji | 发表情(按名字,支持部分匹配) |
| douyin_sticker_grab | 把视频评论区里的表情收集到本地表情库 |
| douyin_sticker_list | 看本地表情库 |
| douyin_sticker_send | 从本地表情库发一个给好友 |
| douyin_sticker_remove | 从库里删一个 |
| douyin_history | 读某个好友的完整历史(从 DSH 会话日志,不受抖音虚拟列表限制) |
| douyin_duty | 读值班章程 |
| douyin_status | 看桥接状态(含当前模型、附件服务有没有挂上) |
| douyin_whoami | 看登录态 |
| douyin_login | 打开浏览器登录 |
| douyin_selftest | 选择器自检(改版时先跑这个) |

douyin_share / douyin_dm_send / douyin_dm_send_image / douyin_dm_send_emoji
的 to 留空 = 当前会话对应的好友,所以在某个好友的会话里聊天时不用传参数。

发送类工具受白名单约束:peers 配了就只有名单里的人能收到消息。

评论区

douyin_comment_list → douyin_comment_post / douyin_comment_share 是三步走:

douyin_comment_list { video: "7697459346984897955" }
→ { comments: [ { i: 0, author: "…", text: "…", hasShare: true }, … ] }

douyin_comment_post { video: "…", text: "这条猫也太可爱了" }
→ { ok: true, posted: true, comment: "…" }

douyin_comment_share { video: "…", index: 0, to: "某个好友" }
→ { ok: true, sent: true, target: "某个好友" }

分享出去的评论,好友那边会收到一条卡片,内容形如 分享 @某人 的评论 「…」,来自视频 「…」。

⚠️ 发评论会被抖音要求人机验证(新号常见)。工具会返回 { ok: false, code: "NEEDS_VERIFY" } 并带上被遮的手机号尾号;到浏览器里把短信验证码填了点「验证」之后,这个号就能正常发评论了。
这不是 bug,是抖音的风控,代码绕不过去。

本地表情库

抖音没有收藏表情的接口,UI 上也没有入口(表情面板只有「表情 / GIF」两个 tab,格子上 hover、右键都没反应)。所以这里走的是另一条路:

douyin_sticker_grab { video: "…" }
→ 把评论区里的表情图全抓下来,存进本地库
→ { ok: true, candidates: 32, saved: 32, library: { total: 32, kinds: {…} } }

douyin_sticker_list { query: "猫" }
→ { stickers: [ { id: "3bf853fc8482", name: "1f49a", ext: ".png" }, … ] }

douyin_sticker_send { sticker: "3bf853fc8482", to: "某个好友" }
→ { ok: true, verified: true }

为什么这条路是稳的:

- 评论区里的表情本身就是普通 CDN 图片(p*-pc-sign.douyinpic.com、 byteimg.com/…/twemoji/),Node 直接 fetch 就是 200,连 referer 都不用带
- 发送复用已经跑通的发图链路(sendImage),不需要碰表情面板
- webp 会自动转 png —— 抖音的上传控件不认 webp,塞进去只会得到「选完文件后没弹出发送确认框」,而且报错完全不提格式

库落在 $DSH_HOME/douyin-bridge/stickers/,index.json 是清单,图片按内容指纹命名(同一张图只存一份)。

图片是真的给模型看

对方发来图片时,桥接会:

1. 从 DOM 里把图片的 data: URL 抠出来(抖音网页端自己就把图转成 base64 内联了)
2. 用 attachments.saveImages() 存进 DSH 的附件库
3. 在注入的消息里挂一个 {type:'image', attachment: ref} 块

模型收到的是图片本身,不是「[图片 200×150]」这行字。

⚠️ 前提是模型支持图像输入。文本模型收到 image 块时,DSH 会把它换成一句 [image omitted because this model accepts text only; …],模型只看到一串 sha。

查当前模型支不支持:

curl "http://127.0.0.1:<DSH端口>/dsh-douyin-bridge/models" # 看 canSeeImagebash
curl "http://127.0.0.1:<DSH端口>/dsh-douyin-bridge/status" # 看 agentModel / attachments

如果 canSeeImage 是 false,在 profile 的 cordis.patch.yml 里给那个模型补一行(dsh-llm-pi-ai 的 catalog 不一定标对了能力,实测 MiniMax 就是漏标的): yaml
- id: llm-pi-ai
config:
providers:
<provider>:
models:
- id: <model>
input: [text, image] # ← 补这个

改完不用重启,llm.listModels() 会立刻读到新值。

值班章程

prompts/duty.md 是注入进桥接会话的系统提示(怎么回话、什么时候分享、什么不做)。
你可以直接改它,改完新会话立刻生效。

数据落在哪

| 数据 | 位置 |
| 对话正文 | DSH 的 session 日志(~/.dsh/sessions/...) |
| 好友名 ↔ session id 映射 | $DSH_HOME/douyin-bridge/sessions.json |
| 消息去重指纹 | 同上 |
| 配置 | $DSH_HOME/douyin-bridge/config.json |
| 抖音登录态 | $DSH_HOME/douyin-bridge/profile/ |
| 运行日志 | $DSH_HOME/douyin-bridge/bridge.log |

这个插件不另存对话副本。 会话数据全在 DSH 里 —— 这是它跟一堆「自己搞个 jsonl 存聊天记录」的玩具脚本最本质的区别。

已知限制

- 抖音改版就会失效。 本仓库的 DOM 选择器都是 2026-10 实测的。
失效时先跑 node tools/probe-canary.mjs 看哪条降级链挂了。
- 视频页会被风控挡掉。 短时间开太多视频页会被重定向到 /jingxuan,分享会失败。插件返回 VIDEO_UNAVAILABLE,不会假装成功。
- 私信面板需要够宽的屏幕。 视口 <1800 CSS px 时面板渲染成 0×0。
屏幕本身不够宽的话(比如 1920 物理 + 125% 缩放 = 1536 CSS px),把系统缩放调到 100%。
- 轮询别太频繁。 20 秒一轮是实测能用的节奏;5 秒一轮大概率触发风控。
- 私信只能读最近一屏(虚拟列表),历史要靠 scrollBack 往上滚。
想看完整历史用 douyin_history(读 DSH 会话日志,不受这个限制)。
- mirror 模式有重复发的风险:agent 自己调 douyin_dm_send 发的内容也会被 mirror 回发一遍。同一时刻只用一种模式。
- 发评论会触发人机验证。 新号在抖音发评论经常弹短信验证码,工具会报 NEEDS_VERIFY 而不是假装成功;人工过一次之后这个号就正常了。
- 分享评论只在视频页布局下能展开「分享给朋友」(/video/<id>)。
沉浸式浮层(?modal_id=)里点「分享」点不开 —— 所以这两个动作走的是两条打开策略。
- 语音只能读、不能发。 网页端没找到发送入口。

想改代码?

抖音的页面结构、cordis 的坑、媒体的坑,全在 PITFALLS.md。
30 条,都是实测撞出来又修掉的 —— 改之前先扫一眼,能省很多时间。

几条最要命的先放这:

- ctx.agents 读一下就抛异常(不是 undefined),整条插件会不激活,而且不报错
- 改浏览器窗口大小会把私信面板关掉
- 发消息只看「输入框空不空」会假成功 —— 输入框可能在视口外,insertText 静默失败

隐私与合规

先读 DISCLAIMER.md。 摘要:

- 本项目只用于学习研究,使用后果由使用者自行承担
- 你必须自行遵守抖音的平台规则和适用法律法规
- 插件会读你的私信 ⇒ 好友的消息会进模型上下文,你选的模型服务商看得到
- 推到 GitHub 之前自己查一遍隐私(DISCLAIMER 里给了自查命令)

致谢与许可

MIT。实现上参考了 dsh-bili-scroll(同为 MIT)与 DSH 内置的插件开发指引,详见 NOTICE.md。
预览分享卡片长什么样 ↓pcmxiao/dsh-douyin-bridge
分享 · DeepSeek Harness Hub
pcmxiao/dsh-douyin-bridge

把抖音私信接入会话,让智能体收发消息并刷视频

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部