본문으로 건너뛰기
취준생을 위한 n8n 실전 워크플로우 레시피 · 31/44시리즈 보기 →

슬랙 대화를 쌓아두고 AI가 주간 리포트로 — n8n Slack 아카이브와 스케줄 리포트 두 흐름

· 약 9분
Datapopcorn CEO / AI automation educator
이 글과 연결된 글 보기
7편 · 20개 연결
100%
n8n Data Table 처음 써보기 — 트렌드 3개를 합쳐 매일 아침 분석 주제 뽑는 워크플로우n8n으로 정적 웹서버 운영하기 — 수료증 발급부터 진위 확인까지, 멱등 처리로 안전하게벡터DB 없이 실시간으로 사이트를 읽는 챗봇 — 경복대학교 안내 챗봇 해부n8n으로 반복업무 자동화 포트폴리오 만들기구글시트에 쌓인 데이터를 인스타그램 카드뉴스로 — n8n 시트 인스타그램 자동발행슬랙 대화를 쌓아두고 AI가 주간 리포트로 — n8n Slack 아카이브와 스케줄 리포트 두 흐름서브워크플로우를 Tool로 감싸 AI Agent에게 서버 점검시키기 — 그리고 시스템 프롬프트만으로는 부족한 이유

드래그로 이동 · 휠/두 손가락으로 확대 · 방향키로 글 선택 · 0으로 맞춤. 실선: 본문 링크, 점선: 시리즈·주제의 대표 연결.

표시된 글 7편 목록
전체 글 연결 탐색

슬랙 채널에 쌓이는 대화는 스크롤을 한참 올리지 않으면 지난주에 뭘 논의했는지 다시 보기 어렵습니다. 이 워크플로우는 Slack Trigger로 메시지를 실시간으로 받아 봇 메시지는 거르고 사람이 보낸 메시지만 Supabase에 시계열로 쌓아둔 뒤, 별도의 스케줄 워크플로우가 그 데이터로 AI가 "이번 주 누가 무엇을 논의했는지" 정리한 리포트를 슬랙으로 보내는 구조입니다. 그대로 옮기면 채널을 거슬러 훑어보지 않아도 한 주 요약을 받아볼 수 있습니다.

이 워크플로우 하나로 보여줄 수 있는 것​

이메일 파싱 편, 음식 평가 슬랙 봇 편, Gmail 분류 편, 구글시트 AI 리포트 편까지 오면서 이벤트 트리거, AI 판단, DB 저장, 스케줄 리포트를 하나씩 따로 만들어봤다면 이번 편은 그 네 가지를 한 워크플로우 안에 넣어봅니다.

  • 이벤트 트리거 — 음식 평가 슬랙 봇 편의 Slack Trigger로, 이번엔 답장 한 통이 아니라 채널 메시지 전체를 실시간으로 받습니다
  • AI 판단이 섞인 필터링 — Gmail 분류 편이 메일을 분류했다면, 여기서는 사용자 목록과 대조해 봇 메시지를 걸러냅니다
  • 시계열 DB 저장 — Gmail 분류 편의 Supabase 저장 패턴 그대로입니다. 저장 대상만 메일이 아니라 메시지입니다
  • 스케줄 AI 리포트 — 구글시트 AI 리포트 편처럼, 정해진 시각에 쌓인 데이터를 AI에게 넘겨 리포트로 만듭니다

네 가지를 각각 만들어봤다면 이 워크플로우에 새로운 노드는 거의 없습니다. 대신 트리거가 다른 흐름 두 개를 한 캔버스에 같이 두는 법과, 그렇게 만든 캔버스가 실제로는 얼마나 쉽게 어긋나는지를 보여줍니다.

배경 — 대화는 흘러가고 기록은 남지 않습니다​

팀 슬랙 채널에는 매일 대화가 쌓이지만, 지나간 이야기는 스크롤을 한참 올려야 다시 보입니다. 여러 명이 짧게 주고받는 채널일수록 "이번 주에 뭘 했더라"를 정리하려면 사람이 직접 채널을 거슬러 읽어야 합니다. 이 워크플로우는 데이터팝콘 n8n 인스턴스에 실제로 켜져 있는(Active) 것으로, 대화를 흘려보내지 않고 DB에 쌓아 AI가 주기적으로 요약하도록 설계돼 있습니다. 설치와 기본 노드 설명은 n8n으로 반복업무 자동화 포트폴리오 만들기에 정리돼 있으니 여기서는 워크플로우 자체만 다룹니다.

구조 — Trigger / Task / Target​

  • Trigger — Slack 메시지 이벤트(실시간) / 스케줄(매주 금요일)
  • Task — (실시간) 사용자 목록 대조로 봇 제외 후 Supabase 적재 / (정기) 최근 7일 조회 후 사용자별로 묶어 AI 요약
  • Target — Supabase 테이블 / 슬랙 채널

재고 알림 편이나 명함 OCR 편은 트리거가 하나였습니다. 이 워크플로우는 트리거가 최소 두 개(Slack 이벤트, 스케줄)이고 서로 하는 일도 다릅니다. n8n에서는 이런 흐름을 워크플로우 파일 두 개로 나눌 수도 있고, 이 캔버스처럼 트리거만 다른 흐름을 한 파일 안에 같이 둘 수도 있습니다. Error Trigger 편은 여러 워크플로우가 하나의 에러 처리 워크플로우를 공유하는 구조였는데, 이번은 정반대로 하나의 캔버스 안에 시작점이 다른 파이프라인이 함께 있는 경우입니다.

만들기​

1. Slack Trigger — 채널의 message 이벤트 구독​

Slack Trigger 자체를 처음 만드는 방법은 음식 평가 슬랙 봇 편에서 다뤘으니, 여기서는 이 워크플로우만의 설정을 짚습니다. Trigger 항목에서 이벤트 종류를 message로 두고, 감시할 채널을 고릅니다. 이게 스티키 노트가 말하는 "Event Subscription"으로, 슬랙 앱이 그 채널의 메시지 이벤트를 웹훅으로 n8n에 그대로 넘겨주는 방식입니다.

2. bot 메시지 걸러내기 — 사용자 목록과 대조​

메시지가 도착하면 곧바로 Slack 사용자 목록 전체를 가져옵니다(Get many users, Resource: User). 그 목록을 Filter 노드에서 is_bot이 false이고 deleted가 false인 사용자만 남기고, Edit Fields로 id·name·real_name·display_name만 추립니다. 마지막으로 If 노드에서 방금 메시지를 보낸 사용자의 id가 이 걸러낸 목록 안에 있는지 비교합니다. 있으면 사람이 보낸 메시지로 보고 넘어가고, 없으면 조건이 false가 되어 조용히 멈춥니다. 재고 알림 편의 Filter 노드와 같은 성질로, 조건에 안 맞으면 뒤 노드가 아예 실행되지 않습니다.

사람인 게 확인되면 Set 노드(Prepare Message Data)에서 저장할 형태로 정리합니다. 방금 조회한 사용자 정보와 원본 트리거 데이터를 함께 참조하는 게 특징입니다.

user_id = {{ $json.id }}
user_name = {{ $json.real_name }}
channel_id = {{ $('Slack Message Trigger').item.json.channel }}
message_text = {{ $('Slack Message Trigger').item.json.text }}
ts = {{ $('Slack Message Trigger').item.json.ts }}
thread_ts = {{ $('Slack Message Trigger').item.json.event_ts }}

$('Slack Message Trigger').item.json처럼 노드 이름으로 다른 노드의 출력을 직접 참조하는 표기입니다. 현재 아이템이 사용자 조회 결과로 바뀐 뒤에도, 몇 단계 앞선 트리거 노드의 원본 데이터를 그대로 가져올 수 있습니다.

3. Supabase — 시계열로 쌓기, 왜 시트가 아니라 DB인지​

Supabase에 slack_chat_histories 테이블을 만들고 channel_id·ts·thread_ts·user_id·user_name·message_text·created_at 컬럼을 둡니다. Supabase 노드(Insert)에서는 앞서 Set 노드가 만든 필드 이름 그대로 각 컬럼에 매핑하면 됩니다. created_at은 컬럼 기본값을 now()로 두면 저장 시점이 자동으로 찍히니 따로 매핑할 필요가 없습니다. 연결은 URL과 서비스 키를 노드에 직접 적지 않고, n8n의 Supabase credential에 한 번 등록해두고 고르기만 하면 됩니다.

왜 시트가 아니라 DB일까요. 채널 하나가 하루에 메시지를 수십, 수백 건 만들어내면 한 주 뒤에는 행이 수천 개가 됩니다. 시트는 이 규모에서 전체를 불러와 걸러내야 해서 느려지고, "최근 7일치만" 같은 조건 조회도 함수로는 번거롭습니다. DB는 created_at 컬럼에 조건을 걸어 원하는 기간만 바로 받아옵니다. 아래 스케줄 워크플로우가 실제로 쓰는 조회 조건이 그 예입니다.

created_at >= {{ $now.minus({ days: 7 }).toISO() }}

4. Schedule Trigger — 매주 금요일에 지난 7일을 모으기​

Schedule Trigger를 추가하고, 주 단위 반복에 요일을 금요일로 둡니다. 스케줄이 울리면 Supabase 노드(Get Many)로 slack_chat_histories에서 위 조건을 만족하는 행을 전부 가져옵니다.

5. Code — 사용자별로 묶기​

Code 노드에서 조회한 메시지들을 사용자 단위로 묶어 AI가 읽기 좋은 형태로 만듭니다.

const items = $input.all();
const userActivities = {};

for (const item of items) {
const userName = item.json.user_name || '알 수 없는 사용자';
const message = item.json.message_text || '';

if (!userActivities[userName]) {
userActivities[userName] = { userName, messageCount: 0, messages: [] };
}
userActivities[userName].messageCount++;
userActivities[userName].messages.push(message);
}

return [{ json: { userActivities: Object.values(userActivities) } }];

원본 코드는 message_text 대신 message, channel_id 대신 channel처럼 지금 저장 스키마에는 없는 필드 이름을 참조합니다. 왜 그런지, 그대로 두면 무슨 일이 생기는지는 아래 한계에서 다시 짚습니다.

6. AI Agent — 주간 리포트 만들기​

AI Agent 노드에 System Message를 넣고, Require Specific Output Format을 켠 뒤 Structured Output Parser를 붙입니다. 원본 System Message는 영어인데, 뜻을 옮기면 이렇습니다.

당신은 Slack Intelligence Bot입니다. 최근 7일치 슬랙 메시지를 분석해 팀 주간 리포트를 만드세요.

1. 사용자별로 무엇을 했는지 정리
2. 사람마다 핵심 성과와 집중 영역을 뽑기
3. 결과는 출력 파서가 정의한 형식으로만 반환

"누가 무엇을 했는가"에 집중해, 실행 가능한 인사이트로 정리하세요.

파서의 JSON Example은 이렇게 들어 있습니다.

{
"team_contributions": [
{
"user_name": "Mr. Kim",
"activities": "Fixed login bug, reviewed API documentation"
},
{
"user_name": "Ms. Lee",
"activities": "Researched marketing trends, prepared campaign materials"
}
]
}

Chat Model은 어떤 provider를 붙여도 됩니다. Agent 노드가 Chat Model을 갈아 끼울 수 있는 구조라 Gemini나 OpenAI의 무료·저가 티어를 연결해도 동일하게 동작합니다. 이 캔버스에는 실제로 Upstage의 Solar Pro 2가 OpenAI 호환 노드로 연결돼 있습니다.

7. Slack — 리포트 전송​

Send a message 노드에서 채널을 고르고, Text에 파서 결과를 조립합니다.

📅 *WEEKLY TEAM REVIEW*

{{ $json.output.team_contributions.map(c => `👤 *${c.user_name}*${c.activities}`).join("") }}

원본 캔버스에 남아 있는 흔적​

교육용이 아니라 실제로 Active 상태인 워크플로우라, 캔버스를 뜯어보면 만들다 만 흔적이 남아 있습니다. 사실을 그대로 옮깁니다.

첫째, 저장 경로가 스티키 노트와 다릅니다. 스티키 노트는 "Supabase에 적재"라고 적혀 있고 Supabase 노드(Save to Database)도 캔버스에 있지만, 지금 메시지가 실제로 흐르는 경로는 n8n 자체의 Data Table 기능(Insert row 노드)입니다. Supabase 노드는 연결도 끊겨 있고, 컬럼 매핑도 message_text 대신 message_content를, created_at 대신 timestamp를 참조합니다. 둘 다 앞 노드가 만드는 필드 이름이 아닙니다. 저장 방식을 Data Table로 옮기면서 예전 노드를 정리하지 않고 남겨둔 흔적으로 보입니다. 외부 계정 없이 시작하고 싶다면 이 글의 레시피 대신 Data Table을 그대로 써도 됩니다.

둘째, 리포트 흐름과 스케줄이 끊겨 있습니다. Weekly Report Schedule 노드의 출력이 어디로도 연결돼 있지 않고, 리포트 체인(Supabase 조회 → 사용자별 묶기 → AI Agent → 슬랙 전송) 자체는 이어져 있지만 시작점이 없습니다. 금요일이 와도 지금은 자동으로 아무 일도 일어나지 않는다는 뜻입니다. 일간 버전(23시 30분 스케줄)도 AI Agent까지는 도는데, 결과를 슬랙으로 보내는 노드와는 연결돼 있지 않습니다. 직접 만든다면 Schedule Trigger와 조회 노드를 반드시 연결해야 리포트가 실제로 옵니다.

셋째, AI 모델도 한 번 바뀐 흔적이 있습니다. Claude Sonnet 4.5를 연결하는 노드가 두 개(일간·주간용) 캔버스에 놓여 있지만, 실제로 AI Agent에 연결된 모델은 Upstage Solar Pro 2입니다. Claude 노드는 자리만 차지할 뿐입니다.

넷째, Slack Trigger는 채널 하나만 보지 않습니다. Switch 노드가 채널별로 갈래를 나누는데, 그중 하나는 음식 평가 슬랙 봇 편과 같은 방식(이미지 다운로드 → LLM 페르소나 → 스레드 답장)으로 완전히 다른 채널에 붙어 있습니다. 트리거 하나를 여러 목적으로 재사용한 사례입니다.

한계​

  • Code 노드의 필드 이름 불일치 — 원본 코드는 item.json.message, item.json.channel을 참조하지만 저장된 행에는 message_text, channel_id만 있습니다. 그대로 실행하면 메시지는 빈 문자열로, 채널은 전부 "Unknown Channel"로 찍힙니다.
  • 매 메시지마다 사용자 목록을 다시 조회 — bot 필터링이 메시지가 올 때마다 워크스페이스 사용자 전체를 다시 불러와서, 인원이 많아지면 호출도 늘어납니다.
  • user_name 기준 그룹핑 — 사용자를 아이디가 아니라 이름 문자열로 묶어서, 표시 이름이 같은 사람이 둘이면 한 사람으로 합쳐집니다.
  • 프롬프트와 조회 조건이 어긋남 — 시스템 프롬프트는 "지난 7일(월~금)"이라 설명하지만, 실제 조회 조건은 요일과 무관한 최근 7일입니다. 금요일이 아닌 날 돌면 두 설명이 어긋납니다.

포트폴리오·면접 포인트​

포트폴리오에는 이 구조를 그대로 재현했다는 설명보다, 원본에서 끊어져 있던 연결(스케줄과 리포트 체인, Supabase와 Data Table)을 스스로 찾아 고쳤다는 한 문단이 더 강한 인상을 줍니다. 튜토리얼을 따라간 사람과, 실제 워크플로우를 읽고 무엇이 작동하지 않는지 진단한 사람은 다르게 보입니다.

면접에서 "왜 대화를 시트가 아니라 DB에 쌓았나요?"라는 질문이 오면, 메시지 볼륨이 쌓일수록 시트는 전체를 읽어 걸러내야 하지만 DB는 조건으로 원하는 기간만 바로 받아온다고 답하면 됩니다. "실시간 수집과 정기 리포트를 왜 같은 트리거로 묶지 않았나요?"에는, 메시지는 언제 올지 예측할 수 없어 이벤트 트리거가 맞고 리포트는 정해진 시각에 한 번이면 되니 트리거 종류 자체가 다르다고 답할 수 있습니다.

다음 액션​

다음 편부터는 쌓아둔 데이터를 다시 찾아 쓰는 쪽으로 넘어갑니다. 내 문서를 업로드하면 그 내용을 근거로 답하는 RAG 챗봇을 n8n으로 만드는 편입니다. 이번 편의 "데이터를 쌓아두고 나중에 AI가 읽는다"는 구조가, 다음 편에서는 "쌓아둔 문서를 검색해서 그 자리에서 답한다"는 구조로 이어집니다.