Żeby wysyłać powiadomienia z Claude Code na Telegram, Slack lub Discord, utwórz w tej aplikacji bota albo incoming webhook, a potem dodaj hook Claude Code, który wysyła do niego krótką wiadomość przez curl. Hook Notification obsługuje „Claude potrzebuje twojej zgody” i „Claude czeka”, a hook Stop – „Claude skończył”. Telegram wymaga tokena bota i twojego chat ID, a Slack i Discord tylko URL-a webhooka. Ten sam skrypt działa na Macu i Linuxie, a krótka wersja w PowerShell obsługuje Windows.
01Zanim zaczniesz: wiadomość i sekret
Każdy hook dostaje JSON na standardowe wejście. Przydatne pola to hook_event_name, cwd (folder projektu), message w zdarzeniach Notification oraz last_assistant_message w zdarzeniach Stop. Poniższe przykłady składają z nich jedną linijkę, np. Claude needs you in my-app: Claude needs your permission to use Bash.
Tokeny botów i URL-e webhooków to hasła: każdy, kto je ma, może pisać jako twój bot. Dokumentacja Slacka wprost mówi, żeby nie udostępniać URL-i webhooków ani nie commitować ich do repozytorium. Trzymaj je w osobnym pliku, który tylko ty możesz odczytać:
mkdir -p ~/.claude
touch ~/.claude/chat-notify.env
chmod 600 ~/.claude/chat-notify.env
02Telegram: bot, który do ciebie pisze
- W Telegramie otwórz czat z @BotFather, wyślij
/newboti postępuj zgodnie z instrukcjami. W odpowiedzi dostaniesz token, np.123456789:AA.... - Otwórz czat z nowym botem i wyślij mu dowolną wiadomość, żeby mógł ci odpisywać.
- Znajdź swoje chat ID. Otwórz ten URL ze swoim tokenem i poszukaj w odpowiedzi
"chat":{"id"::
curl "https://api.telegram.org/bot<TOKEN>/getUpdates"
- Wpisz obie wartości do
~/.claude/chat-notify.env:
SERVICE=telegram
TELEGRAM_TOKEN=123456789:AA...
TELEGRAM_CHAT_ID=987654321
Metoda sendMessage Telegrama przyjmuje chat_id i text (od 1 do 4096 znaków). Obsługuje też disable_notification=true, które dostarcza wiadomość bez dźwięku. Skrypt używa tego dla wiadomości „skończone”, a dźwięk zostawia dla próśb o zgodę.
03Slack: incoming webhook
- Utwórz aplikację Slack na api.slack.com/apps (albo otwórz istniejącą).
- W sekcji Incoming Webhooks włącz Activate Incoming Webhooks.
- Kliknij Add New Webhook to Workspace, wybierz kanał i kliknij Authorize.
- Skopiuj URL zaczynający się od
https://hooks.slack.com/services/.
SERVICE=slack
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX
Każdy webhook pisze na jeden kanał, wybrany przy tworzeniu, i nie da się zmieniać nazwy ani ikony dla pojedynczych wiadomości. Najlepiej sprawdza się mały prywatny kanał tylko dla ciebie – na ruchliwym kanale alert łatwo przegapić.
04Discord: webhook kanału
- Na swoim serwerze otwórz Server Settings, potem Integrations, a następnie Webhooks.
- Utwórz webhook, wybierz kanał i skopiuj jego URL.
SERVICE=discord
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/1234/abcd
Endpoint execute-webhook Discorda przyjmuje body JSON z polem content (do 2000 znaków) i opcjonalnym username, które nadpisuje nazwę webhooka.
05Skrypt hooka (Mac i Linux)
Zapisz to jako ~/.claude/chat-notify.sh i uruchom chmod +x ~/.claude/chat-notify.sh. Potrzebujesz curl i jq (brew install jq albo 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
Budowanie JSON-a przez jq -n --arg ma znaczenie: odpowiedzi Claudea zawierają cudzysłowy, backslashe i znaki nowej linii, a ręczne wklejenie ich do stringa JSON psuje request.
Przetestuj go, zanim go podepniesz:
echo '{"hook_event_name":"Notification","cwd":"/tmp/demo","message":"Test"}' | ~/.claude/chat-notify.sh
06Dodaj hooki
W ~/.claude/settings.json, wewnątrz istniejącego obiektu hooks, jeśli już jest:
{
"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 }]
}
]
}
}
Uruchom nową sesję Claude Code, żeby hooki się załadowały. idle_prompt i Stop się pokrywają: Stop odpala w chwili, gdy Claude kończy, a idle_prompt mniej więcej minutę później, jeśli nic nie wpisałeś. Zostaw oba albo usuń jeden; poradnik o ntfy wyjaśnia, co na tym zyskujesz, a co tracisz.
07Windows (PowerShell)
Zapisz jako %USERPROFILE%\.claude\chat-notify.ps1. Ta wersja wysyła na Discord; dla Slacka zmień body na @{ text = $text } i podmień 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
Wpis hooka:
{
"type": "command",
"shell": "powershell",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"$HOME\\.claude\\chat-notify.ps1\""
}
W WSL użyj skryptu dla Maca i Linuxa.
08Co warto wiedzieć o komunikatorach jako powiadomieniach
- To, co wysyłasz, opuszcza twój komputer. Wiadomość „skończone” zawiera początek odpowiedzi Claudea. Na współdzielonym kanale Slack czy Discord każdy jego członek może to przeczytać. Jeśli twój kod jest prywatny, usuń
$detail. - Komunikatory grupują i wyciszają powiadomienia. Ruchliwy workspace albo wyciszony serwer może ukryć alert. Dedykowana aplikacja do push, np. ntfy (zobacz poradnik o ntfy), rzadziej coś gubi.
- Hooki nie wiedzą, czy siedzisz przy biurku.
Stopwysyła wiadomość za każdym razem.idle_promptipermission_promptto najbliższy wbudowany filtr „nie ma mnie”.
09Gdzie pasuje Claude Code Notifier
Webhook to dobry sposób na log tego, co zrobił Claude, a dla zespołu może być właściwym narzędziem. Dla jednej osoby, która chce zareagować na alert, to za mało: czytasz, że Claude potrzebuje zgody, i musisz wrócić do terminala, żeby jej udzielić. Bot na Telegramie teoretycznie mógłby przyjmować odpowiedzi, ale musiałbyś sam napisać hook, który na nie czeka i zwraca decyzję.
Claude Code Notifier robi to za ciebie. Ze sparowanym telefonem możesz z poziomu telefonu zezwolić jednorazowo, zezwolić na całą sesję albo odrzucić prośbę o zgodę, odpowiadać na pytania wielokrotnego wyboru od Claudea i wysłać kolejne polecenie, gdy Claude skończy. Jeśli pisałeś coś w ciągu ostatnich 30 sekund, terminal pyta jak zwykle i nic nie czeka na telefonie. To niezależne narzędzie, nie od Anthropic, a ccn działa na Macu, Windows i Linuxie. Zobacz porównanie, stronę ccn i cennik.
10FAQ
Czy Claude Code może pisać na Slack bez skryptu?
Claude Code ma hooki http, które wysyłają JSON hooka POST-em na URL, ale webhooki Slacka i Discorda oczekują własnego formatu body (text lub content), więc bezpośredni hook http do nich nie zadziała. Potrzebny jest mały skrypt albo pośrednik.
Jak znaleźć swoje chat ID na Telegramie?
Wyślij wiadomość do swojego bota, a potem otwórz https://api.telegram.org/bot<TOKEN>/getUpdates. Liczba po "chat":{"id": to chat ID. W przypadku grupy najpierw dodaj do niej bota i wyślij tam wiadomość.
Czy mogę odpowiadać Claude Code ze Slack albo Discord?
Nie przez incoming webhook, bo on tylko wysyła wiadomości. Do odpowiadania potrzebny jest hook, który czeka na twoją odpowiedź i zwraca decyzję, a do tego właśnie służą narzędzia do zdalnego zatwierdzania.
Czy hook spowolni Claude Code?
Wpis Stop używa "async": true, więc wysyła w tle. Hooki Notification i tak działają równolegle z Claude, nie blokując go.