# Slack 통합 레벨 3 구현 계획 **작성일**: 2025-08-28 **작성자**: 51123 서버 관리자 **상태**: 🟢 실행 가능 **목표**: Frontend 레벨 3 로빙을 위한 Slack 완전 통합 --- ## 1. 개요 ### 목표 - **모든 레벨**: Google OAuth + Slack 로그인 (둘 다 사용 가능) - **레벨 2**: Gmail 권한 아이템 획득 (Gmail API 접근) - **레벨 3**: Slack 아이템 획득 (**확인 필요**: Frontend 레벨 3 버튼 구현 여부) - Workspace 봇 설치 - 대화 동기화 (Frontend ↔ Slack) - 멘션(@) 및 슬래시(/) 명령 ### 현재 상태 및 정책 - **엔드포인트**: `/auth/slack/login/`, `/auth/slack/login/callback` 구조 - **localStorage**: `token` 키 통일, JWT 24시간, refresh 없음 - **OAuth**: auth-server 직접, API는 Gateway 경유 - **테이블**: slack_workspaces, slack_user_mapping 존재 --- ## 2. 구현 단계 ### Phase 1: Sign in with Slack ⚠️ 목업 부분 완료 ``` Frontend → auth-server → Slack OIDC → UUID 생성 → JWT 발급 ``` **백엔드 엔드포인트**: - `GET /auth/slack/login/` - OAuth 시작 - `GET /auth/slack/login/callback` - 토큰 교환, UUID 매핑, JWT 발급 - `GET /api/slack/mapping/{slack_user_id}` - UUID 조회 **구현 상세**: 1. Slack 앱 설정에서 "Sign in with Slack" 활성화 (OpenID Connect) - Redirect URL: `https://auth.ro-being.com/auth/slack/login/callback` 2. User Token 스코프: `openid`, `profile`, `email` (로그인용) 3. 콜백에서 `openid.connect.userInfo` 호출하여 사용자 정보 획득 4. DB 저장: users 테이블 UUID, slack_user_mapping 매핑 저장 **주의**: `identity.*` 레거시 스코프는 사용 금지 ### Phase 2: Add to Slack ⚠️ 목업 부분 완료 ``` Frontend(Slack 아이템 획득) → auth-server → OAuth 2.0 → 봇 토큰 저장 ``` **Slack 패스포트 엔드포인트** (2025-08-29 부분 구현): - `GET /auth/slack/passport/install?user_id={user_id}` - 봇 설치 OAuth 시작 - 파일: `/home/admin/auth-server/app/providers/slack.py:104` - 변경: workspace_id → user_id 파라미터 - 처리: user_id로 workspace_member 테이블에서 workspace_id 조회 - `GET /auth/slack/passport/callback` - bot_token 저장 - `GET /auth/slack/passport/status/{workspace_id}` - 아이템 상태 확인 - `DELETE /auth/slack/passport/uninstall/{workspace_id}` - 아이템 취소 - `POST /auth/slack/passport/activate` - 아이템 장착 - `POST /auth/slack/passport/deactivate` - 아이템 해제 **구현 상태** (2025-08-29): 1. Frontend 호출: ✅ 완료 - `src/components/skills-items-panel.tsx:handleSlackItemClick()` - Gmail 패턴과 통일: user_id 파라미터 사용 2. OAuth 2.0 플로우 (**별도**: Sign in with Slack과 분리) - Add to Slack 버튼: `https://slack.com/oauth/v2/authorize?...` - 콜백: `/auth/slack/passport/callback` 2. Bot Token Scopes: ``` 읽기: channels:read, groups:read, channels:history, groups:history, im:history, mpim:history 이벤트: app_mentions:read, commands 쓰기: chat:write (메시지 전송), im:write (DM 개설) 사용자: users:read, users:read.email ``` 3. `oauth.v2.access`로 bot_access_token 획득 → 암호화 저장 4. 재설치 시 기존 토큰 교체, 다중 workspace 지원 ### Phase 3: 대화 동기화 ``` Slack Event → rb8001 → DB → SSE/WebSocket → Frontend 전송: rb8001 → skill-slack → Slack ``` **구현**: 1. Events API 구독 - Request URL: `rb8001/slack/events` - 이벤트: `message.channels`, `message.groups`, `message.im`, `message.mpim`, `app_mention` - 쓰레드: `message.message_replied` 이벤트 존재하나 `thread_ts` 확인 권장 2. 채널 타입: C(공개), G(비공개/그룹), D(DM) 3. conversation_log 저장: team_id, channel_id, thread_ts 4. 초기 동기화: `conversations.history`로 백필 ### Phase 4: 명령 처리 ``` Slack → @robeing 또는 /robeing → rb8001 → skill-slack → Slack 응답 ``` **구현**: 1. 멘션: `app_mention` 이벤트 → rb8001가 skill-slack `/send` 호출 → Slack 2. 슬래시 명령 (앱 설정 또는 Manifest API로 등록): - `/robeing help`, `/robeing status`, `/robeing level` - Request URL: `rb8001/slack/commands` 3. **응답 처리**: 3초 내 200 OK 필수, response_url로 30분 내 최대 5회 후속 응답 가능 4. 서명 검증: X-Slack-Signature, X-Slack-Request-Timestamp (5분 윈도) 5. **Rate Limits**: 메시지 전송 채널당 초당 1회 권장 --- ## 3. 데이터베이스 설계 ### 기존 테이블 활용 - **users**: id(UUID), email, slack_user_id, slack_team_id - **slack_workspaces**: team_id, team_name, bot_token(암호화), installed_by_user_id, scopes, installed_at - **slack_user_mapping**: team_id + slack_user_id 복합키, user_id(UUID) - **conversation_log**: team_id, channel_id, channel_type, user_id, text, ts, thread_ts ### 필요 컬럼 추가 ```sql ALTER TABLE user ADD COLUMN slack_user_id VARCHAR(50); ALTER TABLE user ADD COLUMN slack_team_id VARCHAR(50); ALTER TABLE conversation_log ADD COLUMN thread_ts VARCHAR(20); ALTER TABLE conversation_log ADD COLUMN channel_type VARCHAR(20); ``` --- ## 4. 보안 및 운영 ### 보안 - **토큰 암호화**: bot_access_token 암호화 저장 필수 - **서명 검증**: X-Slack-Signature로 재생공격 방지 - **스코프 분리**: Sign in with Slack(사용자) vs Add to Slack(봇) ### 운영 - **3초 규칙**: Events API/Slash Commands 모두 3초 내 ACK - **채널 접근**: 봇이 채널 초대되어야 이벤트 수신 - **Rate Limits**: - Events: 시간당 30,000건 (초당 ~8건) - Web API: 메서드별 상이 (chat.postMessage: 채널당 초당 1회) - 메시지: 채널당 초당 1회 --- ## 5. 테스트 시나리오 ### Phase 1 테스트 - 테스트 워크스페이스에서 OIDC 로그인 - users 테이블에 UUID 생성 확인 - JWT 발급 및 세션 로그인 확인 ### Phase 2 테스트 - 워크스페이스 앱 설치 - 토큰 암호화 저장 확인 - skill-slack `/send`로 헬스체크 ### Phase 3 테스트 - 공개/비공개 채널, DM, 멀티DM 각각 송수신 - Frontend 실시간 반영 확인 - conversations.history로 초기 동기화 ### Phase 4 테스트 - /robeing help 호출 → ephemeral 응답 - @robeing 멘션 → 응답 확인 - 긴 작업 시 response_url 후속 메시지 --- ## 6. 참고 문서 ### Slack API - [Sign in with Slack](https://api.slack.com/authentication/sign-in-with-slack) - [OAuth v2](https://api.slack.com/authentication/oauth-v2) - [Events API](https://api.slack.com/events-api) - [Conversations API](https://api.slack.com/apis/conversations-api) - [Slash Commands](https://api.slack.com/slash-commands) - [Permission Scopes](https://api.slack.com/scopes) ### 내부 문서 - [auth_login_sequences.md](../300_architecture/sequences/auth_login_sequences.md) - [tables.md](../300_architecture/database/tables.md) - [250828_conversation_log_channel_구분_개선.md](../troubleshooting/250828_conversation_log_channel_구분_개선.md)