要把 Claude Code 的通知傳到 Telegram、Slack 或 Discord,先在該 app 建立 bot 或 incoming webhook,再加一個 Claude Code hook,用 curl 送一則簡短訊息過去。Notification hook 負責「Claude 需要你的權限」和「Claude 正在等待」,Stop hook 則負責「Claude 已完成」。Telegram 需要 bot token 和你的 chat ID,Slack 和 Discord 只需要 webhook URL。同一支腳本可在 Mac 和 Linux 上使用,Windows 則有一個簡短的 PowerShell 版本。
01開始之前:訊息內容與密鑰
每個 hook 都會從標準輸入收到 JSON。實用的欄位有 hook_event_name、cwd(專案資料夾)、Notification 事件中的 message,以及 Stop 事件中的 last_assistant_message。以下範例會把它們組成一行訊息,例如 Claude needs you in my-app: Claude needs your permission to use Bash。
Bot token 和 webhook URL 等同密碼:拿到的人都能以你的 bot 名義發訊息。Slack 的文件明確表示不要分享 webhook URL,也不要提交到版本控制。請把它們放在只有你能讀取的獨立檔案中:
mkdir -p ~/.claude
touch ~/.claude/chat-notify.env
chmod 600 ~/.claude/chat-notify.env
02Telegram:傳訊息給你的 bot
- 在 Telegram 中開啟與 @BotFather 的對話,傳送
/newbot,依照提示操作。它會回覆一組 token,例如123456789:AA...。 - 開啟與新 bot 的對話並隨便傳一則訊息,這樣它才能回傳訊息給你。
- 找出你的 chat ID。用你的 token 開啟這個 URL,在回應中找
"chat":{"id"::
curl "https://api.telegram.org/bot<TOKEN>/getUpdates"
- 把這兩個值寫進
~/.claude/chat-notify.env:
SERVICE=telegram
TELEGRAM_TOKEN=123456789:AA...
TELEGRAM_CHAT_ID=987654321
Telegram 的 sendMessage 方法接受 chat_id 和 text(1 到 4,096 個字元),也支援 disable_notification=true,讓訊息靜音送達。腳本對「已完成」訊息使用靜音,權限請求則保留提示音。
03Slack:incoming webhook
- 到 api.slack.com/apps 建立 Slack app(或開啟現有的 app)。
- 在 Incoming Webhooks 下開啟 Activate Incoming Webhooks。
- 點選 Add New Webhook to Workspace,選擇頻道後按 Authorize。
- 複製以
https://hooks.slack.com/services/開頭的 URL。
SERVICE=slack
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX
每個 webhook 只會發到建立時選定的一個頻道,而且無法逐則訊息更改名稱或圖示。最好用一個只有自己的小型私人頻道,免得通知被熱鬧的頻道淹沒。
04Discord:頻道 webhook
- 在你的伺服器中依序開啟 Server Settings、Integrations、Webhooks。
- 建立 webhook,選擇頻道,然後複製它的 URL。
SERVICE=discord
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/1234/abcd
Discord 的 execute-webhook endpoint 接受含 content(最多 2,000 個字元)的 JSON body,另可選用 username 覆寫 webhook 名稱。
05Hook 腳本(Mac 和 Linux)
將以下內容存成 ~/.claude/chat-notify.sh,並執行 chmod +x ~/.claude/chat-notify.sh。需要 curl 和 jq(brew install jq 或 apt install jq)。
#!/bin/sh
. "$HOME/.claude/chat-notify.env"
input=$(cat)
event=$(printf '%s' "$input" | jq -r '.hook_event_name')
project=$(basename "$(printf '%s' "$input" | jq -r '.cwd')")
if [ "$event" = "Stop" ]; then
detail=$(printf '%s' "$input" | jq -r '(.last_assistant_message // "") | .[0:300]')
text="Claude finished in $project. $detail"
quiet=true
else
detail=$(printf '%s' "$input" | jq -r '.message // "Needs your attention"')
text="Claude needs you in $project: $detail"
quiet=false
fi
case "$SERVICE" in
telegram)
curl -s "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage" \
--data-urlencode "chat_id=$TELEGRAM_CHAT_ID" \
--data-urlencode "text=$text" \
--data-urlencode "disable_notification=$quiet" > /dev/null ;;
slack)
jq -n --arg t "$text" '{text: $t}' | curl -s -X POST \
-H 'Content-Type: application/json' --data @- "$SLACK_WEBHOOK_URL" > /dev/null ;;
discord)
jq -n --arg t "$text" '{content: $t, username: "Claude Code"}' | curl -s -X POST \
-H 'Content-Type: application/json' --data @- "$DISCORD_WEBHOOK_URL" > /dev/null ;;
esac
exit 0
用 jq -n --arg 組 JSON 很重要:Claude 的回覆含有引號、反斜線和換行,手動貼進 JSON 字串會讓請求失敗。
接上之前先測試:
echo '{"hook_event_name":"Notification","cwd":"/tmp/demo","message":"Test"}' | ~/.claude/chat-notify.sh
06加入 hook
在 ~/.claude/settings.json 中加入以下內容(若已有 hooks 物件,就放在裡面):
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt|idle_prompt",
"hooks": [{ "type": "command", "command": "~/.claude/chat-notify.sh" }]
}
],
"Stop": [
{
"hooks": [{ "type": "command", "command": "~/.claude/chat-notify.sh", "async": true }]
}
]
}
}
開一個新的 Claude Code session 讓 hook 載入。idle_prompt 和 Stop 會重疊:Stop 在 Claude 完成的當下觸發,idle_prompt 則在你約一分鐘沒輸入後觸發。可以兩個都留,也可以只留一個;ntfy 指南有說明其中的取捨。
07Windows(PowerShell)
存成 %USERPROFILE%\.claude\chat-notify.ps1。這個版本發送到 Discord;若要用 Slack,把 body 改成 @{ text = $text } 並更換 URL。
$url = 'https://discord.com/api/webhooks/1234/abcd'
$in = [Console]::In.ReadToEnd() | ConvertFrom-Json
$project = Split-Path $in.cwd -Leaf
if ($in.hook_event_name -eq 'Stop') { $text = "Claude finished in $project." }
else { $text = "Claude needs you in ${project}: $($in.message)" }
$json = @{ content = $text; username = 'Claude Code' } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri $url -ContentType 'application/json; charset=utf-8' `
-Body ([Text.Encoding]::UTF8.GetBytes($json)) | Out-Null
Hook 設定:
{
"type": "command",
"shell": "powershell",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"$HOME\\.claude\\chat-notify.ps1\""
}
在 WSL 中請使用 Mac 和 Linux 的腳本。
08用聊天 app 當通知工具須知
- 送出的內容會離開你的電腦。「已完成」訊息包含 Claude 回覆的開頭。在共用的 Slack 或 Discord 頻道裡,所有成員都看得到。如果程式碼是私有的,請拿掉
$detail。 - 聊天 app 會合併通知或被靜音。忙碌的 workspace 或靜音的伺服器可能讓通知被忽略。專用的 push app 如 ntfy(參見 ntfy 指南)比較不容易漏掉。
- Hook 不知道你是否在座位上。
Stop每次都會發送。idle_prompt和permission_prompt是最接近「離開」篩選的內建選項。
09Claude Code Notifier 的角色
Webhook 很適合記錄 Claude 做了什麼,對團隊來說也可能是合適的工具。但對想直接處理通知的個人來說就不夠了:你看到 Claude 需要權限,還是得走回 terminal 去核准。Telegram bot 理論上可以接收回覆,但你得自己寫等待回覆並回傳決定的 hook。
Claude Code Notifier 處理的正是這部分。配對手機後,你可以直接在手機上允許一次、在整個 session 中允許或拒絕權限請求,回答 Claude 的選擇題,並在 Claude 完成時送出後續指示。如果你在 30 秒內有輸入,terminal 會照常詢問,手機上不會有任何等待。它是獨立產品,並非 Anthropic 出品,ccn 可在 Mac、Windows 和 Linux 上執行。請參考比較說明、ccn 頁面和價格。
10常見問題
Claude Code 不用腳本可以直接發到 Slack 嗎?
Claude Code 有 http hook,會把 hook 的 JSON POST 到指定 URL,但 Slack 和 Discord 的 webhook 要求各自的 body 格式(text 或 content),所以直接用 http hook 會失敗。中間需要一支小腳本或轉發服務。
如何找到我的 Telegram chat ID?
先傳訊息給你的 bot,再開啟 https://api.telegram.org/bot<TOKEN>/getUpdates。"chat":{"id": 後面的數字就是 chat ID。若是群組,請先把 bot 加入群組,並在群組中傳一則訊息。
可以從 Slack 或 Discord 回覆 Claude Code 嗎?
用 incoming webhook 不行,它只能發送訊息。要回覆的話,需要一個會等待你回應並回傳決定的 hook,而這正是遠端核准工具的用途。
hook 會拖慢 Claude Code 嗎?
Stop 項目使用 "async": true,所以會在背景發送。Notification hook 本來就與 Claude 並行執行,不會造成阻塞。