Claude Code 和 Codex CLI 的飞书任务完成通知工具。
- 🎯 自动识别来源: 支持 Claude Code (stdin) 和 Codex CLI (命令行参数)
- 🎨 优化卡片格式: 使用飞书官方推荐的
div.fields多列布局,信息清晰美观 - 🔖 并发任务区分: 通过 session_id/task_id 区分不同任务
- 📊 详细信息展示: 状态、耗时、文件修改、工具调用等
- 🔍 Payload 透出: 自动附带 Codex payload 字段清单(key/type/preview);可选 JSON 预览(
VIBE_NOTIFY_SHOW_PAYLOAD_JSON=1) - 📝 可选日志记录: 自动保存任务详情到本地
三种方式任选其一:
# 方式1: 环境变量 (推荐)
export FEISHU_WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/..."
export FEISHU_SECRET="..." # 可选,签名校验
# 方式2: webhook.txt 文件
echo "https://open.feishu.cn/open-apis/bot/v2/hook/..." > webhook.txt
# 方式3: .env 文件
cat > .env << EOF
FEISHU_WEBHOOK_URL=https://open.feishu.cn/open-apis/bot/v2/hook/...
FEISHU_SECRET=...
EOFClaude Code - 编辑 ~/.claude/settings.json:
{
"hooks": {
"Stop": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "python3 xxx/tools/vibe-notify/notify.py"
}]
}]
}
}Codex CLI - 编辑 ~/.codex/config.toml:
notify = ["python3", "xxxxx/tools/vibe-notify/notify.py"]# 测试 Codex 格式
python3 notify.py '{"type":"agent-turn-complete","session_id":"test123","cwd":"/tmp","task_summary":"测试任务","status":"success","duration":10.5}'
# 只预览卡片 JSON(不发送)
python3 notify.py --dry-run '{"type":"agent-turn-complete","session_id":"test123","cwd":"/tmp","task_summary":"测试任务","status":"success","duration":10.5}'
# 额外展示 Payload JSON 预览(默认关闭)
VIBE_NOTIFY_SHOW_PAYLOAD_JSON=1 python3 notify.py --dry-run '{"type":"agent-turn-complete","session_id":"test123","cwd":"/tmp","task_summary":"测试任务","status":"success","duration":10.5}'
# 测试 Claude Code 格式
echo '{"session_id":"test456","cwd":"/tmp","transcript":[{"type":"assistant","message":{"content":[{"type":"text","text":"测试完成"}]}}]}' | python3 notify.py🤖 Codex 任务完成
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
任务ID 状态
test123 ✅ 成功
项目 时间
my-project 14:30:00
任务
分析 Python 代码质量
耗时 轮次
10.5s 5
工具调用
12
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
修改文件: main.py, utils.py, test.py
目录: /home/user/my-project
颜色规则:
- ✅ 成功 → 绿色
- ❌ 失败 → 红色
⚠️ 部分完成 → 橙色
🤖 Claude Code 完成
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
会话ID 项目
abc123... my-project
时间 目录
14:30:00 /home/user/my-project
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
最后消息:
已完成代码重构,修复了 3 个类型错误...
当同时运行多个任务时,通过 session_id 或 task_id 自动区分:
# 终端 1
codex "分析代码质量" # session_id: aaa111
# 终端 2
codex "重构 API" # session_id: bbb222
# 飞书会收到两条通知,标题分别显示不同的任务ID创建日志目录后自动启用:
mkdir -p ~/.ai-tasks-log日志文件格式:
- Codex:
codex-20260112-143000-abc123.json - Claude:
claude-20260112-143000-xyz789.json
只通知特定项目:
#!/bin/bash
# wrapper.sh
data="$1"
# 只通知 important-project
if echo "$data" | jq -e '.cwd | contains("/important-project")' > /dev/null; then
python3 notify.py "$data"
fi配置:
notify = ["bash", "/path/to/wrapper.sh"]{
"hooks": {
"Stop": [{
"hooks": [
{"type": "command", "command": "python3 notify.py"},
{"type": "command", "command": "python3 notify-slack.py"},
{"type": "command", "command": "mail -s 'Done' user@example.com"}
]
}]
}
}{
"type": "agent-turn-complete",
"timestamp": "2026-01-12T14:30:00Z",
"session_id": "uuid",
"task_id": "task-id",
"cwd": "/path/to/project",
"task_summary": "任务描述",
"status": "success|failed|partial",
"duration": 45.2,
"turn_count": 5,
"tool_calls": 12,
"files_modified": ["file1.py", "file2.py"]
}{
"session_id": "uuid",
"cwd": "/path/to/project",
"transcript": [
{
"type": "assistant",
"message": {
"content": [
{"type": "text", "text": "消息内容"}
]
}
}
]
}{
"hooks": {
"Stop": [{
"hooks": [
{"type": "command", "command": "python3 notify.py"},
{"type": "command", "command": "paplay /usr/share/sounds/freedesktop/stereo/complete.oga"}
]
}]
}
}{
"hooks": {
"Stop": [{
"hooks": [{
"type": "command",
"command": "notify-send 'Claude Code' '任务完成'"
}]
}]
}
}{
"hooks": {
"Stop": [{
"matcher": "/my-project",
"hooks": [
{"type": "command", "command": "python3 notify.py"},
{"type": "command", "command": "sh -c 'cd $PWD && git add -A && git commit -m \"AI: $(date)\"'"}
]
}]
}
}{
"hooks": {
"Stop": [{
"hooks": [{
"type": "command",
"command": "curl -X POST https://ci.example.com/trigger"
}]
}]
}
}# track-time.sh
#!/bin/bash
start=$(cat /tmp/claude-start-time 2>/dev/null || echo 0)
end=$(date +%s)
duration=$((end - start))
echo "本次会话: ${duration}s" >> ~/claude-time.log配置:
{
"hooks": {
"Start": [{"hooks": [{"type": "command", "command": "date +%s > /tmp/claude-start-time"}]}],
"Stop": [{"hooks": [{"type": "command", "command": "bash track-time.sh"}]}]
}
}检查:
# 测试 webhook 配置
python3 notify.py '{"type":"agent-turn-complete","session_id":"test"}'
# 查看错误信息
python3 notify.py '...' 2>&1原因: 飞书 API 版本或格式限制
解决: 检查飞书机器人设置,确保支持交互式卡片
检查: 确认 Codex 传递的数据中包含 session_id 字段
# 添加调试输出
echo "$1" >> /tmp/codex-debug.log
python3 notify.py "$1"vibe-notify/
├── notify.py # 主脚本 (唯一必需文件)
├── webhook.txt # Webhook 配置 (可选)
├── .env # 环境变量配置 (可选)
├── .gitignore # Git 忽略规则
└── README.md # 本文档
-
不要提交 webhook.txt 到 Git
- 已在
.gitignore中配置 - 使用环境变量更安全
- 已在
-
启用签名校验
export FEISHU_SECRET="your-secret"
-
限制通知频率
- 使用
matcher只在特定项目触发 - 避免在测试项目中启用
- 使用
- Python 3.6+
- 仅使用标准库,无需额外安装
MIT License