매일 아침 한 명이 30분씩 시트를 열어 수치를 정리하고, 전날과 비교해 코멘트를 달아 공유했습니다. 사람이 바뀌면 양식과 기준도 흔들렸습니다.
데이터는 이미 데이터베이스 안에 다 있었습니다. 빠진 건 그걸 매일 같은 모양으로 정리해 주는 손이었죠. 그 손을 워크플로우로 대체했습니다. Postgres에서 두 개의 집계 쿼리를 돌리고, 결과를 GPT에게 넘겨 3–4문장 한국어 요약을 만들고, #daily-sales 채널로 자동 발송합니다.
CR매일 06:00PG데이터 집계AIAI 요약SLSlack 발송
어떻게 동작하나
Schedule Trigger노드가 매일 오전 6시(KST) 크론으로 시작합니다.- 두 개의 Postgres 쿼리 — 하나는 어제 매출 집계(주문 수, 매출, 고유 고객, 최상위 채널), 다른 하나는 전전일 매출 집계(전일 대비 증감 계산용).
Code노드가 두 결과를 병합해 원 단위 콤마 포맷(예:1,666,500원)과 % 증감 지표를 계산하고, OpenAI API에 보낼 messages 배열을 통째로 준비합니다.HTTP Request노드가https://api.openai.com/v1/chat/completions로 POST — 자격증명은 n8n의openAiApicredential을 재사용하되, OpenAI 노드가 아닌 HTTP Request를 쓰는 이유는 아래 '기술 노트'에 정리했습니다.Slack Send Message노드가 AI 요약과 원본 수치를 함께#daily-sales채널로 게시합니다.
필요한 것
- n8n 2.29.9 이상 (자체 호스팅 또는 Cloud). 검증은 자체 호스팅 Docker에서 진행했습니다.
- Postgres 데이터베이스 —
orders테이블에id, order_no, customer_id, total (numeric), channel (text), order_date (date)컬럼. 다른 스키마여도 두 SQL 쿼리만 수정하면 됩니다. - OpenAI API key —
platform.openai.com에서 발급, 결제 수단 등록 필수 (없으면 API가Welcome to the OpenAI API!안내 텍스트만 반환합니다). n8n Credentials에OpenAI account로 등록. - Slack Bot User OAuth Token —
chat:write,channels:read스코프.xoxb-로 시작. n8n Credentials에Slack API로 등록. - Slack 채널 — 리포트를 받을 채널.
/invite @your-bot필수. - GPT 비용: 하루 한 번 실행 기준 월 100원 미만 (
gpt-4o-mini, 프롬프트 컨텍스트 300 토큰 내외).
샘플 SQL 스키마
CREATE TABLE orders (
id bigserial PRIMARY KEY,
order_no text NOT NULL,
customer_id bigint NOT NULL,
total numeric(12,2) NOT NULL,
channel text NOT NULL, -- 'web' | 'naver-store' | 'coupang' | 'kakao-channel' | ...
order_date date NOT NULL,
created_at timestamptz NOT NULL DEFAULT now()
);실제 발송되는 Slack 메시지 예시
📈 *어제 매출 리포트 · 2026-07-14*
전일 매출 총액은 1,666,500원으로, 전전일 대비 84.1% 증가하였습니다. 주문 건수는 10건으로 66.7% 증가하였으며, 이 중 웹 채널에서 가장 높은 매출을 기록하였습니다. 특히 고객 수가 7명으로 늘어나 재구매가 활발히 이루어진 것으로 보입니다.
_원본 수치_ · 주문 10 · 매출 1,666,500원 · 평균주문가 166,650원 · 고유고객 7명 · 매출 +84.1%⬇︎ 워크플로우 다운로드 (sales-report.json)
Postgres · OpenAI · Slack 세 개 자격증명 + 채널 이름만 넣으면 즉시 실행됩니다. SQL 쿼리는 예시 스키마 기준; 다른 스키마라면 두 개의 Postgres 노드만 수정하세요.
이 워크플로우는 n8n 2.29.9에서 실제 Postgres 17 컨테이너 + OpenAI API + Slack 워크스페이스에 붙여 검증했습니다. 정상 데이터가 있을 때 · 어제 주문이 0건일 때(AI가 "매출 0원, 100% 감소" 요약 생성) 모두 확인. 마지막 검증: 2026-07-15.
기술 노트 — 왜 n8n의 OpenAI 노드가 아니라 HTTP Request인가
- n8n의 OpenAI 노드(
typeVersion 1.7, 2026-07 시점)는 요청 구성 방식이 특정 조건에서 OpenAI API로부터Welcome to the OpenAI API!안내 텍스트를 유발하는 이슈가 있어, 실제 completions 대신 안내 문구가 반환됩니다. - 동일한
openAiApi자격증명을 HTTP Request 노드에Authentication → Predefined Credential Type → OpenAI API로 붙이면 정상 completion이 반환됩니다. 자격증명은 완전히 동일하며, 요청 페이로드가 명시적이라 디버깅도 쉽습니다. - 이 패턴은 다른 AI 케이스(
cs-triage,meeting-notes)에도 그대로 재사용합니다. 향후 n8n의 OpenAI 노드가 안정화되면 교체 가능하지만, 지금은 HTTP Request가 프로덕션 신뢰성 면에서 우위.
예외 상황 처리
- 어제 주문 0건 — 두 Postgres 쿼리 모두
COALESCE(sum(total), 0)로 감싸 NULL이 오지 않습니다. AI가 "매출 0원" 요약을 생성하고 Slack에 정상 게시됩니다 (아침에 매출 발생 여부 자체를 확인할 수 있음). - OpenAI API 오류 — HTTP Request는 기본적으로 실패 시 워크플로우를 에러로 종료합니다. n8n Executions 탭에서 즉시 확인. 프로덕션에서는 노드 옵션
Retry on Fail을 켜서 일시적 rate limit을 흡수할 수 있습니다. - Slack 채널에 봇이 초대되지 않음 — Slack API가
not_in_channel을 반환해 에러로 종료. 채널 초대 상태 사전 확인 필수. - 타임존 — 크론은 n8n 인스턴스의 시스템 타임존을 따릅니다.
TZ=Asia/Seoul환경변수를 n8n 컨테이너에 설정하면 06:00 KST 스케줄이 정확히 동작합니다.
30분 → 0분
일일 리포트 작성
매일 06:00
자동 발송
365일
빠짐없이
월 100원
GPT 비용
사장님이 아침 리포트로 저를 칭찬했어요. 사실 제가 한 게 아닙니다.— 운영 주임