DOCS/troubleshooting/250903_slack_multi_workspace_token_issue.md

2.8 KiB

Slack 멀티 워크스페이스 토큰 관리 문제

작성일: 2025-09-03

작성자: 51123 서버 관리자

상태: 🟡 해결 방안 확정 (구현 대기)

영향: Company-X, GoodGang Labs 워크스페이스 응답 실패


1. 문제 상황

  • 현상: Company-X에서 메시지 수신은 정상, 응답 전송 실패
  • 원인: rb8001이 단일 SLACK_BOT_TOKEN 환경변수만 사용
  • 에러: channel_not_found - 잘못된 토큰으로 채널 접근

2. 토큰 현황 (2025-09-03 DB 확인)

  • Robeing (T0925SXPS4D): xoxb-9073915808149-9107868204992-... (DB 등록)
  • Company-X (T097FCTDVEX): xoxb-9253435471507-... (DB 등록)
  • GoodGang Labs (T035VFRKCN6): xoxb-3199535658754-... (DB 등록)
  • 문제: rb8001이 환경변수 토큰만 사용, DB 토큰 미조회
  • DB 구조: 모든 팀이 container_port 8001 (rb8001 공유)

3. 상세 분석

3.1 이벤트 수신 ( 정상)

  • U09BQSN72UT(김종태) 봇 멘션: <@U09DWLARFQQ> 하이
  • app_mention 이벤트 정상 수신

3.2 처리 과정 ( 정상)

  • UUID 변환 성공
  • 응답 생성 성공: "김종태님, 안녕하세요! 로빙입니다."
  • ChromaDB/PostgreSQL 저장 성공

3.3 응답 전송 ( 실패)

ERROR: Failed to send final response: The request to the Slack API failed.
The server responded with: {'ok': False, 'error': 'channel_not_found'}

4. 해결 방안 (2025-09-03 확정)

4.1 Gateway 경유 방식 채택

  • Slack Event URL을 Gateway(8100)로 변경
  • Gateway에서 team_id별 토큰 조회 및 주입
  • rb8001은 헤더에서 토큰 읽어 사용

4.2 구현 상세

  1. nginx 설정: /api/* → Gateway(8100) 프록시
  2. Slack App: Event URL을 https://ro-being.com/api/slack/events로 변경
  3. Gateway: team_id로 DB 조회, 헤더에 토큰 추가
  4. rb8001: 헤더 우선, 환경변수 폴백

5. 구현 필요 코드 (로컬 개발자)

5.1 Gateway 추가 (robeing-gateway)

@app.post("/api/slack/events")
async def handle_slack_event(request: Request):
    # Slack 서명 검증
    verify_slack_signature(request)
    
    # team_id별 토큰 조회
    body = await request.json()
    team_id = body.get("team_id")
    
    result = await db.fetch_one(
        "SELECT bot_token FROM slack_workspaces WHERE team_id = :team_id",
        {"team_id": team_id}
    )
    
    # rb8001로 전달
    headers = {
        "X-Slack-Bot-Token": result["bot_token"] if result else None,
        "Content-Type": "application/json"
    }
    
    return await forward_to_rb8001("/api/slack/events", body, headers)

5.2 rb8001 수정 (slack_handler.py)

# 기존: 환경변수만 사용
slack_token = os.environ.get("SLACK_BOT_TOKEN")

# 수정: 헤더 우선, 환경변수 폴백
slack_token = request.headers.get("X-Slack-Bot-Token") \
    or os.environ.get("SLACK_BOT_TOKEN")