Skip to content

fix: Unify creative URL extraction and update GAM macro mappings#1035

Open
BaiyuScope3 wants to merge 6 commits intomainfrom
fix/creative-url-extraction-and-macros
Open

fix: Unify creative URL extraction and update GAM macro mappings#1035
BaiyuScope3 wants to merge 6 commits intomainfrom
fix/creative-url-extraction-and-macros

Conversation

@BaiyuScope3
Copy link
Collaborator

@BaiyuScope3 BaiyuScope3 commented Feb 12, 2026

Summary

Fixes #1020 - Creative upload incorrectly uses click URL for image URL

  • Code refactoring and Consolidate URL extraction logic into shared helpers in creative_helpers.py
  • Both media buy creation and creative sync now use the same extraction logic
  • Update GAM macro mappings to match actual GAM macros

Changes

URL Extraction (creative_helpers.py)

  • extract_media_url_and_dimensions(): Prioritizes format spec asset types (image/video/audio), then fallback IDs
  • extract_click_url(): Checks format spec for url_type='clickthrough', then fallback IDs
  • extract_impression_tracker_url(): Checks format spec for url_type='tracker_pixel', then fallback IDs
  • Never falls back to root-level URL fields which may contain incorrect data

Code Cleanup

  • Remove duplicated extraction logic from creatives.py and media_buy_create.py
  • Pass impression tracker URL in delivery_settings.tracking_urls.impression format expected by GAM adapter

GAM Macro Mappings (macros.py)

  • Add ID macros: {MEDIA_BUY_ID}%ebuy!, {PACKAGE_ID}%eaid!, {CREATIVE_ID}%ecid!
  • Fix privacy macros: {US_PRIVACY}${US_PRIVACY}, add {GPP_SID}${GPP_SID}
  • Update {AXEM}%%PATTERN:axem%%

Test plan

  • All 407 creative/media_buy/macro related tests passing
  • All 1659 unit tests passing (excluding pre-existing failures)
  • Manual test with GAM to verify correct image/click URL assignment

Made with Cursor

- Consolidate URL extraction logic into shared helpers in creative_helpers.py
- extract_media_url_and_dimensions: prioritizes format spec, then fallback IDs
- extract_click_url: checks format spec for url_type='clickthrough', then fallback
- extract_impression_tracker_url: checks format spec for url_type='tracker_pixel'
- Remove duplicated extraction logic from creatives.py and media_buy_create.py
- Pass impression tracker URL in delivery_settings format expected by GAM adapter
- Update GAM macro mappings:
  - Add ID macros: MEDIA_BUY_ID->%ebuy!, PACKAGE_ID->%eaid!, CREATIVE_ID->%ecid!
  - Fix privacy macros: US_PRIVACY->${US_PRIVACY}, add GPP_SID
  - Update AXEM->%%PATTERN:axem%%
- Update tests to match new macro mappings

Co-authored-by: Cursor <cursoragent@cursor.com>
@BaiyuScope3
Copy link
Collaborator Author

BaiyuScope3 commented Feb 12, 2026

iskcache 5.6.3 vulnerability (GHSA-w8v5-vhqr-4h9v) has no patch available yet, this lib comes with fastmcp lib we're using , I already filed a issue on their github here

image

Not directly used in the repo, ignored GHSA-w8v5-vhqr-4h9v in the scan

- cryptography 46.0.3 -> 46.0.5 (GHSA-r6ph-v2qm-q3c2)
- pillow 12.0.0 -> 12.1.1 (GHSA-cfh3-3jmp-rvhc)

Note: diskcache 5.6.3 vulnerability (GHSA-w8v5-vhqr-4h9v) has no fix available yet.
Co-authored-by: Cursor <cursoragent@cursor.com>
@BaiyuScope3 BaiyuScope3 force-pushed the fix/creative-url-extraction-and-macros branch from d56b38f to f8ce95a Compare February 12, 2026 17:56
"{CREATIVE_ID}": None, # Creative ID (should already be filled)
"{MEDIA_BUY_ID}": "%ebuy!", # GAM Order ID
"{PACKAGE_ID}": "%eaid!", # GAM Line Item ID
"{CREATIVE_ID}": "%ecid!", # GAM Creative ID
Copy link
Collaborator Author

@BaiyuScope3 BaiyuScope3 Feb 12, 2026

Choose a reason for hiding this comment

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

Flow of these values between buyer agent and sales agent:

  • create_media_buy → returns media_buy_id (= GAM Order ID) to buyer agent → {MEDIA_BUY_ID} → %ebuy!
  • create_media_buy → returns package_id per package to buyer agent (= GAM Line Item ID) → {PACKAGE_ID} → %eaid!
  • add_creative_assets → returns creative_id (= GAM Creative ID) to buyer agent → {CREATIVE_ID} → %ecid!

return MediaBuyStatus.active.value


def _extract_creative_url_and_dimensions(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

duplicated logic

logger.debug(
f"[sync_creatives] Extracted URL from assets.{asset_id}.url for data storage (fallback)"
)
break
Copy link
Collaborator Author

@BaiyuScope3 BaiyuScope3 Feb 12, 2026

Choose a reason for hiding this comment

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

This is where the bug comes from
Previous flow:

  1. check common asset_ids
  2. fall back on first available url assets !! (issue here, the first url asset could be anything clickthough, impression tracker etc)
    ...

Fixed flow:

  1. dynamically get the asset id from format_spec (from creative agent), find asset type in image, video, audio.
  2. fallback to common media url id list [main, image, videos, etc]
  3. fallback to to root-level fields for simple creatives without assets (legacy)

BaiyuScope3 and others added 4 commits February 12, 2026 13:17
When creative data has no 'assets' dict, fall back to root-level
'url', 'width', 'height' fields. This supports legacy/simple creative
formats used in tests and basic creative submissions.

Fixes integration test failures in test_creative_lifecycle_mcp.py

Co-authored-by: Cursor <cursoragent@cursor.com>
GHSA-w8v5-vhqr-4h9v (CVE-2025-69872): diskcache pickle deserialization
- Transitive dependency: fastmcp -> py-key-value-aio[disk] -> diskcache
- Not exploitable: salesagent does not use diskcache or pickle serialization
- Tracking upstream: jlowin/fastmcp#3166

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@BaiyuScope3 BaiyuScope3 requested a review from gravelg February 13, 2026 17:25
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.

Creative upload incorrectly uses click URL for image URL

1 participant