#!/usr/bin/env python3 # 在 ads-center 上运行:从 report_api.db 取 mintegral/bigo/mediago 三渠道 # 按 campid 匹配 Voypace 产品,聚合(日期+campid+国家),输出 JSON 到 stdout。 # 参数:start_date(含) end_date(含),格式 yyyy-MM-dd import sqlite3, json, sys, os from collections import defaultdict DB = "/Users/ads-center/Documents/database/report_api.db" START = sys.argv[1] if len(sys.argv) > 1 else "2026-07-15" END = sys.argv[2] if len(sys.argv) > 2 else "2026-12-31" # campid -> 产品信息(从同目录 campaigns.json 读取) HERE = os.path.dirname(os.path.abspath(__file__)) _camps = json.load(open(os.path.join(HERE, "campaigns.json"))) CAMPS = {r["campid"]: {"product": r["product"], "pkg": r["pkg"]} for r in _camps} conn = sqlite3.connect(DB) conn.row_factory = sqlite3.Row # 聚合容器:key=(date,channel,campid,location) -> 累加指标 agg = defaultdict(lambda: {"impression":0,"clicks":0,"conversions":0,"spend":0.0}) meta = {} def campid_of(text): t = str(text or "") for cid in CAMPS: if cid in t: return cid return None # ---- Mintegral ---- # 广告单元名(如 91555309_Viu_ID)可能落在 Offer_Name 或 Campaign_Id,两字段都匹配 like = " OR ".join([f"Offer_Name LIKE '%{cid}%' OR Campaign_Id LIKE '%{cid}%'" for cid in CAMPS]) sql = f"""SELECT Date d, Offer_Name nm, Campaign_Id cmp, Location loc, Impression imp, Click clk, Conversion cv, Spend sp FROM mintegral WHERE Date>=? AND Date<=? AND ({like})""" for r in conn.execute(sql, (START, END)): cid = campid_of(r["nm"]) or campid_of(r["cmp"]) if not cid: continue k = (r["d"], "Mintegral", cid, (r["loc"] or "").upper()) a = agg[k] a["impression"] += int(r["imp"] or 0); a["clicks"] += int(r["clk"] or 0) a["conversions"] += int(r["cv"] or 0); a["spend"] += float(r["sp"] or 0) meta[k] = (r["nm"] or r["cmp"], CAMPS[cid]) # ---- Bigo ---- like = " OR ".join([f"campaignName LIKE '%{cid}%'" for cid in CAMPS]) sql = f"""SELECT aggregateTime d, campaignName nm, country loc, tgtPkgName pkg, impression imp, click clk, real_result_conversion cv, totalCost cost FROM bigo WHERE aggregateTime>=? AND aggregateTime<=? AND ({like})""" for r in conn.execute(sql, (START, END)): cid = campid_of(r["nm"]) if not cid: continue k = (r["d"], "Bigo", cid, (r["loc"] or "").upper()) a = agg[k] a["impression"] += int(r["imp"] or 0); a["clicks"] += int(r["clk"] or 0) a["conversions"] += int(r["cv"] or 0); a["spend"] += float(r["cost"] or 0)/100.0 meta[k] = (r["nm"], CAMPS[cid]) # ---- MediaGo ---- (ad级明细,需聚合;spend = cpc*click 反算) like = " OR ".join([f"campaign_name LIKE '%{cid}%'" for cid in CAMPS]) sql = f"""SELECT date d, campaign_name nm, adset_country loc, vimp imp, click clk, cv cvn, cpc FROM mediago WHERE date>=? AND date<=? AND ({like})""" for r in conn.execute(sql, (START, END)): cid = campid_of(r["nm"]) if not cid: continue k = (r["d"], "MediaGo", cid, (r["loc"] or "").upper()) a = agg[k] clk = int(r["clk"] or 0) a["impression"] += int(r["imp"] or 0); a["clicks"] += clk a["conversions"] += int(r["cvn"] or 0); a["spend"] += float(r["cpc"] or 0) * clk meta[k] = (r["nm"], CAMPS[cid]) conn.close() out = [] for k, a in agg.items(): date, channel, cid, loc = k nm, info = meta[k] imp, clk, cv = a["impression"], a["clicks"], a["conversions"] out.append({ "date": date, "channel": channel, "campid": cid, "offer_name": nm, "product": info["product"], "pkg": info["pkg"], "location": loc, "bid_type": "", "impression": imp, "clicks": clk, "conversions": cv, "ctr": round(clk/imp, 5) if imp else 0.0, "cvr": round(cv/clk, 5) if clk else 0.0, "spend": round(a["spend"], 2), }) out.sort(key=lambda x: (x["date"], x["channel"], -x["impression"])) print(json.dumps(out, ensure_ascii=False))