@bluevs/ttcli 0.0.2 → 0.0.4
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": "@bluevs/ttcli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "TikTok CLI - designed for AI Agent and developers",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ttcli": "scripts/run.js"
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"postinstall": "node -e \"console.log('\\n📦 ttcli installed. To install the openclaw skill, run:\\n bash $(npm root -g)/@bluevs/ttcli/skills/ttcli/scripts/install-skill.sh\\n')\""
|
|
10
10
|
},
|
|
11
11
|
"optionalDependencies": {
|
|
12
|
-
"@bluevs/ttcli-darwin-arm64": "0.0.
|
|
13
|
-
"@bluevs/ttcli-darwin-x64": "0.0.
|
|
14
|
-
"@bluevs/ttcli-linux-arm64": "0.0.
|
|
15
|
-
"@bluevs/ttcli-linux-x64": "0.0.
|
|
16
|
-
"@bluevs/ttcli-win32-arm64": "0.0.
|
|
17
|
-
"@bluevs/ttcli-win32-x64": "0.0.
|
|
12
|
+
"@bluevs/ttcli-darwin-arm64": "0.0.4",
|
|
13
|
+
"@bluevs/ttcli-darwin-x64": "0.0.4",
|
|
14
|
+
"@bluevs/ttcli-linux-arm64": "0.0.4",
|
|
15
|
+
"@bluevs/ttcli-linux-x64": "0.0.4",
|
|
16
|
+
"@bluevs/ttcli-win32-arm64": "0.0.4",
|
|
17
|
+
"@bluevs/ttcli-win32-x64": "0.0.4"
|
|
18
18
|
},
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">=16"
|
package/skills/ttcli/SKILL.md
CHANGED
|
@@ -1,14 +1,48 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ttcli
|
|
3
|
+
version: 0.0.4
|
|
3
4
|
description: 直接调用 TikTok Marketing API(access token 鉴权,不经 VH 平台/项目层)。当用户提供原生 TikTok access_token + advertiser_id、要直连 TikTok 创建或查询 Smart+ campaign/adgroup/ad、或查 identity/app/region 等元数据时使用。注意:用户走 VH 项目流程(po_xxxx + account_id)的 TikTok 创编应改走 vhcli tiktok。
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# TikTok CLI (`ttcli`)
|
|
7
8
|
|
|
9
|
+
> **Skill version**: `0.0.4`
|
|
10
|
+
>
|
|
11
|
+
> 当用户问"ttcli skill 版本是多少 / skill 装好了吗 / 升级生效了没" 时,**直接念出上面的版本号**。
|
|
12
|
+
> 用户期望更高版本但没看到 → 让他们:(1) 重跑 `npm install -g @bluevs/ttcli && bash $(npm root -g)/@bluevs/ttcli/skills/ttcli/scripts/install-skill.sh` (2) 然后**新开一个会话**(skill 在会话启动时加载,老会话不刷新)。
|
|
13
|
+
|
|
8
14
|
`ttcli` wraps TikTok Marketing API (`business-api.tiktok.com`) as a CLI optimized for AI agents. JSON output by default; the `--human` flag exists for project-owner debugging only — agents should never pass it.
|
|
9
15
|
|
|
10
16
|
This skill is intentionally short. Always treat `ttcli -h` and `ttcli <subcommand> -h` as the primary reference for flags.
|
|
11
17
|
|
|
18
|
+
## 🚨 与用户对话的硬性约定:错误信息要翻译
|
|
19
|
+
|
|
20
|
+
ttcli 和 TikTok 返回的报错都是技术语言(`missing required fields: [adgroup_id]`、`Invalid optimization goal`、`code=40002 ...`)。**严禁原样把这些贴给用户**——非技术用户看到字段名、code 数字会懵。
|
|
21
|
+
|
|
22
|
+
**做法**:把每个技术错误翻译成业务语言后回给用户,**保留 request_id 仅供你自己排查**。
|
|
23
|
+
|
|
24
|
+
参考翻译表(不全,按这个方式扩展):
|
|
25
|
+
|
|
26
|
+
| 技术错误(你看到的) | 翻给用户(你要说的) |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `missing required fields: [adgroup_id]` | "我还需要知道把广告挂在哪个广告组下,能告诉我广告组 ID 或名字吗?" |
|
|
29
|
+
| `missing required fields: [campaign_name]` | "你这条 campaign 想叫什么名字?" |
|
|
30
|
+
| `code=40105 Access token is incorrect or has been revoked` | "你的授权过期或被撤销了,请去 TikTok Marketing 后台重新生成 access token 给我" |
|
|
31
|
+
| `code=40001 No permission to operate advertiser` | "当前 token 没权限管这个广告主,你的 token 对应的广告主 ID 可能不一样" |
|
|
32
|
+
| `code=40002 placement_type only supports PLACEMENT_TYPE_NORMAL` | "小游戏只能选'手动版位',我帮你设好" |
|
|
33
|
+
| `code=40002 Invalid optimization goal. Please change your goal or promotion type` | "这个推广类型不支持你说的优化目标,小游戏一般用 ROAS(投产比)优化,要换吗?" |
|
|
34
|
+
| `code=40002 This ad does not support infinite budget mode` | "这种广告必须有日预算,不能无限。我帮你设个最低日预算" |
|
|
35
|
+
| `code=40002 Allowlist not enabled` | "这个高级功能你账户没开通白名单,要联系 TikTok 客户经理开通;我们换一种简单方案吧" |
|
|
36
|
+
| `code=40002 Something went wrong. Contact support` | "TikTok 后台报了个不明错误。我先把请求 ID 记下来:`<request_id>`,必要时你拿这个找 TikTok 技术支持。我们试另一种配置看能不能绕过" |
|
|
37
|
+
| `body is not a JSON object` / 客户端 validation | 不要暴露 JSON / body 概念。直接说"我组装的请求格式有问题,让我重做"——然后自己重组 |
|
|
38
|
+
| 网络层错误(EOF、context deadline)| "网络抖了一下,我重试一次" |
|
|
39
|
+
|
|
40
|
+
**原则**:
|
|
41
|
+
- 用户看到的应该是"接下来你/我做什么",不是"什么字段错了"
|
|
42
|
+
- 翻译要保留**关键判断点**(让用户能给出对的输入),不能含糊到"出错了"
|
|
43
|
+
- 多个字段同时缺 → 合并成一个自然问句,不要逐个列字段名
|
|
44
|
+
- request_id 留你脑子里 / 日志里,**不主动甩给用户**,除非用户明确要"找 TikTok 提工单"
|
|
45
|
+
|
|
12
46
|
## ttcli vs vhcli tiktok — 选哪一个
|
|
13
47
|
|
|
14
48
|
openclaw 同时装了两个 TikTok 广告工具,触发条件不同:
|
|
@@ -68,7 +102,9 @@ Before creating a campaign or adgroup, gather the IDs you'll reference:
|
|
|
68
102
|
|
|
69
103
|
```
|
|
70
104
|
ttcli auth show # confirm credentials loaded + their source
|
|
71
|
-
ttcli app list # → app_id
|
|
105
|
+
ttcli app list # → app_id (Android/iOS apps)
|
|
106
|
+
ttcli minis list # → minis_id (TikTok Minis: MINI_GAME / MINI_SERIES)
|
|
107
|
+
ttcli identity list # → identity_id (Spark Ads publishing identity)
|
|
72
108
|
ttcli smart-plus campaign list # → existing campaign_id (or you'll create one)
|
|
73
109
|
ttcli tool region \
|
|
74
110
|
--placements=PLACEMENT_TIKTOK \
|
|
@@ -264,11 +300,15 @@ Per the doc: "对于现有广告账号,当广告组的投放广告位为自动
|
|
|
264
300
|
|
|
265
301
|
| Need | Endpoint | ttcli command |
|
|
266
302
|
|---|---|---|
|
|
303
|
+
| List apps under advertiser | `/app/list/` | `ttcli app list` |
|
|
304
|
+
| List Minis under advertiser | `/minis/get/` | `ttcli minis list` |
|
|
267
305
|
| List identities under advertiser | `/identity/get/` | `ttcli identity list` (filter by `--identity-type`) |
|
|
268
306
|
| `tiktok_item_id` (Spark Ads) | `/tt_video/info/` | `ttcli tt-video info --auth-code=...` |
|
|
269
307
|
| List posts under an identity | `/identity/video/get/` | `ttcli identity video list --identity-id=... --identity-type=...` |
|
|
270
308
|
| Verify `identity_id` | `/identity/info/` | `ttcli identity info --identity-id=... --identity-type=...` |
|
|
271
|
-
|
|
|
309
|
+
| Search ad-library videos (`video_id`) | `/file/video/ad/search/` | `ttcli file video search` |
|
|
310
|
+
| Search ad-library images (`image_id`) | `/file/image/ad/search/` | `ttcli file image search` |
|
|
311
|
+
| Upload video → `video_id` | `/file/video/ad/upload/` | ⏳ not yet wrapped |
|
|
272
312
|
| Upload image → `web_uri` | `/file/image/ad/upload/` | ⏳ not yet wrapped |
|
|
273
313
|
| Music → `music_id` | (separate music API) | ⏳ not yet wrapped |
|
|
274
314
|
|
|
@@ -33,13 +33,32 @@ WORKSPACE_SKILL_DIR="$WORKSPACE/skills/ttcli"
|
|
|
33
33
|
NPM_ROOT="$(npm root -g 2>/dev/null || echo '')"
|
|
34
34
|
PKG_DIR="${NPM_ROOT:+$NPM_ROOT/@bluevs/ttcli}"
|
|
35
35
|
|
|
36
|
-
#
|
|
36
|
+
# 版本来源(按优先级):
|
|
37
|
+
# 1. SKILL.md frontmatter 的 version: 字段 —— 单一权威源
|
|
38
|
+
# 2. SKILL.md mtime fallback —— frontmatter 缺 version: 字段时兜底
|
|
39
|
+
#
|
|
40
|
+
# 开发期(SOURCE_DIR 不在 npm 包目录内)会在 frontmatter 版本号后加 -dev-{mtime}
|
|
41
|
+
# 后缀,确保改 SKILL.md 不动 frontmatter 时也能触发同步。
|
|
42
|
+
# 生产期(SOURCE_DIR 在 npm 包目录内,post-install 场景)直接用 frontmatter
|
|
43
|
+
# 版本号,跟 npm package.json 对齐,便于用户报"我装的是哪个版本"。
|
|
37
44
|
get_version() {
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
local v
|
|
46
|
+
v=$(awk -F': *' '/^version: *[^ ]/ { print $2; exit }' "$SKILL_FILE" | tr -d '\r ')
|
|
47
|
+
if [ -z "$v" ]; then
|
|
48
|
+
date -r "$SKILL_FILE" "+local-%Y%m%d-%H%M%S" 2>/dev/null || echo "local-unknown"
|
|
49
|
+
return
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# 生产模式:SOURCE_DIR 在 npm 包内 → 直接用 frontmatter 版本
|
|
53
|
+
if [ -n "$PKG_DIR" ] && [ -d "$PKG_DIR" ] && [[ "$SOURCE_DIR" == "$PKG_DIR"* ]]; then
|
|
54
|
+
echo "$v"
|
|
55
|
+
return
|
|
40
56
|
fi
|
|
41
|
-
|
|
42
|
-
|
|
57
|
+
|
|
58
|
+
# 开发模式:加 -dev-{mtime} 后缀
|
|
59
|
+
local mtime
|
|
60
|
+
mtime=$(date -r "$SKILL_FILE" "+%Y%m%d-%H%M%S" 2>/dev/null || echo "unknown")
|
|
61
|
+
echo "${v}-dev-${mtime}"
|
|
43
62
|
}
|
|
44
63
|
|
|
45
64
|
# ============================================================
|