Um Claude Code-Benachrichtigungen an Telegram, Slack oder Discord zu schicken, legst du in der jeweiligen App einen Bot oder einen Incoming Webhook an und fügst dann einen Claude Code-Hook hinzu, der per curl eine kurze Nachricht dorthin postet. Ein Notification-Hook deckt „Claude braucht deine Erlaubnis“ und „Claude wartet“ ab, ein Stop-Hook „Claude ist fertig“. Telegram braucht einen Bot-Token und deine Chat-ID, Slack und Discord nur eine Webhook-URL. Dasselbe Skript läuft auf Mac und Linux, eine kurze PowerShell-Version deckt Windows ab.
01Bevor du loslegst: die Nachricht und das Secret
Jeder Hook bekommt JSON über die Standardeingabe. Die nützlichen Felder sind hook_event_name, cwd (der Projektordner), message bei Notification-Events und last_assistant_message bei Stop-Events. Die Beispiele unten machen daraus eine Zeile wie Claude needs you in my-app: Claude needs your permission to use Bash.
Bot-Tokens und Webhook-URLs sind Passwörter: Wer eins hat, kann als dein Bot posten. Die Doku von Slack sagt klar, dass du Webhook-URLs weder teilen noch ins Versionskontrollsystem committen sollst. Leg sie in eine separate Datei, die nur du lesen kannst:
mkdir -p ~/.claude
touch ~/.claude/chat-notify.env
chmod 600 ~/.claude/chat-notify.env
02Telegram: ein Bot, der dir schreibt
- Öffne in Telegram einen Chat mit @BotFather, schick
/newbotund folge den Anweisungen. Als Antwort bekommst du einen Token wie123456789:AA.... - Öffne einen Chat mit deinem neuen Bot und schick ihm irgendeine Nachricht, damit er dir zurückschreiben darf.
- Finde deine Chat-ID. Ruf diese URL mit deinem Token auf und such in der Antwort nach
"chat":{"id"::
curl "https://api.telegram.org/bot<TOKEN>/getUpdates"
- Trag beide Werte in
~/.claude/chat-notify.envein:
SERVICE=telegram
TELEGRAM_TOKEN=123456789:AA...
TELEGRAM_CHAT_ID=987654321
Die Methode sendMessage von Telegram nimmt chat_id und text (1 bis 4.096 Zeichen). Außerdem akzeptiert sie disable_notification=true, womit die Nachricht ohne Ton ankommt. Das Skript nutzt das für „fertig“-Nachrichten und lässt den Ton bei Berechtigungsanfragen an.
03Slack: ein Incoming Webhook
- Leg unter api.slack.com/apps eine Slack-App an (oder öffne eine bestehende).
- Aktiviere unter Incoming Webhooks die Option Activate Incoming Webhooks.
- Klick auf Add New Webhook to Workspace, wähl einen Channel und dann Authorize.
- Kopier die URL, die mit
https://hooks.slack.com/services/beginnt.
SERVICE=slack
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX
Jeder Webhook postet in genau einen Channel, den du beim Anlegen festlegst, und Name oder Icon lassen sich nicht pro Nachricht ändern. Am besten nimmst du einen kleinen privaten Channel nur für dich, damit der Alert nicht in einem vollen Channel untergeht.
04Discord: ein Channel-Webhook
- Öffne auf deinem Server Server Settings, dann Integrations, dann Webhooks.
- Leg einen Webhook an, wähl den Channel und kopier die URL.
SERVICE=discord
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/1234/abcd
Der Execute-Webhook-Endpoint von Discord erwartet einen JSON-Body mit content (bis zu 2.000 Zeichen) und optional username, um den Namen des Webhooks zu überschreiben.
05Das Hook-Skript (Mac und Linux)
Speicher das als ~/.claude/chat-notify.sh und führ chmod +x ~/.claude/chat-notify.sh aus. Du brauchst curl und jq (brew install jq oder 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
Das JSON mit jq -n --arg zu bauen, ist wichtig: Die Antworten von Claude enthalten Anführungszeichen, Backslashes und Zeilenumbrüche, und wenn du sie von Hand in einen JSON-String einfügst, geht der Request kaputt.
Teste es, bevor du es einbindest:
echo '{"hook_event_name":"Notification","cwd":"/tmp/demo","message":"Test"}' | ~/.claude/chat-notify.sh
06Hooks hinzufügen
In ~/.claude/settings.json, innerhalb des vorhandenen hooks-Objekts, falls es eins gibt:
{
"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 }]
}
]
}
}
Starte eine neue Claude Code-Session, damit die Hooks geladen werden. idle_prompt und Stop überschneiden sich: Stop feuert, sobald Claude fertig ist, idle_prompt etwa eine Minute später, wenn du nichts getippt hast. Behalte beide oder lass einen weg; der ntfy-Guide erklärt die Vor- und Nachteile.
07Windows (PowerShell)
Speicher es als %USERPROFILE%\.claude\chat-notify.ps1. Diese Version postet an Discord; für Slack änderst du den Body zu @{ text = $text } und passt die URL an.
$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-Eintrag:
{
"type": "command",
"shell": "powershell",
"command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"$HOME\\.claude\\chat-notify.ps1\""
}
Innerhalb von WSL nimmst du das Skript für Mac und Linux.
08Was du über Chat-Apps als Notifier wissen solltest
- Was du sendest, verlässt deinen Rechner. Die „fertig“-Nachricht enthält den Anfang von Claudes Antwort. In einem geteilten Slack- oder Discord-Channel kann das jeder dort lesen. Lass
$detailweg, wenn dein Code privat ist. - Chat-Apps bündeln und stummschalten. Ein aktiver Workspace oder ein stummgeschalteter Server kann den Alert verschlucken. Eine eigene Push-App wie ntfy (siehe den ntfy-Guide) geht seltener unter.
- Hooks wissen nicht, ob du am Schreibtisch sitzt.
Stoppostet jedes Mal.idle_promptundpermission_promptsind das, was einem eingebauten „abwesend“-Filter am nächsten kommt.
09Wo Claude Code Notifier ins Spiel kommt
Ein Webhook ist gut, um mitzuloggen, was Claude gemacht hat, und für ein Team kann er genau das richtige Tool sein. Wenn du allein bist und auf den Alert reagieren willst, reicht er nicht ganz: Du liest, dass Claude eine Erlaubnis braucht, und musst dann zurück ans Terminal, um sie zu erteilen. Ein Telegram-Bot könnte theoretisch Antworten entgegennehmen, aber dann müsstest du selbst den Hook schreiben, der darauf wartet und eine Entscheidung zurückgibt.
Genau das übernimmt Claude Code Notifier. Mit gekoppeltem Handy kannst du eine Berechtigungsanfrage einmalig erlauben, für die Session erlauben oder ablehnen, Claudes Multiple-Choice-Fragen beantworten und eine Folgeanweisung schicken, wenn Claude fertig ist – alles vom Handy aus. Hast du in den letzten 30 Sekunden getippt, fragt das Terminal wie gewohnt und auf dem Handy wartet nichts. Das Tool ist unabhängig, nicht von Anthropic, und ccn läuft auf Mac, Windows und Linux. Sieh dir den Vergleich, die ccn-Seite und die Preise an.
10FAQ
Kann Claude Code ohne Skript an Slack posten?
Claude Code hat http-Hooks, die das JSON des Hooks per POST an eine URL schicken, aber Webhooks von Slack und Discord erwarten ihr eigenes Body-Format (text bzw. content), daher scheitert ein direkter http-Hook. Du brauchst ein kleines Skript oder ein Relay dazwischen.
Wie finde ich meine Telegram-Chat-ID?
Schick deinem Bot eine Nachricht und öffne dann https://api.telegram.org/bot<TOKEN>/getUpdates. Die Zahl nach "chat":{"id": ist die Chat-ID. Für eine Gruppe fügst du den Bot zur Gruppe hinzu und schickst dort vorher eine Nachricht.
Kann ich Claude Code aus Slack oder Discord heraus antworten?
Nicht mit einem Incoming Webhook, der kann nur posten. Zum Antworten brauchst du einen Hook, der auf deine Antwort wartet und eine Entscheidung zurückgibt – genau dafür sind Remote-Approval-Tools gebaut.
Bremst der Hook Claude Code aus?
Der Stop-Eintrag nutzt "async": true und sendet daher im Hintergrund. Notification-Hooks laufen ohnehin parallel zu Claude, ohne es zu blockieren.