📋 Please confirm content compliance before publishing:
~/clawd/projects/MediaClaw/references/platforms/douyin.md(11 major categories of community guideline violations, AIGC labeling, account health score)
⚠️ Default publishing strategy
- The default goal is to save as draft, not to publish directly.
- Only after Daniel explicitly confirms is clicking "Publish" allowed.
- After the automation finishes filling in the content, prioritize sending back a screenshot of the current page to confirm that the title/description/cover/hashtags are all correct.
- If you encounter login verification, sliders, rate limits, or uploads getting stuck, do not keep struggling; keep the screenshot and current state, and switch to "awaiting Daniel to take over".
⚡ v1.1 Safety Enhancements
Pre-flight Checklist
All of the following items must be verified before each publish; none can be missing:
# 1. 浏览器连接测试
curl -s http://127.0.0.1:18800/json/version | grep -q webkit && echo "✅ Browser OK" || echo "❌ Browser Down"
# 2. 登录态验证
python3 scripts/publish.py doctor --no-headless \
--url "https://creator.douyin.com/creator-micro/content/upload?default-tab=3" \
--screenshot /tmp/douyin_preflight.png
# 3. 文件验证
ls -lh "$VIDEO_OR_IMAGE_FILE"
Checklist:
- Browser running
- Login session valid (not expired)
- File exists and format is correct
- doctor smoke test passes (all selectors can be found)
Safety Screenshots
The current state must be screenshotted before each button click:
打开上传页 → [截图#1: 页面加载] → 上传文件 → [截图#2: 文件上传完成]
→ 填描述 → [截图#3: 描述已填] → 设置封面 → [截图#4: 封面已选]
→ 填话题 → [截图#5: 话题已填] → 点击存草稿 → [截图#6: 草稿确认]
Screenshot naming:/tmp/douyin_safety_{N}_{step_name}_{timestamp}.png
Error Escalation
Stop after 3 failures:
| Failure point | Failure count | Behavior |
|---|---|---|
| File upload | ≥3 failures | Stop, screenshot, report |
| Description filling | ≥3 failures | Stop, screenshot, report |
| Button click | ≥2 failures | Stop, screenshot, report |
| Login verification | Failure | Stop, prompt to log in again |
Actions after stopping:
- Screenshot the current page
- Save all safety screenshots to
/tmp/douyin_safety/ - Report the specific failed step and error message
- Switch to "awaiting Daniel to take over"
Recovery Mode
If the publishing process is interrupted:
- Check the draft box:
https://creator.douyin.com/creator-micro/content/manage - View the safety screenshots:
ls /tmp/douyin_safety/*.png - Determine whether a rerun is needed:
- Screenshot #5 already exists → it failed before the draft button, need to rerun
- Screenshot #4 already exists → it failed after filling in the hashtags, need to rerun
- Screenshot #2 already exists → the file has already been uploaded, can skip the upload step
- When rerunning, use
--mode draft, never automatically switch to--mode publish
Draft button text variants
Known variants(Douyin UI changes frequently):
| Text | Occurrence scenario | Corresponding selector |
|---|---|---|
存草稿 |
Video upload page | button:has-text('存草稿') |
暂存离开 |
Image-text upload page | button:has-text('暂存离开') |
草稿 |
Some versions | button:has-text('草稿') |
The script already covers all variants:button:has-text('存草稿'), button:has-text('草稿'), button:has-text('暂存离开')
Platform entry
- Creator Center: https://creator.douyin.com
- Content Upload: https://creator.douyin.com/creator-micro/content/upload
- Image-Text Upload: https://creator.douyin.com/creator-micro/content/upload?default-tab=3
- Login Method: Douyin APP QR code scan / phone number verification code
Publish Type
| Type | URL Parameter | Description |
|---|---|---|
| Video | default-tab=1(Default) |
Short video/Long video |
| Image-Text | default-tab=3 |
Image carousel + description |
| Panoramic video | default-tab=3(Panoramic) |
VR video |
| Article | default-tab=4 |
Long text (≤8000 characters + 30 images) |
Formatting Rules
Video Specifications
| Item | Rule |
|---|---|
| Duration | 15 seconds-60 minutes (≥15 minutes requires ≥1000 followers) |
| Format | MP4, WebM (MP4 H.264 recommended) |
| Resolution | ≥720×1280, 1080×1920 recommended, up to 4K |
| Frame Rate | ≤60fps, 30fps recommended |
| Size | ≤16GB |
| Aspect Ratio | 9:16 vertical (optimal) / 16:9 horizontal / 3:4 / 4:3 |
Image-Text Specifications
| Item | Rule |
|---|---|
| Number of Images | 2-35 images |
| Format | JPG, JPEG, PNG, WebP(GIF not supported) |
| Size | ≤50MB per image |
| Ratio | 3:4 or 4:3 recommended, not recommended to exceed 1:2 |
Description/Title Specifications
| Item | Rule |
|---|---|
| Title | ≤55 characters (tested, excess will be truncated) |
| Description | Recommended ≤200 characters (including hashtags) |
| Hashtags | #hashtag format, 3-5, precise ones first, broad ones after |
| @Mention | @username increases interaction |
| POI Location | Location can be added (local recommendation weighting) |
| emoji | Use in moderation, 1 per 2-3 sentences |
Cover Specifications
| Item | Rule |
|---|---|
| Video Cover | Select from video frames or upload custom (1080×1920) |
| Image-Text Cover | Select from uploaded images |
| Recommendation | Vertical 9:16, clear large text, contrasting colors |
AIGC Labeling Requirements (since 2023.9)
- AI-generated content must be labeled "Content generated by AI"
- Fictional plots labeled "Scenario reenactment, for entertainment only"
Content Adaptation Template
When converting content to Douyin format:
- Title/Description: Put core information at the beginning (first 3 seconds rule), add emoji and hashtags
核心卖点/痛点句 emoji 补充说明(1-2句) #精准话题1 #精准话题2 #泛话题3 - Hashtag Strategy: 1-2 precise hashtags + 2-3 broad hashtags, avoid irrelevant hashtags (may be considered clickbait)
- Description Length: Keep within 100-200 characters, concise and powerful
- Interaction Guidance: Add a question or CTA at the end
Publishing Process
Key safety gate: Screenshot confirmation → then publish
- After the automation is filled in,screenshot first(as confirmation credential).
- By default, only execute Save Draft。
- Only after receiving explicit confirmation from Daniel is it permitted to switch to
--mode publish。
Requires takeover/risk control/stop rules: see
references/handoff-and-human-trace.md
March 27, 2026 field-verification conclusion (already fully tested)
This skill has already completed one full image-and-text draft test in a real Douyin creator backend, and the flow is as follows:
- Reuse
storage_statelogged-in state to enter the creator backend - Successfully uploaded 3 images
- Successfully filled in the title
- Successfully filled in the description
- Successfully clicked the draft button and saved it to the drafts box
What was obtained from this field testKey experience:
- Authorize first, then publish: when not logged in, the upload control may not exist at all on the page; do not misjudge "upload failed" as a selector problem.
- Login detection cannot rely on URL alone: even if the URL is already under
creator-micro/*, the page may still be in QR-code login state; you must also check the page copy/QR-code area. - The draft button copy on the current Douyin image-and-text page may not be
存草稿, but rather暂存离开。 - The image-and-text page has a real
inp 6ut[type=file], which can be uploaded directly after successful authorization; the previouscount=0root cause was the login page, not a lack of upload capability.
Recommended troubleshooting order:
- First confirm whether login actually succeeded
- Then confirm whether
input[type=file]exists - Then confirm whether the bottom button copy is
发布 / 暂存离开or another variant - Only then modify the selector
Video publishing
1. 打开 creator.douyin.com/creator-micro/content/upload
2. 上传视频文件 (拖拽或点击)
3. 等待上传+转码完成
4. 选择/上传封面
5. 填写描述 + #话题 + @提及
6. 🎵 选择BGM(从推荐/热门中选取适合作品氛围的音乐)
7. 设置:可见性(公开/好友/私密)、合拍、下载
8. 可选:定时发布(最远10天)、POI定位
9. 点击 [发布] 或 [存草稿]
Image-and-text publishing
1. 打开 creator.douyin.com/creator-micro/content/upload?default-tab=3
2. 上传图片 (2-35张,拖拽排序)
3. 选择封面图
4. 填写描述 + #话题
5. 设置发布选项
6. [发布] 或 [存草稿]
Script usage
# 0) 冒烟检查(不上传,只打开页面+截图+输出关键信号)
python scripts/publish.py doctor --no-headless \
--screenshot /tmp/douyin_doctor.png
# 1) 从 daily-content 产物直接发布到草稿箱(推荐,SOP直连)
# - 支持 md/txt 两种格式:
# /home/aa/clawd/docs/daily-content/YYYY-MM-DD/douyin/douyin-content-YYYY-MM-DD.md
# /home/aa/clawd/docs/daily-content/YYYY-MM-DD/douyin/douyin-3posts-YYYY-MM-DD.txt
# - pick=1/2/3 选择第几条
# - 默认 mode=draft(只存草稿)
python scripts/publish.py daily \
--source "/home/aa/clawd/docs/daily-content/2026-03-24/douyin/douyin-content-2026-03-24.md" \
--pick 1 \
--type image \
--files "/path/to/img1.jpg,/path/to/img2.jpg" \
--mode draft
# 2) 视频发布(草稿模式)
python scripts/publish.py video \
--file "/path/to/video.mp4" \
--title "可选标题(≤55字)" \
--desc "描述文字 #话题1 #话题2" \
--cover "/path/to/cover.jpg" \
--mode draft
# 3) 图文发布
python scripts/publish.py image \
--files "/path/to/img1.jpg,/path/to/img2.jpg" \
--title "可选标题(≤55字)" \
--desc "图文描述 #话题1" \
--mode draft
# 4) 定时发布(⚠️仅在 Daniel 明确确认后使用 publish)
python scripts/publish.py daily \
--source "/home/aa/clawd/docs/daily-content/2026-03-25/douyin/douyin-3posts-2026-03-25.txt" \
--pick 2 \
--type video \
--file "/path/to/video.mp4" \
--schedule "2026-03-27 21:30" \
--mode publish
UI selector reference (React SPA, class names contain hashes)
| Element | Locating strategy | Description |
|---|---|---|
| Upload area | input[type="file"] / button:has-text("上传视频") |
File upload;First confirm you are logged in, when not logged in it may be 0 |
| Description input | [class*="desc"] [contenteditable] / textarea / [placeholder*="添加作品描述"] |
Description editing area |
| Topic input | Enter in the description area # to trigger topic search |
Topic popup selection |
| Cover selection | [class*="cover"] / cover editing popup |
Video frame or custom |
| Music selection | 添加音乐 button / music search panel |
Select BGM from recommended/trending |
| Publish button | button:has-text("发布") |
Publish confirmation |
| Draft button | button:has-text("存草稿") / button:has-text("暂存离开") |
Currently, the image-and-text page in actual testing is commonly 暂存离开 |
| Scheduled switch | [class*="schedule"] / time picker |
Scheduled publishing |
| Visibility | [class*="permission"] / radio button |
Public/Friends/Private |
| Image sorting | Drag operation | Adjust image order |
Note: Douyin uses React + CSS Modules, class names contain hash prefixes; prioritize text matching (
has-text) orplaceholderlocating.
Publishing time suggestions
| Time period | Recommendation level | Description |
|---|---|---|
| 7:00-9:00 | ⭐⭐⭐ | Morning commute |
| 11:30-13:00 | ⭐⭐⭐ | Lunch break |
| 17:30-19:00 | ⭐⭐⭐ | Evening commute |
| 20:00-22:00 | ⭐⭐⭐⭐⭐ | Prime time evening |
| 22:00-00:00 | ⭐⭐⭐⭐ | Before bed |
Error handling
| Error | Handling |
|---|---|
| Login expired | Prompt to scan QR code,--headless false |
| Slider verification | Pause and wait for manual completion |
| Upload timeout | Retry 3 times, exponential backoff (10s/30s/90s) |
| Transcoding failed | Check format/resolution, downgrade and re-upload |
| Description too long | Truncate to 200 characters and warn |
| Rate limit | Recommended ≤3 per day, interval ≥30 minutes |
Algorithm key points
- Within 2 hours after publishing, the "horse racing mechanism" determines recommendation volume
- Completion rate > Like rate > Comment rate > Share rate
- The first 3 seconds determine whether users continue watching
- Hashtags affect recommendation pool allocation
- Vertical content has higher recommendation weight
Pre-publish checklist
- Description ≤200 characters, including 3-5 hashtags
- Video: MP4/WebM format, ≤16GB, ≤60 minutes
- Image-text: 2-35 images, JPG/PNG/WebP, each ≤50MB
- Cover is clear, vertical 9:16 is optimal
- No watermarks from other platforms
- AI content is labeled (if applicable)
- Non-reposted content
- Screenshot has been sent back for confirmation
- If using
dailymode: verifiedpickcorresponds to the correct piece of content
File structure
douyin-smart-publish/
├── SKILL.md
├── scripts/
│ └── publish.py # Playwright 自动发布脚本
├── references/
│ └── platform-rules.md # 完整平台规则
└── templates/
└── desc-template.md # 描述/话题排版模板
🎵 Select BGM (music selection step)
Execute after filling in the description and before saving the draft.
Operation flow
1. 在发布页面找到"添加音乐"按钮(通常在描述区下方)
2. 点击打开音乐选择面板
3. 切换到"推荐"或"热门"标签页
4. 搜索与作品内容匹配的音乐(搜索关键词参考下方匹配表)
5. 试听前10秒,判断节奏和氛围是否贴合
6. 选择合适音乐 → 点击"使用"
Browser operation (OpenClaw Browser)
# 找到并点击"添加音乐"按钮
browser(action="act", kind="evaluate", targetId=编辑页targetId, fn="""
() => {
const btns = document.querySelectorAll('button, div, span');
for (const btn of btns) {
const text = btn.textContent.trim();
if (text === '添加音乐' || text === '选择音乐' || text.includes('音乐')) {
if (btn.offsetParent !== null) {
btn.click();
return 'clicked: ' + text;
}
}
}
return 'not found';
}
""")
# 等待音乐面板加载
browser(action="act", kind="wait", timeMs=2000)
# 切换到"推荐"或"热门"标签
browser(action="act", kind="evaluate", targetId=编辑页targetId, fn="""
() => {
const tabs = document.querySelectorAll('div, span, button');
for (const tab of tabs) {
const text = tab.textContent.trim();
if ((text === '推荐' || text === '热门') && tab.offsetParent !== null) {
tab.click();
return 'switched to: ' + text;
}
}
return 'not found';
}
""")
# 搜索匹配音乐(根据内容主题)
browser(action="act", kind="evaluate", targetId=编辑页targetId, fn="""
() => {
const input = document.querySelector('input[placeholder*="搜索音乐"]');
if (input) {
input.value = '{搜索关键词}';
input.dispatchEvent(new Event('input', { bubbles: true }));
return 'searched';
}
return 'search input not found';
}
""")
Content × BGM search keyword matching
| Content type | Recommended search keywords | Style direction |
|---|---|---|
| AI/Tech | "Tech feel" "Electronic" "Cyberpunk" | Strong rhythm, futuristic feel |
| Programming/Technology | "Light music" "lofi" "Study" | Comfortable, non-disruptive |
| Industry analysis | "Business" "Calm" "Grand" | Professional, credible |
| Comparison review | "Rhythm" "Suspense" "Dynamic" | Sense of ups and downs, attracts attention |
| Tool recommendations | "Light and brisk" "Vitality" "Sunny" | Positive, light and brisk |
| In-depth interpretation | "Epic" "Cinematic" "Immersive" | Grand, layered |
Selection strategy
优先级:
1. 推荐列表前5首中找风格匹配的 → 直接使用
2. 热门榜前10首中找风格匹配的 → 直接使用
3. 搜索关键词后选播放量最高的 → 使用
4. 都不合适 → 跳过音乐选择(不强制)
Notes
- Only select from the Douyin music library(automatically authorized, no copyright risk)
- Do not upload local audio(may infringe copyright)
- Prioritize recommended ones(algorithm recommendation = currently trending = higher exposure)
- Preview the first 10 seconds(Check whether the rhythm matches the content rhythm)
- If it doesn't fit, skip it(Better to have no BGM than to use music that doesn't match)
Changelog
- v1.2.0 (2026-04-16): Added BGM selection step
- Publishing Process Step 6: Select BGM (choose from recommended/trending)
- 6 content types × BGM search keyword matching
- OpenClaw Browser music panel operation code
- Added "Music Selection" entry to UI selectors
- v1.1.0 (2026-04-16): Security enhancements
- Pre-flight checklist (browser, login state, files, doctor smoke test)
- Safety screenshots (screenshots of 6 key checkpoints)
- Error escalation (stop after 3 failures)
- Recovery mode documentation
- Draft button text variants documentation (Save Draft/Save and Leave/Draft)
- v1.0.0 (2026-03-27): Initial version, validated in real-world testing