# support-email ## 项目概览 这是一组自动化脚本,用来: 1. 通过 `fetch_requests.py` 登录 IMAP 邮箱,筛选 Steam Curator 索要激活码的邮件,导出 `curator_requests.xlsx`; 2. 再用 `send_keys.py` 读取导出的 Excel 和 `steam_key.txt` 里的激活码池,批量发送 HTML 邮件,并记录每个 key 的派发日志。 ## 环境准备 1. 安装 Python 3.10 或更新版本(macOS 可用 `brew install python@3.10`,Windows 直接从 python.org 下载)。 2. 建议使用虚拟环境隔离依赖: ```bash python3 -m venv .venv source .venv/bin/activate # Windows 里是 .venv\Scripts\activate ``` 3. 安装依赖: ```bash pip install -r requirements.txt ``` 若首次安装 pip 版本过旧,可先 `python -m pip install --upgrade pip`。 4. 目录布局(已建好): - `configs/settings.json`:统一配置 IMAP/SMTP、默认文件路径(records/……)、主题、起始日期、最小 UID 等(仓库里只放模板 `configs/settings.template.json`,自己复制为 `settings.json` 使用); - `configs/curator_status.json`:脚本自动维护的书签与已发送邮箱; - `templates/`:HTML 邮件模板(默认使用 `templates/email_template.html`); - `records/`:输入/输出数据文件(默认 `curator_requests.xlsx`、`send_log.xlsx`、`steam_key.txt` 都在这里)。 `configs/settings.template.json` 示例(复制为 settings.json 后填入真实凭证): ```jsonc { "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_status.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)。 ## `fetch_requests.py` ### 作用 登录 IMAP 邮箱、抓取自上次书签之后的邮件,排除回复/转发,提取 Curator 名称、邮箱、社交链接、所需 key 数等信息写入 `records/curator_requests.xlsx`。脚本会把已处理的邮箱/UID 存在 `configs/curator_status.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` 指向原邮件,确保邮件客户端能按对话显示。 ### 常用命令 ```bash # 1. 连通性测试(只确认能否登录,不读写状态) python fetch_requests.py --config configs/settings.json --test # 2. 正式导出(使用/更新书签) python fetch_requests.py --config configs/settings.json # 3. 重置书签后再导出(强制从 START_DATE 开始) python fetch_requests.py --config configs/settings.json --reset-state # 4. 导出后顺便把匹配的邮件标记为已读 python fetch_requests.py --config configs/settings.json --mark-read ``` 运行完成后会在 `records/curator_requests.xlsx` 中追加 `curtor_YYYYMMDD##` 的表格,`configs/curator_status.json` 记录最新 `last_uid`。脚本结束时,还会贴心打印三条推荐命令(Dry-run / Test / Real)。 ## `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_status.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 覆盖)。 ### 示例 ```bash # 1. 预览模式:只渲染邮件,不发送、不消耗 key python send_keys.py --config configs/settings.json \ --sheet curtor_2025111907 \ --dry-run --limit 5 # 2. 测试发送:发给指定测试邮箱,记录日志但不扣除 key python send_keys.py --config configs/settings.json \ --sheet curtor_2025111907 \ --test --test-email your_test@example.com \ --no-consume --no-sentemail # 3. 正式批量发送,并把成功邮件标记 \Answered python 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` 确认内容。