# slack-notifier Gitea webhook · Notion webhook 알림을 받아 **담당자에게 Slack 개인 DM**으로 보내는 중계 서버. - 담당자 매핑: 이메일 자동 매칭(Gitea/Notion 이메일 → Slack `users.lookupByEmail`) + **수동 매핑 보강**(관리 페이지) - 스택: **Go + Gin** (저사양 환경 대응, 단일 정적 바이너리), 관리 UI는 html/template + HTMX ``` [Gitea] ──webhook──┐ ├─▶ slack-notifier ─▶ (매핑 해석) ─▶ users.lookupByEmail ─▶ chat.postMessage(DM) [Notion] ─webhook──┘ (서명검증) 자동+수동 이메일→Slack ID ``` ## 빠른 시작 (로컬) Go는 [mise](https://mise.jdx.dev)로 관리합니다 (`mise use go@1.26`). ```bash cd slack-notifier cp .env.example .env # 값 채우기 go run . # 기본 :8000 ``` - 헬스체크: `curl localhost:8000/health` - 관리 페이지: 브라우저로 `http://localhost:8000/admin/mappings` - 테스트: `go test ./...` - 빌드: `go build -o slack-notifier .` Docker: ```bash docker compose up --build # distroless 기반 경량 이미지 ``` ## 엔드포인트 | 메서드 | 경로 | 설명 | |---|---|---| | GET | `/health` | 헬스체크 | | POST | `/webhooks/gitea` | Gitea webhook 수신 | | POST | `/webhooks/notion` | Notion webhook 수신 (+ 최초 검증 핸드셰이크) | | GET | `/admin/mappings` | 유저 매핑 관리 페이지 | | POST | `/admin/mappings` | 매핑 추가 (HTMX) | | DELETE | `/admin/mappings/:source` | 매핑 삭제 (HTMX) | ## 담당자 매핑 1. **자동(이메일)**: Gitea/Notion 이벤트의 이메일을 그대로 Slack에서 조회. 2. **수동(오버라이드)**: `/admin/mappings`에서 `소스(이메일 또는 로그인) → Slack 이메일`을 등록. 시스템 간 이메일이 다르거나 자동 조회가 안 될 때 보강. `data/mappings.json`에 저장됨. 3. 그래도 못 찾으면 `DEFAULT_SLACK_CHANNEL`로 fallback(설정 시), 없으면 skip. ## Slack 앱 준비 1. https://api.slack.com/apps 에서 앱 생성 → **Bot Token Scopes**: `chat:write`, `users:read.email`, `im:write` 2. 워크스페이스에 설치 후 **Bot User OAuth Token**(`xoxb-...`)을 `SLACK_BOT_TOKEN`에 설정 ## Gitea 설정 저장소/조직 → Settings → Webhooks → Add Webhook (Gitea) - **Target URL**: `https://<배포주소>/webhooks/gitea` - **Secret**: `GITEA_WEBHOOK_SECRET`와 동일하게 입력 (HMAC-SHA256 서명 검증) 처리하는 이벤트 → 담당자: | 이벤트 | 알림 대상 | |--------|-----------| | PR `assigned` / `opened` / `reopened` | 담당자(assignees) | | PR `review_requested` | 리뷰어 | | PR `closed`(merged) | PR 작성자 | | PR review 등록 | PR 작성자 | | 이슈 `assigned` | 담당자 | | 이슈/PR 댓글 | 담당자 + 작성자 (댓글 단 본인 제외) | > 그 외 이벤트(예: push)는 기본 무시. 필요하면 `internal/gitea/gitea.go`에 핸들러를 추가하세요. ## Notion 설정 1. **Integration** 생성 → `NOTION_API_TOKEN` 설정, 대상 DB/페이지에 integration 연결(공유) 2. Notion **Webhook subscription** 생성 → endpoint `https://<배포주소>/webhooks/notion` 3. 최초 구독 시 Notion이 `verification_token`을 POST → 서버 로그에 출력됨 → `NOTION_VERIFICATION_TOKEN`에 넣고 재시작 4. 담당자는 페이지의 **People 속성**(이름은 `NOTION_ASSIGNEE_PROPERTY`, 기본 `담당자`)에서 읽어 이메일로 매핑 ## 저사양 배포 메모 - 단일 정적 바이너리(distroless 이미지 ~10MB대), idle 메모리 수십 MB 수준. - 메모리가 빠듯하면 `GOMEMLIMIT=200MiB` 등으로 상한을 줄 수 있음(README/`.env.example` 참고). - webhook 수신을 위해 외부 접근 가능한 HTTPS 엔드포인트 필요. 로컬 테스트는 `ngrok http 8000` 같은 터널 사용.