← Back to Skills Marketplace
scs001

Douyin Send DM

by FindData · GitHub ↗ · v0.1.0 · MIT-0
cross-platform ⚠ suspicious
22
Downloads
0
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install douyin-send-dm
Description
Send a direct message (私信) to a specific Douyin user via the user's logged-in Chrome through OpenClaw's browser tool. Use whenever the user asks to send, DM,...
README (SKILL.md)

Douyin: Send a DM via Chrome

Send a text DM to a Douyin user from the user's signed-in Chrome session, then verify the message actually delivered (Douyin will silently render bubbles even when DMs are banned — never claim success without checking).

When to use

Trigger on any of:

  • "send a message to \x3Cname> on Douyin / 抖音"
  • "DM \x3Cname> on douyin.com"
  • "tell \x3Cname> '\x3Ctext>' on Douyin"
  • 抖音 / 私信 / 发私信 mentioned alongside a target user

If the user wants to control the desktop app (抖音聊天.app / Douyin Chat for Mac) rather than the website, this skill does not apply — that requires macOS Accessibility automation, not browser control.

Prerequisites (one-time setup)

  1. Chrome 144+ exposing CDP on 127.0.0.1:9222. The user can launch Chrome with --remote-debugging-port=9222, or open chrome://inspect/#remote-debugging, click Configure…, and follow the in-page steps until they see Server running at: 127.0.0.1:9222.
  2. OpenClaw user browser profile (built-in: driver=existing-session, transport=chrome-mcp). No extra config needed — browser action=start profile=user will spawn chrome-devtools-mcp and attach.
  3. User logged into douyin.com in that Chrome.
  4. Sender and recipient must be mutual followers (相互关注). Douyin web blocks DMs to non-mutuals. If the target's profile shows only "关注" (follow) instead of "相互关注", stop and tell the user.
  5. Sender's DM privilege not banned. If banned, the message bubble still renders locally with a tip "私信功能已被封禁" — see Verify step.

Workflow

1. Attach to Chrome

browser action=start profile=user
browser action=tabs profile=user

Pick an empty tab from tabs, or be prepared to open a new one. Save its targetId — pass it on every subsequent call to keep the same tab.

2. Find the target user

Navigate the chosen tab to a user search:

browser action=navigate profile=user targetId=\x3Cid>
  url=https://www.douyin.com/search/\x3CURL-encoded query>?type=user

Snapshot with refs="aria" and pick the result whose card shows "相互关注" and whose 抖音号 / bio matches what the user described. If multiple plausible results exist, ask the user to confirm before proceeding.

Click that result link by ref — it opens the profile in a new tab. Snapshot or browser action=tabs again to find the new targetId (URL pattern: https://www.douyin.com/user/MS4wLj…). Switch to that tab for the rest of the flow.

3. Open the DM panel from the profile

Critical: there are two 私信 controls on the page.

  • Header 私信 (top-right, around x≈1542) opens the global DM panel with no conversation selected.
  • Profile-page 私信 button (next to "相互关注", around x≈1562 y≈158) opens the panel with the right conversation already selected.

Always click the profile-page button. Find it via DOM filter, not by ref (the ref tree sometimes returns the wrong element):

browser action=act profile=user targetId=\x3Cprofile-tab>
  request={"kind":"evaluate","fn":"() => { const btns=[...document.querySelectorAll('button')].filter(b=>(b.innerText||'').trim()==='私信' && b.offsetParent!==null); for (const b of btns){ const r=b.getBoundingClientRect(); if (r.width>30 && r.width\x3C200 && r.height>20 && r.height\x3C60 && r.x>200){ b.click(); return JSON.stringify({clicked:true,x:Math.round(r.x),y:Math.round(r.y)}); } } return JSON.stringify({found:btns.length}); }"}

Then wait for the panel to render:

browser action=act profile=user targetId=\x3Cid>
  request={"kind":"wait","timeMs":1500}

Verify the right conversation is selected by reading .RightPanelHeadertitle:

browser action=act profile=user targetId=\x3Cid>
  request={"kind":"evaluate","fn":"() => { const h=document.querySelector('.RightPanelHeadertitle'); return h?h.innerText:null; }"}

The result must equal the target user's display name. If null or wrong, the DM panel didn't open or the wrong row got selected — retry the click.

4. Type the message

The message editor is a [contenteditable="true"] with placeholder 发送消息. Standard act:type rejects pure-coords focus on existing-session driver, so write the text via execCommand:

browser action=act profile=user targetId=\x3Cid>
  request={"kind":"evaluate","fn":"() => { const ed=[...document.querySelectorAll('[contenteditable=\"true\"]')].find(e=>{const r=e.getBoundingClientRect();return r.width>100 && r.height>20;}); if(!ed) return 'no-editor'; ed.focus(); const sel=window.getSelection(); const range=document.createRange(); range.selectNodeContents(ed); range.collapse(false); sel.removeAllRanges(); sel.addRange(range); document.execCommand('insertText',false,'\x3CMESSAGE TEXT>'); return ed.innerText; }"}

Replace \x3CMESSAGE TEXT> with the user's message. Escape single quotes ('\\'). The returned innerText should match the message (a trailing zero-width char is fine).

5. Send

browser action=act profile=user targetId=\x3Cid>
  request={"kind":"press","key":"Enter"}

6. Verify delivery — do not skip

Inspect the DOM for both signals:

browser action=act profile=user targetId=\x3Cid>
  request={"kind":"evaluate","fn":"() => { const ed=[...document.querySelectorAll('[contenteditable=\"true\"]')].find(e=>{const r=e.getBoundingClientRect();return r.width>100 && r.height>20;}); const editorText=ed?ed.innerText.trim():null; const list=document.querySelector('.messageMessageListwrapper'); const listText=list?list.innerText.slice(0,400):''; const banned=/私信功能已被封禁|对方拒收|不是Ta的好友|无法发送/.test(listText); return JSON.stringify({editorEmpty:!editorText||editorText==='\u200b'||editorText==='', listText, banned}); }"}

Outcome matrix:

editorEmpty banned Result
true false ✅ delivered — confirm to user
true true ⚠️ Sent locally but Douyin blocked it. Tell the user the bubble appears but the recipient won't receive it; they should check Douyin notifications for the ban reason.
false ❌ Send didn't fire (Enter consumed by IME, no focus, etc.). Retry steps 4–5.

Always quote the exact tip text Douyin shows when reporting a ban — don't paraphrase.

Failure modes & recovery

  • Search returns multiple "相互关注" matches. Ask the user to disambiguate by 抖音号 or bio before clicking.
  • No 私信 button on profile, only "关注" / "相互关注". Not mutuals. Tell the user — Douyin web doesn't allow DMs to non-mutuals.
  • browser action=screenshot fails with ENOENT … openclaw-chrome-mcp-…. Known existing-session driver quirk. Skip screenshots; rely on DOM inspection (evaluate) for verification.
  • Header 私信 click instead of profile button. Closes / reopens the global panel without selecting a chat. Always re-check .RightPanelHeadertitle matches the target.
  • Massive evaluate blocks accidentally clicking page-wide containers. Constrain queries with getBoundingClientRect size filters (e.g. width\x3C400 && height\x3C100).
  • act:type errors with "type requires ref or selector". Existing-session driver doesn't accept coords-only focus. Use the execCommand('insertText', …) evaluate pattern in step 4.
  • Chrome MCP attach times out (Chrome MCP existing-session attach … timed out). Verify curl -s http://127.0.0.1:9222/json/version returns JSON. If 404, Chrome's chrome://inspect proxy is on but the actual DevTools endpoint isn't — relaunch Chrome with --remote-debugging-port=9222.

Reuse on another machine

Copy this SKILL.md (and parent directory) to that machine's skills root (e.g. ~/.openclaw/workspace/skills/douyin-send-dm/ or ~/.agents/skills/douyin-send-dm/). Then just say "send a Douyin DM to \x3Cuser>: \x3Ctext>" — OpenClaw's skill discovery will load it.

If the target user is not the same person as on this machine, redo step 2 (search + confirm 相互关注) before sending.

Honest reporting rules

  • Never say "message sent" based only on the bubble appearing. Always run the verify step.
  • If banned/blocked, surface Douyin's exact tip in your reply and recommend the user check their Douyin notifications.
  • If the user asks "did it actually send?", re-run the verify-step query and report the live DOM state.
Usage Guidance
Review this skill before installing. Only use it if you are comfortable with it operating your Douyin account, and require explicit confirmation of the recipient and exact message text before any DM is sent.
Capability Assessment
Purpose & Capability
Sending Douyin private messages is coherent with the apparent purpose, but it is a high-impact outbound communication action on behalf of the user.
Instruction Scope
The supplied scan context points to broad triggers such as casual recipient/message phrasing or merely mentioning Douyin private messaging with a target user, without clear evidence of a mandatory confirmation step before sending.
Install Mechanism
No evidence of a hidden or deceptive install mechanism was supplied or found in the available workspace context.
Credentials
Use of the user's authenticated Douyin/browser session is proportionate to sending DMs, but it exposes account, privacy, and reputational risk if activation is ambiguous.
Persistence & Privilege
No evidence was supplied of background persistence, privilege escalation, destructive local changes, or unrelated data access.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install douyin-send-dm
  3. After installation, invoke the skill by name or use /douyin-send-dm
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v0.1.0
Initial release: send DMs on douyin.com via Chrome (CDP), with mutual-follow + ban-tip verification
Metadata
Slug douyin-send-dm
Version 0.1.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

What is Douyin Send DM?

Send a direct message (私信) to a specific Douyin user via the user's logged-in Chrome through OpenClaw's browser tool. Use whenever the user asks to send, DM,... It is an AI Agent Skill for Claude Code / OpenClaw, with 22 downloads so far.

How do I install Douyin Send DM?

Run "/install douyin-send-dm" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Douyin Send DM free?

Yes, Douyin Send DM is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does Douyin Send DM support?

Douyin Send DM is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Douyin Send DM?

It is built and maintained by FindData (@scs001); the current version is v0.1.0.

💬 Comments