Slack AI & 고급 활용

학습 시간: 45분 목표: Slack을 단순 메신저를 넘어 업무 자동화 플랫폼으로 활용 대상: PM, 개발자, 운영팀, Admin

📚 공식 문서

리소스링크설명
Slack AIslack.com/features/aiAI 기능 소개
Workflow Builderslack.com/help/articles/360041352714워크플로우 가이드
Incoming Webhooksapi.slack.com/messaging/webhooks웹훅 API 문서
Apps Directoryslack.com/apps앱 마켓플레이스

Slack이란?

Slack은 팀 협업을 위한 메시징 플랫폼입니다. 2026년 현재는 AI 기반 생산성 도구로 확장되어, 업무 자동화, 정보 검색, 외부 도구 연동의 중심 허브로 활용됩니다.

Slack의 핵심 강점

강점설명활용 예시
채널 기반 조직프로젝트/팀/주제별 채널 분리proj-website, team-sales
AI 통합Claude 기반 Slackbot정보 검색, 이메일 작성
무제한 연동5,000+ 앱 연동 가능Google Workspace, GitHub
워크플로우노코드 자동화폼 제출 → Slack 알림
검색전체 메시지/파일 검색6개월 전 논의 찾기

Slack vs 다른 메신저

구분SlackTeamsDiscord
강점개발자 친화, 자동화MS 365 통합커뮤니티
AI 기능Claude 기반Copilot없음
외부 연동5,000+ 앱제한적봇 중심
요금제무료~ProMS 구독무료
타겟스타트업, 개발팀대기업게이머

🆕 2026 AI 신기능

1. AI-Powered Slackbot (2026.01.13 출시)

Salesforce가 Anthropic Claude를 탑재한 새로운 Slackbot을 출시했습니다.

주요 기능

  • 정보 검색: 채널 히스토리, 업로드된 파일, 외부 연동 도구(Gmail, Notion) 통합 검색
  • 이메일 초안 작성: “고객사에 보낼 제안서 이메일 작성해줘”
  • 미팅 일정 제안: Calendar 연동으로 자동 스케줄링
  • 요약 & 번역: 긴 스레드를 한눈에 요약

사용 방법

@Slackbot 지난주 마케팅 회의 요약해줘
@Slackbot 이 PDF 파일 요약해서 3줄로 정리

플랜: Business+ 및 Enterprise+ 고객만 사용 가능


2. AI 생산성 기능

AI Explain (모바일 지원)

  • 전문 용어에 마우스 오버 → AI가 자동 설명
  • 예: “ROI”에 커서 → “투자 대비 수익률…”

AI 파일 요약 + 번역

  • PDF/문서 업로드 시 자동 요약
  • “Translate” 버튼으로 다국어 번역

Unreads Summarize

  • 10개 이상 읽지 않은 메시지 → AI 자동 요약
  • Unreads pill에 “Summarize” 버튼 내장

AI 응답 공유

  • AI 검색 결과를 팀 채널에 바로 공유

3. Enterprise Search 연동

외부 도구 통합 검색

  • Gmail, Outlook 이메일
  • Dropbox, Google Drive 파일
  • Notion, Confluence 문서

커스텀 API 커넥터 (곧 출시):

  • 사내 시스템 (ERP, CRM) 연동
  • 온프레미스 소프트웨어 검색

📐 Part 1. Slack 조직 설계

채널 네이밍 컨벤션

잘 설계된 채널 이름은 팀 생산성의 핵심입니다. 다음 원칙을 따르세요.

1. Prefix 전략

Prefix용도예시
proj-프로젝트proj-website-redesign
team-팀/부서team-marketing, team-sales
client-고객사client-acme, client-samsung
help-헬프데스크help-it, help-hr
announce-공지announce-company
social-친목social-lunch, social-gaming
wip-임시 작업wip-q1-planning

2. 네이밍 규칙

해야 할 것

  • 소문자만 사용 (team-sales ✅)
  • 하이픈(-) 구분자 (proj-web-redesign ✅)
  • 15개 이하 prefix 제한

하지 말 것

  • 대문자 사용 (Team-Sales ❌)
  • 언더스코어 (team_sales ❌)
  • 너무 긴 이름 (proj-website-redesign-q1-2026-final ❌)

3. 조직 규모별 템플릿

스타트업 (7개 prefix)

proj-    프로젝트
team-    팀
help-    헬프데스크
announce- 공지
social-  친목
wip-     임시 작업
archive- 보관

중견기업 (12개 prefix)

proj-    프로젝트
team-    팀
dept-    부서
client-  고객사
help-    헬프데스크
announce- 공지
social-  친목
wip-     임시 작업
rnd-     연구개발
ops-     운영
hr-      인사
archive- 보관

4. 채널 수명주기 관리

생성 → 활성 → 아카이브

  1. 생성 시: 목적과 종료 조건 명시

    채널 설명: Q1 웹사이트 리뉴얼 프로젝트 (종료: 2026.03.31)
  2. 활성 유지: 최소 주 1회 활동

  3. 아카이브: 프로젝트 종료 후 30일 이내

    • Admin → Channels → Archive
  4. Sidebar Sweeper (2026 신기능):

    • 비활성 채널 자동 숨김
    • Settings → Sidebar → Sidebar Sweeper

🔧 Part 2. Apps Script로 Slack 자동화

서버 없이 Google Apps Script로 Slack과 연동하세요. 무료이고 Google Workspace와 바로 통합됩니다.

실습 1: Slack Webhook으로 메시지 보내기

Step 1: Slack Webhook URL 생성

  1. Slack Workspace → Apps → “Incoming Webhooks” 검색
  2. “Add to Slack” 클릭
  3. 채널 선택 (예: #dev-alerts)
  4. Webhook URL 복사
    https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXX

Step 2: Google Sheets에서 Apps Script 열기

  1. Google Sheets 열기
  2. 확장 프로그램Apps Script

Step 3: 간단한 메시지 보내기

function sendToSlack() {
  const webhookUrl = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL";

  const message = {
    text: "안녕하세요! Apps Script에서 보낸 메시지입니다.",
    username: "업무봇",
    icon_emoji: ":robot_face:",
  };

  const options = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(message),
  };

  UrlFetchApp.fetch(webhookUrl, options);
  Logger.log("메시지 전송 완료");
}

Step 4: 실행

  1. 상단 메뉴에서 sendToSlack 함수 선택
  2. 실행 버튼 클릭
  3. 권한 승인 (처음 실행 시)
  4. Slack 채널에서 메시지 확인

실습 2: Google Forms → Slack 알림

시나리오: 고객 문의 폼 제출 시 자동으로 Slack에 알림

Step 1: Google Forms 생성

질문 1: 이름
질문 2: 부서
질문 3: 이메일
질문 4: 문의 내용

Step 2: Forms 응답 시트 연결

  1. Forms → 응답
  2. 스프레드시트 만들기 클릭

Step 3: Apps Script 작성

스프레드시트에서 확장 프로그램Apps Script

function onFormSubmit(e) {
  const webhookUrl = "YOUR_WEBHOOK_URL";

  // 폼 응답 가져오기
  const responses = e.values;
  const timestamp = responses[0]; // 타임스탬프
  const name = responses[1]; // 이름
  const dept = responses[2]; // 부서
  const email = responses[3]; // 이메일
  const content = responses[4]; // 문의 내용

  // Slack 메시지 작성 (Attachment 형식)
  const message = {
    text: "🔔 새로운 고객 문의가 접수되었습니다!",
    attachments: [
      {
        color: "#36a64f",
        fields: [
          { title: "이름", value: name, short: true },
          { title: "부서", value: dept, short: true },
          { title: "이메일", value: email, short: false },
          { title: "문의 내용", value: content, short: false },
          { title: "제출 시간", value: timestamp, short: false },
        ],
        footer: "고객 문의 시스템",
        footer_icon:
          "https://platform.slack-edge.com/img/default_application_icon.png",
      },
    ],
  };

  const options = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(message),
  };

  try {
    UrlFetchApp.fetch(webhookUrl, options);
    Logger.log("Slack 알림 전송 완료");
  } catch (error) {
    Logger.log("에러: " + error);
  }
}

Step 4: 트리거 설정

  1. Apps Script 편집기 → 좌측 메뉴 트리거 (시계 아이콘)
  2. 트리거 추가 클릭
  3. 설정:
    • 실행할 함수: onFormSubmit
    • 이벤트 소스: 스프레드시트에서
    • 이벤트 유형: 양식 제출 시
  4. 저장
  5. 권한 승인 (Google 계정 로그인)

Step 5: 테스트

  1. Google Forms에서 테스트 응답 제출
  2. Slack 채널에서 알림 확인

실습 3: Google Sheets 변경 → Slack 알림

시나리오: 중요한 데이터(A열) 수정 시 Slack 알림

function onEdit(e) {
  const webhookUrl = "YOUR_WEBHOOK_URL";

  // 편집된 정보
  const sheet = e.source.getActiveSheet();
  const range = e.range;
  const editedCell = range.getA1Notation();
  const oldValue = e.oldValue || "(비어있음)";
  const newValue = e.value || "(삭제됨)";
  const user = Session.getActiveUser().getEmail();

  // A열(중요 컬럼)만 알림
  if (range.getColumn() !== 1) return;

  // 헤더 행(1행) 제외
  if (range.getRow() === 1) return;

  const message = {
    text: "📝 중요 데이터가 수정되었습니다!",
    attachments: [
      {
        color: "warning",
        fields: [
          { title: "시트", value: sheet.getName(), short: true },
          { title: "셀", value: editedCell, short: true },
          { title: "이전 값", value: oldValue, short: true },
          { title: "새 값", value: newValue, short: true },
          { title: "수정자", value: user, short: false },
        ],
      },
    ],
  };

  const options = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(message),
  };

  UrlFetchApp.fetch(webhookUrl, options);
}

트리거 설정

트리거 추가
- 실행할 함수: onEdit
- 이벤트 소스: 스프레드시트에서
- 이벤트 유형: 수정 시
→ 저장

주의: onEdit는 간단한 트리거로 자동 작동하지만, UrlFetchApp 사용 시에는 설치 가능한 트리거 필요


실습 4: 시간 기반 자동 리포트

시나리오: 매일 오전 9시 일일 리포트 자동 발송

function sendDailyReport() {
  const webhookUrl = "YOUR_WEBHOOK_URL";
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("데이터");

  // 오늘 날짜 데이터 집계
  const lastRow = sheet.getLastRow();
  const data = sheet.getRange(2, 1, lastRow - 1, 3).getValues();

  let todayCount = 0;
  let todayTotal = 0;

  const today = new Date().toDateString();

  data.forEach((row) => {
    const rowDate = new Date(row[0]).toDateString();
    if (rowDate === today) {
      todayCount++;
      todayTotal += row[2]; // 3번째 컬럼 = 금액
    }
  });

  const message = {
    text: "📊 일일 리포트",
    attachments: [
      {
        color: "#0066cc",
        fields: [
          {
            title: "오늘 처리 건수",
            value: todayCount + "건",
            short: true,
          },
          {
            title: "총 금액",
            value: todayTotal.toLocaleString() + "원",
            short: true,
          },
        ],
        footer: "매일 오전 9시 자동 발송",
        ts: Math.floor(Date.now() / 1000),
      },
    ],
  };

  const options = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(message),
  };

  UrlFetchApp.fetch(webhookUrl, options);
}

트리거 설정

트리거 추가
- 실행할 함수: sendDailyReport
- 이벤트 소스: 시간 기반
- 시간 유형: 일 타이머
- 시간: 오전 9시~10시
→ 저장

실습 5: 재고 부족 알림 (조건부)

시나리오: 재고가 10개 이하로 떨어지면 매시간 체크해서 알림

function checkInventory() {
  const webhookUrl = "YOUR_WEBHOOK_URL";
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("재고");

  const lastRow = sheet.getLastRow();
  const data = sheet.getRange(2, 1, lastRow - 1, 3).getValues();
  // 컬럼: [제품명, SKU, 재고수량]

  let lowStockItems = [];

  data.forEach((row) => {
    const productName = row[0];
    const sku = row[1];
    const stock = row[2];

    if (stock <= 10) {
      lowStockItems.push({
        title: productName + " (SKU: " + sku + ")",
        value: "⚠️ 재고: " + stock + "개",
        short: false,
      });
    }
  });

  // 재고 부족 항목이 없으면 알림 안 보냄
  if (lowStockItems.length === 0) {
    Logger.log("재고 부족 항목 없음");
    return;
  }

  const message = {
    text: "🚨 재고 부족 알림",
    attachments: [
      {
        color: "danger",
        fields: lowStockItems,
        footer: "재고 관리 시스템",
      },
    ],
  };

  const options = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(message),
  };

  UrlFetchApp.fetch(webhookUrl, options);
}

트리거 설정

트리거 추가
- 실행할 함수: checkInventory
- 이벤트 소스: 시간 기반
- 시간 유형: 시간 타이머
- 간격: 1시간마다
→ 저장

💡 Part 3. 실전 활용 사례

시나리오별 구현

시나리오트리거구현
고객 문의 접수Forms 제출Google Forms → Apps Script → Slack #cs-team
재고 부족 알림1시간마다Sheets 재고<10 체크 → Slack #ops
일일 매출 리포트매일 18시Sheets 집계 → Slack #sales
중요 데이터 변경Sheets 수정A열 변경 감지 → Slack #admin
프로젝트 마감 리마인더매일 9시Calendar → D-7 체크 → Slack #pm

고급: Slack Message 포맷팅

1. 기본 텍스트 포맷

const message = {
  text: "*굵게* _기울임_ ~취소선~ `코드`\n<https://example.com|링크 텍스트>",
};

2. Attachment (Block Kit)

const message = {
  attachments: [
    {
      color: "#36a64f", // 좌측 바 색상
      pretext: "선택적 상단 텍스트",
      title: "제목",
      title_link: "https://example.com",
      text: "본문 내용",
      fields: [
        { title: "라벨1", value: "값1", short: true },
        { title: "라벨2", value: "값2", short: true },
      ],
      footer: "Footer 텍스트",
      ts: 1234567890, // Unix timestamp
    },
  ],
};

3. 멘션 & 채널

const message = {
  text: "<@U123456> 님, <#C123456> 채널 확인해주세요!\n<!here> 모두 확인!",
};
// @유저명, #채널명, @here

⚠️ 주의사항 & 제약

Apps Script 제한사항

항목제한해결책
UrlFetchApp하루 20,000회배치 처리 (여러 메시지 모아서 전송)
실행 시간최대 6분작업 분할, 여러 함수로 나누기
트리거계정당 20개불필요한 트리거 정리
동시 실행30회시간 분산 (트리거 시간 다르게)

Slack Webhook 제한

  • 초당 1회 요청 제한
  • 중첩 JSON 불가 (평평한 구조 사용)
  • Legacy Incoming Webhooks 단종 예정 (Slack Apps 권장)

보안 고려사항

절대 하지 말 것

// Webhook URL을 코드에 직접 노출 (위험!)
const webhookUrl = "https://hooks.slack.com/services/...";

권장 방법

// Properties Service 사용
const webhookUrl =
  PropertiesService.getScriptProperties().getProperty("SLACK_WEBHOOK");

설정 방법

Apps Script 편집기 → 프로젝트 설정 → 스크립트 속성
- 속성: SLACK_WEBHOOK
- 값: https://hooks.slack.com/services/...

🎯 팁 & 베스트 프랙티스

1. 에러 핸들링

function sendToSlackSafe(message) {
  const webhookUrl =
    PropertiesService.getScriptProperties().getProperty("SLACK_WEBHOOK");

  try {
    const options = {
      method: "post",
      contentType: "application/json",
      payload: JSON.stringify(message),
      muteHttpExceptions: true, // 에러 무시하지 않음
    };

    const response = UrlFetchApp.fetch(webhookUrl, options);
    const responseCode = response.getResponseCode();

    if (responseCode !== 200) {
      Logger.log("에러: " + responseCode + " - " + response.getContentText());
      return false;
    }

    return true;
  } catch (error) {
    Logger.log("예외 발생: " + error);
    return false;
  }
}

2. 배치 처리 (Rate Limit 회피)

function sendBatchMessages() {
  const webhookUrl =
    PropertiesService.getScriptProperties().getProperty("SLACK_WEBHOOK");

  const messages = ["메시지 1", "메시지 2", "메시지 3"];

  messages.forEach((msg, index) => {
    const message = { text: msg };
    const options = {
      method: "post",
      contentType: "application/json",
      payload: JSON.stringify(message),
    };

    UrlFetchApp.fetch(webhookUrl, options);

    // 1초 대기 (Rate Limit 회피)
    if (index < messages.length - 1) {
      Utilities.sleep(1000);
    }
  });
}

3. 캐싱으로 중복 알림 방지

function sendUniqueAlert(alertKey, message) {
  const cache = CacheService.getScriptCache();
  const cached = cache.get(alertKey);

  // 1시간 내 같은 알림은 보내지 않음
  if (cached) {
    Logger.log("중복 알림 방지: " + alertKey);
    return;
  }

  // 알림 전송
  sendToSlack(message);

  // 캐시 저장 (1시간)
  cache.put(alertKey, "sent", 3600);
}

다음 학습


참고 자료

공식 문서

실습 예제

커뮤니티

목차

Part 1. 시작하기
Part 2. 핵심 스킬
Part 3. 역할별 가이드
Part 4. 직무별 활용
Part 5. 도구 레퍼런스 > 5.1 전략 가이드
Part 6. 실습 워크북 > 6.1 핵심 스킬 실습
Part 6. 실습 워크북 > 6.2 무역실무 특화 실습