03 · 个人开源项目 · Next.js 15 / Electron · v0.1.5
Email2Job · 招聘邮件求职进度同步
粘贴或邮箱授权码自动拉取招聘邮件,抽字段、判阶段,写入本地求职进度和事件流水,可选同步到飞书多维表格。v0.1.5 起打包为 Windows 桌面版,免 Node.js 安装。三条硬约束贯穿全程:不读邮箱授权以外的内容、不外发邮件原文、密钥本地加密持久化。
概览
求职时招聘邮件散落在邮箱里,要把公司、岗位、面试时间、地点、当前阶段一项项抄进 Excel 或飞书表格,重复且容易漏。
这个工具把这件事压成一次操作:邮件正文贴进去,或在 v0.1.5 起配置邮箱授权码自动拉取;模型识别出结构化字段,自动判断处在哪一阶段(简历筛选 / 笔试 / 一面 / 二面 / offer),写入本地进度表和事件流水。飞书同步是可选的,不配置也能完整使用;桌面版同样可以独立运行,关闭软件后本地解析与同步随之停止。
数据流
问题
-
手动整理进度表费时且易漏
要从每封邮件里找出公司、岗位、面试时间、地点,判断当前阶段,再填进表格。邮件一多就跟不上,漏掉一个面试邀请代价很大。
-
依赖大模型带来成本与可用性风险
免费额度用完要付费,API 限流或网络不通时功能直接不可用。一个纯前端小工具如果模型挂了就全废,那它是脆的。
方案
-
01本地优先的数据存储
数据写在项目根目录的
data/下:jobs.json是当前状态表,events.json是完整的事件流水。data/已加入.gitignore,适合本地使用和自行备份。为什么用文件而不是数据库:求职数据规模很小(几十到几百条),JSON 文件可读、可 diff、可手写修正,比引入一整套存储更合适。
-
02大模型识别 + 规则兜底
优先走大模型(Kimi / DeepSeek),处理"我们计划在本周五下午 3 点安排一次技术面试"这类复杂表述。调用失败或无结果时降级到规则解析:关键词匹配,"笔试" → 阶段:笔试。
为什么明知道准确率低还要做兜底:规则解析的准确率明显低于 LLM,但它换来的不是精度,是可用性下限——模型不可用、额度用尽、网络不通的时候,功能不会整个塌掉。
-
03可选飞书同步
配置页填写飞书 App ID、App Secret、表格 Token、表格 ID,识别结果自动写入飞书多维表格,支持多人协作。同步失败时本地数据不受影响,密钥不在浏览器持久保存。
为什么做成可选:同步能力依赖用户自己的飞书应用配置,强依赖等于把门槛放在第一步。可选化之后,零配置也能完整跑通主流程。
-
04响应式与验证脚本
求职进度保留最近 6 个岗位卡片,按可用宽度自动排 1–3 列;明细表格每页 10 条,页数多时折叠中间页码。覆盖 320–1920px,并留了可复跑的验证脚本:
npm run desktop:prepare && node tests/layout-smoke.cjs为什么要脚本化:布局这类问题靠肉眼看一遍只能覆盖当下这次改动。脚本化之后,每次改样式都能用同一把尺子复验。
-
05Windows 桌面打包(v0.1.5 起)
v0.1.5 把 Next.js 通过
electron-builder输出为 Windows x64 桌面应用(176 MB),安装包无需 Node.js 或 Git,附带 SHA-256 校验文件供用户自验。包内不预置 API Key、邮箱授权码或飞书密钥——用户在设置页录入后加密保存在本机配置目录。为什么从 Web 转向桌面:"本地优先"在浏览器里其实是被绕了一道——浏览器存储易被云同步、密钥进
localStorage即便不上云也仍在浏览器进程内。桌面版让"本地"二字落到 OS 用户目录,关闭即停,无自动更新、无开机自启,对应个人本机使用而非公网服务的定位。
关键决策
为什么从"只能粘贴"演化到"授权码拉取"?
早期只做手动粘贴——读邮箱需要 OAuth 或 IMAP 密码,多数人不会为一个小工具交出邮箱全权限。但手动粘贴有两个问题:① 邮件一多就漏;② 每次都要打开邮箱、复制、切回来,重复劳动明显。v0.1.5 加入新路径:用户自行为各邮箱生成 IMAP 授权码(QQ / 网易 / Outlook 等均提供),凭授权码在桌面版本地拉取,邮件原文不出本机;授权码可随时吊销,比第三方 OAuth 更轻。代价是每换设备 / 邮箱要重配,但这个代价比粘贴重复劳动小。
为什么要规则兜底,明知道它的准确率不如 LLM?
规则兜底的准确率明显不如 LLM,但它换来的不是精度,是可用性下限——模型不可用、额度用尽、网络不通的时候,功能不会整个塌掉。一个纯前端小工具如果模型挂了就全废,那它是脆的。规则降级保证了任何情况下都有输出,用户可以基于不完美的结果手动修正,总比什么都没有强。
为什么数据存本地,而不是云端为主?
求职数据包含公司名、岗位、面试时间、联系人,上传第三方有隐私风险。本地优先意味着数据可控、可离线使用、可随时删除。飞书同步是可选的——配置了才开启,没配也能完整跑通主流程。代价是多设备同步要自己解决,但求职工具的使用场景主要是单设备(电脑),这个代价可以接受。
为什么从 Web 转向桌面版?
"本地优先"在浏览器里其实是被绕了一道——浏览器存储易被云同步、密钥进 localStorage 即便不上云也仍在浏览器进程内。桌面版让"本地"二字落到 OS 用户目录,关闭即停,无自动更新、无开机自启,对应个人本机使用而非公网服务的定位。v0.1.5 桌面版 176 MB,安装包无需 Node.js 或 Git,用户在设置页录入密钥后加密保存在本机配置目录,不预置任何凭证。
结果
176 MB
v0.1.5 Windows 安装包
免 Node.js · 附 SHA-256 校验
未评测
规则兜底准确率
低于 LLM;换来功能可用性下限
0
邮件原文上传量
含 IMAP 授权码拉取路径
已知边界
-
01
自动拉取依赖各服务商授权码。目前只接入了主流邮箱的 IMAP 授权码流程;服务商策略变更、接口字段调整、授权码被吊销都需要重配。
-
02
桌面版目前仅 Windows x64。v0.1.5 安装包基于 electron-builder 的 Windows 目标,macOS / Linux 暂未提供;Web 版仍可在其他系统使用。
-
03
规则兜底只能处理简单场景。准确率明显低于 LLM,意味着降级路径下需要人工核对,它保证的是"还能用",不是"还准"。
-
04
飞书同步是单向的。只能从本地推到飞书,不能把飞书里的改动拉回本地,双向会引入冲突处理,当前没有做。