@acedatacloud/skills 2026.801.2 → 2026.801.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/tiktok/SKILL.md +64 -73
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acedatacloud/skills",
|
|
3
|
-
"version": "2026.801.
|
|
3
|
+
"version": "2026.801.3",
|
|
4
4
|
"description": "Agent Skills for AceDataCloud AI services — music, image, video generation, LLM chat, web search. Compatible with Claude Code, GitHub Copilot, Gemini CLI, OpenAI Codex, and 30+ AI coding agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
package/skills/tiktok/SKILL.md
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tiktok
|
|
3
|
-
description:
|
|
3
|
+
description: Upload videos to the user's TikTok drafts/inbox, where they finish posting in the TikTok app. Use when the user wants to publish or post a generated video to TikTok, or send a video to their TikTok drafts.
|
|
4
4
|
when_to_use: |
|
|
5
5
|
Trigger when the user wants to push a video (e.g. one generated by
|
|
6
|
-
the video skills) to TikTok.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
the video skills) to TikTok. Upload drops it into their drafts and
|
|
7
|
+
they finish posting in the app — this is the working path. Direct
|
|
8
|
+
Post (publishing immediately with caption + privacy) requires an
|
|
9
|
+
audit this app has not passed yet; do not use it.
|
|
10
10
|
connections: [tiktok]
|
|
11
11
|
allowed_tools: [Bash]
|
|
12
12
|
license: Apache-2.0
|
|
13
13
|
metadata:
|
|
14
14
|
author: acedatacloud
|
|
15
|
-
version: "2.
|
|
15
|
+
version: "2.2"
|
|
16
16
|
---
|
|
17
17
|
|
|
18
18
|
Call the **TikTok API v2** with `curl + jq`. The user's OAuth bearer token is in
|
|
@@ -42,65 +42,42 @@ scopes (`user.info.stats`, `user.info.profile`, `video.list`), which this app
|
|
|
42
42
|
has not been granted — don't call `/v2/video/list/` or request those fields,
|
|
43
43
|
they will fail with `scope_not_authorized`.
|
|
44
44
|
|
|
45
|
-
##
|
|
45
|
+
## Upload the video to the user's drafts
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
This is the working path. The video lands in the creator's TikTok **inbox /
|
|
48
|
+
drafts**; they open the TikTok app to add caption, sound and privacy, then post.
|
|
49
|
+
Confirm with the user before uploading.
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
Two source modes. **`FILE_UPLOAD` is the reliable one** — `PULL_FROM_URL` only
|
|
52
|
+
works from a domain verified in the developer portal, and ours is not verified
|
|
53
|
+
yet (it returns `url_ownership_unverified`).
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
54
|
-
"$T/post/publish/creator_info/query/" | jq '.data, .error.code'
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Returns `creator_nickname`, `privacy_level_options`, `comment_disabled`,
|
|
58
|
-
`duet_disabled`, `stitch_disabled`, `max_video_post_duration_sec`.
|
|
59
|
-
|
|
60
|
-
Use it to:
|
|
61
|
-
- **Show the user `creator_nickname`** so they know which account will receive
|
|
62
|
-
the post.
|
|
63
|
-
- **Offer only the returned `privacy_level_options`** — a public account gets
|
|
64
|
-
`PUBLIC_TO_EVERYONE` / `MUTUAL_FOLLOW_FRIENDS` / `SELF_ONLY`; a private one
|
|
65
|
-
gets `FOLLOWER_OF_CREATOR` / `MUTUAL_FOLLOW_FRIENDS` / `SELF_ONLY`.
|
|
66
|
-
- **Reject a too-long video** against `max_video_post_duration_sec`.
|
|
67
|
-
- Not offer comment/duet/stitch toggles that come back disabled.
|
|
68
|
-
- If it returns a spam/cap error, **stop** and tell the user to try later.
|
|
55
|
+
### FILE_UPLOAD (default)
|
|
69
56
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Before initializing, the user must explicitly confirm — this is a TikTok
|
|
73
|
-
requirement, not just good manners:
|
|
74
|
-
|
|
75
|
-
- the **caption** (max 2200 UTF-16 chars; `#tag` and `@mention` work),
|
|
76
|
-
- the **privacy level**, **chosen by them from the options above — never
|
|
77
|
-
default to one, never assume `PUBLIC_TO_EVERYONE`**,
|
|
78
|
-
- and tell them: *"By posting, you agree to TikTok's Music Usage Confirmation."*
|
|
79
|
-
|
|
80
|
-
### 3. Initialize the post
|
|
57
|
+
Download the video locally first, then init with its exact byte size. Files
|
|
58
|
+
under 64 MB go up as a single chunk.
|
|
81
59
|
|
|
82
60
|
```bash
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
"$T/post/publish/video/init/"
|
|
61
|
+
SIZE=$(stat -f%z video.mp4 2>/dev/null || stat -c%s video.mp4)
|
|
62
|
+
|
|
63
|
+
INIT=$(curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
64
|
+
-d "$(jq -n --argjson s "$SIZE" \
|
|
65
|
+
'{source_info:{source:"FILE_UPLOAD", video_size:$s, chunk_size:$s, total_chunk_count:1}}')" \
|
|
66
|
+
"$T/post/publish/inbox/video/init/")
|
|
67
|
+
echo "$INIT" | jq '{publish_id:.data.publish_id, error:.error.code}'
|
|
68
|
+
|
|
69
|
+
UPLOAD_URL=$(echo "$INIT" | jq -r '.data.upload_url')
|
|
70
|
+
curl -sS -X PUT "$UPLOAD_URL" \
|
|
71
|
+
-H "Content-Type: video/mp4" \
|
|
72
|
+
-H "Content-Length: $SIZE" \
|
|
73
|
+
-H "Content-Range: bytes 0-$((SIZE-1))/$SIZE" \
|
|
74
|
+
--data-binary @video.mp4 -o /dev/null -w '%{http_code}\n'
|
|
89
75
|
```
|
|
90
76
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
disclosure, and omitting it risks the post being taken down.
|
|
94
|
-
|
|
95
|
-
Optional `post_info` fields: `disable_comment`, `disable_duet`,
|
|
96
|
-
`disable_stitch`, `video_cover_timestamp_ms`. If the user says the video is a
|
|
97
|
-
paid partnership, set `brand_content_toggle: true` (which cannot be combined
|
|
98
|
-
with `SELF_ONLY`); for promoting their own business use `brand_organic_toggle`.
|
|
77
|
+
The `PUT` returns **201** when the whole file landed (206 for intermediate
|
|
78
|
+
chunks). `upload_url` expires in **1 hour**.
|
|
99
79
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
When the user would rather finish in the app, use the inbox endpoint — no
|
|
103
|
-
caption or privacy, and **no `creator_info` call needed**:
|
|
80
|
+
### PULL_FROM_URL (only from a verified domain)
|
|
104
81
|
|
|
105
82
|
```bash
|
|
106
83
|
curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
@@ -108,35 +85,49 @@ curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
|
108
85
|
"$T/post/publish/inbox/video/init/" | jq '{publish_id:.data.publish_id, error}'
|
|
109
86
|
```
|
|
110
87
|
|
|
111
|
-
|
|
88
|
+
Needs HTTPS and **no redirects** (any 3xx fails). Domain verification covers
|
|
89
|
+
subdomains downward only.
|
|
90
|
+
|
|
91
|
+
## Poll status
|
|
112
92
|
|
|
113
93
|
```bash
|
|
114
94
|
curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
|
115
95
|
-d "$(jq -n --arg id "$PUBLISH_ID" '{publish_id:$id}')" \
|
|
116
|
-
"$T/post/publish/status/fetch/" | jq '.data | {status, fail_reason
|
|
96
|
+
"$T/post/publish/status/fetch/" | jq '.data | {status, fail_reason}'
|
|
117
97
|
```
|
|
118
98
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
99
|
+
`PROCESSING_UPLOAD` / `PROCESSING_DOWNLOAD` → **`SEND_TO_USER_INBOX`** = done,
|
|
100
|
+
the video is waiting in the creator's TikTok inbox. Tell them to open the
|
|
101
|
+
TikTok app to finish posting, and that processing takes a few minutes.
|
|
122
102
|
|
|
123
103
|
Don't retry on `auth_removed`, `spam_risk_text`, `spam_risk`, or
|
|
124
104
|
`spam_risk_user_banned_from_posting` — those are terminal. `internal` is
|
|
125
105
|
retryable.
|
|
126
106
|
|
|
107
|
+
## Direct Post — NOT available yet
|
|
108
|
+
|
|
109
|
+
Direct Post (`/v2/post/publish/video/init/`) publishes straight to the profile
|
|
110
|
+
with a caption and privacy level. **Do not call it.** It needs a Content
|
|
111
|
+
Posting API audit this app has not passed, so every attempt fails:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
403 unaudited_client_can_only_post_to_private_accounts
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The `video.publish` scope is granted and `creator_info/query` works, which
|
|
118
|
+
makes it look available — it is not. Until the audit clears, use the drafts
|
|
119
|
+
path above.
|
|
120
|
+
|
|
127
121
|
## Gotchas
|
|
128
122
|
|
|
129
|
-
- **Never hardcode `privacy_level
|
|
130
|
-
`privacy_level_options`
|
|
131
|
-
|
|
132
|
-
- `publicaly_available_post_id` (TikTok's own spelling — don't "fix" it) is a
|
|
133
|
-
**list**, and is **empty for non-public posts and for public posts still in
|
|
134
|
-
moderation**. Empty ≠ failure.
|
|
135
|
-
- `PULL_FROM_URL` needs the URL's domain verified in the developer app, HTTPS,
|
|
136
|
-
and **no redirects** (any 3xx fails). Verification covers subdomains
|
|
137
|
-
downward only. If the video isn't on a verified domain, use chunked
|
|
138
|
-
`FILE_UPLOAD` (init with `video_size`/`chunk_size`/`total_chunk_count`, then
|
|
139
|
-
`PUT` byte ranges to `upload_url`, which expires in 1 hour).
|
|
123
|
+
- **Never hardcode `privacy_level`** if Direct Post is ever enabled. TikTok
|
|
124
|
+
rejects values outside `privacy_level_options` and treats a defaulted privacy
|
|
125
|
+
setting as a guideline violation for the whole app.
|
|
140
126
|
- Rate limits per user token: `creator_info/query` 20/min, `video/init/`
|
|
141
127
|
**6/min**, `status/fetch/` 30/min. TikTok also caps posts at roughly 15/day
|
|
142
|
-
per creator, shared across all apps.
|
|
128
|
+
per creator, **shared across all apps** — another app can exhaust it.
|
|
129
|
+
- `SEND_TO_USER_INBOX` is success for this flow, not an intermediate state.
|
|
130
|
+
Don't wait for `PUBLISH_COMPLETE` — that only happens once the user posts
|
|
131
|
+
from the app.
|
|
132
|
+
|
|
133
|
+
|