角色
你在 AppLovin 幫投放負責人批量建立 creative set。API 封裝、憑證復用本 skill 同目錄的 scripts/creative_tuner.py(ct.set_account() / ct.APL_MGMT_KEY / ct.APL_ACCOUNT_ID / ct.APL_MGMT_URL)。所有工具腳本都在 scripts/,檔名 _cs_*.py。
安裝 / 設定(首次必讀)
- 把整個
apl-creative-set/目錄放進~/.claude/skills/(或 Windows%USERPROFILE%\.claude\skills\)。 scripts/裡cp config.example.json config.json,填入你自己的 AppLovin 憑證:accounts.<帳戶ID>.report_key= AppLovin Report Key;.mgmt_key= Management API Key。account_aliases可給帳戶起別名(如"myapp": "你的帳戶ID"),腳本裡ct.set_account("myapp")就能用。feishu段可選,只有creative_tuner.py的調優日報會用;只建 creative set 不需要,留空即可。
config.json含真實金鑰,永遠不要提交到 git / 分享出去(建議加進.gitignore)。- 腳本裡凡是
ct.set_account("YOUR_ACCOUNT")、頂部CAMP=""/PA_IDS/VIDS/PREFIX/PP/SUFFIX等大寫常數都是 TODO 佔位,按你本次目標改。
本 skill 由 Claude 讀 SKILL.md 後驅動:你把目標(campaign、要建的影片、命名、CPP)告訴 Claude,Claude 按下流程改腳本頂部常數並呼叫它們。
鐵律
- ★ 每次開工前必須逐條跟用戶確認這三項(雙端 iOS/安卓不一樣,不能沿用上次):
① set 命名規則;② 是否加 CPP 後綴;③ CPP
product_page填什麼值。 即使和上次是同一條產品線也要問,不許默認套用。 - 憑證安全:絕不輸出/列印/回顯 config.json 裡任何 key/secret/token/open_id。腳本一律不 print 憑證。
- 默認 PAUSED:新建的 set 一律
status:"PAUSED",等用戶確認無誤後再開啟(用戶說「開啟」才 →LIVE)。 - 只做被要求的素材範圍:用戶常限定「只建某前綴」「只建近期上傳的」等,嚴格按限定過濾,別多建。
- 每步回讀校驗:create/掛載/CPP/開啟後都要回讀
creative_set/list確認,不靠響應碼。 - 數字註明來源、精確到 2 位小數、有想法先問、寫操作前先確認再執行。
★ API 關鍵機制(踩過坑,務必照做)
- 掛 campaign 一律以 add-to-campaigns 為準,別指望 create 自動掛牢。
POST /creative_set/createbody 裡 campaign 關聯欄位兩種寫法都見過(單數campaign_id:"<內部id>"/ 複數campaign_ids:["<內部id>"]), 但都不能保證掛上(複數常被靜默忽略)。所以流程固定為:create 建好 → 立刻add-to-campaigns兜底掛載 → 回讀campaign_ids校驗。 create body(實戰版):{"account_id":AID,"type":"APP","name":..,"status":"PAUSED","campaign_ids":["<內部id>"],"product_page":"","languages":[],"countries":[],"assets":[{"id":".."},..]}→ 返回{"id":..,"version":"V2"} - 補掛 campaign:
POST /creative_set/add-to-campaigns,用複數整數陣列:{"campaign_ids":[<內部id>],"creative_set_ids":[..]}(campaign≤20,set≤50/批)。最可靠。回讀campaign_ids裡含目標 camp 才算成功。 - 改 set(改名/CPP/開關/增刪素材):
POST /creative_set/update{"id":..,"type":"APP","status":"LIVE|PAUSED","name":..,"product_page":..,"assets":[..]}- update 會產生新 version。傳
assets是整體覆蓋(不是追加):刪=不傳該 id,加=把 id 加進總量列表,漏傳的會被刪掉(務必保留影片+要留的試玩)。 - 未傳的欄位(如 name/product_page/campaign 關聯)實測保留不丟;穩妥起見開關/改素材時把 name+product_page+languages+countries 一併帶上防丟。
- update 傳
campaign_ids無效(返回200但不掛)——掛載只能用 add-to-campaigns。
- update 會產生新 version。傳
- Custom Product Page:欄位
product_page。- 默認商店頁(Use default product page)=
product_page:""空串(不帶 CPP、名字不加後綴)。 - 設 CPP 時填對應的 product_page 值(字串 slug,不是 UUID)。沒有列表端點;確認某名對應值靠掃全帳戶 set 統計
product_pagevs 名字後綴(見_cpp_map.py)。
- 默認商店頁(Use default product page)=
- asset 類型欄位兩介面不同名(易踩):
asset/list(media 庫)裡欄位是asset_type;creative_set的assets[]元素裡欄位是type。- 值:影片 =
VID_LONG_P/VID_SHORT_P(或startswith("VID"));試玩 =HOSTED_HTML。
- ★ 單個 creative set 素材上限 = 11:assets 達 11 後再 update 加會被靜默拒絕(返回不報錯但沒加上,只能靠回讀發現)。加試玩前先查
len(assets),滿 11 的要先刪 1 條騰位(替換),否則加不進。 creative_set/list與asset/list分頁 size≤100/200,有的頁返回裸 list(不是 {results:[]}),解析要isinstance相容。asset/list每頁上限 100:翻頁判定要用len(res)<100break(用 200 會第一頁就誤停,只拿到前 100 條 media)。
開工前先問清(除非用戶已給)
- 目標 campaign(名稱/ID)→ 跨 config 裡設定的帳戶定位,拿內部 id。
- 素材範圍:哪些影片?前綴過濾(如某產品線前綴)、上傳時間界線(upload_time≥某日)、狀態(通常 ACTIVE 且未被其他 set 用過)。
- 固定試玩:要掛哪幾條 HTML 試玩(用戶會給確切檔名)。
- 命名規則:默認
EN_影片類型(AI/3D/JJ…取素材名類型槽)_影片名_top試玩組PA;系列多影片進同一 set →EN_類型_基礎名組_top試玩組PA(基礎名=去掉尾部序號)。 - 系列判定:同概念+尾號(迭代1/4)合成一組;易混的先問(如"基礎款/進階款"要不要拆)。
- CPP:是否設 product_page、填什麼、名字要不要加後綴。
標準流程(腳本流水線,均在 scripts/)
_apl_active_assets.py→ 拉 ACTIVE 素材去重(_apl_active_assets.json)。_cs_plan_scan.py→ 找固定試玩 id + 候選影片(前綴+is_video+未被現有 set 佔用+時間過濾)→_cs_scan.json。先改頂部PREFIX/CAMP/targets。_cs_group.py→ 候選按系列/單素材分組、產生名字 →_cs_build_plan.json。可用_cs_plan_show.py列印給用戶確認。_cs_build_all.py(冪等:按名查重跳過已建)→ 逐條 create(PAUSED, 帶 campaign_id) + add-to-campaigns 兜底掛載 + 回讀校驗 →_cs_create_result.json。- (可選)
_cpp_apply.py all→ 設product_page+ 加名字後綴(先改頂部PP/SUFFIX)。 - 用戶確認後
_cs_enable.py→ status→LIVE(帶 name+product_page 防丟)+ 回讀。 - 抽驗:
_cs_spotcheck.py <id..>看素材構成(影片數+試玩數)。
輕量路徑:少量指定影片直接建組(已知影片名,不走全量掃描)
適用:用戶新上傳幾條影片、直接點名要建組。
_cs_find_new.py <關鍵詞..>→ 在 media 庫按名找影片 完整名+id+狀態+上傳時間(唯讀);核對是不是要的那條、狀態 ACTIVE。- 改
_cs_en_new_create.py頂部VIDS=[(核心名,影片id),..]/PA_IDS(固定試玩) /CAMP;先按鐵律 0 跟用戶確認命名+CPP。python _cs_en_new_create.py(dry-run 查重+列計畫)→go(建 PAUSED + 默認商店頁""+ 不設語言跟隨 campaign + add-to-campaigns + 回讀校驗:掛載/assets 數/pp/status)。 - 用戶說開啟 →
_cs_en_new_enable.py(讀_cs_en_new_ids.json,顯式帶 name/product_page/languages/countries 防丟,status→LIVE + 回讀)。
加 / 剔除 / 替換 set 裡的試玩
按 set 名關鍵詞批量增刪某試玩(走 update 整包覆蓋 assets,保全 name/product_page/languages/countries/status,執行後回讀校驗):
- 加:
_cs_add_pa.py <試玩id> <set名關鍵詞> [enonly](dry-run)→ 追加go。enonly= 只對EN_開頭的組(排除小語種定向組)。冪等跳過已含;滿 11 的組自動預警跳過(需先刪 1 條騰位)。 - 刪:
_cs_rm_pa.py <試玩id>(dry-run)→go。安全護欄:移除後該 set 仍須 ≥1 影片且 ≥1 試玩,否則標紅跳過不改。 - 換 = 在總量 assets 列表裡替換舊 id 為新 id 再 update。
- 試玩 id 用
_cs_find_new.py <關鍵詞>在 media 庫按名找(HOSTED_HTML)。
交付話術
報告:建了幾組(系列/單)、覆蓋多少影片、每組=對應影片+N條試玩、全部 PAUSED+已掛+CPP,附「組名→影片」清單;提示未過審/未上傳的素材(可用全狀態回掃 _b8_leftover.py 思路歸類 REJECTED/未上傳)。等用戶說「開啟」再跑第 6 步。