gitea, notion webhook
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

4.8 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

slack-notifier

Gitea/Notion webhook 알림을 담당자에게 Slack 개인 DM으로 중계하는 Go(Gin) 서버. 워크스페이스 규칙은 상위 ../CLAUDE.md 참고.

스택 / 실행

  • Go 1.26 (Gin) — 버전은 mise로 관리(mise use go@1.26)
  • 관리 UI: 표준 html/template + HTMX (Node 빌드 불필요), 템플릿은 go:embed로 바이너리에 포함
  • 명령은 Makefile에 정리되어 있음(환경은 명령어로 분기, APP_ENV에 의존 안 함):
    • make run-dev / make run-prodgo run . -env {dev,prod} (dev=text·debug·콘솔, prod=JSON·info·logs/app.log)
    • make test (go test ./...) · make vet · make fmt(gofmt -w .)
    • make build(현재 OS) · make build-linux ARCH=arm64|amd64(EC2 배포용 정적 바이너리, 기본 arm64/Graviton)
  • 단일 테스트: go test ./internal/gitea -run TestName -v (테스트는 현재 internal/gitea에만 있음)
  • 헬스체크 GET /health, 관리 페이지 http://localhost:8000/admin/mappings
  • 배포: docker compose up --build(distroless, host:6000→컨테이너:8000) 또는 deploy/의 systemd+Caddy. 외부 접근은 HTTPS 필요.

구조

main.go                       # 조립: config → mapping/slack/notion → server.Run
internal/
  config/      config.go      # env 설정 (.env, godotenv) + 환경/로그 기본값
  logging/     logging.go     # log/slog 환경별 설정 + Gin 액세스로그 미들웨어
  security/    security.go    # HMAC-SHA256 서명 검증 (Gitea/Notion 공용)
  slack/       slack.go       # users.lookupByEmail + chat.postMessage(DM), email 캐시
  notify/      notify.go      # Notification 모델 + Block Kit 헬퍼
  mapping/     mapping.go     # 수동 매핑 스토어 (data/mappings.json, thread-safe)
  gitea/       gitea.go(+test)# Gitea 이벤트 → 담당자 이메일/로그인 + 메시지
  notion/      notion.go      # Notion 이벤트 → 페이지 People 속성 → 이메일
  server/      server.go      # Gin 엔진, 라우트, deliver()
               webhooks.go    # POST /webhooks/{gitea,notion}
               admin.go       # /admin/mappings (GET/POST/DELETE, HTMX)
               templates/     # mappings.html (embed)
data/mappings.json            # 런타임 매핑 데이터 (gitignore)
deploy/                       # 비-Docker 배포: slack-notifier.service(systemd) + Caddyfile(HTTPS 리버스 프록시) + run.sh

핵심 동작

  • 담당자 해석 순서: 수동 매핑(이메일→, 로그인→) 우선, 없으면 원래 이메일 그대로 → Slack 조회.
    • 못 찾으면 DEFAULT_SLACK_CHANNEL fallback, 그것도 없으면 skip(로그만).
  • 모든 webhook은 raw body 기준 HMAC-SHA256 검증. secret 미설정 시 검증 skip(개발용, WARN 로그).
  • Notion은 최초 구독 시 받은 verification_token을 로그에서 확인해 .env에 넣어야 정상 검증됨.
  • 관리 페이지에서 추가/삭제한 매핑은 즉시 data/mappings.json에 저장.
  • 환경은 실행 명령어 -env 플래그로 분기(go run . -env prod). 값은 dev|prod(긴 형태 development/production도 정규화됨). 미지정 시 APP_ENVdev 순 fallback.
    • 환경별 .env 로드: .env.{env}.local.env.{env}.env(앞이 우선). 예: .env.dev, .env.prod.
  • 로깅은 log/slog 표준 라이브러리. 환경별로 결정:
    • dev → text 포맷 + debug 레벨 + Gin debug 모드, 콘솔(IDE)만 출력
    • prod → JSON 포맷 + info 레벨 + Gin release 모드, logs/app.log 파일로 추출(+ stdout)
    • LOG_LEVEL/LOG_FORMAT/LOG_FILE로 개별 오버라이드. 코드에선 slog.Info/Warn/Error 사용(표준 log 금지).
    • LOG_FILE 지정 시 부모 디렉터리는 자동 생성, stdout과 파일에 동시 기록. dev 기본값은 빈 값(콘솔만).
    • 파일은 날짜별로 회전됨: LOG_FILE=logs/app.log → 실제 기록은 logs/app-YYYY-MM-DD.log. 날짜가 바뀌면 새 파일 생성, LOG_RETENTION_DAYS(기본 7)일치만 보존하고 초과분 자동 삭제. 구현은 internal/logging/rotate.go(표준 라이브러리만, 외부 회전 의존성 없음).

작업 시 주의

  • 이벤트별 "담당자" 로직은 제품 정책에 가까움. 새 이벤트/대상 규칙은 internal/gitea·internal/notionBuildNotifications에 추가하고, 가능하면 테스트(*_test.go)도 같이.
  • 메시지는 한국어 + Block Kit(notify.SimpleBlocks).
  • 비밀값(SLACK_BOT_TOKEN, secret, Notion 토큰)은 .env로만 관리, 커밋 금지(.gitignore 확인).
  • 저사양 타겟이므로 무거운 의존성 추가 자제. 라우터는 Gin, 그 외는 표준 라이브러리 위주.