Skip to content

Commit 71f34a9

Browse files
authored
feat(debug): implement debug tiktok-ads raw API passthrough (#18)
Wires pipeboard debug tiktok-ads to POST /api/debug/tiktok-ads (admin-only). Adds a --method flag (GET default) and parses --params as arbitrary JSON so nested TikTok bodies work (e.g. creative portfolio create, /ad/create/). Replaces the not-implemented stub.
1 parent fc9f56b commit 71f34a9

1 file changed

Lines changed: 44 additions & 5 deletions

File tree

‎cmd/debug.go‎

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ func init() {
9797

9898
// TikTok Ads debug
9999
debugTikTokAdsCmd.Flags().StringVar(&debugTikTokAdvertiserID, "advertiser-id", "", "TikTok advertiser ID (required)")
100-
debugTikTokAdsCmd.Flags().StringVar(&debugTikTokEndpoint, "endpoint", "", "TikTok API endpoint path (required)")
101-
debugTikTokAdsCmd.Flags().StringVar(&debugTikTokParams, "params", "{}", "JSON params for the request")
100+
debugTikTokAdsCmd.Flags().StringVar(&debugTikTokEndpoint, "endpoint", "", "TikTok API endpoint path, e.g. /creative/portfolio/list/ or /ad/create/ (required)")
101+
debugTikTokAdsCmd.Flags().StringVar(&debugTikTokMethod, "method", "GET", "HTTP method: GET or POST")
102+
debugTikTokAdsCmd.Flags().StringVar(&debugTikTokParams, "params", "{}", "JSON params for the request (GET: query; POST: body)")
102103
debugTikTokAdsCmd.MarkFlagRequired("advertiser-id")
103104
debugTikTokAdsCmd.MarkFlagRequired("endpoint")
104105
debugCmd.AddCommand(debugTikTokAdsCmd)
@@ -354,22 +355,60 @@ func runDebugGoogleAdsCall(cmd *cobra.Command, args []string) error {
354355
return callGoogleAdsTool(debugGoogleToolName, toolArgs)
355356
}
356357

357-
// --- TikTok Ads debug (placeholder - not yet implemented server-side) ---
358+
// --- TikTok Ads debug ---
358359

359360
var debugTikTokAdsCmd = &cobra.Command{
360361
Use: "tiktok-ads",
361362
Short: "Send raw API query to TikTok Ads API",
362-
RunE: runDebugTikTokAds,
363+
Long: `Send a raw TikTok Marketing API request through Pipeboard (admin only).
364+
365+
Returns TikTok's full envelope ({ code, message, request_id, data }) and never
366+
throws on a non-zero code, so you can iterate against opaque 40002s field-by-field.
367+
368+
Examples:
369+
pipeboard debug tiktok-ads --advertiser-id 123 --endpoint /creative/portfolio/get/ --params '{"creative_portfolio_id":"765..."}'
370+
pipeboard debug tiktok-ads --advertiser-id 123 --endpoint /creative/portfolio/create/ --method POST --params '{"portfolio_type":"CALL_TO_ACTION","portfolio_content":[{"asset_content":"SHOP_NOW","asset_ids":["1"]}]}'`,
371+
RunE: runDebugTikTokAds,
363372
}
364373

365374
var (
366375
debugTikTokAdvertiserID string
367376
debugTikTokEndpoint string
377+
debugTikTokMethod string
368378
debugTikTokParams string
369379
)
370380

371381
func runDebugTikTokAds(cmd *cobra.Command, args []string) error {
372-
return fmt.Errorf("not yet implemented server-side. Coming soon")
382+
token, err := getToken()
383+
if err != nil {
384+
return err
385+
}
386+
387+
// Parse optional params as arbitrary JSON — TikTok bodies nest arrays/objects
388+
// (e.g. portfolio create, /ad/create/ creatives), so map[string]string is too narrow.
389+
var params map[string]interface{}
390+
if debugTikTokParams != "" && debugTikTokParams != "{}" {
391+
if err := json.Unmarshal([]byte(debugTikTokParams), &params); err != nil {
392+
return fmt.Errorf("invalid JSON in --params: %w", err)
393+
}
394+
}
395+
396+
body := map[string]interface{}{
397+
"advertiser_id": debugTikTokAdvertiserID,
398+
"endpoint": debugTikTokEndpoint,
399+
"method": debugTikTokMethod,
400+
}
401+
if params != nil {
402+
body["params"] = params
403+
}
404+
405+
c := client.NewREST(getWebAPIURL(), token, Version)
406+
result, err := c.Post("/api/debug/tiktok-ads", body)
407+
if err != nil {
408+
return fmt.Errorf("debug query failed: %w", err)
409+
}
410+
411+
return printJSON(result)
373412
}
374413

375414
func printJSON(v interface{}) error {

0 commit comments

Comments
 (0)