🧑‍💻 dx: Claude hooks stdin 처리 및 JSON 직렬화 개선

- stdin에서 JSON 입력을 먼저 읽은 후 파싱하도록 수정
- jq를 사용한 안전한 JSON payload 생성으로 특수문자 이스케이프 처리
- curl에 Content-Type 헤더 추가 및 -s(silent) 옵션 적용
- 디버그용 echo 로그 제거
This commit is contained in:
hyeonggil
2026-03-08 21:25:19 +09:00
parent 4f8e225727
commit 9909813c18
2 changed files with 37 additions and 25 deletions

32
.claude/hooks/notification-hook.sh Normal file → Executable file
View File

@@ -18,8 +18,11 @@ if [ -z "$SLACK_WEBHOOK_URL" ]; then
exit 1
fi
# JSON 입력에서 메시지 추출 (있는 경우)
MESSAGE=$(jq -r '.message')
# stdin에서 JSON 입력 읽기
STDIN_DATA=$(cat)
# JSON 입력에서 메시지 추출
MESSAGE=$(echo "$STDIN_DATA" | jq -r '.message // empty')
# 프로젝트명 추출
PROJECT_NAME=$(basename "$CLAUDE_PROJECT_DIR")
@@ -27,19 +30,22 @@ PROJECT_NAME=$(basename "$CLAUDE_PROJECT_DIR")
# 현재 시간
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# 디버깅을 위한 변수 출력 (stderr로 출력)
echo "DEBUG: MESSAGE = '$MESSAGE'" >&2
echo "DEBUG: PROJECT_NAME = '$PROJECT_NAME'" >&2
echo "DEBUG: TIMESTAMP = '$TIMESTAMP'" >&2
# JSON payload 생성
PAYLOAD=$(printf '{"channel": "#claude-code", "username": "Claude Code", "text": "🔔 권한 요청 알림\n\n프로젝트: %s\n상태: %s\n시간: %s\n\nClaude Code에서 알림이 도착했습니다.", "icon_emoji": ":bell:"}' "$PROJECT_NAME" "$MESSAGE" "$TIMESTAMP")
echo "DEBUG: PAYLOAD = '$PAYLOAD'" >&2
# jq를 사용해 안전하게 JSON payload 생성 (특수문자 이스케이프 처리)
PAYLOAD=$(jq -n \
--arg project "$PROJECT_NAME" \
--arg message "$MESSAGE" \
--arg timestamp "$TIMESTAMP" \
'{
channel: "#claude-code",
username: "Claude Code",
icon_emoji: ":bell:",
text: ("🔔 권한 요청 알림\n\n프로젝트: " + $project + "\n상태: " + $message + "\n시간: " + $timestamp + "\n\nClaude Code에서 알림이 도착했습니다.")
}')
# Slack으로 알림 전송
curl -X POST \
--data-urlencode "payload=$PAYLOAD" \
curl -s -X POST \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"$SLACK_WEBHOOK_URL" > /dev/null 2>&1
# 성공 여부 확인

30
.claude/hooks/stop-hook.sh Normal file → Executable file
View File

@@ -24,22 +24,28 @@ PROJECT_NAME=$(basename "$CLAUDE_PROJECT_DIR")
# 현재 시간
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# JSON 입력에서 정보 추출 (있는 경우)
REASON=$(jq -r '.hook_event_name')
# stdin에서 JSON 입력 읽기
STDIN_DATA=$(cat)
# 디버깅을 위한 변수 출력 (stderr로 출력)
echo "DEBUG: REASON = '$REASON'" >&2
echo "DEBUG: PROJECT_NAME = '$PROJECT_NAME'" >&2
echo "DEBUG: TIMESTAMP = '$TIMESTAMP'" >&2
# JSON 입력에서 정보 추출
REASON=$(echo "$STDIN_DATA" | jq -r '.hook_event_name // empty')
# JSON payload 생성
PAYLOAD=$(printf '{"channel": "#claude-code", "username": "Claude Code", "text": "✅ 작업 완료 알림\n\n프로젝트: %s\n상태: %s\n시간: %s\n\nClaude Code 작업이 완료되었습니다.", "icon_emoji": ":white_check_mark:"}' "$PROJECT_NAME" "$REASON" "$TIMESTAMP")
echo "DEBUG: PAYLOAD = '$PAYLOAD'" >&2
# 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 -X POST \
--data-urlencode "payload=$PAYLOAD" \
curl -s -X POST \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
"$SLACK_WEBHOOK_URL" > /dev/null 2>&1
# 성공 여부 확인