">
← 返回项目列表

03 · 个人开源项目 · Next.js 15 / Electron · v0.1.5

Email2Job · 招聘邮件求职进度同步

粘贴或邮箱授权码自动拉取招聘邮件,抽字段、判阶段,写入本地求职进度和事件流水,可选同步到飞书多维表格。v0.1.5 起打包为 Windows 桌面版,免 Node.js 安装。三条硬约束贯穿全程:不读邮箱授权以外的内容、不外发邮件原文、密钥本地加密持久化。

我的工作 独立开发
技术栈 Next.js 15 · TypeScript · React 19 · Electron 32 · Kimi / DeepSeek · 飞书多维表格 API

概览

求职时招聘邮件散落在邮箱里,要把公司、岗位、面试时间、地点、当前阶段一项项抄进 Excel 或飞书表格,重复且容易漏。

这个工具把这件事压成一次操作:邮件正文贴进去,或在 v0.1.5 起配置邮箱授权码自动拉取;模型识别出结构化字段,自动判断处在哪一阶段(简历筛选 / 笔试 / 一面 / 二面 / offer),写入本地进度表和事件流水。飞书同步是可选的,不配置也能完整使用;桌面版同样可以独立运行,关闭软件后本地解析与同步随之停止。

数据流

邮箱输入 粘贴 · 授权码拉取 v0.1.5 起支持自动 大模型识别 Kimi / DeepSeek 失败则规则降级 结构化数据 公司 · 岗位 阶段 · 时间 地点 · 联系人 JSON Schema 校验 本地存储 data/jobs.json 求职进度表 data/events.json 事件流水 飞书同步 App ID + Secret 表格 Token 可选 · 失败不影响本地 可视化面板 进度卡片 事项明细 响应式 1–3 列 本地优先 · 密钥不持久化 · 邮件原文不出本机
数据流。v0.1.5 起新增"邮箱授权码自动拉取"路径——用户为各邮箱生成 IMAP 授权码、在桌面版设置页录入后由本地服务拉取,邮件原文不出本机;虚线表示可选路径——飞书同步挂掉,本地功能完全不受影响,这是设计时就划好的边界。

问题

  1. 手动整理进度表费时且易漏

    要从每封邮件里找出公司、岗位、面试时间、地点,判断当前阶段,再填进表格。邮件一多就跟不上,漏掉一个面试邀请代价很大。

  2. 依赖大模型带来成本与可用性风险

    免费额度用完要付费,API 限流或网络不通时功能直接不可用。一个纯前端小工具如果模型挂了就全废,那它是脆的。

方案

  1. 01本地优先的数据存储

    数据写在项目根目录的 data/ 下:jobs.json 是当前状态表,events.json 是完整的事件流水。data/ 已加入 .gitignore,适合本地使用和自行备份。

    为什么用文件而不是数据库:求职数据规模很小(几十到几百条),JSON 文件可读、可 diff、可手写修正,比引入一整套存储更合适。

  2. 02大模型识别 + 规则兜底

    优先走大模型(Kimi / DeepSeek),处理"我们计划在本周五下午 3 点安排一次技术面试"这类复杂表述。调用失败或无结果时降级到规则解析:关键词匹配,"笔试" → 阶段:笔试。

    为什么明知道准确率低还要做兜底:规则解析的准确率明显低于 LLM,但它换来的不是精度,是可用性下限——模型不可用、额度用尽、网络不通的时候,功能不会整个塌掉。

  3. 03可选飞书同步

    配置页填写飞书 App ID、App Secret、表格 Token、表格 ID,识别结果自动写入飞书多维表格,支持多人协作。同步失败时本地数据不受影响,密钥不在浏览器持久保存。

    为什么做成可选:同步能力依赖用户自己的飞书应用配置,强依赖等于把门槛放在第一步。可选化之后,零配置也能完整跑通主流程。

  4. 04响应式与验证脚本

    求职进度保留最近 6 个岗位卡片,按可用宽度自动排 1–3 列;明细表格每页 10 条,页数多时折叠中间页码。覆盖 320–1920px,并留了可复跑的验证脚本:

    npm run desktop:prepare && node tests/layout-smoke.cjs

    为什么要脚本化:布局这类问题靠肉眼看一遍只能覆盖当下这次改动。脚本化之后,每次改样式都能用同一把尺子复验。

  5. 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
    飞书同步是单向的。只能从本地推到飞书,不能把飞书里的改动拉回本地,双向会引入冲突处理,当前没有做。