슬랙봇으로 업무 흐름 자동화하기
출처: https://m.youtube.com/watch?v=dyENPJdtsmQ · 마량 maryang · 31:10 · 2024-05-14
요지
- 봇은 사람이 반복하던 작업을 대신 수행하는 프로그램이며, 슬랙봇은 그 프로그램의 알림과 명령 인터페이스로 슬랙을 사용한다.
- 전 직원이 상시 사용하는 메신저를 업무 자동화의 공통 창구로 삼으면, 사용자가 여러 시스템을 직접 방문하거나 사용법을 익혀야 하는 부담을 줄일 수 있다.
- 알림만 보내려면 Incoming Webhook이 가장 간단하고, 양방향 상호작용이나 외부 시스템 연동이 필요하면 Bolt 또는 Slack SDK로 서버를 구현한다.
- Slack 앱과 서버는 토큰으로 연결하며, 이벤트 구독, OAuth 권한 범위와 외부 접근 가능 여부를 함께 설정해야 실제로 작동한다.
- 가치 있는 슬랙봇은 기술에서 출발하기보다 휴가 안내, 예약 조회, 채널 관리처럼 여러 사람이 반복하는 업무 흐름에서 자동화 후보를 찾는 데서 출발한다.
개요
슬랙봇은 별개의 업무 시스템을 새로 만드는 것이라기보다, 기존 시스템의 기능을 슬랙이라는 공통 인터페이스에 연결하는 도구다. 외부 시스템에서 발생한 일을 슬랙으로 알리거나, 사용자가 슬랙에서 내린 명령을 서버가 받아 데이터베이스·GitHub·Jira·사내 API 등에 전달할 수 있다.
핵심 가치는 접근성에 있다. 특정 데이터베이스나 분석 도구를 다룰 줄 모르는 사람도 슬랙 메시지나 명령만으로 필요한 정보를 얻을 수 있다. 조직 구성원이 이미 오래 사용하는 도구 안에서 알림 수신과 간단한 조작이 이어지므로 업무의 맥락 전환도 줄어든다.
배경 / 사전 지식
봇은 반복적인 작업을 사람 대신 수행하는 소프트웨어다. GitHub Actions의 빌드·배포, Jira Automation의 이슈 상태 변경, 고객 상담 챗봇, 티켓 구매 매크로 등이 넓은 의미의 봇에 해당한다. 자동화 자체는 중립적인 기술이며, 조직의 생산성을 높일 수도 있고 불공정한 선점에 악용될 수도 있다.
슬랙봇을 이해하려면 다음 구성 요소를 구분해야 한다.
- Slack 워크스페이스: 조직의 사용자와 채널이 존재하는 공간이다.
- Slack 앱: 슬랙과 외부 프로그램 사이의 접점이다. 워크스페이스에 설치되며 봇 사용자, 권한과 이벤트 설정을 갖는다.
- 봇 사용자: 채널에서 이름과 아이콘을 가지고 메시지를 보내거나 멘션을 받는 앱의 대표 사용자다.
- 애플리케이션 서버: 실제 업무 규칙을 실행하고 외부 서비스와 통신하는 코드다.
- 외부 서비스: GitHub, Jira, 데이터베이스, 사내 인사·예약·운항 시스템 등 자동화 대상이다.
개발자는 HTTP와 REST API, 환경 변수, 서버 배포의 기초를 알고 있으면 좋다. Node.js 예제를 실행하려면 Node.js 18 이상과 npm이 필요하며, Slack API 사이트에서 앱을 만들고 개발용 워크스페이스에 설치할 권한도 필요하다.
핵심 개념
슬랙은 봇의 인터페이스다
업무를 수행하는 주체는 서버 프로그램이고, 슬랙은 명령과 결과가 오가는 통로다. 서버가 독립적으로 스케줄 작업을 실행한 뒤 슬랙으로 결과를 보낼 수도 있고, 사용자가 슬랙에 메시지를 남기면 서버가 이를 받아 외부 시스템을 조작할 수도 있다.
Incoming Webhook
Incoming Webhook은 Slack 앱이 발급한 전용 URL에 HTTP 요청을 보내 채널에 메시지를 게시하는 방식이다. 외부 서비스가 Webhook URL 호출을 지원하거나 간단한 REST 요청을 보낼 수 있다면 별도의 Slack 통신 서버 없이도 알림을 구현할 수 있다.
장점은 설정과 구현이 매우 간단하다는 것이다. 반면 사용자 메시지를 받거나 채널을 만들고 구성원을 초대하는 등 복잡한 동작에는 적합하지 않다. 따라서 요구사항이 단방향 알림뿐인지 먼저 확인해야 한다.
Bolt 프레임워크
Bolt는 Slack과의 통신에 필요한 서버 구성과 이벤트 처리를 추상화한 공식 프레임워크다. JavaScript·Python·Java를 지원한다. 앱 객체에 봇 토큰을 연결한 뒤 message, app_mention 같은 이벤트 리스너를 등록하고 say 등의 메서드로 답할 수 있어 빠르게 봇을 만들기 좋다.
Bolt는 서버의 기본 구조까지 제공하므로 구현 편의성이 높지만, 기존 애플리케이션의 프레임워크와 구조를 세밀하게 유지하려는 조직에는 제약이 될 수 있다.
Slack SDK
Slack SDK는 메시지 전송과 API 호출 같은 기능을 제공하는 라이브러리 모음이다. 서버 프레임워크는 포함하지 않으므로 Express, NestJS, Spring, Django, Flask 등 원하는 프레임워크와 결합한다. 서버 환경을 자유롭게 구성하거나 기존 서비스에 Slack 기능만 추가할 때 적합하다.
Node.js에서는 @slack/web-api의 WebClient를 만들고 봇 토큰을 전달한 뒤 chat.postMessage 같은 Web API 메서드를 호출한다. 각 메서드의 매개변수와 필요한 권한은 Slack API 레퍼런스에서 확인해야 한다.
권한 범위와 토큰
Slack API는 토큰에 부여된 OAuth scope로 가능한 작업을 제한한다. 예를 들어 봇이 메시지를 게시하려면 일반적으로 chat:write가 필요하다. 사용할 Web API 메서드의 문서에서 요구 scope를 확인하고 OAuth & Permissions에서 봇 토큰 권한을 추가한 뒤 앱을 다시 설치해야 변경된 권한이 반영된다.
봇 토큰과 앱 레벨 토큰은 용도가 다르다. 봇 토큰은 봇 사용자 권한으로 Web API를 호출할 때 사용하고, 앱 레벨 토큰은 Socket Mode처럼 앱 전체 수준의 연결에 사용한다. 두 토큰은 소스 코드나 저장소에 넣지 않고 환경 변수와 비밀 관리 도구로 보관해야 한다.
Events API와 Socket Mode
공개 HTTPS 엔드포인트를 운영할 수 있다면 Event Subscriptions에서 요청 URL과 구독할 이벤트를 등록한다. 채널 메시지나 앱 멘션 같은 사건이 발생하면 Slack이 서버 URL을 호출한다.
사내망이나 방화벽 때문에 Slack이 서버로 들어오는 요청을 보낼 수 없다면 Socket Mode를 사용할 수 있다. 서버가 Slack으로 WebSocket 연결을 먼저 열고 그 연결을 통해 이벤트를 받으므로 공개 수신 URL이 필요하지 않다. 이때 앱 레벨 토큰과 Socket Mode용 클라이언트를 사용한다.
작동 원리
- Slack API 사이트에서 새 앱을 만들고 대상 워크스페이스를 선택한다.
- 앱을 대표할 봇 사용자의 표시 이름과 아이콘을 설정한다.
- 필요한 Web API와 이벤트를 정하고 문서에서 요구하는 OAuth scope를 조사한다.
- OAuth & Permissions에 scope를 추가하고 앱을 워크스페이스에 설치한다.
- 발급된 봇 토큰을 서버의 비밀 환경 변수로 저장한다.
- 단방향 알림만 필요하면 Incoming Webhook을 발급해 외부 서비스가 URL을 호출하게 한다.
- 양방향 기능이 필요하면 Bolt 또는 SDK로 서버를 만들고 봇 토큰을 사용해 Slack 앱과 연결한다.
- 공개 엔드포인트를 사용할 수 있으면 Event Subscriptions에 요청 URL과 이벤트를 등록한다. 외부 요청을 받을 수 없으면 Socket Mode를 활성화한다.
- 서버는 Slack 이벤트를 업무 명령으로 해석하여 데이터베이스나 외부 API를 호출한다.
- 처리 결과를
chat.postMessage등의 메서드로 원래 채널이나 지정된 채널에 돌려준다.
예를 들어 휴가 안내 봇은 매일 오전 9시에 스케줄러가 인사 시스템에서 당일 휴가자를 조회하고 Slack 서버에 전달한 뒤 지정 채널에 명단을 게시한다. 항공 예약 조회 봇은 사용자의 명령에서 날짜와 노선을 추출하고 예약 시스템을 조회하여 잔여 좌석을 답한다. 운항 관리 봇은 다음 날 비행편별 채널을 만들고 승무원을 초대한 뒤, 운항 종료 후 채널을 보관하고 평가 링크를 전달할 수 있다.
코드 예시
다음은 Bolt for JavaScript로 앱 멘션에 응답하는 최소 예제다. Slack 앱에 app_mentions:read와 chat:write 권한을 추가하고 Socket Mode를 활성화한 뒤, connections:write 권한이 있는 앱 레벨 토큰을 발급한다.
mkdir slack-bot-demo
cd slack-bot-demo
npm init -y
npm install @slack/bolt
export SLACK_BOT_TOKEN='xoxb-...'
export SLACK_APP_TOKEN='xapp-...'
app.js를 다음과 같이 작성한다.
const { App } = require('@slack/bolt');
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
appToken: process.env.SLACK_APP_TOKEN,
socketMode: true,
});
app.event('app_mention', async ({ event, client, logger }) => {
try {
await client.chat.postMessage({
channel: event.channel,
thread_ts: event.ts,
text: `요청을 받았습니다: ${event.text}`,
});
} catch (error) {
logger.error(error);
}
});
(async () => {
await app.start();
console.log('Slack bot is running');
})();
다음 명령으로 실행한다.
node app.js
Slack 앱 설정의 Event Subscriptions에서 app_mention 봇 이벤트를 구독한 뒤 앱을 채널에 초대한다. 사용자가 채널에서 봇을 멘션하면 Bolt가 이벤트를 수신하고, chat.postMessage가 같은 메시지의 스레드에 응답한다. 실제 업무 봇에서는 event.text를 곧바로 명령으로 실행하지 말고 허용된 명령인지 검증한 뒤 별도의 서비스 계층에서 외부 API를 호출해야 한다.
알림만 필요하다면 Incoming Webhook으로 더 단순하게 구현할 수 있다.
curl -X POST \
-H 'Content-type: application/json' \
--data '{"text":"오늘의 자동화 작업이 완료되었습니다."}' \
"$SLACK_WEBHOOK_URL"
함정·실수
- 앱 생성만으로 동작한다고 생각한다: Slack 앱은 통신 접점일 뿐이다. 복잡한 업무 로직은 별도의 서버나 자동화 서비스에 구현해야 한다.
- 필요한 scope를 빠뜨린다: API 호출이 실패하면 해당 메서드 문서의 required scope를 확인한다. 권한 변경 후 앱 재설치가 필요한 경우도 놓치지 않는다.
- 봇 토큰과 앱 토큰을 혼동한다: Web API 호출에는 봇 토큰, Socket Mode 연결에는 앱 레벨 토큰을 사용한다.
- 사내 서버를 Event Subscriptions URL로 등록한다: Slack에서 접근할 수 없는 내부 URL은 호출되지 않는다. 공개 HTTPS 엔드포인트, 보안 프록시 또는 Socket Mode를 선택한다.
- Webhook URL이나 토큰을 코드에 넣는다: URL 자체가 메시지 게시 권한을 가지므로 노출되면 즉시 폐기하고 재발급해야 한다.
- 과도한 권한을 한꺼번에 부여한다: 편의를 위해 넓은 scope를 주면 침해 사고의 영향이 커진다. 구현할 기능에 필요한 최소 권한만 부여한다.
- 중복 이벤트를 고려하지 않는다: 네트워크 재시도로 같은 이벤트가 다시 도착할 수 있다. 이벤트 ID를 저장해 중복 처리를 방지하고, 외부 시스템 변경 작업은 멱등하게 설계한다.
- Slack의 입력을 신뢰한다: 사용자 권한, 채널, 명령 형식과 인자를 검증하지 않으면 민감 정보 조회나 위험한 작업이 실행될 수 있다.
- API 제한과 실패를 무시한다: rate limit, 외부 API 지연과 부분 실패를 고려해 재시도, 백오프, 타임아웃과 오류 알림을 구현한다.
베스트 프랙티스
자동화 대상은 “어떤 봇을 만들까?”보다 “여러 사람이 되풀이하며 병목을 겪는 업무가 무엇인가?”라는 질문으로 찾는다. 빈도, 소요 시간, 참여 인원과 오류 비용이 큰 업무부터 후보로 삼고, 담당자와 함께 현재 절차와 예외 상황을 먼저 정리한다.
구현 방식은 가장 단순한 수단부터 선택한다. 단방향 알림이면 Incoming Webhook, Slack 중심의 새 봇이면 Bolt, 기존 서버에 통합하거나 프레임워크 선택권이 중요하면 SDK가 적합하다. 공개 요청 URL을 안전하게 제공할 수 없을 때만 Socket Mode를 선택한다.
운영 단계에서는 다음 원칙이 유용하다.
- 개발·스테이징·운영 앱과 토큰을 분리한다.
- 토큰은 환경 변수보다 전용 비밀 관리 시스템을 우선 사용하고 주기적으로 교체한다.
- Slack 요청의 서명을 검증하고, Socket Mode에서도 사용자와 채널 권한을 확인한다.
- 오래 걸리는 작업은 이벤트 수신 즉시 확인 응답을 보낸 뒤 작업 큐에서 비동기로 처리한다.
- 사용자에게 처리 시작, 성공, 실패와 복구 방법을 명확히 알려 조용한 실패를 막는다.
- 이벤트 ID, 요청자, 실행한 명령과 결과를 감사 로그에 남기되 토큰과 민감 정보는 기록하지 않는다.
- 메시지는 짧고 행동 가능하게 작성하며, 복잡한 입력에는 버튼·모달·슬래시 명령을 활용한다.
- 조직 전체에 배포하기 전에 작은 채널에서 시험하고 실제 사용자의 피드백으로 업무 규칙을 다듬는다.
슬랙봇의 성과는 코드의 복잡도가 아니라 사람이 하던 단계가 얼마나 줄었는지, 처리 시간과 오류가 얼마나 감소했는지로 평가한다. 자동화가 잘못된 결과를 만들 때 사람이 중단하거나 수정할 수 있는 수동 절차도 함께 유지해야 한다.
참고
- Slack API 앱 관리 페이지:
api.slack.com/apps - Slack API 문서와 Web API 메서드·이벤트·OAuth scope 레퍼런스
- Bolt for JavaScript·Python·Java 문서
- Slack SDK for Node.js·Python·Java 문서
- 영상에서 사례로 언급한 Polly, Donut, Jira의 Slack 연동
- 영상에서 배포 자동화 사례의 출처로 언급한 뱅크샐러드 기술 블로그