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

재고 10개 미만이면 슬랙으로 알려주는 n8n 워크플로우 — 첫 자동화로 이걸 추천하는 이유

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

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

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

구글시트에 재고 관리표가 있다면, n8n 노드 5개로 매시간 재고 10개 미만 상품만 골라 슬랙으로 받는 알림을 만들 수 있습니다. 스케줄 트리거, 조건 필터, 메시지 조립이라는 자동화의 기본 패턴 세 가지가 한 워크플로우에 다 들어가서, 취준생이 포트폴리오에 넣을 첫 워크플로우로 이만한 게 없습니다.

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

면접에서 "n8n 써봤어요"라고 말하면 바로 따라오는 질문이 "뭘 만들었는데요?"입니다. 이 워크플로우는 그 질문에 한 문장으로 답할 수 있게 해줍니다. "재고표를 매시간 읽어서 임계값 아래로 떨어진 상품만 슬랙으로 보내는 알림을 만들었습니다."

짧은 문장이지만 안에 들어간 역량은 세 가지입니다.

  • 스케줄 운영 — 사람이 실행 버튼을 누르지 않아도 정해진 주기로 도는 자동화를 켜본 경험
  • 조건 필터링 — 전체 데이터에서 조건에 맞는 행만 남기고, 조건에 맞는 게 없으면 아무 일도 하지 않게 설계한 경험
  • 메시지 조립 — 여러 행을 사람이 읽기 좋은 메시지 한 통으로 합쳐본 경험

이 세 가지는 재고 알림뿐 아니라 매출 급감 알림, 서버 에러 건수 알림, 신규 가입자 알림처럼 "숫자가 조건을 넘으면 알려줘" 유형의 자동화 전부에 그대로 쓰입니다. 하나를 만들면 나머지는 시트와 조건만 바꾸는 일이 됩니다.

배경 — 매일 아침 시트를 열어 눈으로 훑는 일​

작은 이커머스 팀의 재고 확인은 대개 이렇습니다. 구글시트에 상품명, 현재재고, 일평균판매량이 정리돼 있고, 담당자가 매일 아침 시트를 열어 위에서 아래로 훑으며 "이거 곧 떨어지겠네"를 찾습니다. 상품이 30개면 30줄을 봐야 하고, 바쁜 날은 건너뛰고, 건너뛴 날 품절이 납니다.

이 워크플로우는 데이터팝콘 n8n 인스턴스에 교육용으로 만들어 둔 것입니다. 캔버스의 스티키 노트에 단계마다 "이 노드는 왜 있는지"가 적혀 있고 노드도 최소한으로 줄여 놓아서, 처음 만들어보는 사람이 구조를 한눈에 이해하기 좋습니다. 설치나 기본 노드 설명은 n8n으로 반복업무 자동화 포트폴리오 만들기에 정리돼 있으니, 이 글에서는 워크플로우 자체만 다룹니다.

구조 — Trigger / Task / Target​

데이터팝콘은 워크플로우를 설계할 때 항상 세 칸으로 나눠 적습니다. 언제 시작하는가(Trigger), 무엇을 하는가(Task), 결과를 어디로 보내는가(Target). 이 워크플로우는 세 칸이 아래처럼 채워집니다.

  • Trigger — 1시간 간격 스케줄
  • Task — 시트 읽기 → 재고 10개 미만만 남기기 → 필요한 컬럼만 추리기 → 메시지로 합치기
  • Target — 슬랙 채널

여기에 본 흐름과 분리된 작은 워크플로우가 하나 더 붙어 있습니다. 슬랙 봇을 알림 채널에 입장시키는 한 줄짜리 흐름인데, 처음 한 번만 실행합니다. 왜 따로 두는지는 아래에서 설명합니다.

만들기​

0. 시트 준비​

시트에는 헤더 행에 상품명, 현재재고, 일평균판매량 세 컬럼만 있으면 됩니다. 컬럼이 더 있어도 상관없습니다. 뒤에서 필요한 세 개만 골라내기 때문입니다. 실습이라면 상품 10개 정도를 넣고, 그중 두세 개는 재고를 10 미만으로 적어두세요. 그래야 알림이 실제로 오는 걸 볼 수 있습니다.

1. 슬랙 봇을 채널에 먼저 입장시키기​

Slack 노드로 메시지를 보내려면 봇이 그 채널의 멤버여야 합니다. 봇이 채널에 없는 상태로 전송하면 not_in_channel 에러가 납니다. 그래서 이 워크플로우는 Manual Trigger → Slack 노드(Resource: Channel, Operation: Join) 두 개짜리 흐름을 본 흐름 옆에 따로 두고, 처음 한 번만 실행해 봇을 입장시킵니다.

채널 ID는 슬랙에서 채널 이름을 우클릭 → 채널 세부정보 보기 → 화면 하단에서 확인할 수 있습니다. 본 흐름의 Send a message 노드에도 같은 채널 ID를 넣습니다.

2. Schedule Trigger — 1시간마다​

Schedule Trigger 노드에서 Trigger Interval을 Hours, Hours Between Triggers를 1로 둡니다. 실습 중에는 이 노드를 기다리지 말고 캔버스 상단의 Execute workflow 버튼으로 바로 실행해서 확인하면 됩니다. 스케줄이 실제로 돌기 시작하는 건 마지막에 Active 토글을 켠 뒤부터입니다.

3. Google Sheets — 시트 읽기​

Google Sheets 노드에서 Operation을 Get Row(s)로 두고 문서와 시트를 고릅니다. 실행하면 시트의 행 하나가 n8n의 아이템 하나가 되어 다음 노드로 넘어갑니다. 이 시점에 오른쪽 출력 패널에서 컬럼명이 현재재고처럼 시트 헤더 그대로 들어오는지 확인해두세요. 다음 노드의 조건식이 이 컬럼명을 그대로 씁니다.

4. Filter — 현재재고가 10 미만인 행만​

Filter 노드에 조건 하나를 넣습니다.

  • 왼쪽 값: {{ $json['현재재고'] }}
  • 연산자: Number → is less than
  • 오른쪽 값: 10

컬럼명이 한글이라 $json.현재재고 대신 대괄호 표기 $json['현재재고']를 썼습니다. 점 표기도 대부분 동작하지만, 컬럼명에 공백이나 특수문자가 섞이는 순간 깨지기 때문에 시트 컬럼을 참조할 때는 대괄호로 통일해두는 편이 안전합니다.

이 노드의 중요한 성질이 하나 있습니다. 조건에 맞는 행이 0개면 워크플로우는 여기서 조용히 끝납니다. 뒤의 Set, Code, Slack 노드는 실행되지 않고, 알림도 가지 않습니다. 재고가 전부 넉넉한 시간에 "부족한 상품 없음" 같은 빈 메시지가 오지 않는 건 이 성질 덕분입니다. 처음에는 "왜 슬랙에 아무것도 안 오지?"라고 당황하기 쉬운데, 시트에 10 미만인 상품이 하나도 없어서 그런 경우가 대부분입니다.

5. Set — 필요한 컬럼 세 개만​

Edit Fields(Set) 노드에서 상품명(String), 현재재고(Number), 일평균판매량(Number) 세 필드만 남깁니다. 시트에 컬럼이 열 개 있어도 알림에는 세 개면 충분하고, 다음 Code 노드가 다룰 데이터도 그만큼 단순해집니다.

6. Code — 여러 행을 메시지 한 통으로​

여기가 이 워크플로우에서 유일하게 코드를 쓰는 곳입니다. Filter를 통과한 상품이 3개면 아이템도 3개인데, 슬랙 메시지는 3통이 아니라 1통으로 받고 싶습니다. Code 노드(Run Once for All Items)에서 아이템 전체를 문자열 하나로 합칩니다.

// 헤더에 총 개수 추가
let message = `📣 *10개 미만 재고 알림* (총 ${items.length}개)\n\n`;
message += `_일평균판매량은 최근 일주일 평균 판매량입니다._\n\n\n`;

// 각 상품 정보 추가
message += items.map(item => {
return `📦 *${item.json.상품명}*
재고: ${item.json.현재재고}개 | 일평균판매량: ${item.json.일평균판매량}개`;
}).join('\n\n\n');

return [{
json: {
text: message
}
}];

items는 이 노드로 들어온 아이템 전체이고, items.length가 부족 상품 개수가 됩니다. 마지막에 text 필드 하나만 가진 아이템 1개를 돌려주기 때문에, 다음 Slack 노드는 이 text를 그대로 보내기만 하면 됩니다.

7. Slack — 전송하고 Active 켜기​

Send a message 노드에서 채널을 1번에서 입장시킨 채널로 고르고, Text에 {{ $json.text }}를 넣습니다. Execute workflow로 한 번 돌려 메시지가 도착하는 걸 확인한 뒤, 캔버스 상단의 Inactive 토글을 Active로 바꾸면 그때부터 매시간 자동으로 돕니다.

원본 캔버스에 남아 있는 두 가지 경고​

이 워크플로우는 교육용이라 한 달치 운영 데이터 같은 건 없습니다. 대신 원본 캔버스의 스티키 노트에 만든 사람이 일부러 적어 둔 경고가 두 개 있어서 그걸 옮깁니다. 둘 다 처음 만들 때 실제로 부딪히는 지점입니다.

첫째는 채널 입장 흐름을 "처음 1회만 실행"하라는 메모입니다. 이걸 건너뛰고 바로 Send a message를 실행하면 not_in_channel 에러를 만납니다. 봇도 채널 멤버여야 한다는 사실은 한 번 겪으면 잊지 않습니다. 둘째는 Filter 노드 옆의 "10개 미만인 상품이 없을 경우 워크플로우가 여기서 종료되며 알림이 발송되지 않습니다"라는 메모입니다. 실행 결과 화면에서 Filter 노드의 출력이 "0 items"이고 뒤 노드가 회색이면 에러가 아니라 정상 동작입니다.

한계 — 그대로 운영에 쓰기엔 세 가지가 빠져 있습니다​

실습용이라 의도적으로 뺀 것들인데, 포트폴리오로 가져가려면 이 세 가지를 스스로 채워보는 걸 권합니다.

  1. 중복 알림 — 1시간마다 도는데 재고가 채워지지 않으면 같은 상품이 매시간 다시 올라옵니다. 시트에 마지막 알림 시각 컬럼을 두고 하루 한 번만 보내게 하거나, 스케줄을 매일 아침 한 번으로 바꾸는 게 현실적입니다.
  2. 임계값 하드코딩 — "10개 미만"이 Filter 노드 안에 박혀 있습니다. 시트에 알림 기준 컬럼을 추가하고 {{ $json['현재재고'] < $json['알림 기준'] }}처럼 상품별로 다르게 비교하면 운영자가 n8n을 열지 않고도 기준을 바꿀 수 있습니다.
  3. 소진 예상일 없음 — 일평균판매량을 가져오면서 정작 계산에는 안 씁니다. 현재재고 / 일평균판매량으로 며칠 뒤 품절인지 계산해서 메시지에 넣으면 알림의 가치가 확 올라갑니다. Code 노드에 한 줄이면 됩니다.

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

포트폴리오에는 워크플로우 캔버스 스크린샷과 실제 도착한 슬랙 메시지 캡처 두 장이면 충분합니다. 거기에 위의 한계 세 가지 중 하나를 직접 고쳐서 "처음 버전에서 이 문제를 발견하고 이렇게 바꿨다"는 한 문단을 붙이면, 따라 만든 사람과 문제를 이해한 사람이 구분됩니다.

면접에서는 "왜 슬랙 메시지를 상품마다 보내지 않고 한 통으로 합쳤나요?" 같은 질문이 올 수 있습니다. 답은 간단합니다. 부족 상품이 8개면 알림 8통은 소음이고, 한 통에 정리된 목록이 담당자가 실제로 원하는 형태이기 때문입니다. 이런 답을 할 수 있으면 노드 사용법이 아니라 사용자 관점에서 설계했다는 인상을 줍니다.

다음 액션​

같은 구조로 시트 대신 외부 API를 읽는 편이 이어집니다. 날씨 API를 매일 아침 디스코드로 보내는 워크플로우인데, 이 글의 Google Sheets 노드 자리에 HTTP Request 노드가 들어가는 것 말고는 뼈대가 같습니다. 그다음에는 워크플로우가 실패했을 때 조용히 멈추지 않도록 Error Trigger를 붙이는 편으로 넘어갑니다. 이 두 편까지 만들면 "운영까지 고려한 자동화"를 포트폴리오에 쓸 수 있습니다.