← All guides

Claude API 슬랙봇 만들기: Bolt.js + Claude 통합 가이드

Bolt.js와 Claude API로 슬랙봇을 만드는 방법 — 앱 설정, 대화 스레딩, 슬래시 커맨드, 비용 관리까지 TypeScript 예제와 함께 설명합니다.

🇺🇸 Read in English →

Claude API 슬랙봇 만들기: Bolt.js + Claude 통합 가이드

Claude API로 슬랙봇을 만들려면 Slack 앱을 생성해 Bot Token과 Signing Secret을 발급받고, @slack/bolt@anthropic-ai/sdk 패키지를 설치한 뒤 두 클라이언트를 연결하면 됩니다. Bolt.js는 Slack의 공식 Node.js 프레임워크로, 이벤트 수신·응답 처리·슬래시 커맨드를 몇 줄로 처리합니다. Claude API는 대화 맥락을 이해하고 자연어로 응답합니다. 이 가이드에서는 슬랙 앱 설정부터 대화 스레딩, 비용 관리까지 프로덕션에 바로 적용 가능한 TypeScript 예제와 함께 설명합니다.


슬랙 앱 설정

1. Slack 앱 생성

api.slack.com/apps에서 Create New App → From scratch를 선택합니다.

앱 이름과 워크스페이스를 지정한 후 아래 권한(OAuth Scopes)을 추가합니다:

Bot Token Scopes:

2. 이벤트 구독 활성화

Event Subscriptions에서 다음 이벤트를 등록합니다:

Request URL은 봇 서버 주소(https://your-domain.com/slack/events)를 입력합니다. 로컬 개발 시에는 ngrok을 사용합니다.

3. 환경변수 설정

SLACK_BOT_TOKEN=xoxb-...        # OAuth & Permissions → Bot User OAuth Token
SLACK_SIGNING_SECRET=...        # Basic Information → App Credentials
SLACK_APP_TOKEN=xapp-...        # Socket Mode 사용 시 (App-Level Tokens)
ANTHROPIC_API_KEY=sk-ant-...

Bolt.js 기본 구조

npm install @slack/bolt @anthropic-ai/sdk dotenv
npm install -D typescript @types/node ts-node
// src/app.ts
import { App, LogLevel } from '@slack/bolt';
import Anthropic from '@anthropic-ai/sdk';
import 'dotenv/config';

const app = new App({
  token: process.env.SLACK_BOT_TOKEN,
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  socketMode: true,                        // Socket Mode로 ngrok 없이 로컬 테스트 가능
  appToken: process.env.SLACK_APP_TOKEN,
  logLevel: LogLevel.INFO,
});

const claude = new Anthropic();

(async () => {
  await app.start();
  console.log('슬랙봇 시작 완료');
})();

Socket Mode를 사용하면 외부 URL 없이 로컬에서 이벤트를 수신할 수 있어 개발 단계에서 편리합니다.


Claude API 연동

봇 멘션을 받으면 Claude API를 호출하고 응답을 슬랙에 전송합니다:

// src/handlers/mention.ts
import { App } from '@slack/bolt';
import Anthropic from '@anthropic-ai/sdk';

export function registerMentionHandler(app: App, claude: Anthropic) {
  app.event('app_mention', async ({ event, say }) => {
    // 멘션 텍스트에서 봇 ID 제거
    const userText = event.text.replace(/<@[A-Z0-9]+>/g, '').trim();

    try {
      const response = await claude.messages.create({
        model: 'claude-haiku-4-5',           // 슬랙봇은 Haiku로 비용 절감
        max_tokens: 1024,
        system: `당신은 팀 슬랙 어시스턴트입니다.
간결하고 명확하게 한국어로 답변하세요.
기술적인 질문에는 코드 예제를 포함하세요.`,
        messages: [
          { role: 'user', content: userText }
        ],
      });

      const replyText = response.content[0].type === 'text'
        ? response.content[0].text
        : '응답을 처리할 수 없습니다.';

      await say({
        text: replyText,
        thread_ts: event.ts,              // 스레드로 답장
      });
    } catch (error) {
      await say({
        text: '오류가 발생했습니다. 잠시 후 다시 시도해 주세요.',
        thread_ts: event.ts,
      });
    }
  });
}

슬랙봇, GitHub Actions 에이전트, 멀티에이전트 파이프라인 — 30개 이상의 실전 레시피

Agent SDK Cookbook (₩64,000)은 Bolt.js 슬랙봇 완성본, 툴 체이닝, 비용 최적화 패턴, 오류 처리 전략을 포함합니다.

Agent SDK Cookbook 구매 — ₩64,000


대화 스레딩

슬랙 스레드 단위로 대화 맥락을 유지하려면 스레드 ID별 히스토리를 서버 메모리(또는 Redis)에 저장합니다:

// src/handlers/thread.ts
import { App } from '@slack/bolt';
import Anthropic from '@anthropic-ai/sdk';
import type { MessageParam } from '@anthropic-ai/sdk/resources/messages';

// 인메모리 저장소 (프로덕션에서는 Redis 사용 권장)
const threadHistory = new Map<string, MessageParam[]>();

const MAX_HISTORY = 20;   // 스레드당 최대 메시지 수
const SYSTEM_PROMPT = `당신은 팀 슬랙 어시스턴트입니다. 한국어로 간결하게 답변하세요.`;

export function registerThreadHandler(app: App, claude: Anthropic) {
  app.event('app_mention', async ({ event, say }) => {
    // 스레드 키: thread_ts가 있으면 스레드, 없으면 원본 메시지 ts
    const threadKey = (event as any).thread_ts ?? event.ts;
    const userText = event.text.replace(/<@[A-Z0-9]+>/g, '').trim();

    // 기존 히스토리 불러오기
    const history = threadHistory.get(threadKey) ?? [];

    // 사용자 메시지 추가
    history.push({ role: 'user', content: userText });

    // 히스토리 크기 제한 (오래된 메시지 제거)
    if (history.length > MAX_HISTORY) {
      history.splice(0, history.length - MAX_HISTORY);
    }

    const response = await claude.messages.create({
      model: 'claude-haiku-4-5',
      max_tokens: 1024,
      system: SYSTEM_PROMPT,
      messages: history,
    });

    const assistantText = response.content[0].type === 'text'
      ? response.content[0].text
      : '';

    // 어시스턴트 응답 히스토리에 추가
    history.push({ role: 'assistant', content: assistantText });
    threadHistory.set(threadKey, history);

    await say({ text: assistantText, thread_ts: threadKey });
  });
}

thread_ts가 있으면 기존 스레드에 이어지는 대화이고, 없으면 새 대화입니다. 이 키로 히스토리를 분리하면 여러 스레드가 서로 간섭하지 않습니다.


슬래시 커맨드

슬래시 커맨드로 특정 기능을 빠르게 실행할 수 있습니다.

Slack 앱에서 커맨드 등록

Slash Commands 메뉴에서 /ask를 추가하고 Request URL을 설정합니다.

// src/handlers/slash.ts
import { App } from '@slack/bolt';
import Anthropic from '@anthropic-ai/sdk';

export function registerSlashCommands(app: App, claude: Anthropic) {
  // /ask [질문] — Claude에게 빠른 질문
  app.command('/ask', async ({ command, ack, respond }) => {
    await ack();   // Slack에 3초 내 응답 확인 필수

    if (!command.text.trim()) {
      await respond('사용법: `/ask [질문 내용]`');
      return;
    }

    // 즉시 처리 중 메시지 전송 (3초 타임아웃 방지)
    await respond({ text: '처리 중...', response_type: 'ephemeral' });

    const response = await claude.messages.create({
      model: 'claude-haiku-4-5',
      max_tokens: 512,
      messages: [{ role: 'user', content: command.text }],
    });

    const answer = response.content[0].type === 'text'
      ? response.content[0].text
      : '응답 없음';

    await respond({
      text: `*질문:* ${command.text}\n\n*답변:* ${answer}`,
      response_type: 'in_channel',   // 채널 전체에 표시
      replace_original: true,
    });
  });

  // /summarize — 최근 채널 메시지 요약 (예시)
  app.command('/summarize', async ({ command, ack, respond }) => {
    await ack();
    await respond('요약 기능은 channels:history 권한이 필요합니다. 권한 확인 후 사용하세요.');
  });
}

슬래시 커맨드는 3초 이내ack()를 호출해야 합니다. 처리 시간이 길면 즉시 ack()한 뒤 respond()로 나중에 결과를 전송합니다.


비용 관리

슬랙봇은 반복 호출이 많으므로 비용 관리가 중요합니다. 시스템 프롬프트 캐싱과 모델 선택으로 비용을 크게 줄일 수 있습니다.

모델별 비용 비교 (1,000회 호출 기준)

시나리오 모델 입력(토큰) 출력(토큰) 1회 비용 1,000회 비용
간단한 Q&A Haiku 3.5 200 300 $0.00018 $0.18
일반 대화 Sonnet 4.5 500 500 $0.0090 $9.00
복잡한 분석 Opus 4.5 1,000 800 $0.0870 $87.00
Haiku + 캐싱 Haiku 3.5 200+캐시800 300 $0.000056 $0.056

슬랙봇의 일반 Q&A는 Haiku로 충분합니다. 동일한 시스템 프롬프트를 반복 전송하면 프롬프트 캐싱으로 비용을 추가 절감할 수 있습니다.

프롬프트 캐싱 적용

const response = await claude.messages.create({
  model: 'claude-haiku-4-5',
  max_tokens: 1024,
  system: [
    {
      type: 'text',
      text: SYSTEM_PROMPT,                  // 동일 프롬프트 반복 전송
      cache_control: { type: 'ephemeral' }, // 캐싱 활성화
    },
  ],
  messages: history,
});

// 캐시 히트 확인
const cacheHit = response.usage.cache_read_input_tokens ?? 0;
console.log(`캐시 히트: ${cacheHit}토큰`);

시스템 프롬프트가 1,024토큰 이상이면 캐싱이 활성화됩니다. 캐시된 토큰은 일반 입력 토큰 대비 90% 저렴합니다. 자세한 비용 최적화 전략은 Claude API 비용 모니터링 가이드모델 선택 가이드를 참고하세요.

일일 호출 제한 구현

// 사용자별 일일 호출 횟수 제한
const dailyUsage = new Map<string, number>();

function checkRateLimit(userId: string, limit = 50): boolean {
  const key = `${userId}:${new Date().toDateString()}`;
  const count = dailyUsage.get(key) ?? 0;
  if (count >= limit) return false;
  dailyUsage.set(key, count + 1);
  return true;
}

멀티에이전트 파이프라인이나 자동화 봇을 구성하는 경우 Agent SDK 활용 가이드에서 더 고급 패턴을 확인할 수 있습니다.


슬랙봇 완성본 코드 + 30개 이상의 Claude API 실전 레시피

Agent SDK Cookbook (₩64,000)은 Bolt.js 슬랙봇 전체 소스, 스레딩 Redis 구현, 비용 대시보드, 멀티에이전트 패턴을 포함합니다.

Agent SDK Cookbook 구매 — ₩64,000


Frequently Asked Questions

Bolt.js 슬랙봇에서 Claude API를 어떻게 연결하나요?

@slack/bolt@anthropic-ai/sdk를 모두 설치한 뒤 각각의 클라이언트 인스턴스를 생성합니다. Bolt.js의 이벤트 핸들러(app.event, app.command) 안에서 claude.messages.create()를 호출하면 됩니다. 슬랙 이벤트를 수신하면 사용자 텍스트를 추출해 Claude에 전달하고, 응답을 say() 또는 respond()로 슬랙에 전송합니다.

슬랙 슬래시 커맨드가 타임아웃 오류(dispatch_failed)를 반환하는 이유는 무엇인가요?

슬랙은 커맨드 수신 후 3초 이내에 응답을 요구합니다. Claude API 호출은 보통 1~3초가 소요되므로 타임아웃이 발생할 수 있습니다. 해결책은 즉시 ack()를 호출해 수신을 확인한 뒤, Claude 응답이 완료되면 respond()로 결과를 전송하는 것입니다. 두 동작이 비동기로 분리되므로 타임아웃 문제가 사라집니다.

여러 슬랙 스레드에서 각각 독립적인 대화 맥락을 유지하려면 어떻게 해야 하나요?

event.thread_ts(기존 스레드) 또는 event.ts(새 메시지)를 키로 사용해 대화 히스토리를 Map에 저장합니다. 각 스레드 키별로 독립적인 MessageParam[] 배열을 유지하면 스레드 간 맥락이 섞이지 않습니다. 서버 재시작 후에도 히스토리를 유지하려면 Redis나 데이터베이스에 영구 저장하세요.

슬랙봇에 어떤 Claude 모델을 사용하는 것이 좋나요?

일상적인 Q&A나 간단한 요약에는 claude-haiku-4-5가 가장 적합합니다. 비용이 Sonnet의 약 1/50 수준이며 응답 속도도 빠릅니다. 복잡한 코드 분석이나 긴 문서 요약이 필요할 때만 claude-sonnet-4-5로 전환하세요. 모델별 성능과 비용 비교는 Claude 모델 선택 가이드를 참고하세요.

Socket Mode와 HTTP 서버 방식 중 어떤 것을 선택해야 하나요?

로컬 개발 및 사내 내부 봇에는 Socket Mode가 편리합니다. 외부 URL과 ngrok 없이 앱 토큰(xapp-...)만으로 이벤트를 수신할 수 있습니다. 프로덕션 공개 봇에는 HTTP 서버 방식을 권장합니다. Vercel, AWS Lambda, Fly.io 등에 배포하고 HTTPS Request URL을 슬랙 앱에 등록합니다. Bolt.js는 두 방식을 동일한 코드로 지원하므로 socketMode: false로 변경하면 HTTP 모드로 전환됩니다.

도구와 자료