Files
ql-scripts/cmcc/README.md
zhuhjay 27e3c95585 feat(cmcc): 中国移动签到有礼自动签到(Python3 重放素材链路)
协议链路 2026-11-07 全实验裁决后投产:
- 重放 autoLogin 素材换会话(命中即停 + 15 败长静默防风暴冷却)
- appTokenLogin 换 QWHD_SESSION_TOKEN(token=原始 Set-Cookie 全值)
- mark31/domark 签到 + 幂等(markstatus 先行)
- 出口 IP 无关/素材无小时级寿命 已实测证伪,云青龙可直接部署
- 通知走 webhook+pushplus 双通道(与 common.js 契约同名的 Python 实现)
- 素材获取:保持登录态等自动续期抓一次即可,无每日仪式
2026-11-07 16:48:50 +08:00

61 lines
3.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 中国移动自动签到(scrip_cmcc_mark.py)
中国移动 APP「签到有礼」自动签到,青龙 Python3 零第三方依赖(只用 requests,面板自带)。
协议底座(全部实测,2026-11-07):重放抓包素材 `autoLogin` 换 APP 会话 →
`appTokenLogin` 换 `QWHD_SESSION_TOKEN` → `mark31/domark` 签到。
三大前提已实验裁决:出口 IP 无关、素材寿命是「冷却」机制而非小时数、
抓素材需登录态但**一次登录长期收**(已登录冷启动不发 autoLogin,无每日仪式)。
> **文件名必须带 `scrip_` 前缀**:订阅白名单规则(根 README)。
> 元数据头两行 `// cron:` / `// name:`(Python 用 `#`)已按仓库约定写好,
> 新增后跑 `node _probe_meta.js` 需把 `.py` 加入扫描范围(当前探针只扫 js,
> Python 侧由本 README 说明兜底)。
## 环境变量
| 变量 | 必填 | 说明 |
|---|---|---|
| `CMCC_AUTOLOGIN_CURL` | ✅(与 CMCC_TOKEN 二选一) | 整段 cURL(手机抓包导出 autoLogin 请求)。多号用 `CMCC_AUTOLOGIN_CURL_2` / `_3` … 编号变量,**每号一份素材**(素材与账号一对一) |
| `CMCC_TOKEN` | 备选 | 直通 token(仅当天调试;TTL≈30min,隔日必死) |
| `CMCC_NOTIFY_ON_SUCCESS` | 可选 | `1` = 签到成功也推送(默认只推失败) |
| `WEBHOOK_URL` / `PUSH_PLUS_TOKEN` 等 | 可选 | 通知通道,与仓库 `common.js` 契约同名同义(Python 侧同语义实现) |
## 素材怎么抓(一次登录,长期收)
1. 手机保持 APP **登录态**(不用清数据——已实测清数据后冷启动不发 autoLogin)
2. 开抓包(Reqable/HttpCanary/mitmproxy),在 APP 里触发一次登录或等它自动续期
3. 找 `client.app.coc.10086.cn` 的 `uamrandcodelogin/autoLogin` 请求
(**响应必须含 `Set-Cookie: JSESSIONID`**,没有的是失败记录不是素材)
4. 导出为 cURL(含 header + body),整段贴进 `CMCC_AUTOLOGIN_CURL`
5. **抓完立刻关手机代理**(`settings put global http_proxy :0`,否则 APP 断网)
素材失效的信号是**连续多次全 64B**(会话层死)——这时才需要重抓。
88B ≠ 失效(素材活着只是没命中,稍后再跑);236B ≠ 封号(慢节拍通道,快节拍重试)。
## 定时
```
40 8 * * * # 主任务(脚本头注已写,订阅自动建任务用)
0 12 * * * # 建议手动补一条错峰补签——命中即停模式下 30 发全败概率 ≈36%,双 cron 把日失败率压到 <13%
```
同一日重复运行幂等(`HAVE_MARKED`/markstatus 先行判断),多补一条 cron 无副作用。
## 退出码
| 码 | 含义 |
|---|---|
| 0 | 成功 / 今日已签 |
| 1 | 签到动作失败(复核未通过) |
| 2 | 素材问题(重放未命中 / cURL 解析损坏) |
| 3 | 换票失败([C]/[D] 层) |
## 实现关键坑(改动前必读)
1. **token 必须用原始合并 Set-Cookie 全值**(`split("; Secure")` 前段,含 Comment/Path 属性碎片)——结构化重建三段式实测报「APP登录状态已过期」
2. **[A] 重放必须无状态 `requests.post`**——Session 的 `prepare_cookies` 会用 jar 覆盖素材 Cookie 头 → 64B
3. **Set-Cookie 名字判定必须 `re.findall`**——服务端把 JSESSIONID+UID+ticketID 合并在同一条头里,`re.match` 取首个恒漏 UID
4. **命中即停**——命中后立刻冷却(连打全 88B),循环里多打是纯浪费还喂风暴
5. sid 正则必须 `[A-Za-z0-9]+`——大写版截断尾部随机串 → 换票 404(但 code 仍 SUCCESS,判据是 url 含 404)