TikTok Upload Pipeline
The TikTok upload pipeline is a 43-step ADB automation that pushes a video to the device, opens TikTok’s share intent, adds captions and hashtags, configures ad disclosure, and posts (or saves as a draft for scheduled publishing).
Overview
Section titled “Overview”Push video to device -> Share intent to TikTok -> Add text/TTS overlay -> Type caption + hashtags -> Configure ad disclosure -> Post or Save as Draft -> Tag draft with unique #zzdfXXXXXX for later identificationPrerequisites
Section titled “Prerequisites”- Physical Android phone connected via USB
- TikTok v44.3.3 installed and logged in
- Video file on your computer (MP4, vertical preferred)
Quick Start
Section titled “Quick Start”# Upload as draft (safest -- review before publishing)python3 -m marketing_system.bots.tiktok.upload \ /path/to/video.mp4 \ --caption "Check this out!" \ --hashtags "cat,aicat,trending" \ --action draft
# Upload and post immediatelypython3 -m marketing_system.bots.tiktok.upload \ /path/to/video.mp4 \ --caption "Amazing content" \ --hashtags "viral,fyp" \ --action post
# Upload with text-to-speech overlaypython3 -m marketing_system.bots.tiktok.upload \ /path/to/video.mp4 \ --caption "Listen to this!" \ --inject-tts \ --action draftREST API
Section titled “REST API”curl -X POST http://localhost:5055/api/skills/tiktok/run \ -H "Content-Type: application/json" \ -d '{ "workflow": "upload_video", "device": "L9AIB7603188953", "params": { "video_path": "/path/to/video.mp4", "caption": "Check this out!", "hashtags": ["cat", "aicat"], "action": "draft" } }'Python
Section titled “Python”from marketing_system.skills.tiktok import loadfrom marketing_system.bots.common.adb import Device
dev = Device()skill = load()wf = skill.get_workflow("upload_video", dev, video_path="/path/to/video.mp4", caption="Check this out!", hashtags=["cat", "aicat"], action="draft")result = wf.run()The 43-Step Flow
Section titled “The 43-Step Flow”The upload script (bots/tiktok/upload.py) performs these steps in sequence:
- Push video to device via
adb push - Send share intent to TikTok (
am start -a SEND -t video/mp4) - Wait for TikTok editor to load
- Dismiss any “Continue editing?” overlay if present
- Wait for the “Next” button to appear
- Tap “Next” to proceed to the caption screen
- Clear any existing caption text
- Type the caption text
- Add each hashtag one by one (type
#tag, wait for suggestion, tap suggestion) - Validate each hashtag was accepted in the XML
- Navigate to “More options”
- Toggle “Content disclosure” ON
- Tap “Authorize” to confirm ad disclosure
- Save disclosure settings
- Close the disclosure panel
- Tap “Post” or “Save to drafts” depending on
--action
Steps 17-43 handle edge cases: popup dismissal, retry logic for failed hashtag suggestions, draft-tag generation, account verification, and cleanup.
Draft Tags
Section titled “Draft Tags”When saving as a draft, the system generates a unique hashtag in the format #zzdfXXXXXX (6 random hex chars). This tag serves as a reliable identifier to find the draft later, since TikTok doesn’t expose draft IDs via the UI.
# Find a specific draft by its tagdev.go_to_drafts_screen()xml = dev.dump_xml()# Search for the draft-tag in the XML to locate the correct draftDraft management methods:
- Count drafts — navigate to drafts screen, count grid items
- Find by tag — search draft descriptions for the
#zzdftag - Publish draft — open draft, tap publish, confirm
- Delete draft — open draft, tap delete, confirm
Ad Disclosure
Section titled “Ad Disclosure”TikTok requires ad disclosure for branded content. The upload flow handles this automatically:
- Tap “More options” below the caption
- Toggle “Content disclosure” to ON
- Tap “Authorize” in the confirmation dialog
- Tap “Save” to confirm
- Close the panel and return to the post screen
Scheduling (Draft-then-Publish)
Section titled “Scheduling (Draft-then-Publish)”The recommended workflow for scheduled posts:
- Upload as draft with
--action draft - Create a scheduler entry for
publish_draftat the desired time - The scheduler will find the draft by its tag and publish it
# Create a schedule to publish at 6 PM dailycurl -X POST http://localhost:5055/api/schedules \ -H "Content-Type: application/json" \ -d '{ "name": "Publish 6PM", "job_type": "publish_draft", "device": "L9AIB7603188953", "schedule_type": "daily_times", "daily_times": ["18:00"], "params": {"draft_tag": "zzdf1a2b3c"} }'Content Pipeline Integration
Section titled “Content Pipeline Integration”The full automated pipeline:
LLM Agent plans content (styles, captions, schedule times) -> KIE AI / Sora generates video from prompt -> Download generated video -> ADB draft upload with #zzdf tag -> Scheduler publishes at planned time -> Post analytics scraper captures metricsLaunch the full pipeline:
# Plan 3 days of content (dry run first)python3 -m marketing_system.agent.agent_core --days 3 --dry-run
# Execute for realpython3 -m marketing_system.agent.agent_core --days 3Troubleshooting
Section titled “Troubleshooting”Upload fails at hashtag step
Section titled “Upload fails at hashtag step”TikTok’s hashtag suggestion dropdown can interfere. Each hashtag is validated in the XML before proceeding. Try shorter, more popular hashtags.
”Continue editing?” popup
Section titled “”Continue editing?” popup”This invisible overlay appears when TikTok was killed mid-edit. The script detects it via pixel scanning for the red Edit button. restart_tiktok() handles this automatically.
Draft-tag visible on published post
Section titled “Draft-tag visible on published post”The #zzdfXXXXXX tag is intentionally added to drafts for identification. It should be removed before publishing. The publish_draft workflow handles this automatically.
Related
Section titled “Related”- Scrape Profiles — find influencers to repost
- Send DMs — outreach after posting
- Scheduler — automate the publish schedule