הגדרת Stop Hook כדי ש-Claude ישלח התראות אוטומטיות דרך שולחן העבודה, Slack או Telegram בסיום משימה
הרצת משימות ב-Claude Code לוקחת לפעמים כמה דקות ויותר. אתה מבקש ממנו לעשות רפקטורינג למודול, להריץ סט בדיקות, לעבד קבצים — ואז עובר לחלון אחר לעבוד על משהו אחר. הבעיה: אתה לא יודע מתי הוא סיים.
חוזר ומגלה שאולי הוא סיים לפני עשר דקות, או שאולי הוא תקוע על חלון אישור ומחכה לך.
עם Hook מסוג Stop אפשר לקבל התראה אוטומטית ברגע ש-Claude מסיים את המשימה או צריך את ההתערבות שלך. לא משנה באיזה חלון או מכשיר אתה — ההתראה מגיעה ישירות.
ל-Claude Code יש אירוע Stop — הוא מופעל בכל פעם ש-Claude עוצר, בין אם השלים את המשימה, נתקל בשגיאה שדורשת אישור, או מחכה לקלט מהמשתמש.
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "bash .claude/hooks/notify.sh"
}
]
}
]
}
}
ה-Hook מקבל דרך stdin אובייקט JSON שמכיל stop_reason (סיבת העצירה) ו-stop_message (ההודעה האחרונה של Claude). על בסיס המידע הזה אפשר להתאים את תוכן ההתראה.
מבנה הנתונים ב-stdin:
{
"session_id": "xxx",
"stop_reason": "end_turn",
"stop_message": "重构完成,所有测试通过。"
}
ב-Linux משתמשים ב-notify-send, ב-macOS ב-osascript, בלי שום שירות חיצוני:
#!/bin/bash
input=$(cat)
reason=$(echo "$input" | jq -r '.stop_reason // "unknown"')
message=$(echo "$input" | jq -r '.stop_message // "Claude 已停止"' | head -c 200)
case "$(uname)" in
Linux)
notify-send "Claude Code" "$message" --urgency=normal
;;
Darwin)
osascript -e "display notification \"$message\" with title \"Claude Code\""
;;
esac
יתרונות: אפס הגדרות, עובד מיד.
חסרונות: ההתראה מגיעה רק למכשיר הנוכחי. עברת למכשיר אחר — לא תראה אותה.
שימוש ב-Slack Incoming Webhook כדי לשלוח התראות לערוץ מסוים או כהודעה פרטית.
הכנה מקדימה:
1. צרו אפליקציה בדף ניהול האפליקציות של Slack
2. הפעילו Incoming Webhooks וקבלו את כתובת ה-Webhook
3. שמרו את הכתובת במשתנה הסביבה SLACK_WEBHOOK_URL
#!/bin/bash
input=$(cat)
reason=$(echo "$input" | jq -r '.stop_reason // "unknown"')
message=$(echo "$input" | jq -r '.stop_message // "Claude 已停止"' | head -c 300)
webhook_url="${SLACK_WEBHOOK_URL}"
[[ -z "$webhook_url" ]] && exit 0
# 根据停止原因选 emoji
case "$reason" in
end_turn) emoji="✅" ;;
user_input) emoji="⏳" ;;
*) emoji="🔔" ;;
esac
payload=$(jq -n \
--arg text "$emoji *Claude Code* | \`$reason\`
$message" \
'{text: $text}')
curl -s -X POST "$webhook_url" \
-H 'Content-Type: application/json' \
-d "$payload" > /dev/null 2>&1 &
ה-& בסוף השורה חשוב — הוא גורם ל-curl לרוץ ברקע בלי לחסום את Claude.
בוט Telegram מתאים לשימוש אישי — חינמי, מיידי, וההתראות מגיעות ישר לטלפון.
הכנה מקדימה:
1. צרו בוט דרך @BotFather וקבלו Token
2. השיגו את ה-Chat ID שלכם (שלחו הודעה לבוט וקראו ל-API של getUpdates)
3. הגדירו את משתני הסביבה TELEGRAM_BOT_TOKEN ו-TELEGRAM_CHAT_ID
#!/bin/bash
input=$(cat)
reason=$(echo "$input" | jq -r '.stop_reason // "unknown"')
message=$(echo "$input" | jq -r '.stop_message // "Claude 已停止"' | head -c 300)
token="${TELEGRAM_BOT_TOKEN}"
chat_id="${TELEGRAM_CHAT_ID}"
[[ -z "$token" || -z "$chat_id" ]] && exit 0
text="🤖 *Claude Code*
状态:\`$reason\`
$message"
curl -s "https://api.telegram.org/bot${token}/sendMessage" \
-d chat_id="$chat_id" \
-d text="$text" \
-d parse_mode="Markdown" > /dev/null 2>&1 &
אם אתה על אותו מכשיר אבל עברת לחלון אחר, צליל קצר יעיל יותר מהתראה ויזואלית:
#!/bin/bash
input=$(cat)
reason=$(echo "$input" | jq -r '.stop_reason // "unknown"')
case "$(uname)" in
Linux)
paplay /usr/share/sounds/freedesktop/stereo/complete.oga 2>/dev/null &
;;
Darwin)
afplay /System/Library/Sounds/Glass.aiff &
;;
esac
אפשר לשלב עם שיטות אחרות — צליל מקומי + התראה מרוחקת.
בשימוש יומיומי, מומלץ לשלב כמה שיטות בסקריפט אחד:
.claude/hooks/notify.sh:
#!/bin/bash
input=$(cat)
reason=$(echo "$input" | jq -r '.stop_reason // "unknown"')
message=$(echo "$input" | jq -r '.stop_message // "Claude 已停止"' | head -c 300)
# 根据原因选 emoji
case "$reason" in
end_turn) emoji="✅"; title="任务完成" ;;
user_input) emoji="⏳"; title="等待输入" ;;
*) emoji="🔔"; title="Claude 已停止" ;;
esac
# 1. 桌面通知(本地)
case "$(uname)" in
Linux) notify-send "Claude Code: $title" "$message" --urgency=normal ;;
Darwin) osascript -e "display notification \"$message\" with title \"Claude Code: $title\"" ;;
esac
# 2. 声音提示
case "$(uname)" in
Linux) paplay /usr/share/sounds/freedesktop/stereo/complete.oga 2>/dev/null & ;;
Darwin) afplay /System/Library/Sounds/Glass.aiff & ;;
esac
# 3. Slack(如果配了 Webhook)
if [[ -n "$SLACK_WEBHOOK_URL" ]]; then
payload=$(jq -n --arg text "$emoji *$title*
$message" '{text: $text}')
curl -s -X POST "$SLACK_WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-d "$payload" > /dev/null 2>&1 &
fi
# 4. Telegram(如果配了 Bot)
if [[ -n "$TELEGRAM_BOT_TOKEN" && -n "$TELEGRAM_CHAT_ID" ]]; then
curl -s "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
-d chat_id="$TELEGRAM_CHAT_ID" \
-d text="$emoji *$title*
$message" \
-d parse_mode="Markdown" > /dev/null 2>&1 &
fi
.claude/settings.json:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "bash .claude/hooks/notify.sh"
}
]
}
]
}
}
כל בקשות הרשת חייבות לרוץ ברקע
כל curl בסקריפט ההתראות חייב להסתיים ב-& כדי לרוץ ברקע. אם הרשת איטית או שיש timeout, זה יחסום את כל הסשן של Claude. הנוסחה > /dev/null 2>&1 & היא הסטנדרט.
עצירה לא בהכרח אומרת "הושלם בהצלחה"
stop_reason עם ערך end_turn בדרך כלל אומר שהמשימה הושלמה, אבל זה יכול גם להיות ש-Claude לא בטוח מה לעשות הלאה. אם רוצים התראה רק בסיום אמיתי, אפשר לסנן בסקריפט:
[[ "$reason" != "end_turn" ]] && exit 0
חתכו את תוכן ההתראה
ההודעה האחרונה של Claude עלולה להיות ארוכה מאוד (בלוקים של קוד, פלטים ארוכים). לפני שליחה ל-Slack או Telegram, השתמשו ב-head -c 300 כדי לקצר ולמנוע הודעות מנופחות.
משתני סביבה — שמרו בהגדרות גלובליות
כתובות Webhook וטוקנים של בוטים לא צריכים להיות בריפו של הפרויקט. שמרו אותם ב-~/.zshrc (או ~/.bashrc), או נהלו אותם עם direnv.
אחרי ההגדרה, שיטת העבודה שלך משתנה:
בלי לבהות בטרמינל, בלי להחליף חלונות כל הזמן כדי לבדוק התקדמות. Claude עובד, אתה עובד, וכשהוא מסיים — הוא מודיע לך.