@acedatacloud/skills 2026.801.0 → 2026.801.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acedatacloud/skills",
3
- "version": "2026.801.0",
3
+ "version": "2026.801.2",
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",
@@ -1,63 +1,142 @@
1
1
  ---
2
2
  name: tiktok
3
- description: Upload videos to the user's TikTok inbox/drafts and read their TikTok profile via the Content Posting API. Use when the user wants to publish or post a generated video to TikTok, send a video to their TikTok drafts, or check their TikTok account.
3
+ description: Post videos to the user's TikTok — either published directly (with caption and privacy the user chooses) or uploaded to their drafts/inbox. Use when the user wants to publish or post a generated video to TikTok, send a video to their TikTok drafts, or check which TikTok account is connected.
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. v1 uploads to the user's **inbox /
7
- drafts** (they finish posting in the TikTok app) — the safe,
8
- pre-audit path. Confirm before uploading; the video must be a public
9
- URL on a verified domain (or a file you upload in chunks).
6
+ the video skills) to TikTok. Direct Post publishes immediately with a
7
+ caption and a privacy level the user picks; Upload drops it into
8
+ drafts for them to finish in the app. Always confirm caption and
9
+ privacy with the user before posting — never post unattended.
10
10
  connections: [tiktok]
11
11
  allowed_tools: [Bash]
12
12
  license: Apache-2.0
13
13
  metadata:
14
14
  author: acedatacloud
15
- version: "1.0"
15
+ version: "2.1"
16
16
  ---
17
17
 
18
- Call the **TikTok Content Posting API** with `curl + jq`. The user's OAuth bearer
19
- token is in `$TIKTOK_TOKEN`; every call needs `Authorization: Bearer
20
- $TIKTOK_TOKEN`. Base URL: `https://open.tiktokapis.com/v2`.
21
-
22
- Responses wrap everything in `{"data":...,"error":{"code","message","log_id"}}` —
23
- `error.code == "ok"` means success; otherwise show `error.message` verbatim.
24
- `401`/`access_token_invalid` = re-connect TikTok.
18
+ Call the **TikTok API v2** with `curl + jq`. The user's OAuth bearer token is in
19
+ `$TIKTOK_TOKEN`; every call needs `Authorization: Bearer $TIKTOK_TOKEN`. Base
20
+ URL: `https://open.tiktokapis.com/v2`.
25
21
 
26
22
  ```bash
27
23
  T="https://open.tiktokapis.com/v2"; AUTH="Authorization: Bearer $TIKTOK_TOKEN"
28
- # Profile (account card)
24
+ ```
25
+
26
+ Responses wrap everything in `{"data":…,"error":{"code","message","log_id"}}`.
27
+ **Check `error.code`, not just the HTTP status** — several real failures
28
+ (`spam_risk_too_many_posts`, `spam_risk_user_banned_from_posting`,
29
+ `reached_active_user_cap`) come back as **HTTP 200** with a non-`ok` code. Show
30
+ `error.message` verbatim. `401` / `access_token_invalid` = re-connect TikTok.
31
+
32
+ ## Read the account
33
+
34
+ ```bash
35
+ # Basic profile — open_id identifies the user for every posting call
29
36
  curl -sS -H "$AUTH" "$T/user/info/?fields=open_id,display_name,avatar_url" \
30
37
  | jq '.data.user'
31
38
  ```
32
39
 
33
- ## Upload a video to the user's inbox / drafts (v1)
40
+ Follower / like counts, bio, and the user's video list need the **Display API**
41
+ scopes (`user.info.stats`, `user.info.profile`, `video.list`), which this app
42
+ has not been granted — don't call `/v2/video/list/` or request those fields,
43
+ they will fail with `scope_not_authorized`.
44
+
45
+ ## Direct Post — publish straight to the account
46
+
47
+ Three steps, in this order. **Step 1 is mandatory** and its result drives what
48
+ you may offer the user.
34
49
 
35
- The simplest path is `PULL_FROM_URL`: TikTok fetches the video from a public URL
36
- on a **verified domain** (AceData's `cdn.acedata.cloud` is verified for this app).
50
+ ### 1. Query creator info (required before every post)
37
51
 
38
52
  ```bash
39
- VIDEO_URL="https://cdn.acedata.cloud/...mp4" # must be on a verified domain
40
- curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" -d "$(jq -n --arg u "$VIDEO_URL" \
41
- '{source_info:{source:"PULL_FROM_URL", video_url:$u}}')" \
42
- "$T/post/publish/inbox/video/init/" | jq '{publish_id: .data.publish_id, error}'
53
+ curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
54
+ "$T/post/publish/creator_info/query/" | jq '.data, .error.code'
43
55
  ```
44
56
 
45
- This drops the video into the user's TikTok **inbox** — they open the TikTok app
46
- to add caption / sound / privacy and post. Poll status:
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.
69
+
70
+ ### 2. Ask the user to confirm
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
47
81
 
48
82
  ```bash
83
+ VIDEO_URL="https://cdn.acedata.cloud/….mp4" # verified-domain public URL
49
84
  curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
50
- -d '{"publish_id":"PUBLISH_ID"}' "$T/post/publish/status/fetch/" \
51
- | jq '.data | {status, fail_reason}'
85
+ -d "$(jq -n --arg t "$CAPTION" --arg p "$PRIVACY" --arg u "$VIDEO_URL" '{
86
+ post_info: {title:$t, privacy_level:$p, is_aigc:true},
87
+ source_info: {source:"PULL_FROM_URL", video_url:$u}}')" \
88
+ "$T/post/publish/video/init/" | jq '{publish_id:.data.publish_id, error}'
52
89
  ```
53
90
 
91
+ **Set `is_aigc: true` whenever the video was AI-generated** (anything from our
92
+ video skills). TikTok labels it "Creator labeled as AI-generated" — required
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`.
99
+
100
+ ## Upload to drafts instead
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**:
104
+
105
+ ```bash
106
+ curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
107
+ -d "$(jq -n --arg u "$VIDEO_URL" '{source_info:{source:"PULL_FROM_URL", video_url:$u}}')" \
108
+ "$T/post/publish/inbox/video/init/" | jq '{publish_id:.data.publish_id, error}'
109
+ ```
110
+
111
+ ## Poll status (both flows)
112
+
113
+ ```bash
114
+ curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
115
+ -d "$(jq -n --arg id "$PUBLISH_ID" '{publish_id:$id}')" \
116
+ "$T/post/publish/status/fetch/" | jq '.data | {status, fail_reason, publicaly_available_post_id}'
117
+ ```
118
+
119
+ Status: `PROCESSING_DOWNLOAD` / `PROCESSING_UPLOAD` → `SEND_TO_USER_INBOX`
120
+ (drafts flow) or `PUBLISH_COMPLETE` (direct post), or `FAILED` with
121
+ `fail_reason`. Tell the user processing takes a few minutes.
122
+
123
+ Don't retry on `auth_removed`, `spam_risk_text`, `spam_risk`, or
124
+ `spam_risk_user_banned_from_posting` — those are terminal. `internal` is
125
+ retryable.
126
+
54
127
  ## Gotchas
55
128
 
56
- - **v1 = inbox upload only.** True "Direct Post" (set caption + privacy via API,
57
- posts immediately) needs the `video.publish` scope and a passed Content Posting
58
- audit — not available until then. Don't call `creator_info` /
59
- `/post/publish/video/init/` (Direct Post) here; they require that scope.
60
- - `PULL_FROM_URL` only works from a **domain verified** in the TikTok developer
61
- app. If the video isn't on a verified domain, use the chunked `FILE_UPLOAD`
62
- flow instead (init → PUT byte ranges → status).
63
- - Unaudited apps are rate-limited and may restrict visibility to `SELF_ONLY`.
129
+ - **Never hardcode `privacy_level`.** TikTok rejects values outside
130
+ `privacy_level_options` (`privacy_level_option_mismatch`) and treats a
131
+ defaulted privacy setting as a guideline violation for the whole app.
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).
140
+ - Rate limits per user token: `creator_info/query` 20/min, `video/init/`
141
+ **6/min**, `status/fetch/` 30/min. TikTok also caps posts at roughly 15/day
142
+ per creator, shared across all apps.