Чтобы отправлять уведомления Claude Code в Telegram, Slack или Discord, создайте в этом приложении бота или incoming webhook, а затем добавьте hook Claude Code, который отправляет туда короткое сообщение через curl. Hook Notification срабатывает на «Claude нужно Ваше разрешение» и «Claude ждёт», а hook Stop — на «Claude закончил». Для Telegram нужны токен бота и ID чата, для Slack и Discord — только URL вебхука. Один и тот же скрипт работает на Mac и Linux, а для Windows есть короткая версия на PowerShell.
01Перед началом: сообщение и секрет
Каждый hook получает JSON на стандартный ввод. Полезные поля: hook_event_name, cwd (папка проекта), message в событиях Notification и last_assistant_message в событиях Stop. Примеры ниже превращают их в одну строку, например Claude needs you in my-app: Claude needs your permission to use Bash.
Токены ботов и URL вебхуков — это пароли: любой, у кого они есть, может писать от имени Вашего бота. В документации Slack прямо сказано не передавать URL вебхуков и не коммитить их в систему контроля версий. Храните их в отдельном файле, доступном для чтения только Вам:
mkdir -p ~/.claude
touch ~/.claude/chat-notify.env
chmod 600 ~/.claude/chat-notify.env
02Telegram: бот, который пишет Вам
- В Telegram откройте чат с @BotFather, отправьте
/newbotи следуйте подсказкам. В ответ придёт токен вида123456789:AA.... - Откройте чат с новым ботом и отправьте ему любое сообщение, чтобы он мог Вам отвечать.
- Узнайте ID чата. Откройте этот 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
Метод sendMessage в Telegram принимает chat_id и text (от 1 до 4096 символов). Он также поддерживает disable_notification=true — сообщение придёт без звука. Скрипт использует это для сообщений «закончил», а для запросов разрешений звук оставляет.
03Slack: incoming webhook
- Создайте приложение Slack на api.slack.com/apps (или откройте существующее).
- В разделе Incoming Webhooks включите Activate Incoming Webhooks.
- Нажмите Add New Webhook to Workspace, выберите канал и нажмите Authorize.
- Скопируйте URL, начинающийся с
https://hooks.slack.com/services/.
SERVICE=slack
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXXX
Каждый вебхук пишет в один канал, выбранный при создании, и менять имя или иконку для отдельных сообщений нельзя. Лучше всего подойдёт небольшой личный канал, чтобы уведомление не потерялось среди других сообщений.
04Discord: вебхук канала
- На своём сервере откройте Server Settings, затем Integrations, затем Webhooks.
- Создайте вебхук, выберите канал и скопируйте его URL.
SERVICE=discord
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/1234/abcd
Эндпоинт execute-webhook в Discord принимает JSON с полем content (до 2000 символов) и необязательным username, переопределяющим имя вебхука.
05Скрипт hook (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
Собирать JSON через jq -n --arg важно: ответы Claude содержат кавычки, обратные слэши и переводы строк, и если вставлять их в JSON-строку вручную, запрос сломается.
Проверьте скрипт, прежде чем подключать его:
echo '{"hook_event_name":"Notification","cwd":"/tmp/demo","message":"Test"}' | ~/.claude/chat-notify.sh
06Добавьте hooks
В ~/.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, чтобы hooks загрузились. idle_prompt и Stop пересекаются: Stop срабатывает сразу, как только Claude закончил, а idle_prompt — примерно через минуту, если Вы ничего не ввели. Оставьте оба или уберите один; плюсы и минусы описаны в руководстве по ntfy.
07Windows (PowerShell)
Сохраните как %USERPROFILE%\.claude\chat-notify.ps1. Эта версия отправляет сообщения в Discord; для Slack замените тело на @{ 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Что нужно знать о мессенджерах как канале уведомлений
- Отправленное покидает Ваш компьютер. Сообщение «закончил» содержит начало ответа Claude. В общем канале Slack или Discord его прочитают все участники. Если код закрытый, уберите
$detail. - Мессенджеры группируют и заглушают уведомления. В активном workspace или на заглушённом сервере уведомление легко пропустить. Специальное push-приложение, например ntfy (см. руководство по ntfy), надёжнее.
- Hooks не знают, сидите ли Вы за компьютером.
Stopотправляет сообщение каждый раз. Ближе всего к встроенному фильтру «меня нет на месте» —idle_promptиpermission_prompt.
09Место Claude Code Notifier
Вебхук удобен, чтобы вести лог действий Claude, а для команды это может быть как раз подходящий инструмент. Но если Вы работаете один и хотите реагировать на уведомления, этого мало: Вы читаете, что Claude нужно разрешение, и идёте к terminal, чтобы его дать. Бот Telegram в принципе может принимать ответы, но hook, который их ждёт и возвращает решение, придётся писать самому.
Эту часть берёт на себя Claude Code Notifier. С привязанным телефоном Вы прямо с него разрешаете запрос один раз или на всю сессию либо отклоняете его, отвечаете на вопросы Claude с вариантами ответа и отправляете следующую инструкцию, когда Claude закончил. Если Вы печатали в последние 30 секунд, terminal спрашивает как обычно, и на телефоне ничего не ждёт. Это независимый продукт, не от Anthropic, а ccn работает на Mac, Windows и Linux. См. сравнение, страницу ccn и цены.
10FAQ
Может ли Claude Code писать в Slack без скрипта?
В Claude Code есть http hooks, которые отправляют JSON hook POST-запросом на URL, но вебхуки Slack и Discord ожидают собственный формат тела (text или content), поэтому прямой http hook к ним не сработает. Нужен небольшой скрипт или промежуточный relay.
Как узнать ID чата в Telegram?
Отправьте боту сообщение, затем откройте https://api.telegram.org/bot<TOKEN>/getUpdates. Число после "chat":{"id": — это ID чата. Для группы сначала добавьте в неё бота и отправьте туда сообщение.
Можно ли отвечать Claude Code из Slack или Discord?
Через incoming webhook — нет: он умеет только отправлять сообщения. Чтобы отвечать, нужен hook, который ждёт Вашего ответа и возвращает решение, — именно для этого и созданы инструменты удалённого подтверждения.
Не замедлит ли hook работу Claude Code?
Запись Stop использует "async": true, поэтому отправка идёт в фоне. Hooks Notification и так выполняются параллельно с Claude, не блокируя его.