Để gửi thông báo của Claude Code tới Telegram, Slack hoặc Discord, hãy tạo một bot hoặc incoming webhook trong ứng dụng đó, rồi thêm một hook Claude Code dùng curl để gửi một tin nhắn ngắn tới đó. Hook Notification xử lý các trường hợp "Claude cần bạn cấp quyền" và "Claude đang chờ", còn hook Stop xử lý trường hợp "Claude đã xong". Telegram cần bot token và chat ID của bạn, còn Slack và Discord chỉ cần webhook URL. Cùng một script chạy được trên Mac và Linux, và có thêm một phiên bản PowerShell ngắn cho Windows.
01Trước khi bắt đầu: tin nhắn và thông tin bí mật
Mỗi hook nhận JSON qua standard input. Các trường hữu ích gồm hook_event_name, cwd (thư mục dự án), message ở sự kiện Notification, và last_assistant_message ở sự kiện Stop. Các ví dụ dưới đây gộp chúng thành một dòng, chẳng hạn Claude needs you in my-app: Claude needs your permission to use Bash.
Bot token và webhook URL cũng như mật khẩu: ai có được chúng đều có thể đăng tin dưới danh nghĩa bot của bạn. Tài liệu của Slack nói rõ không được chia sẻ webhook URL hay commit chúng vào version control. Hãy lưu chúng trong một file riêng mà chỉ bạn đọc được:
mkdir -p ~/.claude
touch ~/.claude/chat-notify.env
chmod 600 ~/.claude/chat-notify.env
02Telegram: bot nhắn tin cho bạn
- Trong Telegram, mở chat với @BotFather, gửi
/newbotvà làm theo hướng dẫn. Nó sẽ trả về một token dạng123456789:AA.... - Mở chat với bot mới và gửi cho nó một tin nhắn bất kỳ để bot được phép nhắn lại cho bạn.
- Tìm chat ID của bạn. Mở URL này với token của bạn và tìm
"chat":{"id":trong phản hồi:
curl "https://api.telegram.org/bot<TOKEN>/getUpdates"
- Ghi cả hai giá trị vào
~/.claude/chat-notify.env:
SERVICE=telegram
TELEGRAM_TOKEN=123456789:AA...
TELEGRAM_CHAT_ID=987654321
Method sendMessage của Telegram nhận chat_id và text (từ 1 đến 4.096 ký tự). Nó cũng hỗ trợ disable_notification=true để gửi tin nhắn không kèm âm thanh. Script dùng tùy chọn này cho tin "đã xong" và giữ âm thanh cho yêu cầu cấp quyền.
03Slack: incoming webhook
- Tạo một app Slack tại api.slack.com/apps (hoặc mở app có sẵn).
- Trong mục Incoming Webhooks, bật Activate Incoming Webhooks.
- Nhấn Add New Webhook to Workspace, chọn một channel rồi chọn Authorize.
- Sao chép URL bắt đầu bằng
https://hooks.slack.com/services/.
SERVICE=slack
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX
Mỗi webhook chỉ đăng vào một channel được chọn lúc tạo, và bạn không thể đổi tên hay icon cho từng tin nhắn. Tốt nhất nên dùng một channel riêng tư nhỏ của bạn để thông báo không bị trôi mất trong channel đông người.
04Discord: webhook của channel
- Trong server của bạn, mở Server Settings, rồi Integrations, rồi Webhooks.
- Tạo webhook, chọn channel và sao chép URL của nó.
SERVICE=discord
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/1234/abcd
Endpoint execute-webhook của Discord nhận body JSON có content (tối đa 2.000 ký tự) và username tùy chọn để ghi đè tên webhook.
05Script hook (Mac và Linux)
Lưu file này thành ~/.claude/chat-notify.sh và chạy chmod +x ~/.claude/chat-notify.sh. Script cần curl và jq (brew install jq hoặc 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
Việc tạo JSON bằng jq -n --arg rất quan trọng: câu trả lời của Claude có chứa dấu nháy, dấu gạch chéo ngược và xuống dòng, nên tự dán chúng vào chuỗi JSON sẽ làm hỏng request.
Chạy thử trước khi gắn vào hook:
echo '{"hook_event_name":"Notification","cwd":"/tmp/demo","message":"Test"}' | ~/.claude/chat-notify.sh
06Thêm hook
Trong ~/.claude/settings.json, đặt vào bên trong object hooks có sẵn nếu đã có:
{
"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 }]
}
]
}
}
Mở một session Claude Code mới để hook được nạp. idle_prompt và Stop trùng nhau một phần: Stop kích hoạt ngay khi Claude xong, còn idle_prompt kích hoạt khoảng một phút sau nếu bạn chưa gõ gì. Bạn có thể giữ cả hai hoặc bỏ một; hướng dẫn ntfy giải thích ưu nhược điểm.
07Windows (PowerShell)
Lưu thành %USERPROFILE%\.claude\chat-notify.ps1. Phiên bản này gửi tới Discord; với Slack, hãy đổi body thành @{ text = $text } và đổi 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
Mục hook:
{
"type": "command",
"shell": "powershell",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"$HOME\\.claude\\chat-notify.ps1\""
}
Trong WSL, hãy dùng script cho Mac và Linux.
08Những điều cần biết khi dùng ứng dụng chat để nhận thông báo
- Những gì bạn gửi sẽ rời khỏi máy của bạn. Tin "đã xong" có kèm phần đầu câu trả lời của Claude. Trong channel Slack hay Discord dùng chung, mọi người trong đó đều đọc được. Hãy bỏ
$detailnếu code của bạn là riêng tư. - Ứng dụng chat hay gom và tắt tiếng thông báo. Workspace đông đúc hoặc server bị mute có thể làm bạn bỏ lỡ thông báo. Một ứng dụng push chuyên dụng như ntfy (xem hướng dẫn ntfy) ít bị lạc hơn.
- Hook không biết bạn có đang ngồi ở bàn hay không.
Stoplần nào cũng gửi.idle_promptvàpermission_promptlà bộ lọc "vắng mặt" sẵn có gần nhất.
09Claude Code Notifier nằm ở đâu trong bức tranh này
Webhook là cách hay để lưu lại nhật ký những gì Claude đã làm, và với một team thì đó có thể là công cụ phù hợp. Nhưng với người dùng cá nhân muốn xử lý ngay thông báo, nó vẫn còn thiếu: bạn đọc được rằng Claude cần cấp quyền, rồi phải quay lại terminal để cấp. Về lý thuyết, bot Telegram có thể nhận phản hồi, nhưng bạn sẽ phải tự viết hook chờ phản hồi đó và trả về quyết định.
Claude Code Notifier lo phần đó. Khi đã ghép nối điện thoại, bạn có thể ngay trên điện thoại cho phép một lần, cho phép trong cả session hoặc từ chối yêu cầu cấp quyền, trả lời các câu hỏi trắc nghiệm của Claude, và gửi chỉ dẫn tiếp theo khi Claude xong việc. Nếu bạn vừa gõ trong 30 giây gần nhất, terminal sẽ hỏi như bình thường và không có gì chờ trên điện thoại. Đây là sản phẩm độc lập, không phải của Anthropic, và ccn chạy trên Mac, Windows và Linux. Xem so sánh với các giải pháp khác, trang ccn và bảng giá.
10Câu hỏi thường gặp
Claude Code có gửi lên Slack mà không cần script được không?
Claude Code có hook http để POST JSON của hook tới một URL, nhưng webhook của Slack và Discord yêu cầu định dạng body riêng (text hoặc content), nên hook http gửi thẳng tới chúng sẽ thất bại. Bạn cần một script nhỏ hoặc một relay ở giữa.
Làm sao tìm chat ID Telegram của tôi?
Gửi cho bot một tin nhắn, rồi mở https://api.telegram.org/bot<TOKEN>/getUpdates. Con số sau "chat":{"id": chính là chat ID. Với group, hãy thêm bot vào group và gửi một tin nhắn ở đó trước.
Có thể trả lời Claude Code từ Slack hoặc Discord không?
Không thể với incoming webhook, vì nó chỉ gửi tin đi. Muốn trả lời thì cần một hook chờ phản hồi của bạn rồi trả về quyết định, và đó chính là việc các công cụ phê duyệt từ xa được xây dựng để làm.
Hook có làm Claude Code chậm đi không?
Mục Stop dùng "async": true nên việc gửi diễn ra ở chế độ nền. Các hook Notification vốn đã chạy song song với Claude mà không chặn nó.