chore: remove Bigo API integration and token (switching to new data source)
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
{"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlA0SkRvOUx1emlkeUVoZlF6SG1qbHRKR0R5bC81UXNKVzBZMDhkTmkrTHM9In0.eyJhdWQiOlsib3BlbmFwaSJdLCJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbInJlYWQiXSwiZXhwIjoxNzg4OTY5MzA2LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjIzNDVjOWJjLTNkNDYtNGY3Ny04OTlmLTRkODVlZTU2ZDg0ZCIsImNsaWVudF9pZCI6IjI2MDMyNTY0NDIyMTIwNDA2MTAwNDgifQ.B-An6CSSoFY29Lmiol02QbXjQPpNROratIjTjfal0CNx1s17agletk3bcMoQntkujLYTDJYqt4mtZzaA3_IwIf-nuYmiMDe1KAHOIa5wInNtQWRqvHy5vRb8vQ_q9-fFD-BuZX7Qc2IHpDqeR_LIi1cgK2Ps6HVWtY7jdMyvTMiM_jv7cdDSI2fAlvR0FZkDaTzNqC7YebUsmVX500ZMn1iTZpI29s9N3s1zAWjxQyuOV4DKvUFEtTOaloOBF2LxeySdO6IJMnGM4wMbC0Bv1wdWG9NBoHBzFV1c0FL8wGqJ4O1EDwcKr98X_wWD4P99xsTylr3rUliuNtVkISAYGA", "token_type": "bearer", "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlA0SkRvOUx1emlkeUVoZlF6SG1qbHRKR0R5bC81UXNKVzBZMDhkTmkrTHM9In0.eyJhdWQiOlsib3BlbmFwaSJdLCJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbInJlYWQiXSwiYXRpIjoiMjM0NWM5YmMtM2Q0Ni00Zjc3LTg5OWYtNGQ4NWVlNTZkODRkIiwiZXhwIjoxNzkxNDc0OTA2LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjYzMGJhNmUyLTgwZmMtNGQ5Yi1hMTQ5LWM4MzYwMDlhZjgwNCIsImNsaWVudF9pZCI6IjI2MDMyNTY0NDIyMTIwNDA2MTAwNDgifQ.E4c75ef9fBQnJ3Ia1_Llz39_d5IELgyeEHqVZ3JAe1zGgUoew_Vzor2DpkpcmUX4rEIjvbPcYpDSrB1ElEQMeNR3i92--QlL5gNdJ9S0PyHGk2Ufze75Amlnk4FnAWFuXX8daA9Kyo4Kv1Gg8wzHY7_rvtu-6GGZDdyZE-68hOSAFbAq0SfG4A4vEmh-UDXiAUEAY6XIwfk_3-hNhcW9ljpATj9uF-irJFLDbOHWYLzeLua-S2embkv-4EXENzcDQd5DLPJB8o5joOfqKR4yv-RbX99vYRuwl2Rv9XDEk4Mt_ArE8SW7eO-ylNwEvKo26sGOu6Eg2JHYSgopwBz5ig", "expires_in": 86399, "scope": "read", "jti": "2345c9bc-3d46-4f77-899f-4d85ee56d84d"}
|
|
||||||
@@ -7,11 +7,11 @@
|
|||||||
"Mintegral|br.com.netshoes.app": "Pause",
|
"Mintegral|br.com.netshoes.app": "Pause",
|
||||||
"Mintegral|id891130066": "Pause",
|
"Mintegral|id891130066": "Pause",
|
||||||
"Mintegral|id886443637": "Pause",
|
"Mintegral|id886443637": "Pause",
|
||||||
"Mintegral|com.sialiagames.xczyw.gp.tw": "Active",
|
"Mintegral|com.sialiagames.xczyw.gp.tw": "Pause",
|
||||||
"Mintegral|com.qookkagames.xczyw.gp.hk": "Active",
|
"Mintegral|com.qookkagames.xczyw.gp.hk": "Active",
|
||||||
"MediaGo|com.igg.android.lordsmobile": "Pause",
|
"MediaGo|com.igg.android.lordsmobile": "Pause",
|
||||||
"Bigo|com.ddup.zombiewaves.zw": "Pause",
|
"Bigo|com.ddup.zombiewaves.zw": "Pause",
|
||||||
"MediaGo|com.qookkagames.xczyw.gp.hk": "Active",
|
"MediaGo|com.qookkagames.xczyw.gp.hk": "Pause",
|
||||||
"MediaGo|com.sialiagames.xczyw.gp.tw": "Active",
|
"MediaGo|com.sialiagames.xczyw.gp.tw": "Pause",
|
||||||
"Mintegral|com.ddup.zombiewaves.zw": "Pause"
|
"Mintegral|com.ddup.zombiewaves.zw": "Pause"
|
||||||
}
|
}
|
||||||
@@ -4798,5 +4798,101 @@
|
|||||||
"ctr": 0.0,
|
"ctr": 0.0,
|
||||||
"cvr": 0.0,
|
"cvr": 0.0,
|
||||||
"spend": 0.0
|
"spend": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2026-09-08",
|
||||||
|
"channel": "Mintegral",
|
||||||
|
"campid": "91534913",
|
||||||
|
"offer_name": "91534913_xczyw_HK",
|
||||||
|
"product": "灵犀互动",
|
||||||
|
"pkg": "com.qookkagames.xczyw.gp.hk",
|
||||||
|
"location": "HK",
|
||||||
|
"bid_type": "",
|
||||||
|
"impression": 14,
|
||||||
|
"clicks": 1,
|
||||||
|
"conversions": 0,
|
||||||
|
"ctr": 0.07142,
|
||||||
|
"cvr": 0.0,
|
||||||
|
"spend": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2026-09-08",
|
||||||
|
"channel": "Mintegral",
|
||||||
|
"campid": "91530537",
|
||||||
|
"offer_name": "91530537_MBCShahid_SA",
|
||||||
|
"product": "Shahid",
|
||||||
|
"pkg": "net.mbc.shahid",
|
||||||
|
"location": "SA",
|
||||||
|
"bid_type": "",
|
||||||
|
"impression": 5,
|
||||||
|
"clicks": 0,
|
||||||
|
"conversions": 0,
|
||||||
|
"ctr": 0.0,
|
||||||
|
"cvr": 0.0,
|
||||||
|
"spend": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2026-09-08",
|
||||||
|
"channel": "Mintegral",
|
||||||
|
"campid": "91530535",
|
||||||
|
"offer_name": "91530535_HonorofKings_IN",
|
||||||
|
"product": "Honor of Kings",
|
||||||
|
"pkg": "com.levelinfinite.sgameGlobal",
|
||||||
|
"location": "IN",
|
||||||
|
"bid_type": "",
|
||||||
|
"impression": 3,
|
||||||
|
"clicks": 0,
|
||||||
|
"conversions": 0,
|
||||||
|
"ctr": 0.0,
|
||||||
|
"cvr": 0.0,
|
||||||
|
"spend": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2026-09-08",
|
||||||
|
"channel": "Mintegral",
|
||||||
|
"campid": "91533906",
|
||||||
|
"offer_name": "91533906_xczyw_TW",
|
||||||
|
"product": "灵犀互动",
|
||||||
|
"pkg": "com.sialiagames.xczyw.gp.tw",
|
||||||
|
"location": "TW",
|
||||||
|
"bid_type": "",
|
||||||
|
"impression": 3,
|
||||||
|
"clicks": 0,
|
||||||
|
"conversions": 0,
|
||||||
|
"ctr": 0.0,
|
||||||
|
"cvr": 0.0,
|
||||||
|
"spend": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2026-09-08",
|
||||||
|
"channel": "Mintegral",
|
||||||
|
"campid": "91551606",
|
||||||
|
"offer_name": "91551606_ZombieWaves_US",
|
||||||
|
"product": "Zombie",
|
||||||
|
"pkg": "com.ddup.zombiewaves.zw",
|
||||||
|
"location": "US",
|
||||||
|
"bid_type": "",
|
||||||
|
"impression": 1,
|
||||||
|
"clicks": 1,
|
||||||
|
"conversions": 0,
|
||||||
|
"ctr": 1.0,
|
||||||
|
"cvr": 0.0,
|
||||||
|
"spend": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": "2026-09-08",
|
||||||
|
"channel": "Mintegral",
|
||||||
|
"campid": "91530534",
|
||||||
|
"offer_name": "91530534_HonorofKings_PH",
|
||||||
|
"product": "Honor of Kings",
|
||||||
|
"pkg": "com.levelinfinite.sgameGlobal",
|
||||||
|
"location": "PH",
|
||||||
|
"bid_type": "",
|
||||||
|
"impression": 1,
|
||||||
|
"clicks": 0,
|
||||||
|
"conversions": 0,
|
||||||
|
"ctr": 0.0,
|
||||||
|
"cvr": 0.0,
|
||||||
|
"spend": 0.0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -106,90 +106,6 @@ json.dump(out, open("mtg_data.json","w"), ensure_ascii=False, indent=2)
|
|||||||
print(f"[update] Mintegral 合并后共 {len(out)} 条")
|
print(f"[update] Mintegral 合并后共 {len(out)} 条")
|
||||||
PYEOF
|
PYEOF
|
||||||
|
|
||||||
# ============ Bigo 每日更新 ============
|
|
||||||
python3 - <<'PYEOF'
|
|
||||||
import json, os, base64, urllib.request, urllib.parse, urllib.error
|
|
||||||
from datetime import date, timedelta
|
|
||||||
|
|
||||||
CLIENT_ID = "2603256442212040610048"
|
|
||||||
SECRET = "14u0a4anx5a5"
|
|
||||||
TOKEN_URL = "https://api.adsbigo.com/oauth/token"
|
|
||||||
REPORT_URL = "https://api.adsbigo.com/openapi/report/list"
|
|
||||||
STATE = "bigo_token.json"
|
|
||||||
|
|
||||||
# 初始 refresh_token(首次运行用;之后从 STATE 文件读取轮转后的)
|
|
||||||
INIT_REFRESH = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlA0SkRvOUx1emlkeUVoZlF6SG1qbHRKR0R5bC81UXNKVzBZMDhkTmkrTHM9In0.eyJhdWQiOlsib3BlbmFwaSJdLCJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbInJlYWQiXSwiYXRpIjoiMzY2YjMxYTYtYzg2OS00ZDMzLTkyM2EtZjZlZDdjN2QxNzIzIiwiZXhwIjoxNzkxNDQ3NjgxLCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6ImM4MmZiZmNmLTY2YzQtNDE5MS05ZjFkLWViYjVhYTVkNTk1MSIsImNsaWVudF9pZCI6IjI2MDMyNTY0NDIyMTIwNDA2MTAwNDgifQ.VB-ntRjhOvUKIF_BToHOXXT5SCsLKnIyYDGaQwiFICpLHQWJ8Nktyau8FMvbPjIe6DRcYshGCxNRXhP-W1H6R1Nd8Phv-5YW8IUT4ihhHdwarTjpXBU4B9HB9FIatomVr-OubN0RBHWRBy2LArnFIUDvnbD3d6eWr8K0XN8_eGm_5FIT81JhNNVi4jdaeqSMA0cUApQoPyLLZf_CjqyNMlLG3ph4vUm7xD0qM3-T9K7dZCNba2z4FuGZHZ3h_arsFx0nLk0WAIGymuitvY8RNZUbx9EqZdifF__ybtsD-Za2V7KTr37sMXmMnlTaPahBGl2kMfRizgVvwTm0WNw52Q"
|
|
||||||
|
|
||||||
def get_refresh():
|
|
||||||
if os.path.exists(STATE):
|
|
||||||
try: return json.load(open(STATE)).get("refresh_token") or INIT_REFRESH
|
|
||||||
except: return INIT_REFRESH
|
|
||||||
return INIT_REFRESH
|
|
||||||
|
|
||||||
# 1) 用 refresh_token 换新 access_token(并轮转保存新的 refresh_token)
|
|
||||||
auth = base64.b64encode(f"{CLIENT_ID}:{SECRET}".encode()).decode()
|
|
||||||
data = urllib.parse.urlencode({"grant_type":"refresh_token","refresh_token":get_refresh()}).encode()
|
|
||||||
req = urllib.request.Request(TOKEN_URL, data=data, method="POST",
|
|
||||||
headers={"Content-Type":"application/x-www-form-urlencoded","Authorization":"Basic "+auth})
|
|
||||||
try:
|
|
||||||
with urllib.request.urlopen(req, timeout=60) as r:
|
|
||||||
tok = json.loads(r.read().decode())
|
|
||||||
except urllib.error.HTTPError as e:
|
|
||||||
print("[update] Bigo token 刷新失败:", e.read().decode()[:200]); raise SystemExit(0)
|
|
||||||
|
|
||||||
access = tok.get("access_token")
|
|
||||||
if not access:
|
|
||||||
print("[update] Bigo 未拿到 access_token,跳过"); raise SystemExit(0)
|
|
||||||
# 保存轮转后的 token
|
|
||||||
json.dump(tok, open(STATE,"w"))
|
|
||||||
print("[update] Bigo token 已刷新")
|
|
||||||
|
|
||||||
# 2) 拉前一天数据
|
|
||||||
target = (date.today() - timedelta(days=1)).isoformat()
|
|
||||||
camps = json.load(open("campaigns.json"))
|
|
||||||
bigo = {c["pkg"]: c for c in camps if c.get("channel")=="Bigo"}
|
|
||||||
our_pkgs = set(bigo.keys())
|
|
||||||
|
|
||||||
body = {"timezone":8,"startDate":target,"endDate":target,
|
|
||||||
"indicators":["impression","click","ctr","real_result_conversion",
|
|
||||||
"real_result_conversion_rate","totalCost","campaignName","cpm","cpc"],
|
|
||||||
"breakDowns":["campaignId","country","tgtPkgName"],
|
|
||||||
"aggregateType":2,"pageNo":1,"pageSize":100000}
|
|
||||||
req = urllib.request.Request(REPORT_URL, data=json.dumps(body).encode(),
|
|
||||||
headers={"Content-Type":"application/json","Authorization":"Bearer "+access}, method="POST")
|
|
||||||
try:
|
|
||||||
with urllib.request.urlopen(req, timeout=120) as r:
|
|
||||||
d = json.loads(r.read().decode())
|
|
||||||
except urllib.error.HTTPError as e:
|
|
||||||
print("[update] Bigo 报表请求失败:", e.read().decode()[:200]); raise SystemExit(0)
|
|
||||||
if d.get("retcode") != 0:
|
|
||||||
print("[update] Bigo API:", d.get("retmsg")); raise SystemExit(0)
|
|
||||||
|
|
||||||
new_rows = []
|
|
||||||
for r in d["result"].get("list") or []:
|
|
||||||
pkg = r.get("tgtPkgName")
|
|
||||||
if pkg not in our_pkgs: continue
|
|
||||||
rec = bigo[pkg]
|
|
||||||
new_rows.append({
|
|
||||||
"date": r["aggregateTime"], "channel":"Bigo", "campid": rec["campid"],
|
|
||||||
"offer_name": r.get("campaignName",""), "product": rec["product"], "pkg": pkg,
|
|
||||||
"location": (r.get("country") or "").upper(), "bid_type":"",
|
|
||||||
"impression": int(r.get("impression") or 0), "clicks": int(r.get("click") or 0),
|
|
||||||
"conversions": int(r.get("real_result_conversion") or 0),
|
|
||||||
"ctr": float(r.get("ctr") or 0), "cvr": float(r.get("real_result_conversion_rate") or 0),
|
|
||||||
"spend": round(float(r.get("totalCost") or 0)/100.0, 2),
|
|
||||||
})
|
|
||||||
print(f"[update] Bigo 新增匹配 {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] Bigo 合并后共 {len(out)} 条,已写入 mtg_data.json")
|
|
||||||
PYEOF
|
|
||||||
|
|
||||||
# ============ MediaGo 每日更新 ============
|
# ============ MediaGo 每日更新 ============
|
||||||
python3 - <<'PYEOF'
|
python3 - <<'PYEOF'
|
||||||
import json, os, time, urllib.request, urllib.parse, urllib.error
|
import json, os, time, urllib.request, urllib.parse, urllib.error
|
||||||
|
|||||||
Reference in New Issue
Block a user