#!/bin/bash # Claude Code Stop 훅 - 작업 완료 알림 # # 이 스크립트는 Claude Code가 Stop 이벤트를 발생시킬 때 실행됩니다. # Claude가 응답을 완료했을 때 Slack 알림을 보냅니다. # .env 파일에서 Slack 웹훅 URL 로드 (CRLF 호환) ENV_FILE="${CLAUDE_PROJECT_DIR}/.env" # Windows 경로 백슬래시를 슬래시로 변환 ENV_FILE="${ENV_FILE//\\//}" if [ -f "$ENV_FILE" ]; then while IFS='=' read -r key value || [[ -n "$key" ]]; do [[ "$key" =~ ^[[:space:]]*# ]] && continue [[ -z "${key// }" ]] && continue key="${key//$'\r'/}" value="${value//$'\r'/}" export "$key=$value" done < "$ENV_FILE" else echo "오류: .env 파일을 찾을 수 없습니다: $ENV_FILE" >&2 exit 1 fi # Slack 웹훅 URL 확인 if [ -z "$SLACK_WEBHOOK_URL" ]; then echo "오류: SLACK_WEBHOOK_URL이 설정되지 않았습니다." >&2 exit 1 fi # 프로젝트명 추출 (Windows 경로 백슬래시 변환) NORMALIZED_DIR="${CLAUDE_PROJECT_DIR//\\//}" PROJECT_NAME=$(basename "$NORMALIZED_DIR") # 현재 시간 TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') # stdin에서 JSON 입력 읽기 STDIN_DATA=$(cat) # JSON 입력에서 정보 추출 REASON=$(echo "$STDIN_DATA" | jq -r '.hook_event_name // empty') # jq를 사용해 안전하게 JSON payload 생성 (특수문자 이스케이프 처리) PAYLOAD=$(jq -n \ --arg project "$PROJECT_NAME" \ --arg reason "$REASON" \ --arg timestamp "$TIMESTAMP" \ '{ channel: "#claude-code", username: "Claude Code", icon_emoji: ":white_check_mark:", text: ("✅ 작업 완료 알림\n\n프로젝트: " + $project + "\n상태: " + $reason + "\n시간: " + $timestamp + "\n\nClaude Code 작업이 완료되었습니다.") }') # Slack으로 알림 전송 curl -s -X POST \ -H "Content-Type: application/json" \ -d "$PAYLOAD" \ "$SLACK_WEBHOOK_URL" > /dev/null 2>&1 # 성공 여부 확인 if [ $? -eq 0 ]; then echo "Slack 알림이 성공적으로 전송되었습니다." >&2 else echo "Slack 알림 전송에 실패했습니다." >&2 exit 1 fi