Skip to content

Add get_campaign_settings - #111

Merged
kLOsk merged 1 commit into
kLOsk:mainfrom
xgp:feat/campaign-settings
Oct 27, 2026
Merged

kLOsk merged 1 commit into
kLOsk:mainfrom
xgp:feat/campaign-settings

Conversation

@xgp

@xgp xgp commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Closes #109.

Adds the read-only tool get_campaign_settings. It returns one flat record per non-removed Search campaign (or just the one in campaign_id) with every setting that decides how far the campaign reaches. That turns a weekly "did Google switch something back on?" audit into a single call that diffs cleanly week to week.

Fields

All of them are on the v25 Campaign / CampaignBudget resources, in one GAQL query:

Record key Source
bidding_strategy_type, portfolio_bidding_strategy campaign.bidding_strategy_type, campaign.bidding_strategy
cpc_bid_ceiling, target_cpa, target_roas target_spend.cpc_bid_ceiling_micros, target_cpa / maximize_conversions.target_cpa_micros, target_roas / maximize_conversion_value.target_roas
daily_budget, budget_shared campaign_budget.amount_micros, explicitly_shared
google_search, search_partners, display_network network_settings.*
location_option, negative_location_option geo_target_type_setting.positive_geo_target_type / negative_geo_target_type
keyword_match_type campaign.keyword_match_type
tracking_url_template, final_url_suffix, url_custom_parameters same names

The AI Max half (enable_ai_max, asset_automation per type) comes straight from ai_max.read_ai_max_state, so this tool and get_ai_max_settings can never disagree.

Money is converted from micros and labelled with currency from get_currency_code.

widening_settings and insights[]

Each record lists the settings that let ads reach beyond the chosen keywords and locations:

  • search partners on
  • Display on
  • a PRESENCE_OR_INTEREST or SEARCH_INTEREST location option
  • campaign-level broad match on
  • AI Max on
  • any asset automation OPTED_IN

insights[] names each campaign that has any. ad_groups_with_search_term_matching is only filled when AI Max is on, because every ad group defaults to False and the flag does nothing without AI Max.

This is also the read-back the write-side issues (#104 location option, #105 URL options, #106 broad match) would use, so none of them needs GAQL to verify.

Verified against a live account

I ran it read-only against a live account with two paused Search campaigns built through AdLoop. Both came back with widening_settings: ["location option PRESENCE_OR_INTEREST"], the API default that #104 is about, and nothing else.

Tests

There are 12 new tests in tests/test_campaign_settings.py, none of them hitting the live API:

  • the full record for a narrow campaign
  • every widening setting named in order
  • SEARCH_INTEREST
  • search term matching hidden without AI Max
  • targets, portfolio strategy and shared budget
  • the single-campaign filter, with stray rows dropped
  • empty results
  • a non-numeric campaign_id refused before any client is built (same rule as Add AI Max controls: prepare Search campaigns for brand exclusions #77)
  • currency
  • tool registration

One more test walks every selected field against the SDK's own v25 Campaign / CampaignBudget protos, so a renamed field fails in CI rather than with UNRECOGNIZED_FIELD in someone's account. I mutation-checked it with a misspelled field.

uv run pytest
1636 passed, 2 skipped, 6 warnings

Baseline on main was 1624 passed, 2 skipped. This branch is independent of #110.

I haven't regenerated adloop-docs/reference/tools.mdx; I can open that PR in adloop-docs once this one is settled.

One read-only call returning every setting that decides how far a Search campaign reaches: networks, location option, campaign-level broad match, bidding and budget, URL options, and the AI Max state from read_ai_max_state. Each campaign lists its widening_settings and insights[] names the campaigns that have any, so a recurring audit is one call that diffs cleanly. Closes kLOsk#109.

@kLOsk kLOsk left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really useful, and a clean read-back for #104 to #106. Three small things:

  1. campaign.network_settings.target_partner_search_network is selected but not used, so either drop it or surface it.
  2. With an explicit campaign_id the Search filter falls away, so a PMax ID returns a record whose AI Max fields don't apply: keep advertising_channel_type = 'SEARCH' in that branch, or say in the docstring that any channel is returned.
  3. Two blank lines before the next @_tool.

Happy to merge after that.

@kLOsk
kLOsk merged commit ebfdb3e into kLOsk:main Oct 27, 2026
3 checks passed
kLOsk added a commit that referenced this pull request Oct 27, 2026
…used field

Follow-up to #111 (the review notes): with a campaign_id the query no
longer drops the Search filter, so a Performance Max or Display ID comes
back empty instead of as a record whose AI Max and location fields don't
apply; target_partner_search_network was selected but never used; PEP 8
spacing before the next tool.

Co-Authored-By: xgp <xgp@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiC3mRmhzUVXgCexry7GJ3
@xgp

xgp commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for picking up the three review points in 7ff4b69 and for the merge. #115–#117 use it as their read-back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

get_campaign_settings: one read for every setting that widens reach

2 participants