Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 69 additions & 28 deletions webapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,75 @@ def marketo_submit():
original_form_id = form_fields.get("formid", 4198)
enrichment_fields["original_form_id"] = original_form_id

# Only attach UTM values when the user has consented to
# non-essential cookies (functionality, performance, or all)
cookie_consent = flask.request.cookies.get("_cookies_accepted", "unset")
non_essential_consent = cookie_consent in {
"functionality",
"performance",
"all",
}

utm_keys = {
"utm_source",
"utm_medium",
"utm_campaign",
"utm_content",
"utm_term",
"utmcontent",
}

Comment on lines +1106 to +1114
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

This change introduces new consent-dependent behavior for what gets sent to Marketo, but there are no unit tests covering the /marketo/submit path. Since webapp/views.py already has view-level tests for related UTM helpers, add tests that assert UTMs are stripped when consent is essential/missing and preserved when consent is functionality/performance/all (including UTMs provided via hidden fields and via acquisition_url).

Copilot uses AI. Check for mistakes.
encoded_utms = flask.request.cookies.get("utms") or flask.request.form.get(
"utms"
)
if encoded_utms:
form_fields.pop("utms", None)
if non_essential_consent:
utms = unquote(encoded_utms)
utm_dict = dict(i.split(":", 1) for i in utms.split("&"))
approved_utms = [
"utm_source",
"utm_medium",
"utm_campaign",
"utm_content",
"utm_term",
]
for k, v in utm_dict.items():
if k in approved_utms:
if k == "utm_content":
k = "utmcontent"
enrichment_fields[k] = v

# Append utm values in acquisition url
acquisition_url = enrichment_fields.get("acquisition_url")
if acquisition_url:
enriched_acquisition_url = enrich_acquisition_url(
acquisition_url, utm_dict, approved_utms
)
enrichment_fields["acquisition_url"] = enriched_acquisition_url

if not non_essential_consent:
# Strip utm_* keys from form_fields (e.g. hidden inputs)
for key in utm_keys:
form_fields.pop(key, None)

# Strip utm_* keys from enrichment_fields
for key in utm_keys:
enrichment_fields.pop(key, None)

# Strip utm_* query params from acquisition_url
for target in (form_fields, enrichment_fields):
acq_url = target.get("acquisition_url")
if acq_url:
parsed = urlparse(acq_url)
params = parse_qs(parsed.query, keep_blank_values=True)
cleaned = {
k: v for k, v in params.items() if not k.startswith("utm_")
}
target["acquisition_url"] = urlunparse(
parsed._replace(query=urlencode(cleaned, doseq=True))
)

if "formid" not in form_fields:
flask.flash(
"There was a problem submitting your form.",
Expand All @@ -1124,34 +1193,6 @@ def marketo_submit():
],
}

encoded_utms = flask.request.cookies.get("utms") or flask.request.form.get(
"utms"
)
if encoded_utms:
form_fields.pop("utms", None)
utms = unquote(encoded_utms)
utm_dict = dict(i.split(":", 1) for i in utms.split("&"))
approved_utms = [
"utm_source",
"utm_medium",
"utm_campaign",
"utm_content",
"utm_term",
]
for k, v in utm_dict.items():
if k in approved_utms:
if k == "utm_content":
k = "utmcontent"
enrichment_fields[k] = v

# Append utm values in acquisition url
acquisition_url = enrichment_fields.get("acquisition_url")
if acquisition_url:
enriched_acquisition_url = enrich_acquisition_url(
acquisition_url, utm_dict, approved_utms
)
enrichment_fields["acquisition_url"] = enriched_acquisition_url

enriched_payload = {
"formId": "4198",
"input": [{"leadFormFields": enrichment_fields}],
Expand Down
Loading