Skip to content
Agentmart
Submit a tool

tiktok-post-comment

Use when an agent needs to post a single comment under a specific TikTok video by URL — handles Draft.js editor state, submit verification, and ambiguous…

Skill by 271642183

IndexedMIT
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/271642183-tiktok-post-comment

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Use when an agent needs to post a single comment under a specific TikTok video by URL — handles Draft.js editor state, submit verification, and ambiguous duplicate detection (no auto-retry to avoid rate limits)

Use cases: agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found
Runs as
Node.js package

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/tiktok-post-comment

What's inside

Skill name
tiktok-post-comment
Description
Use when an agent needs to post a single comment under a specific TikTok video by URL — handles Draft.js editor state, submit verification, and ambiguous duplicate detection (no auto-retry to avoid rate limits)
License
MIT
Instructions
156 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts

Files (2)

  • SKILL.md
  • probe-deep.mjs · scripts/

SKILL.md (first lines)

## ⚠️ Selector 状态

以下 selector 已通过 `skills/tiktok-post-comment/scripts/probe-deep.mjs` 探测 + 端到端验证。selector 失效 → 重跑 probe,不盲猜。

```yaml
COMMENT_TAB_SELECTOR:      'button[data-testid="tux-web-tab-bar"]'   # 评论 tab;query 后用 JS 过滤 innerText === '评论'
COMMENT_LIST_SELECTOR:     '[class*="DivCommentListContainer" i]'    # 评论流容器(lazy-loaded,需先点 tab)
COMMENT_INPUT_SELECTOR:    '.DraftEditor-root [contenteditable="true"]'  # 评论输入框
COMMENT_SUBMIT_SELECTOR:   'button[data-e2e="comment-post"]'         # 发布按钮
COMMENT_ITEM_SELECTOR:     '[class*="DivCommentObjectWrapper" i]'    # 单条评论
CAPTCHA_SELECTOR:          '[class*="captcha" i]:not([class*="Badge" i]), iframe[src*="captcha" i], iframe[src*="verify" i], [class*="SliderCaptcha" i], [class*="challenge" i]'  # 排除认证徽章装饰元素
```

## 前置条件

1. `chrome-devtools` CLI 在 PATH(由 `lib.mjs:ensureCli()` 校验)
2. daemon 已启动,TikTok 独立 profile
3. `tiktok-ensure-login` 返回 `logged_in = true`
4. `video_url` 通过 `tiktok-browser-navigate-to-video` 校验并成功导航
5. **拒绝空评论**:`content.trim()` 为空 → 立即返回 `reason: 'empty_content'`
6. **拒绝超长评论**:评论 > 150 Unicode code points(emoji 算 1 个)直接失败,不自动截断(挡用户写作意图)

## 操作步骤

### 0. 内容校验

不调任何浏览器 API,纯本地校验:

- `content.trim() === ''` → 立即返回 `{ submitted: false, verified: false, reason: 'empty_content', next_action: '提供非空评论内容后重试' }`
- `[...content].length > 150` → 立即返回 `{ submitted: false, verified: false, reason: 'too_long', next_action: '缩短评论至 150 code points 以内后重试' }`

### 1. 导航 + 校验

调用 `tiktok-browser-navigate-to-video`,记录 `video_id` 和 `final_url`。`valid=false` → 中止。

### 2. 定位评论区

1. `evaluate_script` 找 `COMMENT_TAB_SELECTOR`,过滤 innerText === "评论",点击(评论 tab 默认未激活,评论流 lazy-load)
2. `browser-wait-for-selector` 等 `COMMENT_LIST_SELECTOR`(timeout 10s)
3. `browser-scroll-to-element` 滚到评论区可见
4. `browser-wait-for-selector` 等 `COMMENT_INPUT_SELECTOR`(timeout 10s)
5. 输入框不存在 → 跑 `skills/tiktok-post-comment/scripts/probe-deep.mjs` 重新探测 + 提示用户确认

### 3. 检测验证码

跑一次 `evaluate_script` 检查 `[class*="captcha" i], [class*="verify" i], [class*="challenge" i]` 是否命中,命中 → 返回 `reason: 'verify_required'`,让用户在 Chrome 手动通过。**不重试**。

### 4. 拍提交前快照

```js
() => [...document.querySelectorAll(COMMENT_ITEM_SELECTOR)]
  .map(el => el.innerText.trim())
  .filter(Boolean)
```

存为 `beforeComments`。

### 5. 填充评论

**走 `chrome-devtools fill <uid> <value>`(CDP `Input.insertText`)** —— 唯一能同步 Draft.js React 状态的写入选区:
- 不直接 `innerHTML` / `textContent` 赋值,绕过 React 状态管理会导致下次提交脏数据

步骤:
1. `findUid('textbox', '添加评论...')` 拿 input uid(自动 take_snapshot + 解析,不把 ~14KB snapshot 丢给 agent)
2. `fillByUid(uid, content)` 写入
3. `evaluate_script` 校验 submit 是否激活(`!disabled && aria-disabled !== 'true'`),未激活 → `submit_button_disabled`

### 6. 提交

`findUid('button', '发布')` 拿 submit uid(fill 后 snapshot 可能过期,必须重新查),`clickByUid(uid)` 提交。

### 7. 验证(≤15s 轮询)

每 500ms 跑一次:
```js
() => {
  const items = [...document.querySelectorAll(COMMENT_ITEM_SELECTOR)]
    .map(el => {
      const lines = el.innerText.split('\n').map(l => l.trim()).filter(Boolean);
      const hasContent = lines.some(l => l.includes(content));
      const tsLine = lines.find(l => /秒前|刚刚|s\s*ago|seconds?\s*ago|just\s*now|分钟前|min(ute)?s?\s*ago/i.test(l));
      const freshByTs = tsLine
        ? /^\s*(刚刚|\d+\s*(秒前|s\s*ago|seconds?\s*ago)|just\s*now)\s*$/i.test(tsLine)
          || (m => m && +m[1] < 5)(tsLine.match(/^\s*(\d{1,2})\s*(分钟前|min(ute)?s?\s*ago)\s*$/i))
        : false;
      return { hasContent, tsLine, freshByTs };
    })
    .filter(x => x.hasContent);
  const newByContent = items.length > 0;
  const freshTimestamp = items.some(x => x.freshByTs);
  const inputCleared = document.querySelector(COMMENT_INPUT_SELECTOR)?.textContent?.trim() === '';
  const hasLoginBtn = Array.from(document.querySelectorAll('button, a'))
    .some(el => /log\s*in|sign\s*up/i.test(el.textContent || ''));
  return { newByContent, freshTimestamp, inputCleared, hasLoginBtn, matchedItems: items.map(x => ({ tsLine: x.tsLine, freshByTs: x.freshByTs })) };
}
```

**成功条件(必须**同时**满足)**:
- `newByContent === true`(评论流出现内含 `content` 的 item)
- `freshTimestamp === true`(同一 item 时间戳新鲜:匹配 `刚刚` / `\d+ 秒前` / `just now` / `< 5 分钟前`)
- `inputCleared === true`(输入框已清空)
- `hasLoginBtn === false`(中途 session 过期则归类 `login_required`,见步骤 8)

满足 → 返回 `{ submitted: true, verified: true }`

文字命中但时间戳不新鲜 → `ambiguous_verification`(可能与历史评论撞文本,不重发)

### 8. 失败分类(返回 reason + next_action)

| 检测信号 | reason | next_action |
|---------|--------|-------------|
| `beforeComments` 已有 item 内含 `content` | `ambiguous_verification` | 检查评论是否真的发出去了,未发出再手动重发 |
| 15s 后 `newByContent=false && inputCleared=true` | `submission_unverified` | TikTok 静默吞提交,**停止**。等待 1-2 分钟后人工到 Chrome 看评论是否实际发出 |
| 15s 后 `newByContent=false && inputCleared=false` | `submit_failed` | 提交按钮可能未生效或被拦截,去 Chrome 手动重发 |
| 命中 CAPTCHA_SELECTOR | `verify_required` | 在 Chrome 手动通过验证后重试 |
| `hasLoginBtn` 重新出现 | `login_required` | 重新跑 `tiktok-ensure-login` |
| COMMENT_INPUT_SELECTOR 消失 | `comment_closed` | 视频禁评或评论被折叠 |
| COMMENT_SUBMIT_SELECTOR disabled | `submit_button_disabled` | 风控/限流,等待或换账号 |

From 271642183/tiktok-web-skills, MIT.

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Aug 10, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from 271642183

Cite this page

tiktok-post-comment skill. Agent Mart. https://agentmart.dev/skills/271642183-tiktok-post-comment (last updated 2026-10-24)