Loading...
Sends progress updates to Slack channel for team visibility on Claude's activities
{
"hookConfig": {
"hooks": {
"notification": {
"script": "./.claude/hooks/slack-progress-notifier.sh",
"matchers": [
"*"
]
}
}
},
"scriptContent": "#!/bin/bash\n\n# Read the tool input from stdin\nINPUT=$(cat)\nTOOL_NAME=$(echo \"$INPUT\" | jq -r '.tool_name')\nFILE_PATH=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // .tool_input.path // \"\"')\n\n# Check if Slack webhook URL is configured\nif [ -z \"$SLACK_WEBHOOK_URL\" ]; then\n echo \"โน๏ธ Slack webhook URL not configured - skipping notification\"\n echo \"๐ก Set SLACK_WEBHOOK_URL environment variable to enable Slack notifications\"\n exit 0\nfi\n\necho \"๐ข Slack Progress Notifier - Sending team notification...\"\necho \"๐ง Tool: $TOOL_NAME\"\nif [ -n \"$FILE_PATH\" ]; then\n echo \"๐ File: $(basename \"$FILE_PATH\")\"\nfi\n\n# Determine appropriate emoji based on tool/activity type\nEMOJI=\"๐\" # Default emoji\n\ncase \"$TOOL_NAME\" in\n *test*|*Test*)\n EMOJI=\"๐งช\"\n ACTIVITY=\"Testing\"\n ;;\n *build*|*Build*)\n EMOJI=\"๐๏ธ\"\n ACTIVITY=\"Building\"\n ;;\n *deploy*|*Deploy*)\n EMOJI=\"๐\"\n ACTIVITY=\"Deployment\"\n ;;\n *commit*|*Commit*|*git*)\n EMOJI=\"๐\"\n ACTIVITY=\"Version Control\"\n ;;\n *edit*|*Edit*|*write*|*Write*)\n EMOJI=\"โ๏ธ\"\n ACTIVITY=\"Code Editing\"\n ;;\n *lint*|*Lint*|*format*|*Format*)\n EMOJI=\"๐งน\"\n ACTIVITY=\"Code Quality\"\n ;;\n *install*|*Install*|*package*)\n EMOJI=\"๐ฆ\"\n ACTIVITY=\"Package Management\"\n ;;\n *security*|*Security*|*audit*)\n EMOJI=\"๐\"\n ACTIVITY=\"Security\"\n ;;\n *debug*|*Debug*|*error*)\n EMOJI=\"๐\"\n ACTIVITY=\"Debugging\"\n ;;\n *doc*|*Doc*|*readme*)\n EMOJI=\"๐\"\n ACTIVITY=\"Documentation\"\n ;;\n *)\n EMOJI=\"โก\"\n ACTIVITY=\"Development\"\n ;;\nesac\n\n# Prepare the message\nif [ -n \"$FILE_PATH\" ]; then\n FILENAME=$(basename \"$FILE_PATH\")\n MESSAGE=\"$EMOJI Claude Code: $ACTIVITY - $TOOL_NAME on $FILENAME\"\nelse\n MESSAGE=\"$EMOJI Claude Code: $ACTIVITY - $TOOL_NAME\"\nfi\n\n# Get additional context\nTIMESTAMP=$(date '+%H:%M:%S')\nUSER=$(whoami 2>/dev/null || echo \"developer\")\nBRANCH=\"unknown\"\nif git rev-parse --git-dir >/dev/null 2>&1; then\n BRANCH=$(git branch --show-current 2>/dev/null || echo \"unknown\")\nfi\n\n# Create rich message payload\nREPO_NAME=$(basename \"$(pwd)\" 2>/dev/null || echo \"project\")\n\n# Construct JSON payload with proper escaping\nPAYLOAD=$(cat <<EOF\n{\n \"text\": \"$MESSAGE\",\n \"blocks\": [\n {\n \"type\": \"section\",\n \"text\": {\n \"type\": \"mrkdwn\",\n \"text\": \"$EMOJI *Claude Code Activity*\\n*Action:* $TOOL_NAME\\n*Time:* $TIMESTAMP\\n*User:* $USER\\n*Branch:* $BRANCH\\n*Project:* $REPO_NAME\"\n }\n }\n ]\n}\nEOF\n)\n\necho \"๐ค Sending notification to Slack...\"\n\n# Send to Slack with proper error handling\nif curl -X POST \\\n -H 'Content-type: application/json' \\\n --data \"$PAYLOAD\" \\\n --max-time 5 \\\n --retry 1 \\\n \"$SLACK_WEBHOOK_URL\" \\\n --silent \\\n --show-error 2>/dev/null; then\n echo \"โ
Slack notification sent successfully\"\nelse\n CURL_EXIT_CODE=$?\n case $CURL_EXIT_CODE in\n 6)\n echo \"โ ๏ธ Failed to send Slack notification - couldn't resolve host\"\n ;;\n 7)\n echo \"โ ๏ธ Failed to send Slack notification - couldn't connect to server\"\n ;;\n 22)\n echo \"โ ๏ธ Failed to send Slack notification - HTTP error (check webhook URL)\"\n ;;\n 28)\n echo \"โ ๏ธ Failed to send Slack notification - timeout\"\n ;;\n *)\n echo \"โ ๏ธ Failed to send Slack notification - error code: $CURL_EXIT_CODE\"\n ;;\n esac\n echo \"๐ก Verify SLACK_WEBHOOK_URL is correct and Slack service is accessible\"\nfi\n\necho \"\"\necho \"๐ก Slack Integration Tips:\"\necho \" โข Get webhook URL from: https://api.slack.com/messaging/webhooks\"\necho \" โข Set SLACK_WEBHOOK_URL environment variable\"\necho \" โข Test webhook with: curl -X POST -H 'Content-type: application/json' --data '{\\\"text\\\":\\\"Test\\\"}' \\$SLACK_WEBHOOK_URL\"\necho \" โข Configure channel-specific webhooks for different notification types\"\necho \" โข Consider rate limiting for high-activity periods\"\n\necho \"\"\necho \"๐ฏ Slack notification complete!\"\n\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"notification": {
"script": "./.claude/hooks/slack-progress-notifier.sh",
"matchers": [
"*"
]
}
}
}#!/bin/bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
# Check if Slack webhook URL is configured
if [ -z "$SLACK_WEBHOOK_URL" ]; then
echo "โน๏ธ Slack webhook URL not configured - skipping notification"
echo "๐ก Set SLACK_WEBHOOK_URL environment variable to enable Slack notifications"
exit 0
fi
echo "๐ข Slack Progress Notifier - Sending team notification..."
echo "๐ง Tool: $TOOL_NAME"
if [ -n "$FILE_PATH" ]; then
echo "๐ File: $(basename "$FILE_PATH")"
fi
# Determine appropriate emoji based on tool/activity type
EMOJI="๐" # Default emoji
case "$TOOL_NAME" in
*test*|*Test*)
EMOJI="๐งช"
ACTIVITY="Testing"
;;
*build*|*Build*)
EMOJI="๐๏ธ"
ACTIVITY="Building"
;;
*deploy*|*Deploy*)
EMOJI="๐"
ACTIVITY="Deployment"
;;
*commit*|*Commit*|*git*)
EMOJI="๐"
ACTIVITY="Version Control"
;;
*edit*|*Edit*|*write*|*Write*)
EMOJI="โ๏ธ"
ACTIVITY="Code Editing"
;;
*lint*|*Lint*|*format*|*Format*)
EMOJI="๐งน"
ACTIVITY="Code Quality"
;;
*install*|*Install*|*package*)
EMOJI="๐ฆ"
ACTIVITY="Package Management"
;;
*security*|*Security*|*audit*)
EMOJI="๐"
ACTIVITY="Security"
;;
*debug*|*Debug*|*error*)
EMOJI="๐"
ACTIVITY="Debugging"
;;
*doc*|*Doc*|*readme*)
EMOJI="๐"
ACTIVITY="Documentation"
;;
*)
EMOJI="โก"
ACTIVITY="Development"
;;
esac
# Prepare the message
if [ -n "$FILE_PATH" ]; then
FILENAME=$(basename "$FILE_PATH")
MESSAGE="$EMOJI Claude Code: $ACTIVITY - $TOOL_NAME on $FILENAME"
else
MESSAGE="$EMOJI Claude Code: $ACTIVITY - $TOOL_NAME"
fi
# Get additional context
TIMESTAMP=$(date '+%H:%M:%S')
USER=$(whoami 2>/dev/null || echo "developer")
BRANCH="unknown"
if git rev-parse --git-dir >/dev/null 2>&1; then
BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
fi
# Create rich message payload
REPO_NAME=$(basename "$(pwd)" 2>/dev/null || echo "project")
# Construct JSON payload with proper escaping
PAYLOAD=$(cat <<EOF
{
"text": "$MESSAGE",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "$EMOJI *Claude Code Activity*\n*Action:* $TOOL_NAME\n*Time:* $TIMESTAMP\n*User:* $USER\n*Branch:* $BRANCH\n*Project:* $REPO_NAME"
}
}
]
}
EOF
)
echo "๐ค Sending notification to Slack..."
# Send to Slack with proper error handling
if curl -X POST \
-H 'Content-type: application/json' \
--data "$PAYLOAD" \
--max-time 5 \
--retry 1 \
"$SLACK_WEBHOOK_URL" \
--silent \
--show-error 2>/dev/null; then
echo "โ
Slack notification sent successfully"
else
CURL_EXIT_CODE=$?
case $CURL_EXIT_CODE in
6)
echo "โ ๏ธ Failed to send Slack notification - couldn't resolve host"
;;
7)
echo "โ ๏ธ Failed to send Slack notification - couldn't connect to server"
;;
22)
echo "โ ๏ธ Failed to send Slack notification - HTTP error (check webhook URL)"
;;
28)
echo "โ ๏ธ Failed to send Slack notification - timeout"
;;
*)
echo "โ ๏ธ Failed to send Slack notification - error code: $CURL_EXIT_CODE"
;;
esac
echo "๐ก Verify SLACK_WEBHOOK_URL is correct and Slack service is accessible"
fi
echo ""
echo "๐ก Slack Integration Tips:"
echo " โข Get webhook URL from: https://api.slack.com/messaging/webhooks"
echo " โข Set SLACK_WEBHOOK_URL environment variable"
echo " โข Test webhook with: curl -X POST -H 'Content-type: application/json' --data '{\"text\":\"Test\"}' \$SLACK_WEBHOOK_URL"
echo " โข Configure channel-specific webhooks for different notification types"
echo " โข Consider rate limiting for high-activity periods"
echo ""
echo "๐ฏ Slack notification complete!"
exit 0Notifications fail with 'invalid_payload' error from Slack
Escape special characters in JSON payload. Use jq to construct payload: jq -n --arg msg "$MESSAGE" '{text: $msg}' | curl -d @- $SLACK_WEBHOOK_URL. Avoid shell variable expansion inside JSON strings.
Hook causes timeout on every tool execution slowing workflow
Run curl in background with & to avoid blocking: (curl --max-time 3 "$SLACK_WEBHOOK_URL" &) >/dev/null 2>&1. Add exit 0 immediately after background execution. Reduce timeout from 5s to 3s.
Slack webhook returns HTTP 410 'url_verification_failed'
Webhook URL expired or was revoked. Generate new webhook at https://api.slack.com/messaging/webhooks. Update SLACK_WEBHOOK_URL environment variable. Check workspace permissions for incoming webhooks.
Git branch detection fails showing 'unknown' for detached HEAD
Add fallback to commit SHA: BRANCH=$(git branch --show-current || git rev-parse --short HEAD || echo 'unknown'). Handle detached HEAD state gracefully with descriptive label like 'detached@SHA'.
Notification spam floods channel during rapid file operations
Implement debouncing with timestamp check: LAST_NOTIFY=$(cat /tmp/slack_last 2>/dev/null || echo 0); NOW=$(date +%s); [ $((NOW - LAST_NOTIFY)) -lt 10 ] && exit 0. Skip notifications within 10s window.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters