Add attr_cursoid + attr_utm_source as 4th lead attribution path

For PMX/Search campaigns, match leads by course number and UTM source
when direct campaign ID attribution is missing. Fixes campaigns like
fco_pmx_436 (2→48 leads) and fco_pmx_1525 (0→84 leads).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jose Manuel 2026-05-21 22:31:03 +02:00
parent b30a075c59
commit d82e604a15

View File

@ -339,24 +339,45 @@ class AirtableClient:
def get_leads_this_month_gads(self, campaign_id: str, campaign_name: str = "") -> tuple[int, list[str]]: def get_leads_this_month_gads(self, campaign_id: str, campaign_name: str = "") -> tuple[int, list[str]]:
""" """
Leads del mes actual para una campaña de Google Ads. Leads del mes actual para una campaña de Google Ads.
Cubre tres vías de atribución: Cubre cuatro vías de atribución:
1. GACampaignID / GoogleCampaignID (leads web normales) 1. GACampaignID / GoogleCampaignID (leads web normales)
2. gad_campaignid en attr_referer (UTM web) 2. gad_campaignid en attr_referer (UTM web)
3. attr_referer = campaign_name con UserAgent Google-Ads-Notifications (Lead Form) 3. attr_referer = campaign_name con UserAgent Google-Ads-Notifications (Lead Form)
4. attr_cursoid = course_num AND attr_utm_source = 'pmx'|'google' (atribución por curso)
""" """
now = datetime.now() now = datetime.now()
mes_inicio = f"{now.year}-{now.month:02d}-01" mes_inicio = f"{now.year}-{now.month:02d}-01"
leadform_clause = ( leadform_clause = (
f"AND({{attr_referer}}='{campaign_name}',{{UserAgent del visitante}}='Google-Ads-Notifications')" f"AND({{attr_referer}}='{campaign_name}',{{UserAgent del visitante}}='Google-Ads-Notifications')"
if campaign_name else "FALSE()" if campaign_name else "FALSE()"
) )
# Extraer número de curso y tipo de fuente del nombre de campaña
curso_clause = "FALSE()"
m = re.search(r'fco_(?:search|pmx)_(\d+)', campaign_name, re.IGNORECASE)
if m:
course_num = m.group(1)
if "pmx" in campaign_name.lower() and "_leadform" not in campaign_name.lower():
utm_source = "pmx"
elif "search" in campaign_name.lower():
utm_source = "google"
else:
utm_source = None
if utm_source:
curso_clause = (
f"AND({{attr_cursoid}}='{course_num}',"
f"{{attr_utm_source}}='{utm_source}')"
)
formula = ( formula = (
f"AND(" f"AND("
f"OR(" f"OR("
f"{{GACampaignID}}='{campaign_id}'," f"{{GACampaignID}}='{campaign_id}',"
f"FIND(',{campaign_id},',',' & {{GoogleCampaignID}} & ',')," f"FIND(',{campaign_id},',',' & {{GoogleCampaignID}} & ','),"
f"FIND('gad_campaignid={campaign_id}',{{attr_referer}})," f"FIND('gad_campaignid={campaign_id}',{{attr_referer}}),"
f"{leadform_clause}" f"{leadform_clause},"
f"{curso_clause}"
f")," f"),"
f"{{creado}}>='{mes_inicio}'" f"{{creado}}>='{mes_inicio}'"
f")" f")"