콘텐츠로 이동

Slack 통합 설정

이 가이드에서는 Control Center가 앱을 만들게 하거나 직접 앱을 만들어 Slack을 Control Center 워크스페이스에 연결하는 방법을 설명합니다.

처음 안내 방식으로 진행하려면 Slack을 워크스페이스에 브리지를 참고하세요.

  • Control Center 워크스페이스의 owner 또는 admin 역할 — 채팅 앱 연결은 워크스페이스 설정 변경입니다
  • Slack 워크스페이스에서 앱을 만들고 설치할 권한
  • 공개적으로 접근 가능한 것 없음: 연결은 아웃바운드(Socket Mode)이므로 서버에 인바운드 포트, 터널, 도메인이 필요하지 않습니다
방법 직접 준비하는 것 Control Center가 하는 일
안내 방식 앱 구성 토큰(xoxe-…) 올바른 스코프, 이벤트, Socket Mode, 슬래시 명령으로 앱을 만들고, Slack에 API가 없는 두 단계를 넘겨줍니다
Slack에서 만들기 없음 같은 구성이 미리 채워진 상태로 Slack을 엽니다. 워크스페이스를 고르고 확인하면 됩니다
직접 만들기 완성한 앱의 토큰 검증하고 연결합니다

안내 방식만이 앱을 Control Center에서 관리할 수 있는 상태로 남기며, 채팅 봇 사용자 지정이 가능해지는 이유가 바로 이것입니다. Slack에서 만들기로 만든 앱은 나중에 연결 대화상자에서 구성 토큰을 붙여 넣어 관리 대상으로 승격할 수 있습니다.

“Control Center의 Slack 앱을 설치” 버튼은 일부러 없습니다. 배포되는 Slack 앱을 설치하려면 공유 클라이언트 시크릿이 필요하고(Slack에는 PKCE가 없습니다), Socket Mode는 앱의 이벤트를 여러 연결에 무작위로 분산하므로, 앱 하나를 공유하면 워크스페이스의 메시지가 다른 사람의 서버로 전달됩니다. 그래서 워크스페이스마다 자체 앱을 소유하며, 이 세 가지 방법은 그 작업을 얼마나 줄여 주는지에 관한 것입니다.

방법 A: Control Center가 앱을 만들게 하기

섹션 제목: “방법 A: Control Center가 앱을 만들게 하기”
  1. api.slack.com/apps에서 앱 구성 토큰 쌍을 생성하고 리프레시 토큰(xoxe-…)을 복사합니다
  2. Control Center에서 설정 → 워크스페이스 → 일반으로 이동해 채팅 브리지 카드까지 스크롤합니다
  3. Slack 블록에서 대신 앱 만들기를 클릭합니다
  4. 토큰을 붙여 넣고 앱 이름, 봇 이름, 설명, 슬래시 명령을 조정한 뒤 앱 만들기를 클릭합니다
  5. 대화상자에 표시되는 나머지 두 단계를 따릅니다. 각 단계는 Slack으로 이동하는 링크입니다:
    • Basic Information → App-Level Tokens: connections:write 스코프로 토큰을 생성합니다(xapp-…)
    • Install App: 워크스페이스에 설치하고 Bot User OAuth Token(xoxb-…)을 복사합니다
  6. 자격 증명 붙여넣기를 클릭하고 연결로 계속합니다

구성 토큰은 사용할 때마다 회전합니다. Control Center는 그때그때 회전된 값을 저장하므로, 다시 붙여 넣을 필요가 없습니다.

방법 B: Slack에서 미리 채워진 상태로 만들기

섹션 제목: “방법 B: Slack에서 미리 채워진 상태로 만들기”

같은 앱을 구성 토큰 없이 만듭니다 — Slack이 매니페스트가 모두 채워진 자체 생성 화면을 열어 줍니다.

  1. Control Center에서 설정 → 워크스페이스 → 일반으로 이동해 채팅 브리지 카드까지 스크롤합니다
  2. Slack 블록에서 대신 앱 만들기를 클릭합니다
  3. 앱 이름, 봇 이름, 설명, 슬래시 명령을 조정합니다 — 이 값들은 링크에 함께 실립니다
  4. Slack에서 만들기를 클릭합니다. 브라우저에서 구성이 미리 채워진 Slack 앱 생성 페이지가 열립니다
  5. Slack 워크스페이스를 선택하고 확인합니다. 스코프, 이벤트, Socket Mode, 슬래시 명령은 이미 올바르게 설정되어 있습니다
  6. Control Center로 돌아와 대화상자에 표시되는 나머지 두 단계를 따릅니다:
    • Basic Information → App-Level Tokens: connections:write 스코프로 토큰을 생성합니다(xapp-…)
    • Install App: 워크스페이스에 설치하고 Bot User OAuth Token(xoxb-…)을 복사합니다
  7. 자격 증명 붙여넣기를 클릭하고 연결로 계속합니다

Slack은 자기가 어떤 앱을 만들었는지 알려 주지 않으므로 Control Center는 앱 id를 모르고, 6단계의 링크는 그 앱으로 바로 가지 않고 앱 목록으로 이동합니다. 봇 맞춤 설정에는 구성 토큰이 필요합니다.

api.slack.com/apps에서 앱을 만들고 다음과 같이 설정합니다.

Socket Mode: 사용하도록 설정하고 모든 요청 URL을 비워 둡니다. Slack은 Socket Mode와 웹훅 전달을 동시에 요구하는 매니페스트를 거부합니다.

봇 토큰 스코프(OAuth & Permissions):

app_mentions:read
assistant:write
channels:history
chat:write
commands
groups:history
im:history
users:read
users:read.email

이벤트 구독(봇 이벤트):

app_home_opened
app_mention
message.channels
message.groups
message.im

message.channels와 message.groups가 있어야 이미 브리지된 Slack 스레드 안의 _답장_이 동작합니다. 이것들이 없으면 첫 멘션만 도착합니다.

슬래시 명령: /cc(이름은 무엇이든 됩니다 — 브리지는 마지막으로 호출된 명령을 사용합니다).

App Home: Messages 탭을 사용하도록 설정하고 쓰기 가능한 상태로 둡니다. 그래야 멤버가 봇에게 DM을 보낼 수 있습니다.

토큰: connections:write로 앱 수준 토큰을 생성한 뒤 앱을 설치하고 봇 사용자 OAuth 토큰을 복사합니다.

  1. 설정 → 워크스페이스 → 일반으로 이동해 채팅 브리지 카드까지 스크롤합니다
  2. Slack 블록에서 Slack 연결을 클릭합니다
  3. 다음 필드를 채웁니다:
필드 값 Slack에서 어디에 있는지
봇 토큰 xoxb-… OAuth & Permissions → Bot User OAuth Token
앱 수준 토큰 xapp-… Basic Information → App-Level Tokens (connections:write)
앱 구성 토큰 (선택) xoxe-… api.slack.com/apps의 앱 구성 토큰 쌍

값마다 접두사가 전송 전에 양쪽에서 확인되므로, 잘못된 칸에 붙여 넣은 값은 어느 쪽이든 같은 문장으로 거부됩니다.

  1. 연결을 클릭합니다

Control Center는 무엇이든 저장하기 전에 Slack의 auth.test로 봇 토큰을 검증하므로, 오타는 조용히 동작하지 않는 소켓이 되는 대신 곧바로 보고됩니다. 앱 수준 토큰은 소켓을 열어야만 확인할 수 있으므로, 잘못된 값은 잠시 뒤 같은 행에 연결 오류로 나타납니다.

선택 항목인 앱 구성 토큰이 없어도 연결은 잘 동작합니다 — 다만 Control Center에서 봇을 편집할 수 없습니다.

  • 자격 증명을 워크스페이스 자체 디렉터리에, 그 데이터베이스 옆에 저장하며, 소유자만 읽을 수 있습니다. 자격 증명이 클라이언트로 다시 전달되는 일은 없습니다
  • 이 워크스페이스를 위해 Socket Mode 연결 하나를 열고 멘션, Slack 스레드 답장, DM, 슬래시 명령을 받기 시작합니다
  • 이전에 브리지된 모든 Slack 스레드를 다시 활성화하므로, 다시 연결하면 기존 대화가 끊기지 않고 이어집니다
  • 채팅 앱이 없는 워크스페이스에는 비용이 전혀 들지 않습니다: 소켓도, 타이머도, 트래픽도 없습니다

Slack 행에는 상태 태그가 표시됩니다: 실시간, 연결 중…, 연결 오류(옆에 Slack 자체 오류가 함께 표시됨), 연결되지 않음 중 하나입니다. 처음부터 끝까지 확인하려면:

  1. Slack에서 봇을 채널에 초대합니다: /invite @your-bot-name
  2. 요청과 함께 봇을 멘션합니다
  3. Slack 스레드 답장이 나타나고 Control Center에 대응하는 스페이스가 생깁니다

브리지를 사용하려는 멤버는 각자 자신의 계정을 연결합니다 — Slack 계정 연결을 참고하세요.

스트리밍되는 텍스트 위에는 단계마다 행이 하나씩 있는 카드 하나가 묶여 있습니다. 준비 단계는 제목이 Working on it…에서 Cloning …으로, 다시 Starting the agent…로 바뀌는 행 하나입니다. 추론은 Thinking… 행을 추가하며, 그 단계가 끝나면 짧은 생각이 그 행에 나타날 수 있습니다. 도구마다 각자 행을 갖습니다(Read lib/main.dart). 답변은 카드 아래에 평범한 텍스트로 도착합니다. 카드는 턴이 끝나면 완료로, 실행이 실패하거나 중단되거나 턴 한도에 도달하면 오류로 바뀝니다.

카드는 봇이 멘션을 접수하는 순간 — Working on it… — 시작하므로, 워크스페이스가 아직 만들어지는 동안에도 Slack 스레드가 조용하지 않습니다. Slack 채널에서 보낸 첫 멘션이 대화를 만들고, 대화를 만드는 과정에서 에이전트가 작업할 리포지토리를 클론하므로, 그 준비 행은 Cloning acme/widgets…, 이어서 Setting up Reviewer…, 이어서 Starting the agent…를 거치고, 에이전트가 실제로 추론하기 시작하면 Thinking… 행이 됩니다. 큰 리포지토리에서는 이 첫 준비에 시간이 걸립니다. 카드는 에이전트가 요청을 무시하는 것이 아니라 작업 중임을 알 수 있게 해 줍니다. 같은 Slack 스레드에서 보낸 이후 멘션도 여전히 Working on it…으로 시작하지만, 워크스페이스가 이미 있으므로 클론 단계는 건너뜁니다.

추론은 여러 줄의 텍스트로, 도구 출력은 Control Center를 절대 벗어나지 않습니다 — Thinking… 행의 생각은 트랜스크립트가 아니라 짧은 한 줄입니다. 카드의 View in Control Center는 전체 대화를 데스크톱 앱에서 엽니다 — 링크는 여러분의 Control Center 서버로 가고, 그 서버가 브라우저를 앱으로 넘깁니다.

클릭해도 아무 일도 일어나지 않으면, 메시지를 보낸 서버에 클릭한 머신에서 접근할 수 없거나(예를 들어 루프백 전용 서버를 휴대폰에서 클릭한 경우), 그곳에서 Control Center가 실행 중이 아닙니다. 접근 가능한 주소가 없는 서버는 아무 데도 이어지지 않는 버튼 대신 버튼이 없는 카드를 보냅니다.

연결 대화상자에 새 값을 다시 붙여 넣고 연결을 클릭합니다. 연결하면 이 워크스페이스에서 실행 중이던 연결이 교체되므로, 새 자격 증명으로 소켓이 다시 연결됩니다.

필수 토큰 두 개는 연결할 때마다 있어야 합니다. 선택 항목인 앱 구성 토큰은 입력란을 비워 두면 저장된 값을 유지하므로, 봇 토큰을 회전해도 앱을 편집할 수 있는 능력을 잃지 않습니다.

Slack 행에서 연결 해제를 클릭합니다(관리자만 가능). 소켓이 닫히고 자격 증명은 사라집니다.

스페이스와 사용자 연결은 일부러 유지됩니다: 같은 앱을 다시 연결하면 브리지된 모든 Slack 스레드가 복원됩니다. 이들은 워크스페이스 범위의 행이므로, 워크스페이스를 삭제하면 어차피 함께 사라집니다.

행에 “연결 오류”가 표시됩니다

섹션 제목: “행에 “연결 오류”가 표시됩니다”

태그 옆에 표시된 오류를 읽어 보세요. 거부된 자격 증명(invalid_auth, not_authed, token_revoked, account_inactive)은 종결 상태입니다 — 브리지는 재시도를 멈추고 새 토큰을 기다립니다. 폐기된 토큰을 영원히 재시도하면 속도 제한만 받기 때문입니다. 연결 대화상자에서 토큰을 다시 붙여 넣으세요.

missing_scope 오류는 앱이 브리지에 필요한 것보다 적은 스코프로 설치되었다는 뜻입니다. 빠진 스코프를 추가하고 Slack에서 앱을 다시 설치한 뒤 다시 연결하세요.

일시적인 문제(끊긴 소켓, Slack의 일시적 장애)는 30초로 상한을 둔 지수 백오프로 스스로 다시 연결하며, Slack의 일상적인 소켓 교체는 그 백오프를 키우지 않습니다.

  • 봇이 채널에 있나요? Slack은 멤버인 앱에만 채널 메시지를 전달합니다. /invite @your-bot-name을 실행하세요
  • 연결되어 있나요? 연결하지 않은 멤버는 해당 Slack 스레드에서 연결 방법을 설명하는 답장을 받습니다. Slack 계정 연결을 참고하세요
  • 쓰기 역할을 가진 워크스페이스 멤버인가요? viewer나 guest에게는 자신의 역할이 읽기 전용이라고 알려 줍니다. 브리지는 귀속시킬 수 없는 사람을 대신해 작업을 시작하지 않습니다
  • 워크스페이스에 에이전트가 있나요? 에이전트가 없으면 메시지는 저장되지만 답할 사람이 없습니다

채널에서는 답하지만 일반 메시지는 무시합니다

섹션 제목: “채널에서는 답하지만 일반 메시지는 무시합니다”

의도된 동작입니다. DM이 아닌 곳에서 브리지는 봇을 멘션한 메시지나, 이미 자신이 소유한 Slack 스레드 안의 답장에만 반응합니다. 나머지는 다른 사람들의 대화입니다.

답변이 스트리밍되지 않고 큰 메시지 하나로 도착합니다

섹션 제목: “답변이 스트리밍되지 않고 큰 메시지 하나로 도착합니다”

그 행에는 “이 Slack 앱은 실시간 스트리밍이 꺼져 있어 답변이 한 메시지로 도착합니다.“라고 표시됩니다. Slack의 스트리밍 답변은 유료 플랜의 Agents & AI Apps 기능이 필요합니다. Slack이 이를 거부하면 브리지는 그 연결이 살아 있는 내내 요청을 그만두고 답변을 통째로 게시합니다. 잃는 것은 없습니다 — 전체 트랜스크립트는 언제나 Control Center에 있습니다.

스트리밍에는 Slack 스레드 앵커도 필요하므로, 자라날 Slack 스레드가 없는 답변은 통째로 게시됩니다. 어느 쪽이든 작업 카드는 여전히 도착합니다: 통째로 게시되는 답변에서는 이미 완성된 상태로 같은 메시지에 실려 갑니다.

Slack의 작업 카드는 스트리밍과 같은 새로운 Agents & AI Apps 표면의 일부이며, Slack은 호출 시점에만 거부합니다. 거부하면 Control Center는 그 연결이 살아 있는 내내 답변을 유지하고 카드를 버립니다 — 상태 줄 없는 답변이 답변 없는 상태 줄보다 낫습니다.

“봇을 수정하려면 Control Center에 앱 구성 토큰이 필요합니다”

섹션 제목: ““봇을 수정하려면 Control Center에 앱 구성 토큰이 필요합니다””

연결에 앱 구성 토큰이 없어 봇 맞춤 설정 행이 비활성화되어 있습니다. 직접 만들었거나 Slack에서 만들기로 만든 앱에서는 이것이 정상입니다 — Slack은 Control Center에 자기가 어떤 앱인지 결코 알려 주지 않습니다. api.slack.com/apps에서 토큰 쌍을 생성하고 리프레시 토큰을 채워 다시 연결하세요.

Slack은 메시지 하나를 40,000자로 제한하므로, 브리지는 39,000자에서 자르고 Control Center로 가는 안내를 덧붙입니다 — 짧아진 답변이 Slack이 아예 거부하는 답변보다 낫습니다. 전체 텍스트는 언제나 스페이스 트랜스크립트에 있습니다.