我最近把一个小工具重新整理了一遍:go-codex-notify

它做的事情很简单,就是给 OpenAI Codex 的 notify 钩子接一个 Telegram 通知。Codex 任务跑完,或者跑到某个阶段,你人不在电脑前,也能立刻收到一条消息。

这个东西本身不复杂,但它解决的是一个很实际的问题:AI 在后台干活的时候,你不想一直盯着终端。

以前这类小工具最大的问题,不是功能做不出来,而是用起来太别扭。你得自己下载二进制、选平台、放路径、改配置、处理环境变量,最后还得解释给别人怎么装。对作者来说只是几个步骤,对用户来说就是直接放弃。

所以我这次重点做的不是“让它能发消息”,而是“让它更像一个正常人会愿意用的工具”。

这个工具到底解决什么问题

如果你平时用 Codex 写代码,应该很容易碰到下面这种场景:

  • 任务一跑就是十几分钟,甚至更久
  • 你不想一直把终端窗口切回来看看结束没
  • 你离开电脑去吃饭、开会、刷手机的时候,根本不知道它什么时候完成
  • 等你回来一看,早就结束了,窗口里还堆着一大坨输出

这时候一个最朴素的需求就是:跑完了通知我一下。

Telegram 恰好很适合干这个事:

  • 配一个 bot 很快
  • 消息直达
  • 自己给自己发、发群里都行
  • 不依赖本地弹窗,也不怕远程机器没桌面环境

说白了,这不是一个“炫技型”工具,而是一个很典型的“减少等待焦虑”的工具。

为什么我后来强推 npx,而不是手动下二进制

最早这类东西的常规做法,其实就是放一个 release 二进制。

比如你是 Windows,就下载 notify-telegram-windows-amd64.exe;你是 macOS arm64,就下载另一份;Linux 再来两份。功能当然没问题,但这种方式有几个天然缺点:

第一,用户要先知道自己该下载哪一个

这件事对写代码的人来说很正常,但对很多用户并不自然。

尤其是:

  • Windows arm64 和 amd64 怎么分
  • macOS Intel 和 Apple Silicon 怎么分
  • Linux 服务器是 x64 还是 arm64

很多人其实并不想理解这些。他只想要一个能跑的命令。

第二,路径管理很烦

你下载完以后,还得考虑:

  • 放哪儿
  • 要不要加到 PATH
  • Codex 配置里写相对路径还是绝对路径
  • 换台机器怎么办

这类问题都不难,但都很碎。

第三,别人复用的时候说明成本很高

你自己装一次不觉得什么,真要写 README 给别人看,就会发现“手动下载二进制”这条路的说明会越来越长。

所以我最后把推荐路径改成了:

1
npx -y go-codex-notify

这条命令的价值就在于:

  • 用户不用管包下载在哪
  • 不用自己选平台
  • 不用自己手动下 release
  • 第一次运行时自动拉对应平台的二进制
  • 以后直接继续用

这才像一个现代 CLI 工具应该给人的体验。

现在它是怎么工作的

这个项目现在其实是两层结构。

第一层:Go 二进制

真正负责收集环境信息、读取 Codex payload、再把消息发到 Telegram 的,是 Go 程序本体。

它会带上一些很有用的信息,比如:

  • 当前时间
  • 机器名
  • 当前目录名
  • 当前完整路径
  • Git 根目录
  • Git 分支
  • 最近一次 commit
  • 工作区是否有未提交改动
  • Codex 传进来的任务信息

所以最后发到 Telegram 里的消息,不只是“结束了”,而是能告诉你:在哪个项目、哪个分支、什么任务、什么状态结束了。

第二层:npm wrapper

为了让使用体验更顺,我又加了一层 npm 包。

npm 包本身不负责发消息,它主要做三件事:

  1. 提供 npx go-codex-notify 的入口
  2. 自动识别当前系统和架构
  3. 自动下载对应 GitHub Release 二进制并执行

也就是说,npm 在这里更像一个“分发和启动器”,而不是业务本体。

这套结构的好处是两边都舒服:

  • 对用户来说:用 npx 就够了
  • 对我来说:核心逻辑还是 Go,构建和发布二进制也很稳定

用户现在到底该怎么用

如果你只是想赶紧把通知接上,不想折腾,直接按下面做就行。

第一步:准备 Telegram Bot Token

在 Telegram 里找 @BotFather,发送 /newbot,按提示创建一个 bot。

创建完成后会得到一个 token,长这样:

1
123456789:ABCDEF_xxxxxxxxxxxxx

这就是你的:

1
TELEGRAM_BOT_TOKEN

第二步:拿到 Chat ID

你需要先给这个 bot 发一条消息。

最稳妥的做法是先发一次 /start,然后打开:

1
https://api.telegram.org/bot<你的BotToken>/getUpdates

在返回的 JSON 里找:

1
message.chat.id

如果是私聊,通常是这样的纯数字:

1
123456789

如果是群组,一般会长这样:

1
-100xxxxxxxxxx

这个负号和前面的 -100 不要丢。

第三步:设置环境变量

比如在 macOS / Linux 上:

1
2
export TELEGRAM_BOT_TOKEN="123456789:xxxxxx"
export TELEGRAM_CHAT_ID="123456789"

Windows PowerShell 则可以这样:

1
2
$env:TELEGRAM_BOT_TOKEN="123456789:xxxxxx"
$env:TELEGRAM_CHAT_ID="123456789"

第四步:在 Codex 里配置 notify

现在推荐的配置是:

1
notify = ["npx", "-y", "go-codex-notify"]

就这么一条。

相比“手动下载某个平台的二进制再写路径”,这条配置的优点非常明显:

  • 跨平台
  • 可迁移
  • README 也更好写
  • 别人照着抄就能跑

这个东西带来的方便,不只是“会发消息”

很多人看到这种工具,第一反应会是:“这不就是一个通知脚本么?”

从功能上说,确实是。

但从使用体验来说,它解决的问题不只是通知,而是把 AI 编程这件事从‘必须盯着看’变成‘可以放手让它先跑’。

这个差别其实很大。

1. 减少无意义等待

最直接的一点就是,你不用反复切终端确认结束没。

以前是:

  • 切回来看看
  • 还没结束
  • 再切回来看看
  • 还是没结束

现在是:

  • 开始跑
  • 去做别的事
  • Telegram 一响,回来接下一步

这种体验上的差异,比功能描述本身更重要。

2. 远程机器场景特别舒服

如果你的 Codex 不是跑在本机,而是跑在 VPS、远程 Linux、WSL、甚至某个长期挂着的开发机上,那 Telegram 通知的价值会更明显。

因为这时候你根本不依赖本地系统通知,也不依赖图形界面。

你只要手机还能收 Telegram,任务状态就能到手。

3. 更适合串长任务

有些任务不是一句 prompt 就结束的,而是:

  • 先跑生成
  • 再跑测试
  • 再看结果
  • 再决定下一步

这类流程最烦的,就是人被卡在“等它跑完”这个阶段。加一个通知以后,人就从同步阻塞变成异步处理了。

4. 更容易分享和复用

这个我自己感受很深。

如果一个工具的使用方式是:

“先下载某某 release,注意选对平台,把文件放到某个目录里,再改配置,再设置权限……”

那它的传播效率会非常差。

而如果一个工具的使用方式是:

1
npx -y go-codex-notify

那别人理解成本就低太多了。

很多时候,真正决定一个小工具能不能活下来的,不是它有没有技术含量,而是它是不是足够顺手。

这次顺手还把发布链路也补齐了

既然都整理到这一步了,我就顺手把发布流程也补完整了。

现在这个项目的 release 流程会同时做两件事:

  1. 构建并发布多平台 Go 二进制到 GitHub Releases
  2. 自动把 npm 包发布到 npm registry

也就是说,后面每次发新版,用户会同时得到:

  • GitHub Release 二进制
  • npx / npm install -g 可用的 npm 包

这件事看起来只是“工程化收尾”,但实际上很关键。

因为只有发布链路顺了,README 里的使用方式才不会沦为口头承诺。

最后

我现在越来越觉得,AI 工具真正该优化的,不是“再多做一点功能”,而是把那些本来就该顺手的事情,真的做顺手。

go-codex-notify 就是一个很典型的例子。

它没有多么复杂,也不是什么“大而全”的项目,但它把一个高频、真实、烦人的小问题处理得更像样了:Codex 跑完,第一时间通知我,而不是让我守着它。

如果你也在用 Codex,或者你也有“任务已经跑完了但人还傻等着”的问题,那这个东西大概会比你想象中更有用。

目前最推荐的用法还是这条:

1
notify = ["npx", "-y", "go-codex-notify"]

简单,直接,够用。

评论