From b866ed766f21561331463caf339798f64183f755 Mon Sep 17 00:00:00 2001 From: happybell80 Date: Tue, 2 Sep 2025 15:36:38 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20Slack=20=EB=B4=87=20=EC=84=A4=EC=B9=98?= =?UTF-8?q?=20URL=20=EB=B6=84=EC=84=9D=20=EB=B0=8F=20DB=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EB=AC=B8=EC=84=9C=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Slack OAuth 설치 프로세스 분석 - Event URL 자동 설정 방안 (Manifest API) - slack_workspaces, slack_user_mapping 테이블 구조 현행화 - State 관리 개선 방안 제시 --- 300_architecture/database/tables.md | 18 ++-- .../250902_slack_bot_install_url_analysis.md | 87 +++++++++++++++++++ 2 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 troubleshooting/250902_slack_bot_install_url_analysis.md diff --git a/300_architecture/database/tables.md b/300_architecture/database/tables.md index 2a99d27..683c7af 100644 --- a/300_architecture/database/tables.md +++ b/300_architecture/database/tables.md @@ -81,21 +81,27 @@ | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| | id | UUID | NO | | 워크스페이스 ID | -| team_id | VARCHAR(50) | NO | | Slack Team ID (UNIQUE) | +| company_id | UUID | NO | | 회사 ID (FK → companies) | +| team_id | VARCHAR(100) | NO | | Slack Team ID (UNIQUE) | | team_name | VARCHAR(255) | YES | | 팀 이름 | | bot_token | TEXT | YES | | Bot User OAuth Token | -| bot_user_id | VARCHAR(50) | YES | | Bot User ID | -| created_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 생성 시각 | -| updated_at | TIMESTAMP | YES | CURRENT_TIMESTAMP | 수정 시각 | +| bot_user_id | VARCHAR(100) | YES | | Bot User ID | +| app_id | VARCHAR(100) | YES | | Slack App ID | +| scopes | JSON | YES | | Bot 권한 스코프 목록 | +| is_enterprise_install | BOOLEAN | YES | | 엔터프라이즈 설치 여부 | +| is_active | BOOLEAN | YES | | 활성 상태 | +| installed_at | TIMESTAMP | YES | | 설치 시각 | +| updated_at | TIMESTAMP | YES | | 수정 시각 | ### slack_user_mapping - **용도**: Slack 사용자와 시스템 사용자 매핑 - **Primary Key**: id (UUID) +- **Unique**: (slack_user_id, slack_workspace_id) | 컬럼명 | 타입 | NULL | 기본값 | 설명 | |--------|------|------|--------|------| -| id | UUID | NO | | 매핑 ID | -| slack_user_id | VARCHAR(50) | NO | | Slack User ID (U로 시작) | +| id | UUID | NO | gen_random_uuid() | 매핑 ID | +| slack_user_id | VARCHAR(100) | NO | | Slack User ID (U로 시작) | | slack_workspace_id | UUID | YES | | Slack 워크스페이스 ID (FK → slack_workspaces) | | user_id | UUID | NO | | 시스템 사용자 ID (FK → users) | | workspace_member_id | UUID | YES | | 워크스페이스 멤버 ID (FK → workspace_members) | diff --git a/troubleshooting/250902_slack_bot_install_url_analysis.md b/troubleshooting/250902_slack_bot_install_url_analysis.md new file mode 100644 index 0000000..9d65c9f --- /dev/null +++ b/troubleshooting/250902_slack_bot_install_url_analysis.md @@ -0,0 +1,87 @@ +# Slack 봇 설치 URL 및 Event 수신 구조 분석 + +## 작성일: 2025-09-02 +## 작성자: 51123 서버 관리자 +## 이슈: Slack 봇 설치 URL 직접 생성 및 Event URL 자동 설정 방안 + +--- + +## 1. 현황 분석 + +### 1.1 구현 완료 항목 +- **OAuth 엔드포인트**: `/auth/slack/passport/install` (app/providers/slack.py:387) +- **콜백 처리**: `/auth/slack/passport/callback` (app/providers/slack.py:456) +- **Event 라우터**: `/slack/events/router` (app/api/slack_router.py:49) +- **환경변수**: SLACK_CLIENT_ID, SLACK_CLIENT_SECRET 설정됨 +- **DB 테이블**: slack_workspaces, slack_user_mapping 정상 존재 + +### 1.2 문제점 +- **State 저장**: 메모리 딕셔너리(oauth_states) 사용 → 직접 URL 생성 시 검증 실패 +- **workspace_id**: 하드코딩 (app/providers/slack.py:422) → 실제 매핑 구현 필요 +- **Event URL**: 봇 설치와 별개로 Slack App 설정에서 수동 등록 필요 + +## 2. 해결 방안 + +### 2.1 State 관리 개선 +```python +# 현재: 메모리 딕셔너리 +oauth_states[state] = {...} # line 436 + +# 개선: Redis 사용 (이미 구현된 Redis 활용) +await redis_client.setex(f"oauth:state:{state}", 300, json.dumps(state_data)) +``` + +### 2.2 Event URL 자동 설정 (Manifest API) +```python +# 필요 환경변수 +SLACK_APP_ID = "A..." # Slack App ID +SLACK_APP_CONFIG_TOKEN = "xapp-..." # apps.manifest:write 스코프 + +# Manifest 업데이트 (봇 설치 콜백 후 1회) +manifest = { + "settings": { + "event_subscriptions": { + "request_url": "https://auth.ro-being.com/slack/events/router", + "bot_events": ["app_mention", "message.channels", "message.groups", "message.im"] + } + } +} +``` + +### 2.3 직접 URL 생성 +```bash +# OAuth URL 구조 +https://slack.com/oauth/v2/authorize? +client_id=9073915808149.9085704341778& +scope=chat:write,channels:read,channels:history,groups:read,groups:history,im:read,im:history,users:read,team:read,files:read,app_mentions:read& +redirect_uri=https://auth.ro-being.com/auth/slack/passport/callback& +state={RANDOM_STATE} +``` + +## 3. 실행 계획 + +### 3.1 즉시 적용 가능 +1. Slack App 설정에서 Event URL 수동 등록 (1회) +2. 현재 코드로 봇 설치 진행 가능 + +### 3.2 코드 개선 필요 +1. Redis로 state 저장 로직 변경 +2. workspace_id 하드코딩 제거 +3. Manifest API 자동화 스크립트 추가 (선택) + +## 4. 중요 발견사항 + +### 4.1 Event URL 관련 +- OAuth 설치 ≠ Event URL 설정 (별개 프로세스) +- Manifest API로 자동 업데이트 가능 (apps.manifest.update) +- url_verification 처리 이미 구현됨 (slack_router.py:76) + +### 4.2 아키텍처 +- Gateway 불필요: Slack은 team_id로 라우팅 가능 +- 단일 Event URL로 모든 워크스페이스 처리 +- Interactivity/Slash Commands 없이도 기본 기능 충분 + +## 5. 참고사항 +- Event URL: `https://auth.ro-being.com/slack/events/router` (api 접두사 없음) +- DB 스키마: DOCS 문서 업데이트 완료 (tables.md) +- Python 모델: SlackWorkspace의 workspace_id는 실제로 company_id 사용 \ No newline at end of file