这是一组自动化脚本,用来:
imap_curator_export.py 登录 IMAP 邮箱,筛选 Steam Curator 索要激活码的邮件,导出 curator_requests.xlsx;bulk_send_keys.py 读取导出的 Excel 和 steam_key.txt 里的激活码池,批量发送 HTML 邮件,并记录每个 key 的派发日志。brew install python@3.10,Windows 直接从 python.org 下载)。建议使用虚拟环境隔离依赖:
python3 -m venv .venv
source .venv/bin/activate # Windows 里是 .venv\Scripts\activate
安装依赖:
pip install -r requirements.txt
若首次安装 pip 版本过旧,可先 python -m pip install --upgrade pip。
目录布局(已建好):
configs/settings.json:统一配置 IMAP/SMTP、默认文件路径(records/……)、主题、起始日期、最小 UID 等(仓库里只放模板 configs/settings.template.json,自己复制为 settings.json 使用);configs/curator_state.json:脚本自动维护的书签与已发送邮箱;templates/:HTML 邮件模板(默认使用 templates/email_template.html);records/:输入/输出数据文件(默认 curator_requests.xlsx、send_log.xlsx、steam_key.txt 都在这里)。configs/settings.template.json 示例(复制为 settings.json 后填入真实凭证):
{
"subject": "Steam Keys for Such A Guy -",
"start_date": "18-Oct-2025",
"min_uid": 125,
"files": {
"excel": "records/curator_requests.xlsx",
"keys": "records/steam_key.txt",
"log": "records/send_log.xlsx",
"template": "templates/email_template.html",
"state": "configs/curator_state.json"
},
"smtp": {
"host": "smtp.feishu.cn",
"port": 587,
"user": "support@suchone.com.cn",
"pass": "your-app-pass",
"from_name": "SUCH ONE STUDIO",
"from_email": "support@such-one.com"
},
"imap": {
"host": "imap.feishu.cn",
"port": 993,
"user": "support@suchone.com.cn",
"pass": "your-app-pass",
"mailbox": "INBOX"
}
}
命令行如果只写文件名(如 --excel curator_requests.xlsx),脚本会自动拼接对应目录(records/templates/config)。
imap_curator_export.py登录 IMAP 邮箱、抓取自上次书签之后的邮件,排除回复/转发,提取 Curator 名称、邮箱、社交链接、所需 key 数等信息写入 records/curator_requests.xlsx。脚本会把已处理的邮箱/UID 存在 configs/curator_state.json,下次只扫描新的邮件。
IMAP/起始日期/输出路径等全部在 configs/settings.json 中维护(运行时可改用 --config path/to/settings.json)。
导出的 Excel 列包含:No.、Mailbox Key、Requested Key Count、Date、Curator/Name、Email、Subject、Curator/Social Links、Body (preview)、Original Message-ID。最后一列用于让发送脚本把 In-Reply-To/References 指向原邮件,确保邮件客户端能按对话显示。
# 1. 连通性测试(只确认能否登录,不读写状态)
python imap_curator_export.py --config configs/settings.json --test
# 2. 正式导出(使用/更新书签)
python imap_curator_export.py --config configs/settings.json
# 3. 重置书签后再导出(强制从 START_DATE 开始)
python imap_curator_export.py --config configs/settings.json --reset-state
# 4. 导出后顺便把匹配的邮件标记为已读
python imap_curator_export.py --config configs/settings.json --mark-read
运行完成后会在 records/curator_requests.xlsx 中追加 curtor_YYYYMMDD## 的表格,configs/curator_state.json 记录最新 last_uid。脚本结束时,还会贴心打印三条推荐命令(Dry-run / Test / Real)。
bulk_send_keys.py读取 records/curator_requests.xlsx 与 records/steam_key.txt 中待分发的激活码,按请求数量配给 key,使用 templates/email_template.html(若不存在则用脚本内置模板)渲染 HTML 邮件,通过 SMTP 发送,并在 records/send_log.xlsx 里记录“每个 key 一行”的详细日志(每次运行会新增 sendlog_YYYYMMDD## 的 sheet 并置顶;真实发送开始前会自动清理旧的 DRYRUN/TEST sheet)。脚本还会在 configs/curator_state.json 里维护 sent_emails 列表,防止向已发过 key 的邮箱重复派发。支持 Dry-run、Test 模式、跳过已处理 UID、发送成功后把原邮件标记 \Answered。如果 Excel 中包含 Original Message-ID,回复邮件会自动带上 In-Reply-To/References,方便邮件客户端按对话展示。
默认配置全部来自 configs/settings.json,命令行参数只在需要覆盖默认值时使用。常见参数:
--config:使用其他 settings.json;--excel/--keys/--out/--template:覆盖默认文件,若仅写文件名会自动落在对应目录;--subject:覆盖设置文件中的主题前缀(发送时依旧会拼接原邮件主题);--sheet:指定 Excel 中的工作表;--limit:只处理前 N 条;--dry-run:仅渲染预览;--test:把邮件发送到测试邮箱,默认会记录 sent_emails;若只想验证流程又不想污染状态,可加 --no-sentemail,并常配合 --no-consume;--skip-sent:按照 send_log 里记录的 UID 跳过;--mark-answered:真实发送后将原邮件标记 \Answered(IMAP 参数可来自 settings.json,也可用 CLI 覆盖)。# 1. 预览模式:只渲染邮件,不发送、不消耗 key
python bulk_send_keys.py --config configs/settings.json \
--sheet curtor_2025111907 \
--dry-run --limit 5
# 2. 测试发送:发给指定测试邮箱,记录日志但不扣除 key
python bulk_send_keys.py --config configs/settings.json \
--sheet curtor_2025111907 \
--test --test-email your_test@example.com \
--no-consume --no-sentemail
# 3. 正式批量发送,并把成功邮件标记 \Answered
python bulk_send_keys.py --config configs/settings.json \
--sheet curtor_2025111907 \
--mark-answered
成功发送(非 dry-run/test)后,脚本会更新 records/steam_key.txt 以移除已使用的 key,写入 records/send_log.xlsx(sendlog_YYYYMMDD## sheet),并在真实发送启动前自动清理旧的 DRYRUN/TEST sheet;记得在真实发送前先用 --dry-run 或 --test 确认内容。