抖音智能客服自动化:评论与私信自动化回复功能

从评论区的通知入口,到私信列表的红点标记,我用一套 Chrome 扩展实现了抖音全场景的自动回复。这篇文章拆解完整流程图、关键技术细节和踩过的坑。


1. 系统全景

抖音创作者后台
├── 通知入口 → 评论区自动回复
│   ├── 筛选"全部消息" → "评论"
│   ├── 检测最新评论
│   ├── 关键词匹配 / 默认回复 / 随机回复 / AI 回复
│   └── 支持收藏表情回复
│
└── /user/self → 私信自动回复
    ├── 陌生人消息 → 自动回关
    ├── 小红点检测 → 未读消息
    ├── 多版本 DOM 适配 → 提取昵称和内容
    ├── 关键词匹配 / 默认回复 / AI 回复
    └── 自动关闭会话,避免干扰

2. 评论区自动回复

2.1 入口定位

评论通知藏在右上角 “通知” 按钮的下拉面板里,需要 hover 才能触发:

点击 notifyBtn = find('//p[text()="通知"]')
if (notifyBtn 存在) {
    hover(notifyBtn)   // 悬停展开下拉面板
    wait 1秒

2.2 筛选链路:两步到位

通知面板里消息类型混杂——关注、点赞、@我、评论全在一起。需要两步筛选才能精准拿到评论:

// 第一步:打开下拉筛选项
click( filterDropdown )
click( dropdownList 中 "全部消息" )

// 第二步:切到评论
click( filterDropdown )
click( dropdownList 中 "评论" )

为什么分两步? 实测直接从”通知”切”评论”偶现不生效,先切”全部消息”再切”评论”是最稳定的路径。

2.3 提取最新评论

nickname = 第一条评论中的用户昵称
content  = 第一条评论中的文本内容

2.4 去重:内容比对

current = nickname + ":" + content
if (上一次记录 != "" && 上一次记录 != current) {
    // 是新消息,触发处理流程
}
上一次记录 = current

用简单的字符串比对代替互斥锁——轻量且可靠。

2.5 回复流程

// 1. 先勾住消息
showPopup(current)     // 浮动弹窗提示
hook(nickname, content) // 转发到外部系统

// 2. 点击评论内容,展开回复输入框
click(第一条评论的文本区域)

// 3. 等待"回复"按钮出现(最多6秒)
replyBtn = waitFor( '回复按钮', 6000ms )
click(replyBtn)

// 4. 按优先级决定回复内容
reply = 关键词匹配(content)
    || 默认回复
    || 随机回复
    || AI回复(nickname, content)

回复优先级:关键词 → 默认配置 → 随机池 → AI

2.6 收藏表情的特殊处理

回复内容支持 收藏表情N 格式,N 指收藏表情列表中的序号:

if (reply 匹配 /^收藏表情(\d+)$/) {
    // 点击表情面板按钮
    click( 表情按钮 )
    // 切换到收藏表情 Tab
    click( 收藏表情Tab )
    // 选择第 N 个
    click( 第N个收藏表情 )
} else {
    // 普通文本输入
    input( 输入框, reply )
}

// 点击发送
click( 发送按钮 )

3. 私信自动回复

3.1 页面隔离

私信逻辑只在创作者后台执行,其他页面不触发:

if (当前URL 以 "https://www.douyin.com/user/self" 开头) {
    执行私信流程
}

3.2 会话管理:先清场

进入私信列表后,先把上一次残留的会话面板关掉,确保从干净状态开始:

// 确保私信列表面板打开
if (列表面板未打开) {
    hover( 私信按钮 )
}

// 关闭上次可能残留的会话
click( "关闭会话" )
click( "退出会话" )
click( 返回按钮 )

3.3 陌生人自动回关

抖音把陌生人消息放在独立分组。脚本检测后自动回关:

strangerTab = find( '//div[text()="陌生人消息"]' )
if (strangerTab 存在) {
    click(strangerTab)
    click( 第一条陌生人会话 )
    click( "回关"按钮 )
    click( 详情页中的"关注"按钮 )
}

3.4 未读消息检测:小红点

抖音私信使用 Semi Design 组件库,未读标记是 semi-badge-count 样式的数字 badge:

badge = find( '私信对话框中带 semi-badge-count 类名的 span' )
if (badge 存在) {
    click(badge)    // 点进未读会话

3.5 消息内容提取:四路降级

私信页面的 DOM 结构因 A/B 实验存在多个版本,提取消息内容用了四级 fallback:

content = tryXpath('版本A的消息选择器')
       || tryXpath('版本B的消息选择器')

if (content 为空) {
    content = tryXpath('版本C的消息选择器')
           || tryXpath('版本D的消息选择器')
}

nickname = tryXpath('版本A的昵称选择器')
        || tryXpath('版本B的昵称选择器')

昵称和消息内容都存在多版本适配,确保任何一个页面变体都能正确提取。

3.6 输入与发送:双路径适配

不同版本下输入框和发送按钮的 DOM 结构也不同:

// 输入框
textarea = find( '版本A的输入框路径' )
if (textarea 存在) {
    input( 版本A路径, reply )
} else {
    input( 版本B路径, reply )
}

// 发送按钮
sendBtn = find( '版本A的发送按钮' )
if (sendBtn 不存在) {
    sendBtn = find( '版本B的发送按钮' )
}
click(sendBtn)

3.7 处理完收尾

回复后关闭会话,恢复干净状态,避免面板残留影响下一轮轮询:

click( "关闭会话" )
click( "退出会话" )
click( 返回按钮 )

4. 统一消息分发

评论和私信共享同一套钩子函数:

// 浮动提示
showPopup( 昵称 + ":" + 内容 )

// 转发到外部客服系统 / 记录日志
hook(昵称, 内容, 头像)

hook 函数是插件与外部系统的桥梁,负责把消息推送到客服工单系统或写入数据库。


5. 回复决策树

新消息到达
├── 关键词匹配命中 → 直接回复
│   ├── 收藏表情格式 → 发送表情
│   └── 普通文本 → 输入框 + 点发送
├── 默认回复已配置 → 直接回复
├── 随机回复池有内容 → 随机选一条回复
└── 以上都不满足 → 调用 AI
    ├── Coze Bot(会话缓存 + 异常自动重建)
    └── FastGPT(兼容 /chat/completions 和 /responses 双格式)

6. 架构一览

模块关键设计
评论区hover 触发面板、两步筛选锁定评论、收藏表情发送
私信URL gating、小红点检测、陌生人自动回关、多版本 DOM 适配
回复引擎关键词 → 默认 → 随机 → AI 四级降级链
AI 接入Coze + FastGPT 双后端,异常时自动清除会话重建
会话管理处理前后显式开关面板,不依赖页面自动行为
去重字符串比对代替互斥锁,轻量可靠

7. 设计原则

  1. 面板生命周期显式管理 — 打开 → 操作 → 关闭,每步都不假设页面会自动清理
  2. 操作间必须 sleep — 抖音的虚拟 DOM 需要时间 diff,不等就找不到元素
  3. 先清场再干活 — 开始任何操作前先关掉残留面板,从零开始
  4. 去重用比对而非加锁 — 内容字符串比对简单且不会死锁
  5. 每个选择器都有备胎 — 评论区、私信、输入框、发送按钮,全部做了 fallback
  6. 回复有兜底 — 关键词不命中、默认没配置、随机池为空,最终落到 AI,保证不会冷落用户

阶段一:评论区入口

  1. 循环开始,判断当前在创作者后台页面
  2. 找到”通知”按钮,hover 悬停展开下拉面板
  3. 两步筛选——先切”全部消息”,再切”评论”
  4. 提取第一条评论的昵称和内容
  5. 和上一条消息比对,相同就跳过,不同就进入回复流程

阶段二:评论回复

  1. 弹窗提示 + hook 转发到外部系统
  2. 点击评论内容 → 等待”回复”按钮出现(最多 6 秒)
  3. 按优先级决策回复:关键词 → 默认 → 随机 → AI
  4. 判断回复类型——收藏表情就走表情链路,普通文本就走输入框
  5. 点击发送 → 关闭评论面板 → 按 ESC 退出

阶段三:私信入口

  1. 判断 URL 是 /user/self,不是就结束本轮
  2. 展开私信面板 → 清场(关闭会话、退出会话、返回列表)

阶段四:陌生人处理

  1. 检测是否有”陌生人消息”分组
  2. 有就自动点击 → 回关 → 关注

阶段五:未读消息检测

  1. 查私信列表是否有红点 badge
  2. 没有就收尾退出,有就点击红点进入会话

阶段六:私信内容提取

  1. 昵称提取:选择器 A,不行就选择器 B
  2. 消息提取:选择器 A/B → A 或 B 不行就 C/D

阶段七:私信回复

  1. 弹窗提示 + hook 转发
  2. 同样的四级降级决策:关键词 → 默认 → 随机 → AI
  3. 输入框双路径适配:A 版本不行用 B 版本
  4. 发送按钮双路径适配
  5. 点击发送 → 关闭会话 → 退出会话 → 返回列表 → 本轮结束
程序员老狼

程序员老狼

新浪前高级开发工程师,Golang、PHP 全栈开发者,十余年后端架构实战经验。自研唯一客服系统及配套浏览器自动化插件,专注企业客服生态与 RPA 自动化技术。

了解更多 → 企业备案域名 · 聊城变量网络科技有限公司