1. 为什么 Claude Code 跑完任务,我却总是最后一个知道
你有没有过这种体验:给 Claude Code 扔了一个重构任务,它开始吭哧吭哧改文件、跑测试、写代码,你想着“反正要几分钟,先去倒杯水”,结果回来一看,它早就跑完了,而你在刷手机的时候完全没注意到。更尴尬的是,有时候它中途卡在一个权限确认上,等了你二十分钟,你才发现它根本没往下走。
这个场景在长时间任务里特别常见。我平时会让 Claude Code 处理一些批量重命名、依赖升级、单元测试补全的活,单个任务动辄五到十五分钟。如果一直盯着终端,效率极低;如果不盯,又容易错过完成时机,甚至把整个会话晾在那里。尤其是当你在多个项目之间切换时,一个任务完成了没有通知,你很可能就把它忘了。
Claude Code 本身提供了 hooks 机制,允许在特定事件发生时执行自定义命令。其中Stop事件就是在 Claude Code 完成一次响应、准备把控制权交还给你时触发的。把这个事件接到一个通知脚本上,就能实现“任务完成自动提醒”。而通知渠道,我选择用微信,因为它在手机上推送及时,不需要额外装 App,也不依赖任何特殊网络环境。
整条链路是这样的:Claude Code 触发Stophook → 执行notify.sh→ 脚本调用微信推送接口 → 你的微信收到消息。同时,脚本里还可以顺带通过 TaoToken 的统一 API 通道做一次模型调用,比如让模型生成一句任务摘要,或者记录本次会话的元信息。TaoToken 在这里的角色是统一 Key 管理,你不需要在脚本里硬编码多个平台的密钥,一个 Key 就能覆盖模型调用和后续扩展。
这篇文章会从零开始,把settings.json的 hooks 配置、notify.sh脚本编写、TaoToken 统一 Key 的接入方式,以及一次完整的端到端验证全部走一遍。你照着做,大概十分钟就能让 Claude Code 在完事后给你发微信。
2. TaoToken 统一 Key 与 hooks 通知链路的前置准备
在动手写配置之前,先把几个关键概念和准备工作理清楚。很多人卡住不是因为脚本写错,而是因为前置条件没满足,比如 Key 没拿到、脚本权限不对、或者settings.json被覆盖了。
2.1 TaoToken 统一 Key 是什么,为什么这里要用它
TaoToken 是一个面向开发者的 API 统一接入层,它把模型调用、Key 管理、用量查看这些事集中到一个控制台里。你可以把它理解成一个“API 网关 + 密钥管家”:你只需要在 TaoToken 控制台创建一个 Key,就能通过统一的 Base URL 调用后端模型,不用在每个项目里分别配置不同平台的密钥。
在这个通知链路里,TaoToken 的作用有两个。第一,notify.sh脚本里如果需要调用模型生成任务摘要,可以直接用 TaoToken 的 API 通道,Base URL 是https://taotoken.net/api,Key 就是你在控制台创建的那一个。第二,如果你后续想扩展通知内容,比如让模型判断任务是否成功、提取关键变更,也只需要在这一个 Key 下操作,不用再折腾多套鉴权。
创建 Key 的入口在 TaoToken 控制台的 API Keys 页面。登录后进入控制台,找到 API Keys 菜单,点创建,复制生成的 Key 字符串。这个 Key 只显示一次,建议先存到密码管理器里。模型 ID 方面,你可以根据自己常用的模型来选,比如claude-sonnet-4-20250514这类标识,具体以控制台模型列表为准。
2.2 微信通知渠道的选择与 Token 获取
微信通知这块,我用的是一个常见的公众号推送服务,它通过关注公众号后自动分配一个 Token,然后你往一个固定 URL POST 内容,就能在微信里收到消息。整个流程不需要额外安装任何东西,也不涉及特殊网络配置。
你需要在微信里关注对应的公众号,关注后它会自动回复一个 Token,格式类似一串字母数字组合。把这个 Token 记下来,后面脚本里要用。注意,这个 Token 是跟你的微信绑定的,不要泄露到公开仓库里。
2.3 目录结构与文件规划
Claude Code 的 hooks 配置默认读取~/.claude/settings.json。通知脚本我放在~/.claude/hooks/notify.sh。这样目录结构清晰,也方便后续管理多个 hook 脚本。
在终端里先创建目录:
mkdir -p ~/.claude/hooks然后确认一下~/.claude/settings.json是否存在:
ls -la ~/.claude/settings.json如果文件不存在,后面可以直接创建;如果已经存在,千万不要用cat >直接覆盖,否则你原有的配置全没了。正确做法是用编辑器打开,把hooks字段合并进去。
2.4 环境检查清单
在继续之前,确认这几项:
- 你的系统是 macOS 或 Linux,Windows 用户建议在 WSL 下操作,或者把脚本改成 PowerShell 版本。
bash可用,curl可用。终端里执行which bash curl能返回路径即可。- 你已经拿到微信推送 Token 和 TaoToken 的 API Key。
- 你有权限写入
~/.claude/目录。
这些都没问题的话,就可以进入配置环节了。
3. 可复制的 settings.json 与 notify.sh 完整配置
这一节是核心,所有代码都可以直接复制。我会把settings.json的 hooks 片段、notify.sh的完整脚本、以及 TaoToken 统一 Key 的接入方式都写清楚。你只需要替换两个占位符:微信推送 Token 和 TaoToken API Key。
3.1 settings.json 的 hooks 配置片段
Claude Code 的 hooks 配置结构是:顶层一个hooks对象,里面按事件名分组,每个事件是一个数组,数组里每个元素包含matcher和hooks。Stop事件在 Claude Code 完成响应时触发。
如果你已经有~/.claude/settings.json,用编辑器打开,把下面这段合并进去。如果文件不存在,直接创建:
{ "hooks": { "Stop": [ { "matcher": "", "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/notify.sh" } ] } ] } }这里matcher留空表示匹配所有 Stop 事件。type是command,表示执行一个 shell 命令。command指向我们的通知脚本。
如果你还想在 Claude Code 请求权限时也收到通知,可以再加一个Notification事件:
{ "hooks": { "Stop": [ { "matcher": "", "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/notify.sh" } ] } ], "Notification": [ { "matcher": "", "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/notify.sh permission" } ] } ] } }这样当 Claude Code 需要你确认权限时,也会推一条微信,避免它干等着。
3.2 notify.sh 脚本完整内容
脚本要做几件事:读取微信推送 Token、获取当前时间和工作目录、发送 POST 请求、可选地调用 TaoToken API 生成摘要、最后正常退出。
#!/bin/bash # =============================================================== # Claude Code 任务完成微信通知脚本 # 依赖:bash、curl # 使用前替换 WECHAT_TOKEN 和 TAOTOKEN_API_KEY # =============================================================== # 微信推送 Token,替换为你自己的 WECHAT_TOKEN="YOUR_WECHAT_TOKEN" WECHAT_URL="https://wx.xtuis.cn/${WECHAT_TOKEN}.send" # TaoToken 统一 Key,替换为你自己的 TAOTOKEN_API_KEY="YOUR_TAOTOKEN_API_KEY" TAOTOKEN_BASE_URL="https://taotoken.net/api" TAOTOKEN_MODEL="claude-sonnet-4-20250514" # 通知类型,默认 stop,可由参数覆盖 NOTIFY_TYPE="${1:-stop}" # 获取当前时间和会话标识 TIME=$(date +"%Y-%m-%d %H:%M:%S") SESSION=$(basename "$(pwd)") # 根据类型设置标题 if [ "$NOTIFY_TYPE" = "permission" ]; then TITLE="Claude Code 等待权限确认" else TITLE="Claude Code 任务完成" fi # 可选:调用 TaoToken 生成一句简短摘要 SUMMARY="" if [ -n "$TAOTOKEN_API_KEY" ] && [ "$TAOTOKEN_API_KEY" != "YOUR_TAOTOKEN_API_KEY" ]; then SUMMARY=$(curl -s -X POST "${TAOTOKEN_BASE_URL}/v1/messages" \ -H "Content-Type: application/json" \ -H "x-api-key: ${TAOTOKEN_API_KEY}" \ -H "anthropic-version: 2023-06-01" \ -d "{ \"model\": \"${TAOTOKEN_MODEL}\", \"max_tokens\": 64, \"messages\": [ {\"role\": \"user\", \"content\": \"用一句话总结:Claude Code 在目录 ${SESSION} 完成了一次任务,时间是 ${TIME}。直接输出摘要,不要解释。\"} ] }" | grep -o '"text":"[^"]*"' | head -1 | sed 's/"text":"//;s/"$//') fi # 组装通知内容 DESP="会话: ${SESSION}%0A时间: ${TIME}" if [ -n "$SUMMARY" ]; then DESP="${DESP}%0A摘要: ${SUMMARY}" fi # 发送微信通知 curl -s -X POST "$WECHAT_URL" \ -d "text= ${TITLE}" \ -d "desp=${DESP}" \ > /dev/null 2>&1 exit 0几个关键点说明。第一,WECHAT_TOKEN和TAOTOKEN_API_KEY必须替换成你自己的,否则通知发不出去。第二,TaoToken 的调用是可选的,如果你暂时不想用模型生成摘要,把TAOTOKEN_API_KEY留成占位符,脚本会跳过这一步,只发基础通知。第三,grep -o那段是从返回 JSON 里提取text字段,不同模型返回格式可能略有差异,如果提取不到,摘要为空,不影响主流程。
3.3 脚本权限与路径确认
写完脚本后,给它加执行权限:
chmod +x ~/.claude/hooks/notify.sh然后确认路径正确:
ls -la ~/.claude/hooks/notify.sh应该能看到-rwxr-xr-x权限。如果settings.json里的路径写的是~/.claude/hooks/notify.sh,而你的实际路径不同,记得改成绝对路径,比如/Users/你的用户名/.claude/hooks/notify.sh,避免因为 shell 展开问题导致 hook 执行失败。
3.4 TaoToken 统一 Key 的接入参数对照
下面这张表把脚本里用到的 TaoToken 参数列清楚,方便你对照控制台填写:
| 参数 | 值 | 说明 |
|---|---|---|
| Base URL | https://taotoken.net/api | 统一 API 入口,不加 UTM |
| API Key | 控制台创建 | 放在x-api-key请求头 |
| Model ID | 如claude-sonnet-4-20250514 | 以控制台模型列表为准 |
| 接口路径 | /v1/messages | 消息调用接口 |
| 版本头 | anthropic-version: 2023-06-01 | 兼容 Anthropic 格式 |
如果你用的是其他模型,把TAOTOKEN_MODEL换成对应的 Model ID 即可。Base URL 和 Key 这两项在所有调用里保持一致,这就是统一 Key 的好处。
4. 端到端验证:从手动执行到 Claude Code 触发
配置写完了,接下来要验证它真的能跑通。验证分两步:先手动执行脚本,确认微信能收到;再启动 Claude Code 跑一个任务,确认 hook 被触发。
4.1 手动执行 notify.sh
在终端里直接运行:
bash ~/.claude/hooks/notify.sh如果一切正常,你的微信应该立刻收到一条消息,标题是“Claude Code 任务完成”,内容里包含当前目录名和时间。如果配置了 TaoToken,还会多一行摘要。
如果没收到,先看终端有没有报错。脚本里curl的输出被重定向到了/dev/null,所以终端不会显示返回内容。你可以临时把> /dev/null 2>&1去掉,再跑一次,看看微信接口返回了什么。常见返回是success或类似状态码。
4.2 验证 TaoToken 调用是否成功
单独测一下 TaoToken 的接口,确认 Key 和 Base URL 没问题:
curl -s -X POST "https://taotoken.net/api/v1/messages" \ -H "Content-Type: application/json" \ -H "x-api-key: YOUR_TAOTOKEN_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 32, "messages": [ {"role": "user", "content": "回复 OK"} ] }'如果返回里有content字段和文本内容,说明 Key 和通道都正常。如果返回 401,检查 Key 是否复制完整;如果返回模型不存在,检查 Model ID 是否和控制台一致。
4.3 在 Claude Code 中触发 Stop hook
手动脚本没问题后,启动 Claude Code:
claude在交互界面里输入一个简单任务,比如:
你好,帮我列出当前目录下的文件等 Claude Code 完成响应,Stop hook 会被触发,notify.sh执行,微信收到通知。你也可以直接用命令行参数跑:
claude "你好"任务结束后同样会触发。
4.4 验证权限通知(可选)
如果你在settings.json里加了Notification事件,可以故意让 Claude Code 做一个需要权限确认的操作,比如让它修改一个文件。当它弹出确认提示时,微信应该收到“Claude Code 等待权限确认”的通知。
4.5 一次完整的成功结果记录
我实测下来,从 Claude Code 完成任务到微信收到消息,延迟大概在一到两秒。通知内容里能看到会话目录和时间,如果开了 TaoToken 摘要,还能看到一句简短的描述,比如“在 project-x 目录完成了一次文件列表任务”。这样你即使不在电脑前,也能大致知道是哪个项目跑完了。
5. 常见报错排查:401、local proxy failed、reading choices 与 OAuth
配置过程中最容易遇到的几个报错,我逐个列出来,对照着排查。
5.1 401 鉴权失败
这是最常见的。表现是 TaoToken 接口返回 401,或者微信推送没反应但脚本没报错。
先检查TAOTOKEN_API_KEY是否替换成了真实 Key。很多人复制的时候带了空格,或者把YOUR_TAOTOKEN_API_KEY原样留着。用echo $TAOTOKEN_API_KEY在脚本里打印一下,确认值正确。
再检查请求头字段名。TaoToken 的 Anthropic 兼容接口用的是x-api-key,不是Authorization: Bearer。如果你混用了 OpenAI 风格的鉴权头,就会 401。
微信推送这边,401 通常意味着 Token 不对。检查WECHAT_TOKEN是否和公众号回复的一致,注意大小写。
5.2 local proxy failed
这个报错通常出现在你本地有网络代理设置,但脚本执行时环境变量没继承,或者代理配置和当前网络环境不匹配。表现是curl请求超时或连接被拒绝。
排查方法:在终端里执行env | grep -i proxy,看看有没有http_proxy、https_proxy之类的变量。如果有,确认它们指向的地址是可达的。如果你不需要代理,可以临时取消:
unset http_proxy https_proxy all_proxy然后再跑脚本。注意,这里说的是本地环境变量清理,不涉及任何特殊网络工具。
5.3 reading choices 相关报错
这个报错一般出现在模型返回格式和脚本解析不匹配的时候。比如 TaoToken 返回的 JSON 里content是一个数组,而你的grep表达式没匹配到。表现是摘要为空,但通知还能发出去。
解决办法:先把curl的原始返回打印出来,看看结构。把脚本里grep -o '"text":"[^"]*"'换成更通用的解析,或者直接用jq:
SUMMARY=$(curl -s ... | jq -r '.content[0].text // empty')如果你没装jq,用python3 -c也行。关键是先看清楚返回结构,再写解析。
5.4 OAuth 相关报错
如果你在 Claude Code 里配置了 OAuth 登录,有时候 hook 执行环境和你交互式 shell 的环境不同,可能导致鉴权状态读不到。表现是 Claude Code 本身能用,但 hook 里的模型调用失败。
排查:确认notify.sh里用的是 TaoToken 的 API Key,而不是依赖 Claude Code 的 OAuth 会话。这两者是独立的。TaoToken 的 Key 是显式放在请求头里的,不依赖任何登录态,所以只要 Key 正确,就不会受 OAuth 影响。
5.5 脚本没有执行
如果 Claude Code 跑完了但微信没动静,先确认settings.json的 JSON 格式合法。可以用python3 -m json.tool ~/.claude/settings.json检查。格式错误会导致整个配置被忽略。
再确认command路径正确。如果你写的是~/.claude/hooks/notify.sh,在某些执行环境下~不会展开,建议改成绝对路径。
最后确认脚本有执行权限,chmod +x那一步不能漏。
5.6 微信收到重复通知
如果你同时配置了Stop和Notification,而某些操作既触发 Stop 又触发 Notification,可能会收到两条。这是正常的,按需保留即可。如果只想在任务完成时通知,把Notification那段删掉。
6. 把通知链路用起来:从单次提醒到长期编码工作流
配置跑通之后,这条通知链路的价值不只是“任务完成响一声”。你可以把它嵌进日常的编码工作流里,让 Claude Code 真正变成一个可以后台跑、你只管收结果的助手。
我自己的用法是这样的:早上到工位,先给 Claude Code 扔几个独立任务,比如“把 utils 目录下的函数补上类型注解”“跑一遍测试并修复失败用例”“把 README 里的示例代码更新到最新 API”。每个任务启动后,我就不盯终端了,去处理邮件或者开会。微信一响,我就知道某个任务完成了,抽空回去看一眼结果,再决定下一步。
如果你经常跑长时间任务,可以考虑把 TaoToken 的 Coding Plan 用起来。它适合这种持续性的编码和 Agent 场景,统一 Key 管理多个会话,不用每次切换项目都换密钥。入口在 TaoToken 的 Coding Plan 页面,具体权益以控制台说明为准。
另外,notify.sh里其实还可以做更多事。比如在通知里带上本次任务的 git diff 统计,或者把完成时间追加到一个日志文件里,方便回顾一天跑了多少任务。这些扩展都不难,核心就是 hook 触发脚本,脚本里你想干什么都行。
如果你还没创建 TaoToken 的 Key,可以去控制台的 API Keys 页面建一个,顺便看看模型对话功能,测试一下模型调用是否正常。接入文档里也有完整的参数说明,遇到不确定的字段可以对照查。
最后说一个我踩过的坑:一开始我把notify.sh放在项目目录里,结果换项目后 hook 找不到脚本。后来统一放到~/.claude/hooks/下,用绝对路径引用,就再也没出过问题。脚本里的 Token 也不要提交到 git,建议用环境变量或者单独的配置文件读取,避免泄露。