DOCS/journey/research/260221_companyx_slack_메시지_전송_방법.md

2.8 KiB

Company-X Slack 메시지 전송 방법 (운영 검증)

작성일

  • 2026-02-21 (KST)

목적

  • Company-X 팀의 로빙 채널에 테스트 메시지를 안전하게 전송하는 방법을 기록한다.
  • Gateway 경유 실패 시, 원인 분리용 직접 전송 절차를 남긴다.

대상

  • Slack Team: T09C98KB933 (Company-X Team)
  • Slack Channel: C09CP4MDX71 (robeing-team)

확인된 전송 경로

  • 기본 경로: Slack -> robeing-gateway(/slack/events) -> rb8001(/api/slack/events) -> skill-slack -> Slack
  • 우회 경로(원인 분리): slack_workspace.bot_token 조회 후 chat.postMessage 직접 호출

실측 결과 (2026-02-21)

  • Gateway /slack/events 경유: 500 Internal Server Error
  • 직접 chat.postMessage 호출: 성공 (ok: true)
  • 메시지: hello world
  • Slack ts: 1771672969.619299
  • 시각:
    • UTC: 2026-02-21 11:22:49
    • KST: 2026-02-21 20:22:49

재현 절차

  1. Gateway 헬스 확인
curl -i -sS -m 5 http://127.0.0.1:8100/healthz | sed -n '1,8p'
  1. Company-X 팀 토큰 존재 확인 (slack_workspace)
docker exec -i robeing-gateway python - <<'PY'
import asyncio, os, asyncpg
async def main():
    dsn = os.environ['DATABASE_URL'].replace('postgresql+asyncpg://', 'postgresql://')
    conn = await asyncpg.connect(dsn)
    row = await conn.fetchrow("""
        SELECT slack_team_id, left(bot_token,12) token_prefix
        FROM slack_workspace
        WHERE slack_team_id='T09C98KB933'
        LIMIT 1
    """)
    print(dict(row) if row else None)
    await conn.close()
asyncio.run(main())
PY
  1. 채널 메시지 전송 (chat.postMessage)
docker exec -i robeing-gateway python - <<'PY'
import asyncio, os, asyncpg, requests
TEAM_ID='T09C98KB933'
CHANNEL='C09CP4MDX71'
TEXT='hello world'
async def get_token():
    dsn = os.environ['DATABASE_URL'].replace('postgresql+asyncpg://', 'postgresql://')
    conn = await asyncpg.connect(dsn)
    row = await conn.fetchrow('SELECT bot_token FROM slack_workspace WHERE slack_team_id=$1 LIMIT 1', TEAM_ID)
    await conn.close()
    return row['bot_token'] if row else None
token = asyncio.run(get_token())
resp = requests.post(
    'https://slack.com/api/chat.postMessage',
    headers={'Authorization': f'Bearer {token}', 'Content-Type': 'application/json; charset=utf-8'},
    json={'channel': CHANNEL, 'text': TEXT},
    timeout=10,
)
print(resp.status_code)
print(resp.text)
PY

운영 주의사항

  • 봇 토큰 평문을 문서/로그/커밋에 남기지 않는다.
  • 실패 원인 분리는 다음 순서로 한다.
    1. Gateway health
    2. slack_workspace 팀/토큰 매핑
    3. Slack 사용자 UUID 매핑
    4. rb8001 /api/slack/events 응답코드
  • 직접 chat.postMessage는 장애 분리용 검증으로만 사용하고, 정상 운영은 Gateway 경유 경로를 우선한다.