feat: add MediaGo channel (backfill 08-20~09-06, 30 records) + daily auto-update
This commit is contained in:
@@ -190,4 +190,93 @@ json.dump(out, open("mtg_data.json","w"), ensure_ascii=False, indent=2)
|
||||
print(f"[update] Bigo 合并后共 {len(out)} 条,已写入 mtg_data.json")
|
||||
PYEOF
|
||||
|
||||
# ============ MediaGo 每日更新 ============
|
||||
python3 - <<'PYEOF'
|
||||
import json, os, time, urllib.request, urllib.parse, urllib.error
|
||||
from datetime import date, timedelta
|
||||
|
||||
AUTH_URL = "https://api.mediago.com/manage/api/v1/access_token"
|
||||
COST_URL = "https://api.mediago.com/report/api/v1/cost/daily"
|
||||
TOKENS = [
|
||||
"YWNjb3VundF8zmu5wjlv1vcRwbpdqaCugRvQKslUg9kQH4XnrNXefCbtGDcC",
|
||||
"YWNjb3VundF8XrY8TwaXlX6pJDLnmfqmGgZT654Hh6rBRH9Cj9GzPXpO48BW",
|
||||
"YWNjb3VundF89iFLKQQHlvwxnhVbWvchTAz009Zcjw7jTkOPzCDC3oLK0RGO",
|
||||
"YWNjb3VundF815Lb3KpFWB8pnajnDZwL8Aw0YHpquAqUPWl78NKSaSigRBsY",
|
||||
"YWNjb3VundF8SKbXp3ceGoHmS9SyMBleK2bIglGThBhoHly8yPoYOP8jZtww",
|
||||
"YWNjb3VundF80DXnMfSwD4LWsV1hVVSA2j5FZQsWMSTQbJ6lTZIUhhrQZ9c6",
|
||||
"YWNjb3VundF8gK0LuXHCZkNyC4R14Adayu4j1xnNJMzxvu1hokiwUPNOPJxS",
|
||||
"YWNjb3VundF82rld59cRZIn53Uf0NhkWdcGIdNzOSRCZrkyj81xemBTQrOmi",
|
||||
"YWNjb3VundF86E54f6seADTvrVjgeY3mrFNYsTn4jKVH5G5UyixyKkJi7T1S",
|
||||
"YWNjb3VundF8MCmSFzV7LO4VRrxpJME8YrZCb6MyLp5KhRz4Q3crCjsDxPvI",
|
||||
"YWNjb3VundF8tKh2Lye5ehjWsrSQUBTq6L4caohAKvG71qJVSOkMKDCKcKGu",
|
||||
"YWNjb3VundF8xZYwIg4AFeVlTmrjBovgjxCSsHxYenyTTNbnNo1a0gIgs75V",
|
||||
"YWNjb3VundF8QcNhks2O2ObIVmVXoIr1fuPPGTQ34YsaE0idvLVqTM5bSjbr",
|
||||
"YWNjb3VundF8JtqahIBkypktae5H98q3PYjFXYPzqukmwY2wIOYqLSrYg0JQ",
|
||||
"YWNjb3VundF8x4GsJSnSBns6y5tVGZRlDdC0w40k1ApVlj8v9cme64KNHmKq",
|
||||
"YWNjb3VundF8GbE7ycPaH0fSozZ80v38jC00qdJB5YJRJJeqdy4DomjKG2ns",
|
||||
"YWNjb3VundF83KP9txx57PNlElIa61g7vi7QQ1BTw4nlyPn6Tw8P4bXfX5IT",
|
||||
"YWNjb3VundF8CDELpJV0axNw1AH4Pb7N1yfoe9HzyL0u9XQEnW3tgXVj1rbB",
|
||||
"YWNjb3VundF8AzmnXydKyjDthsIx7BaYn6xof2lRh4pdJRTJT8qmupaLi7pX",
|
||||
"YWNjb3VundF8PwLbajYpTYLe2dVhm1EX8seXxsPJlbpkxT8LhSONHhffW48Z",
|
||||
"YWNjb3VundF8OGELq8i2wxXDw2kniuY9wp9nRz6xvoDU5jfFo2vsiUeoO2MV",
|
||||
"YWNjb3VundF8u5aQbeM0LrTQcxc3t4DcbvZp1kBoDueP0q0rMjDPvLefG3WR",
|
||||
]
|
||||
|
||||
camps = json.load(open("campaigns.json"))
|
||||
mg = {c["campid"]: c for c in camps if c.get("channel") == "MediaGo"}
|
||||
mg_ids = list(mg.keys())
|
||||
if not mg:
|
||||
print("[update] MediaGo 无目标 campid,跳过"); raise SystemExit(0)
|
||||
PKGS = ",".join(sorted({c["pkg"] for c in mg.values()}))
|
||||
target = (date.today() - timedelta(days=1)).isoformat()
|
||||
|
||||
def get_token(api_token):
|
||||
req = urllib.request.Request(AUTH_URL, data=json.dumps({"api_token": api_token}).encode(),
|
||||
headers={"Content-Type": "application/json"}, method="POST")
|
||||
with urllib.request.urlopen(req, timeout=40) as r:
|
||||
return json.loads(r.read().decode())["data"]["AccessToken"]
|
||||
|
||||
def cost_daily(tok):
|
||||
p = [("dimension","campaign"),("tz","UTC+8"),("app_ids",PKGS),
|
||||
("start_date",target),("end_date",target),("page_idx",0),("page_size",100)]
|
||||
req = urllib.request.Request(COST_URL + "?" + urllib.parse.urlencode(p),
|
||||
headers={"Authorization":"Bearer "+tok}, method="GET")
|
||||
with urllib.request.urlopen(req, timeout=60) as r:
|
||||
d = json.loads(r.read().decode())
|
||||
return d.get("data",{}).get("list") or [] if d.get("code")==0 else []
|
||||
|
||||
new_rows = []
|
||||
for api_token in TOKENS:
|
||||
try:
|
||||
tok = get_token(api_token)
|
||||
lst = cost_daily(tok)
|
||||
except Exception:
|
||||
continue
|
||||
for r in lst:
|
||||
cn = r.get("campaign_name","")
|
||||
cid = next((c for c in mg_ids if cn.startswith(c) or c in cn), None)
|
||||
if not cid: continue
|
||||
imp=int(r.get("imp") or 0); clk=int(r.get("click") or 0); cv=int(r.get("cv") or 0); sp=float(r.get("spend") or 0)
|
||||
if imp==0 and clk==0 and sp==0: continue
|
||||
rec = mg[cid]
|
||||
new_rows.append({
|
||||
"date": r.get("date"), "channel":"MediaGo", "campid":cid,
|
||||
"offer_name":cn, "product":rec["product"], "pkg":rec["pkg"],
|
||||
"location":(r.get("geo") or "").upper(), "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(sp,2),
|
||||
})
|
||||
time.sleep(0.3)
|
||||
print(f"[update] MediaGo 新增匹配 {len(new_rows)} 条 ({target})")
|
||||
|
||||
existing = json.load(open("mtg_data.json")) if os.path.exists("mtg_data.json") else []
|
||||
merged = {(r["date"],r["campid"],r["location"],r.get("channel","")): r for r in existing}
|
||||
for r in new_rows:
|
||||
merged[(r["date"],r["campid"],r["location"],r["channel"])] = r
|
||||
out = sorted(merged.values(), key=lambda x:(x["date"], x.get("channel",""), -x["impression"]))
|
||||
json.dump(out, open("mtg_data.json","w"), ensure_ascii=False, indent=2)
|
||||
print(f"[update] MediaGo 合并后共 {len(out)} 条,已写入 mtg_data.json")
|
||||
PYEOF
|
||||
|
||||
echo "[update] $(date '+%Y-%m-%d %H:%M:%S') 完成"
|
||||
|
||||
Reference in New Issue
Block a user