feat(cmcc): 签到天数奖励领取 + 月签转盘接入;修 % 格式化炸点

- claim_day_prizes: mark31/taskAwardChance 查可领 → 逐个 taskAward/<id> 领取
  (11-05 真机「1签2GB」同款接口;服务端发了才领,无奖静默)
- month_lottery: 月签大转盘 /month/getMonthPrize(无池 data=null 静默跳过)
- 单号流程扩展:签到 → 天数奖励 → 转盘,汇总进通知文案
- 修 3 处 % 格式化注入炸点(服务端文本含 % 时 TypeError,
  真机日志 19:44 '天数奖励领取异常' 实证)改 .format
This commit is contained in:
2026-11-07 19:45:18 +08:00
parent 21e4a7a3ae
commit 55e2299efa

View File

@@ -182,7 +182,7 @@ def send_notify(title, content):
j = r.json() if "json" in r.headers.get("content-type", "") else {}
ok = j.get("code") == 200
sent = sent or ok
log("[通知] pushplus code=%s %s" % (j.get("code"), "成功" if ok else (j.get("msg") or "")))
log("[通知] pushplus code={} {}".format(j.get("code"), "成功" if ok else (j.get("msg") or "")))
except Exception as e:
log("[通知] pushplus 异常 %r" % e)
if not hook and not token:
@@ -434,6 +434,46 @@ class Mark:
def mark(self):
return self.post("/mark31/domark", {"date": today_str()})
# ---------------- 签到奖励领取 + 月签转盘(2026-11-07 端点表全量逆向) ----------------
def claim_day_prizes(self):
"""领取「签到天数奖励」:mark31 的累计签到奖励(2/3/5/7/10/14/21/30天档)。
协议:GET taskAwardChance 查可领的 prizeId 列表 → 逐个 POST /mark31/taskAward/<id>。
(11-05 实测 21:29 真机领过「1签2GB」就是这个接口。)"""
out = []
r = self.post("/mark31/taskAwardChance", {})
if r.get("_token_invalid") or r.get("code") != "SUCCESS":
return out
for item in (r.get("data") or []):
pid = item.get("prizeId") or item.get("id")
name = item.get("prizeName") or item.get("name") or ("prize {}".format(pid))
if not pid:
continue
time.sleep(THROTTLE)
rr = self.post("/mark31/taskAward/%s" % pid, {})
ok = rr.get("code") == "SUCCESS"
out.append((name, ok, rr.get("msg") or ""))
log(" [奖] {} → {}".format(name, "✅领取" if ok else (rr.get("msg") or rr.get("code"))))
return out
def month_lottery(self):
"""「连续月签大转盘」:POST /month/getMonthPrize {channel,phone,prov,month}。
无池/无机会时服务端返回 SUCCESS+空 data(实测 monthInfo data=null)——不报错,静默跳过。"""
res = {"config": None, "draw": None}
r = self.post("/month/monthInfo", {})
if r.get("_token_invalid") or not r.get("data"):
return res # 无转盘池(本月未开放)
res["config"] = r.get("data")
# 抽奖参数从 whoami 的数据拿不到 phone/prov(服务端掩码),从 monthInfo 里带啥用啥
d = r["data"] or {}
payload = {k: d.get(k) for k in ("channel", "phone", "prov", "month") if d.get(k)}
if not payload.get("month"):
payload["month"] = today_str()[:6]
time.sleep(THROTTLE)
rr = self.post("/month/getMonthPrize", payload)
res["draw"] = rr
return res
# ---------------------------------------------------------------- 单号流程
@@ -471,25 +511,48 @@ def run_one_account(name, payload, stats):
acct["detail"] = "markstatus 时 token 已失效"
return 3, acct
log("[%s] 今日已签=%s 累计=%s天" % (name, st["signed"], st["days"]))
if st["signed"]:
acct["ok"] = True
acct["detail"] = "今日已签到,幂等跳过(累计 %s 天)" % st["days"]
return 0, acct
mk = m.mark()
if mk.get("_token_invalid"):
acct["detail"] = "domark 时 token 失效"
return 3, acct
log("[%s] 签到 code=%s status=%s msg=%s" % (name, mk.get("code"), mk.get("status"), mk.get("msg")))
extras = []
if not st["signed"]:
mk = m.mark()
if mk.get("_token_invalid"):
acct["detail"] = "domark 时 token 失效"
return 3, acct
log("[{}] 签到 code={} status={} msg={}".format(name, mk.get("code"), mk.get("status"), mk.get("msg")))
st2 = m.state()
if not (st2 and st2["signed"]):
acct["detail"] = "复核未通过:%s/%s" % (mk.get("code"), mk.get("status"))
return 1, acct
extras.append("签到✅ %s→%s天" % (st["days"], st2["days"]))
days_now = st2["days"]
else:
extras.append("已签(%s天)" % st["days"])
days_now = st["days"]
st2 = m.state()
if st2 and st2["signed"]:
acct["ok"] = True
acct["detail"] = "签到成功:累计 %s→%s 天(%s/%s)" % (
st["days"], st2["days"], mk.get("code"), mk.get("status"))
return 0, acct
acct["detail"] = "复核未通过:%s/%s" % (mk.get("code"), mk.get("status"))
return 1, acct
# 签到天数奖励(累计档位奖:7天10元话费这类,服务端发了才能领)
try:
prizes = m.claim_day_prizes()
for pname, ok, msg in prizes:
extras.append("奖[%s]%s" % (pname, "✅" if ok else "×"))
except Exception as e:
log("[%s] 天数奖励领取异常 %r" % (name, e))
# 月签转盘(有池才抽,无池静默)
try:
lot = m.month_lottery()
if lot.get("draw"):
dr = lot["draw"]
prize = ((dr.get("data") or {}).get("prize") if isinstance(dr.get("data"), dict) else None)
if dr.get("code") == "SUCCESS":
extras.append("转盘✅%s" % ((prize or {}).get("name", "中奖") if prize else "已抽"))
else:
extras.append("转盘×%s" % (dr.get("msg") or ""))
except Exception as e:
log("[%s] 月签转盘异常 %r" % (name, e))
acct["ok"] = True
acct["detail"] = " ".join(extras) + "|累计 %s 天" % days_now
return 0, acct
# ---------------------------------------------------------------- 主流程