create_conversion
Create Google Ads conversion actions for tracking signups, purchases, or leads, generating IDs and labels for Google Tag Manager setup.
Instructions
Create a conversion action in Google Ads. Returns the conversion ID and label for GTM setup.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name for the conversion action (e.g., 'Signup', 'Purchase') | |
| value | No | Default conversion value in USD (optional) | |
| category | No | Conversion category (default: LEAD) |
Implementation Reference
- src/index.ts:362-389 (registration)Tool registration defining the create_conversion tool with name, description, and JSON schema for input validation. Accepts name (required), value (optional), and category (optional with enum values).
// ───────────────────────────────────────────────────────────────────────── // CONVERSION TRACKING // ───────────────────────────────────────────────────────────────────────── { name: "create_conversion", description: "Create a conversion action in Google Ads. Returns the conversion ID and label for GTM setup.", annotations: { destructiveHint: true }, inputSchema: { type: "object" as const, properties: { name: { type: "string", description: "Name for the conversion action (e.g., 'Signup', 'Purchase')", }, value: { type: "number", description: "Default conversion value in USD (optional)", }, category: { type: "string", enum: ["PURCHASE", "SIGNUP", "LEAD", "PAGE_VIEW", "ADD_TO_CART", "DOWNLOAD", "OTHER"], description: "Conversion category (default: LEAD)", }, }, required: ["name"], }, }, - src/index.ts:701-956 (handler)Main handler function that executes tool logic. Maps create_conversion tool to google_ads_create_conversion script, transforms arguments to CLI format, and calls the Synter API.
async function handleTool( name: string, args: ToolArgs ): Promise<Record<string, unknown>> { // Map tool names to script names and handle parameters const toolMappings: Record<string, { script: string; platform?: string; argMapper?: (args: ToolArgs) => string[] }> = { // Campaign management list_campaigns: { script: "google_ads_list_campaigns", platform: (args.platform as string) || "google", argMapper: (a) => { const cliArgs: string[] = []; if (a.status) cliArgs.push("--status", a.status as string); if (a.limit) cliArgs.push("--limit", String(a.limit)); return cliArgs; }, }, create_search_campaign: { script: "google_ads_create_search_campaign", platform: "google", argMapper: (a) => { const cliArgs: string[] = [ "--campaign-name", a.campaign_name as string, "--daily-budget", String(a.daily_budget), "--final-url", a.final_url as string, ]; (a.keywords as string[] || []).forEach((k) => cliArgs.push("--keyword", k)); (a.headlines as string[] || []).forEach((h) => cliArgs.push("--headline", h)); (a.descriptions as string[] || []).forEach((d) => cliArgs.push("--description", d)); (a.geo_targets as string[] || []).forEach((g) => cliArgs.push("--geo-targets", g)); return cliArgs; }, }, create_display_campaign: { script: "google_ads_create_display_campaign", platform: "google", argMapper: (a) => { const cliArgs: string[] = [ "--campaign-name", a.campaign_name as string, "--daily-budget", String(a.daily_budget), "--business-name", a.business_name as string, "--final-url", a.final_url as string, ]; if (a.landscape_image_url) cliArgs.push("--landscape-image", a.landscape_image_url as string); if (a.square_image_url) cliArgs.push("--square-image", a.square_image_url as string); (a.headlines as string[] || []).forEach((h) => cliArgs.push("--headline", h)); (a.descriptions as string[] || []).forEach((d) => cliArgs.push("--description", d)); (a.geo_targets as string[] || []).forEach((g) => cliArgs.push("--geo-targets", g)); return cliArgs; }, }, create_pmax_campaign: { script: "google_ads_create_pmax_campaign", platform: "google", argMapper: (a) => { const cliArgs: string[] = [ "--campaign-name", a.campaign_name as string, "--daily-budget", String(a.daily_budget), "--business-name", a.business_name as string, "--final-url", a.final_url as string, "--long-headline", a.long_headline as string, ]; if (a.landscape_image_url) cliArgs.push("--landscape-image-url", a.landscape_image_url as string); if (a.square_image_url) cliArgs.push("--square-image-url", a.square_image_url as string); if (a.logo_url) cliArgs.push("--logo-url", a.logo_url as string); if (a.target_cpa) cliArgs.push("--target-cpa", String(a.target_cpa)); (a.headlines as string[] || []).forEach((h) => cliArgs.push("--headline", h)); (a.descriptions as string[] || []).forEach((d) => cliArgs.push("--description", d)); (a.geo_targets as string[] || []).forEach((g) => cliArgs.push("--geo-targets", g)); return cliArgs; }, }, pause_campaign: { script: "pause_campaign", platform: "google", argMapper: (a) => ["--campaign-id", a.campaign_id as string], }, update_campaign_budget: { script: "update_campaign_budget", platform: "google", argMapper: (a) => [ "--campaign-id", a.campaign_id as string, "--budget", String(a.daily_budget), ], }, // Performance get_performance: { script: "pull_google_ads_data", platform: "google", argMapper: (a) => { const cliArgs: string[] = []; if (a.campaign_id) cliArgs.push("--campaign-id", a.campaign_id as string); if (a.date_range) cliArgs.push("--date-range", a.date_range as string); return cliArgs; }, }, get_daily_spend: { script: "get_account_daily_spend", platform: "google", argMapper: (a) => { const cliArgs: string[] = []; if (a.days) cliArgs.push("--days", String(a.days)); return cliArgs; }, }, // Keywords add_keywords: { script: "google_ads_add_keywords", platform: "google", argMapper: (a) => { const cliArgs: string[] = ["--ad-group-id", a.ad_group_id as string]; (a.keywords as string[] || []).forEach((k) => cliArgs.push("--keyword", k)); if (a.match_type) cliArgs.push("--match-type", a.match_type as string); return cliArgs; }, }, add_negative_keywords: { script: "google_ads_add_negative_keywords", platform: "google", argMapper: (a) => { const cliArgs: string[] = ["--campaign-id", a.campaign_id as string]; (a.keywords as string[] || []).forEach((k) => cliArgs.push("--keyword", k)); if (a.level) cliArgs.push("--level", a.level as string); return cliArgs; }, }, // Conversions create_conversion: { script: "google_ads_create_conversion", platform: "google", argMapper: (a) => { const cliArgs: string[] = ["--name", a.name as string]; if (a.value) cliArgs.push("--value", String(a.value)); if (a.category) cliArgs.push("--category", a.category as string); return cliArgs; }, }, list_conversions: { script: "google_ads_list_conversions", platform: "google", argMapper: () => [], }, diagnose_tracking: { script: "diagnose_conversion_tracking", argMapper: (a) => ["--url", a.url as string], }, // Creative generation generate_image: { script: "generate_image", argMapper: (a) => { const cliArgs: string[] = ["--prompt", a.prompt as string]; if (a.size) cliArgs.push("--size", a.size as string); if (a.provider) cliArgs.push("--provider", a.provider as string); if (a.name) cliArgs.push("--name", a.name as string); return cliArgs; }, }, generate_video: { script: "generate_video_ad", argMapper: (a) => { const cliArgs: string[] = [ "--product", a.product_name as string, "--benefit", a.key_benefit as string, ]; if (a.concept) cliArgs.push("--concept", a.concept as string); if (a.target_audience) cliArgs.push("--audience", a.target_audience as string); if (a.duration) cliArgs.push("--duration", String(a.duration)); if (a.provider) cliArgs.push("--provider", a.provider as string); return cliArgs; }, }, // Meta create_meta_campaign: { script: "meta_ads_create_campaign", platform: "meta", argMapper: (a) => [ "--name", a.name as string, "--objective", a.objective as string, "--daily-budget", String(a.daily_budget), ], }, // LinkedIn create_linkedin_campaign: { script: "linkedin_ads_create_campaign_complete", platform: "linkedin", argMapper: (a) => { const cliArgs: string[] = [ "--name", a.name as string, "--objective", a.objective as string, "--daily-budget", String(a.daily_budget), ]; (a.target_company_sizes as string[] || []).forEach((s) => cliArgs.push("--company-size", s)); (a.target_industries as string[] || []).forEach((i) => cliArgs.push("--industry", i)); (a.target_job_functions as string[] || []).forEach((j) => cliArgs.push("--job-function", j)); return cliArgs; }, }, // Reddit create_reddit_campaign: { script: "reddit_ads_create_campaign", platform: "reddit", argMapper: (a) => { const cliArgs: string[] = [ "--name", a.name as string, "--objective", a.objective as string, "--daily-budget", String(a.daily_budget), ]; (a.subreddits as string[] || []).forEach((s) => cliArgs.push("--subreddit", s)); (a.interests as string[] || []).forEach((i) => cliArgs.push("--interest", i)); return cliArgs; }, }, // Utility list_ad_accounts: { script: "google_ads_list_customers", platform: "google", argMapper: () => [], }, upload_image: { script: "google_ads_upload_image_asset", platform: "google", argMapper: (a) => [ "--image-url", a.image_url as string, "--asset-name", a.asset_name as string, ], }, run_tool: { script: args.script_name as string, platform: (args.platform as string) || undefined, argMapper: (a) => (a.args as string[]) || [], }, }; const mapping = toolMappings[name]; if (!mapping) { throw new Error(`Unknown tool: ${name}`); } const scriptArgs = mapping.argMapper ? mapping.argMapper(args) : []; return callSynterAPI("tools/run", { script_name: mapping.script, args: scriptArgs, platform: typeof mapping.platform === "function" ? mapping.platform : mapping.platform || (args.platform as string), }); } - src/index.ts:666-693 (helper)Helper function that makes HTTP POST requests to the Synter API. Handles authentication, request formatting, and error handling for all tool API calls.
async function callSynterAPI( endpoint: string, body: Record<string, unknown> ): Promise<Record<string, unknown>> { if (!SYNTER_API_KEY) { throw new Error( "SYNTER_API_KEY not set. Get your API key at https://syntermedia.ai/developer" ); } const response = await fetch(`${SYNTER_API_URL}/api/v1/${endpoint}`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${SYNTER_API_KEY}`, }, body: JSON.stringify(body), }); const data = await response.json() as Record<string, unknown>; if (!response.ok) { const errorMsg = (data.error as string) || (data.message as string) || `API error: ${response.status}`; throw new Error(errorMsg); } return data; }