{"id":88487,"plugin_id":"plugin_asdk_app_694a52cfaa3c819192bea84eaa254968","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-11-10T06:07:59.761Z","digest":"1df40d9fc6549b7cbf625b4bbc5756ac23eef3ed3b6777f8455b70f73973addd","against":null,"payload":{"description":"Analyze and manage Google Ads through Windsor.ai. Use when the user asks about their Google Ads performance, such as pulling live campaign, ad group, or keyword metrics (cost, impressions, clicks, conversions, CPA, ROAS), comparing date ranges, or finding top or underperforming campaigns, or when they want to pause or enable campaigns, ad groups or ads, change budgets, bids or bidding strategies, add keywords or negative keywords, set targeting, or create campaigns, ad groups and responsive search ads. Do not use for other ad platforms (Meta/Facebook, TikTok, LinkedIn, Microsoft Ads), organic social, or GA4/website analytics. Also use when the user asks how to connect Google Ads to ChatGPT.","included_files":[{"relative_path":"agents/openai.yaml","size_in_bytes":386}],"name":"google-ads","skill_md_contents":"---\nname: google-ads\ndescription: \"Analyze and manage Google Ads through Windsor.ai. Use when the user asks about their Google Ads performance, such as pulling live campaign, ad group, or keyword metrics (cost, impressions, clicks, conversions, CPA, ROAS), comparing date ranges, or finding top or underperforming campaigns, or when they want to pause or enable campaigns, ad groups or ads, change budgets, bids or bidding strategies, add keywords or negative keywords, set targeting, or create campaigns, ad groups and responsive search ads. Do not use for other ad platforms (Meta/Facebook, TikTok, LinkedIn, Microsoft Ads), organic social, or GA4/website analytics. Also use when the user asks how to connect Google Ads to ChatGPT.\"\n---\n\nExplicit instructions from the user take priority over this skill.\n\n# Google Ads via Windsor.ai\n\nWindsor.ai exposes live Google Ads data (read) and a broad set of campaign\nmanagement actions (write) through MCP tools. The connector id is\n`google_ads`. Pass `google_ads` as the connector on every tool call; the Windsor.ai server\nserves all connectors, so it is never implied.\n\nGolden rules:\n\n- **Never guess field, account, action, or option names.** They come from\n  `get_fields`, `get_connectors`, `list_actions`, and `get_options`. Call those\n  first; do not invent identifiers.\n- **Reads are safe; writes change live ad spend.** Only call `execute_action`\n  after the user has confirmed the specific change.\n- Report numbers the user asked for, concisely. Don't dump raw rows unless asked.\n\n## 1. Check what is connected\n\nCall `get_connectors` to see which Google Ads accounts are connected (each has\nan id and, usually, a name). If none are connected, help the user connect one:\ncall `get_connector_authorization_url` (or `get_connector_connect_info` for the\nauth type and steps) and give them the setup link; do not describe manual\ndashboard navigation.\n\nIf the user names an account, match it to a connected account id. If several are\nconnected and the request is ambiguous, ask which account.\n\n## 2. Reading performance data\n\n1. Call `get_fields` for `google_ads` to get valid field ids (e.g. campaign,\n   ad_group, date, cost/spend, impressions, clicks, conversions, conversion\n   value. Use the exact ids returned, not these examples).\n2. If the analysis needs attribution or segmentation controls, call\n   `get_options` to see the connector's options and valid values.\n3. Call `get_data` with:\n   - `fields`: the ids you actually need (keep the set small).\n   - `accounts`: the target account id(s); omit for all connected accounts.\n   - A date range: either `date_from`/`date_to` (`\"2026-02-01\"`), or\n     `date_preset`: `last_7d`, `last_30d`, `last_Xd`/`last_Xw`/`last_Xm`,\n     `this_month`, `this_year`, `last_year`. Append `T` to include today\n     (e.g. `last_7dT`, `this_monthT`); `T` works on `last_Xd`, `this_month`,\n     `this_year` and `last_year`, not on `last_Xw` or `last_Xm`.\n   - `options`: only if get_options showed relevant ones.\n   - `filters`: optional conditions, e.g. `[[\"cost\", \"gt\", 100]]`; combine with\n     `\"and\"`/`\"or\"` and nest as needed.\n\nCommon requests → recipe:\n\n- **Overview / trend:** fields `date` + the metrics, over a preset range.\n- **By campaign:** fields `campaign` + metrics; sort/aggregate in your answer.\n- **Best / worst campaign:** pull campaign + the metric, then rank; return only\n  what was asked (e.g. just the campaign name) if the user constrained the\n  output format.\n- **Efficiency:** cost per conversion = cost ÷ conversions; ROAS = conversion\n  value ÷ cost. Compute from returned fields; note if conversions are zero.\n\nWatch out: most Google Ads money fields (spend, cost, `budget_amount`) are in\nthe account currency (state it if known); fields ending in `_micros`, and\n`recommended_budget_amount`, `keyword_average_cpc` and `top_of_page_bid_*`,\nare in micros. Check the field description. Conversions can be fractional. If a field the user wants isn't in\n`get_fields`, say so rather than substituting a different metric.\n\n## 3. Managing campaigns (write actions)\n\nGoogle Ads exposes a broad set of write actions via `list_actions` /\n`execute_action`. Always call `list_actions` first for the exact ids and JSON\nschemas, and treat the summary below as a guide. They cover:\n\n- **Create / structure:** `create_campaign` (Search or Display, with a daily\n  budget; created paused), `create_ad_group`, `create_ad_asset`,\n  `rename_campaign`, `rename_ad_group`, `update_ad_group`,\n  `create_responsive_search_ad`\n  (3 to 15 headlines, 2 to 4 descriptions, a final URL; created paused).\n- **Status:** `pause_campaign` / `enable_campaign`, `pause_ad_group` /\n  `enable_ad_group`, `pause_ad` / `enable_ad`.\n- **Keywords:** `push_keywords` (add positive keywords to an ad group; they are created\n  paused by default),\n  `update_keywords`, `remove_keywords`, `push_negative_keywords` and\n  `remove_negative_keywords` (campaign- or ad-group-level).\n- **Targeting and schedule:** `set_campaign_geo_targeting`,\n  `set_campaign_language_targeting`, `set_ad_schedule`.\n- **Budget & bidding:** `set_campaign_budget` (`daily` or `lifetime`, with\n  `apply_to_shared_budget` for shared budgets), `set_campaign_bidding_strategy`\n  (manual CPC, target CPA/ROAS, maximize conversions/clicks, …),\n  `set_target_cpa`, `set_target_roas` (a ratio: 4.0 = 400%, not micros),\n  `set_cpc_bid_ceiling`, `set_max_cpc`.\n- **Customer Match audiences:** `create_customer_match_list`,\n  `upload_customer_match_list` (async; poll `get_customer_match_upload_status`),\n  `rename_customer_match_list`, `delete_customer_match_list`, and\n  `attach_user_list_to_ad_group` / `detach_user_list_from_ad_group`. Upload\n  members as raw email/phone/address; the action hashes them; matching runs in\n  the background and the list isn't targetable until it completes.\n\nBudget mechanics:\n\n- Money amounts are in **micros**: 1,000,000 micros = 1 unit of the account\n  currency, so `50000000` = 50.00. Convert the user's amount to micros.\n- `set_campaign_budget` / targets set an **absolute** value, not a delta. To\n  \"raise by 20%\", read the current value first, compute the new absolute\n  amount, and set that.\n- `create_campaign`, `create_ad_group` and `create_responsive_search_ad`\n  produce **paused** items by default, so nothing serves until the user enables\n  it. `create_ad_asset` has no status, so the asset can start serving once\n  created (call and sitelink assets after Google's review).\n\nWrite workflow; every time:\n\n1. Resolve the campaign to its `campaign_id` (via a `get_data` read on\n   `campaign` + id fields if the user gave a name).\n2. Build the exact params from the `list_actions` schema.\n3. **Show the user the concrete change and ask them to confirm**; e.g.\n   \"Pause campaign 'Summer Sale' (id 123…) on account 456…?\" or \"Set daily\n   budget for campaign X to €50.00 (50000000 micros)?\".\n4. Only after an explicit yes, call `execute_action` and report the result.\n\nIf the user says \"pause the worst campaign\", first do the read + ranking, then\nname the specific campaign and confirm before pausing; don't pause based on the totals alone.\n\n## 4. Reference the user's data, don't fabricate\n\nIf a tool returns an error (unknown field/connector/account), call the relevant\ndiscovery tool (`get_fields`, `get_connectors`, `list_actions`) and retry with\ncorrect ids. Never fill gaps with made-up numbers or campaign names.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}