每天自动给一个或多个 GLaDOS 账号签到、自动兑换流量天数,并把每个账号的签到结果分别发邮件给你。
- ✅ 多账号:一个 Cookie 一行,账号数量不限
- ✅ 每个账号一封独立邮件,收件人可以按账号分别指定(也可以一个账号发给多个邮箱)
- ✅ 发信走 SMTP(推荐):QQ / 163 / Gmail 等普通邮箱的授权码,收件人想发给谁就发给谁
- ✅ 也支持 Resend API,但它要求你自己拥有域名才能发给别人,详见下方「关于 Resend」
- ✅ 邮件正文沿用原格式:签到结果 + 剩余天数 + 当前积分 + 兑换状态 + 目标兑换计划 + 近 7 天积分变化表
- ✅ 敏感信息只放 GitHub Secrets,仓库里不出现任何 Cookie / API Key / 授权码
- ✅ 配置可以「一个 secret 搞定」,也可以拆成一组 secrets,怎么顺手怎么来
- Fork / 克隆本仓库。
- 准备好每个账号的 GLaDOS Cookie(见下方「怎么拿 Cookie」)。
- 准备一个邮箱的 SMTP 授权码(见下方「怎么拿 SMTP 授权码」)。
- 到仓库 Settings → Secrets and variables → Actions → New repository secret 添加 secret(见下方配置说明)。
- 到 Actions → GLaDOS Daily Checkin → Run workflow 手动跑一次,看日志确认成功。
浏览器登录 https://glados.one,F12 → Network → 随便点一个 api/user/... 请求 → 复制请求头里的 Cookie 整行(形如 gld:sess=xxxx; gld:sess.sig=yyyy; koa:sess=...)。
认准
gld:sess。 GLaDOS 现在按gld:sess判断登录态;koa:sess是早期版本遗留的 Cookie,单独发送它一定返回「没有权限」。所以要复制整个 Cookie 请求头,别只挑一条。
要点:
gld:sess和gld:sess.sig必须成对,且是同一时刻复制的。 浏览器每发一次请求都可能刷新它们;用旧的值配新的.sig会签名校验失败,服务器只会回一句「没有权限」——注意它返回的是 HTTP 200,不是 401。- 别用
document.cookie。 会话 Cookie 是 HttpOnly 的,控制台里看不到,抓出来的会是残缺 Cookie。用 Network 面板的请求头,或 Application → Cookies。 - 抓完就存,别再来回刷新。 复制之后浏览器又登录过/退出过,这个会话可能已经被服务端作废。
Cookie 等于账号密码,不要提交到仓库、不要发给别人。过期了就重新抓一次,更新 secret 即可。
另外 GLaDOS 还有设备校验:登录时它会记下设备(浏览器),之后签到请求必须来自同一个设备,否则返回
{"code":4,"reason":"device-mismatch","message":"Automated check-in detected. Please sign in again to continue."}。
它按 User-Agent 判断设备,所以脚本默认用 Windows + Edge 的 UA。如果你是用手机或 Chrome 登录的,
就用 GLADOS_USER_AGENT(或配置里的 user_agent)改成你浏览器的 UA——F12 → Network → 任意请求 →
请求头里的 User-Agent 整行复制即可。日志每次都会打印当前用的 UA,方便比对。
拿不准新 Cookie 能不能用?先本地验一下(只读,不会签到、不消耗当天次数):
python GLaDOS_Checkin.py --check-cookie "gld:sess=xxxx; gld:sess.sig=yyyy"有效会打印登录账号、剩余天数、当前积分;无效会直接告诉你是缺了 .sig,还是两个值不是同一时刻复制的。
用你平时收信的那个邮箱,开启 SMTP 服务,生成一串授权码——注意它不是邮箱登录密码:
| 邮箱 | 服务器 | 端口 | 授权码在哪生成 |
|---|---|---|---|
| QQ 邮箱 | smtp.qq.com |
465 | 设置 → 账户 → 开启「SMTP 服务」→ 生成授权码 |
| 163 邮箱 | smtp.163.com |
465 | 设置 → POP3/SMTP/IMAP → 开启服务 → 新增授权码 |
| Gmail | smtp.gmail.com |
587 | 先开启两步验证,再到「应用专用密码」生成 |
| Outlook / Office365 | smtp.office365.com |
587 | 账户安全 → 高级安全选项 → 应用密码 |
端口 465 走 SSL,其他端口(587 等)走 STARTTLS,脚本自动判断。 SMTP 对收件人没有任何限制,一个账号想同时发给几个邮箱,逗号隔开写就行。
Resend 的 API 用起来确实干净,但不建议没有自己域名的人用,它的免费发件人有硬限制:
- 没验证域名时只能用
onboarding@resend.dev发信,而且只能发给你注册 Resend 用的那个邮箱。发给其他任何地址都会整封失败,报403 You can only send testing emails to your own email address——注意是整封失败,不是只跳过那一个收件人。 - 想发给别人(比如把签到结果发到 QQ 邮箱),必须先 Domains → Add Domain 验证一个你自己拥有的域名,再把
from改成你的名字 <noreply@你的域名>。
也就是说,除非你手上正好有个域名可以做 DNS 验证,否则用 SMTP 更省事,收件人也自由。
如果你确实要用 Resend:https://resend.com/ 用 GitHub 账号登录 → API Keys → Create API Key(权限选 Sending access 就够)→ 复制 re_ 开头的 Key(只显示一次,记得存好),然后按下面的配置写。
只加 一个 repository secret:GLADOS_CONFIG,值就是下面这段文本(GitHub secret 支持多行)。
# ===== 发信配置(全局)=====
[mail]
provider = smtp
smtp_server = smtp.qq.com
smtp_port = 465
user = 你的QQ号@qq.com
pass = 邮箱授权码 # 不是登录密码
from = GLaDOS_Checkin <你的QQ号@qq.com> # 可以不写,不写就用 user
# ===== 账号 1 =====
[account]
name = 主账号
cookie = gld:sess=aaaa; gld:sess.sig=bbbb
mail_to = me@example.com, backup@example.com
plan = plan500
# ===== 账号 2 =====
[account]
name = 小号
cookie = gld:sess=cccc; gld:sess.sig=dddd
mail_to = other@example.com
plan = plan200规则:
[account]出现几次就是几个账号,每个账号会收到自己那封邮件。- Cookie 前面一定要写
cookie =。 直接粘一整行 Cookie 进去会被当成别的键名,账号会被当成「没配 Cookie」而跳过(脚本现在会兜底识别并提醒你补上,但最好一次写对)。 - Cookie 里的
;分隔符不能丢。 从浏览器界面复制时折行很容易把两条粘成一条(例如gld:sess.sig=pefz...IVskoa:sess.sig=TNt...),签名值被污染后必定登录失败。稳妥做法是从 Network 面板复制请求头里那一整行。 [mail]段写发信配置;也可以省略段头,把发信配置直接写在最前面。- 键名不区分大小写,
=和:都行,#开头是注释,行尾# 注释也可以。 - 账号里的
mail_to/plan/ 发信字段会覆盖全局配置;没写的就继承全局。 - 只有一个账号时,可以直接写
cookie = xxx,不用[account]段;多个账号用cookies = cookie1 && cookie2。
| 字段 | 位置 | 说明 |
|---|---|---|
provider |
全局 / 账号 | smtp(推荐)或 resend。两种凭据都配了时 smtp 优先,也可以显式写死 |
smtp_server / smtp_port |
全局 / 账号 | SMTP 服务器与端口,默认 smtp.qq.com:465(465 走 SSL,其他端口走 STARTTLS) |
user / pass |
全局 / 账号 | SMTP 账号与授权码(别名 mail_user / mail_pass) |
api_key |
全局 / 账号 | Resend API Key(别名 resend_api_key),用 Resend 时才需要 |
from |
全局 / 账号 | 发件人,可写 名字 <地址> 或裸地址(别名 mail_from)。不写则 SMTP 用 user、Resend 用默认测试发件人 |
name |
账号 | 账号备注,会出现在邮件正文里,便于区分是哪个号 |
cookie |
账号 | GLaDOS Cookie(必填) |
mail_to |
全局 / 账号 | 收件人,多个用逗号(或分号、空格)分隔 |
plan |
全局 / 账号 | 兑换计划:plan100 / plan200 / plan500,默认 plan500 |
user_agent |
全局 | 请求用的 User-Agent(别名 ua)。GLaDOS 按它比对登录设备,默认是 Windows + Edge;用手机/Chrome 登录的话改成你浏览器的 UA |
用 Resend 的话,把 [mail] 段换成(注意 from 必须是你在 Resend 验证过的域名):
[mail]
provider = resend
api_key = re_你的APIKey
from = GLaDOS_Checkin <noreply@你的域名>也支持本地文件方式(方便调试):把同样的文本存成文件,然后设环境变量 GLADOS_CONFIG_FILE=路径。
不想把 Cookie 和邮件配置放在一个 secret 里,就分开加:
| Secret 名 | 必填 | 说明 |
|---|---|---|
GLADOS_COOKIES |
二选一 | 多个账号,一行一个 Cookie;也可以在行尾用 | 追加信息:cookie | 备注 | 收件邮箱 | 计划 |
GLADOS_COOKIE |
二选一 | 只有一个账号时用它(老配置继续可用) |
GLADOS_EXCHANGE_PLAN |
否 | 全局兑换计划,默认 plan500 |
GLADOS_USER_AGENT |
否 | 覆盖请求 User-Agent(GLaDOS 按它比对登录设备) |
MAIL_PROVIDER |
否 | smtp / resend,一般不用写,脚本会自动判断(有 SMTP 账号就优先 SMTP) |
SMTP_SERVER / SMTP_PORT |
用 SMTP 时 | 默认 smtp.qq.com / 465 |
MAIL_USER / MAIL_PASS |
用 SMTP 时 | 邮箱账号 / 授权码 |
RESEND_API_KEY |
用 Resend 时 | Resend API Key |
MAIL_FROM |
否 | 发件人;不写则 SMTP 用 MAIL_USER、Resend 用 onboarding@resend.dev |
MAIL_TO |
否 | 收件人,多个用逗号分隔。所有账号的结果都会分别发到这些地址 |
GLADOS_COOKIES 的示例(3 个账号,第 3 个用全局收件人):
gld:sess=a1; gld:sess.sig=b1 | 主账号 | me@example.com, backup@example.com | plan500
gld:sess=a2; gld:sess.sig=b2 | 小号 | other@example.com
gld:sess=a3; gld:sess.sig=b3
混用也没问题:比如 GLADOS_CONFIG 里只写 [mail] 或只写 [account],其余凭据仍然从独立的 secret 里读。
正文格式与原项目保持一致(签到结果、剩余服务天数、当前总积分、兑换状态、目标兑换计划、近 7 天积分变化表)。
区别只有一处:配置了账号名(name)或存在多个账号时,正文里会多一行 账号:xxx,用来区分这封邮件是哪个号的。单账号且没写 name 时,邮件内容与原来完全一致。
每个账号单独一封邮件,互不影响;某个账号失败也会继续处理下一个。
日志里收件人会打码显示(如
in***@qq.com)。因为公开仓库的 Actions 日志任何人可读,所以脚本不会把完整邮箱写进日志;邮件本身当然还是发给完整地址。
plan100 = 100 积分兑 10 天,plan200 = 200 积分兑 30 天,plan500 = 500 积分兑 100 天。
积分够当前计划就自动兑换,不够则在邮件里提示还差多少。
pip install requests
# 只想确认某个 Cookie 还有效(只读,不签到):
python GLaDOS_Checkin.py --check-cookie "gld:sess=xxxx; gld:sess.sig=yyyy"
# 把配置文本存成 config.local.txt 后:
GLADOS_CONFIG_FILE=config.local.txt python GLaDOS_Checkin.pyLinux/macOS 上也可以临时导出环境变量跑:
GLADOS_COOKIE='gld:sess=...' MAIL_USER='you@qq.com' MAIL_PASS='授权码' MAIL_TO='me@qq.com' python GLaDOS_Checkin.py本地调试用的配置文件不要提交(
.gitignore已忽略config.local.*)。 想避免 Cookie 留在 shell 历史里,可以用--check-cookie不带参数,然后从标准输入粘贴。
Q:Action 变红了怎么办? 多账号场景下,只要有一个账号签到失败或邮件发送失败,脚本就以退出码 1 结束,方便你收到 GitHub 的失败通知。日志里会列出具体是哪些账号有问题,Actions 页面的 Summary 还有一张结果表。
Q:邮件发送失败,报 403 You can only send testing emails to your own email address?
这是 Resend 的限制:没验证域名时只能发给注册 Resend 用的那个邮箱。最省事的做法是改用 SMTP——把 [mail] 段的 provider 改成 smtp,配上邮箱账号和授权码即可。如果一定要用 Resend,就得先验证自己的域名。
Q:从 Resend 换成 SMTP 后发信报错?
多半是 from 那行还留着 onboarding@resend.dev。SMTP 发信时发件人必须是你自己邮箱的地址,这行要删掉(不写就自动用 user)。
Q:提示 535 认证失败 / 授权码错误?
pass 填的应该是邮箱授权码而不是登录密码;确认该邮箱已开启 SMTP 服务;确认 user 是完整邮箱地址(如 xxx@qq.com)。
Q:多个账号的积分和剩余天数完全一样?
大概率是两条 Cookie 填的是同一个账号。日志里每个账号都有一行「账号指纹」,形如 cookie:6a804c35 账号(email):1c0275f9:两行 Cookie 哈希不同但 账号(email) 哈希相同,就说明这两个 Cookie 属于同一个 GLaDOS 账号,重新登录另一个账号抓一份 Cookie 换上即可。
Q:邮件里写「今日已签到,明天再来吧」,是失败吗? 不是。重复签到算成功,只是没有新积分。
Q:日志写「签到失败:…没有权限」,或者指纹显示「认证失败」,怎么办?
这是 Cookie 没通过 GLaDOS 认证。注意 GLaDOS 不会返回 401,而是 HTTP 200 + {"code":-2,"message":"没有权限"}——所以哪怕 Cookie 完全是空的,站点也返回同样的东西。按顺序排查:
- Cookie 里没有
gld:sess:只带koa:sess已经不能通过认证了,要重新登录后复制包含gld:sess的完整 Cookie; - 两个值不是同一时刻复制的(浏览器一动就会刷新这两条,旧值配新签名必然失败);
- 复制之后浏览器又登录过/退出过,会话已被服务端作废;
- 域名不对:本脚本用
glados.one,其它域名是另一套会话。
本地跑 python GLaDOS_Checkin.py --check-cookie "<你的 Cookie>" 可以直接确认,不用等 Actions。它会顺带检查 Cookie 串本身:成对的 .sig 有没有缺、有没有两条被粘在一起、同一个名字是不是出现了两次且值不同。
Q:日志写「跳过一条没有 cookie 的账号配置」,或者「未找到任何账号配置」?
[account] 段里那行 Cookie 少了 cookie = 前缀。写成 gld:sess=... 时,脚本按 键 = 值 解析会把键名读成 gld,Cookie 就丢了。改写成:
cookie = gld:sess=xxxx; gld:sess.sig=yyyy; ...(新版已能兜底识别这种写法并打印提示,但仍建议按上面的写法规范填写。)
Q:Cookie 看起来是对的,站点还是回「没有权限」?
检查 Cookie 里两条有没有被粘成一条。从浏览器 cookie 列表里复制时,折行处容易丢掉 ; ,出现 ...IVskoa:sess.sig=... 这种形状,被粘住的那条签名值就是坏的。用 --check-cookie 会直接点出来;最稳妥的是从 Network → 某个 glados.one 请求 → 请求头 Cookie 复制一整行。
Q:提示 Cookie 不含 gld:sess?
GLaDOS 用 gld:sess 判断登录态,缺了它必定认证失败。会话 Cookie 是 HttpOnly 的,用 document.cookie 取不到,请从 Network 面板的请求头(或 Application → Cookies)复制完整 Cookie,先本地 --check-cookie 验一下再更新 secret。
Q:日志写「GLaDOS 判定为自动化签到」/ device-mismatch / Automated check-in detected?
Cookie 是有效的,卡在设备校验上。GLaDOS 会记下登录用的设备(按 User-Agent 判断),签到请求必须来自同一设备。
解决:用签到用的那个浏览器重新登录一次,然后把该浏览器的 UA 填进 GLADOS_USER_AGENT
(或配置里写 user_agent = ...)。脚本日志会打印它当前使用的 UA,和浏览器 Network 里的对一下即可。
注意裸 Mozilla/5.0 这类简化 UA 会被判成 Other 而拒绝。
Q:签名/发信失败会让签到白跑吗? 签到本身不受影响,账号该签的都签了,只是邮件没发出去。