Disable ambiguous attribution paths for cursoids with multiple PMX campaigns
When multiple PMX campaigns share the same cursoid (e.g. PMX + Reset), paths 4 (cursoid+utm_source) and 5 (cursoid+UserAgent) are disabled for all of them to prevent double-counting Airtable leads. Only direct paths (GACampaignID, GoogleCampaignID, attr_referer) are used in those cases. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4d03ddf271
commit
858755a6b8
@ -336,7 +336,7 @@ class AirtableClient:
|
||||
for i in range(0, len(cat_batch), 10):
|
||||
self.campaigns.batch_update(cat_batch[i:i+10])
|
||||
|
||||
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 = "", ambiguous_cursoids: set = None) -> tuple[int, list[str]]:
|
||||
"""
|
||||
Leads del mes actual para una campaña de Google Ads.
|
||||
Cubre cinco vías de atribución:
|
||||
@ -362,7 +362,9 @@ class AirtableClient:
|
||||
is_pmx_non_leadform = (
|
||||
"pmx" in campaign_name.lower() and "_leadform" not in campaign_name.lower()
|
||||
)
|
||||
if is_pmx_non_leadform:
|
||||
# Paths 4 y 5 se desactivan para PMX cuando hay múltiples PMX del mismo curso
|
||||
is_ambiguous_pmx = is_pmx_non_leadform and bool(ambiguous_cursoids and course_num in ambiguous_cursoids)
|
||||
if is_pmx_non_leadform and not is_ambiguous_pmx:
|
||||
utm_source = "pmx"
|
||||
elif "search" in campaign_name.lower():
|
||||
utm_source = "google"
|
||||
@ -373,8 +375,8 @@ class AirtableClient:
|
||||
f"AND({{attr_cursoid}}='{course_num}',"
|
||||
f"{{attr_utm_source}}='{utm_source}')"
|
||||
)
|
||||
# Path 5: leadform leads en Airtable, solo para PMX (no search, no _leadform)
|
||||
if is_pmx_non_leadform:
|
||||
# Path 5: leadform leads en Airtable, solo para PMX único (no search, no _leadform, no ambiguo)
|
||||
if is_pmx_non_leadform and not is_ambiguous_pmx:
|
||||
leadform_cursoid_clause = (
|
||||
f"AND({{attr_cursoid}}='{course_num}',"
|
||||
f"{{UserAgent del visitante}}='Google-Ads-Notifications')"
|
||||
|
||||
@ -74,12 +74,22 @@ def run():
|
||||
else:
|
||||
print(" ✓ MetricasDiarias sin cambios.")
|
||||
|
||||
# Cursoids con múltiples campañas PMX activas (mismo criterio que run.py)
|
||||
pmx_count_by_cursoid: dict[str, int] = {}
|
||||
for c in campaigns:
|
||||
num = _course_num(c["curso"])
|
||||
if num and "pmx" in c["curso"].lower() and "_leadform" not in c["curso"].lower():
|
||||
pmx_count_by_cursoid[num] = pmx_count_by_cursoid.get(num, 0) + 1
|
||||
ambiguous_pmx_cursoids = {num for num, cnt in pmx_count_by_cursoid.items() if cnt > 1}
|
||||
if ambiguous_pmx_cursoids:
|
||||
print(f" ⚠️ Cursoids con múltiples PMX (paths 4/5 desactivados): {ambiguous_pmx_cursoids}")
|
||||
|
||||
# Recalcular totales mensuales con la nueva atribución
|
||||
print("\n→ Recalculando totales mensuales (leads_lake acumulado del mes)...")
|
||||
final_leads_data = []
|
||||
for campaign in campaigns:
|
||||
cid = campaign["google_campaign_id"]
|
||||
leads, lead_ids = at.get_leads_this_month_gads(cid, campaign["curso"])
|
||||
leads, lead_ids = at.get_leads_this_month_gads(cid, campaign["curso"], ambiguous_pmx_cursoids)
|
||||
at.update_gacampaignmes_leads_lake(campaign["airtable_id"], lead_ids)
|
||||
final_leads_data.append({
|
||||
"airtable_id": campaign["airtable_id"],
|
||||
|
||||
12
run.py
12
run.py
@ -155,6 +155,16 @@ def run():
|
||||
if "_leadform" in c["curso"].lower() and _course_num(c["curso"])
|
||||
}
|
||||
|
||||
# Cursoids con múltiples campañas PMX activas → paths 4/5 ambiguos, desactivar para evitar doble conteo
|
||||
pmx_count_by_cursoid: dict[str, int] = {}
|
||||
for c in campaigns:
|
||||
num = _course_num(c["curso"])
|
||||
if num and "pmx" in c["curso"].lower() and "_leadform" not in c["curso"].lower():
|
||||
pmx_count_by_cursoid[num] = pmx_count_by_cursoid.get(num, 0) + 1
|
||||
ambiguous_pmx_cursoids = {num for num, cnt in pmx_count_by_cursoid.items() if cnt > 1}
|
||||
if ambiguous_pmx_cursoids:
|
||||
print(f" ⚠️ Cursoids con múltiples PMX (paths 4/5 desactivados): {ambiguous_pmx_cursoids}")
|
||||
|
||||
# Precomputar conversiones Google de cada campaña leadform por número de curso
|
||||
leadform_conv_by_course: dict[str, int] = {}
|
||||
for c in campaigns:
|
||||
@ -183,7 +193,7 @@ def run():
|
||||
for campaign in campaigns:
|
||||
cid = campaign["google_campaign_id"]
|
||||
|
||||
leads, lead_ids = at.get_leads_this_month_gads(cid, campaign["curso"])
|
||||
leads, lead_ids = at.get_leads_this_month_gads(cid, campaign["curso"], ambiguous_pmx_cursoids)
|
||||
at.update_gacampaignmes_leads_lake(campaign["airtable_id"], lead_ids)
|
||||
|
||||
metrics = monthly_metrics.get(cid)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user