gads v3.9.1 — gads audit, register-gcp, mutate fix#2
Merged
Conversation
A) New gads analyze subcommands (checks.py): - rsa-lengths: headline < 20 / description < 60 char flag (HIGH/MEDIUM/INFO) - rsa-duplicates: intra-RSA duplicate headline detection - dki: Dynamic Keyword Insertion presence/absence check - ad-schedule: per-campaign AD_SCHEDULE criteria coverage for SEARCH - attribution: Last-Click conversion attribution model flag - budget-is: search_budget_lost_impression_share > 10% per campaign - qs-distribution: QS sub-signal band distribution (post-click, creative, predicted CTR) B) gads audit [--days N] [--format md|json] — top-level command wrapping the 12-section structural compliance audit (0/50/100 scoring, A-F grade). audit.py implements all 12 sections; render_audit supports md and json. C) 43 new offline tests in tests/test_checks.py (217 total, all pass). 41 tests in tests/test_audit.py (already staged from prior work). Version assertion updated to 3.9.0 in test_gads.py. All checks: read-only GAQL, AED, window ends yesterday, --json + error envelope per v3.8.2 standard. gads kb check exits 0. gads catalog --json includes all new commands.
GAQL fixes (audit.py):
- keyword_view query: add campaign.status, ad_group.status,
ad_group_criterion.status to SELECT (API v24 requires all WHERE
fields to appear in SELECT)
- campaign_criterion negatives query: add campaign.status, type to SELECT
- campaign_asset sitelink query: switch campaign_asset.asset_type
(non-selectable) to asset.type; add campaign.status to SELECT
All three fixes verified live — gads audit now runs clean (56/100 grade C)
merchant register-gcp:
- gads_lib/merchant.py: mc_register_gcp() — POST to
developerRegistration:registerGcp, json_body={"developerEmail": email},
errors routed through request_json error envelope
- cli.py: gads merchant register-gcp --developer-email EMAIL [--account ID]
[--json] — human + JSON output, validation guard for missing MC ID
- gads_lib/__init__.py: export mc_register_gcp
- kb/merchant-api.md: Developer Registration API reference section
- 8 new offline tests in TestMcRegisterGcp (225 total, all pass)
- CHANGELOG, AGENTS.md, llms.txt updated
…vent HTTP 404 P0 bug: passing snake_case resource names (e.g. campaign_criterion) to ads_mutate() built URLs like /campaign_criterion:mutate which Google's REST API returned as HTTP 404 HTML (not a JSON error), blocking all account mutations via the generic mutate escape hatch. Root cause: ads_mutate() used the resource_path string verbatim in the URL. Google Ads REST API requires camelCase plural form (campaignCriteria), not snake_case singular (campaign_criterion). Fix: add _canonicalize_resource() with _RESOURCE_ALIASES dict (21 entries) in ads.py. Snake aliases are mapped to canonical camelCase plural; unknown snake names raise ValueError before any HTTP call; camelCase names pass through unchanged. Tests: 6 new tests in TestAdsMutateUrlConstruction covering the exact 404 regression (campaign_criterion→campaignCriteria URL), camelCase passthrough, version+CID in URL, unknown-alias ValueError, alias map integrity. Version: 3.9.0 → 3.9.1. Test suite: 217 → 231 (all passing).
- RELEASE_NOTES.md: add v3.9.x section (gads audit, 7 gap checks, merchant register-gcp proven live, mutate-404 fix); update title and command-count table through v3.9.1 (115 commands) - README.md: bump command count 108→115; add Audit group row; expand Analyze row with 7 gap checks + audit subcommand; add register-gcp to Merchant row; group count 17→18 - CLAUDE.md: add audit top-level row to taxonomy table; expand analyze subcommands with 7 gap checks + audit; add register-gcp to merchant row
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
gads analyze audit. Read-only; supports--format md|json.gads analyzegap checks —rsa-lengths,rsa-duplicates,dki,ad-schedule,attribution,budget-is,qs-distribution. All read-only,--json-ready, 24-48h attribution lag respected.gads merchant register-gcp— do-it-for-you GCP project registration with Merchant Center (fixesGCP_NOT_REGISTERED). CallsdeveloperRegistration:registerGcp. Proven live on Talas account. Merchant API v1 now LIVE.ads_mutateresource canonicalization — snake_case resource names (e.g.campaign_criterion) now map to camelCase plural form (campaignCriteria) via_canonicalize_resource()+ 21-entry_RESOURCE_ALIASES. Previously all snake_case names hit HTTP 404 silently. Unknown names raiseValueErrorbefore any HTTP call.Test plan
tools/gads --versionreturns3.9.1tools/gads audit --format jsonreturns JSON withoverall_score,grade, per-section scorestools/gads analyze rsa-lengths --jsonexits 0tools/gads merchant register-gcp --helpexits 0tools/gads mutate campaign_criterion '{}' --dry-rundoes not 404 (canonicalized tocampaignCriteria)tools/gads kb checkexits 0