Case studies
CASE STUDY — AI

Daily sales reports — pulled from Postgres, summarized by AI, posted to Slack every morning

Deployed at E-commerce4 days to build
PostgresOpenAISlackn8n Schedule

Every morning someone spent 30 minutes opening a sheet, tallying the numbers, comparing to the day before, and writing a comment. Whenever the person changed, the format and the baselines wobbled with them.

The data was already in the database. What was missing was a pair of hands to put it into the same shape every day. We replaced those hands with a workflow. Two aggregation queries run against Postgres, GPT turns the results into a 3–4 sentence Korean summary, and it posts to #daily-sales automatically.

sales-report.workflowLIVE
CREvery day at 06:00PGAggregate dataAIAI summarySLPost to Slack

How it works

  1. A Schedule Trigger node fires on a cron at 6:00 AM KST every day.
  2. Two Postgres queries — one aggregates yesterday's sales (order count, revenue, unique customers, top channel); the other aggregates the day before yesterday's sales (for day-over-day deltas).
  3. A Code node merges the two results, formats numbers with won-unit commas (e.g. 1,666,500원) and % deltas, and builds the full messages array to send to the OpenAI API.
  4. An HTTP Request node POSTs to https://api.openai.com/v1/chat/completions — reusing n8n's openAiApi credential, but calling via HTTP Request rather than the OpenAI node. Why is explained in the 'Tech notes' section below.
  5. A Slack Send Message node posts the AI summary together with the raw numbers to the #daily-sales channel.

What you need

  • n8n 2.29.9 or later (self-hosted or Cloud). Verified on self-hosted Docker.
  • A Postgres database — an orders table with columns id, order_no, customer_id, total (numeric), channel (text), order_date (date). If your schema differs, only the two SQL queries need editing.
  • An OpenAI API key — from platform.openai.com, with a billing method attached (without one, the API just returns the Welcome to the OpenAI API! help text). Register in n8n Credentials as OpenAI account.
  • Slack Bot User OAuth Tokenchat:write, channels:read scopes. Starts with xoxb-. Register in n8n Credentials as Slack API.
  • A Slack channel to receive the report. /invite @your-bot required.
  • GPT cost: under ₩100/month at one run per day (gpt-4o-mini, prompt context around 300 tokens).

Sample SQL schema

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()
);

Example of the actual Slack message

📈 *어제 매출 리포트 · 2026-07-14*

전일 매출 총액은 1,666,500원으로, 전전일 대비 84.1% 증가하였습니다. 주문 건수는 10건으로 66.7% 증가하였으며, 이 중 웹 채널에서 가장 높은 매출을 기록하였습니다. 특히 고객 수가 7명으로 늘어나 재구매가 활발히 이루어진 것으로 보입니다.

_원본 수치_ · 주문 10 · 매출 1,666,500원 · 평균주문가 166,650원 · 고유고객 7명 · 매출 +84.1%
⬇︎ Download workflow (sales-report.json)
Drop in the three credentials (Postgres · OpenAI · Slack) and the channel name and it runs. The SQL queries assume the sample schema above — if yours differs, only the two Postgres nodes need editing.
This workflow was verified on n8n 2.29.9 against a real Postgres 17 container, OpenAI API, and Slack workspace. Confirmed on both the normal-data path and the zero-orders path (AI generates a "revenue ₩0, 100% down" summary). Last verified: 2026-07-15.

Tech notes — why HTTP Request instead of n8n's OpenAI node

  • As of 2026-07, n8n's OpenAI node (typeVersion 1.7) has an issue where, under certain conditions, its request shape triggers the Welcome to the OpenAI API! help text from the OpenAI API — instead of an actual completion, you get the help string.
  • Attaching the same openAiApi credential to an HTTP Request node via Authentication → Predefined Credential Type → OpenAI API returns a normal completion. The credential is identical; the payload is explicit, which also makes debugging easier.
  • We reuse this pattern in the other AI cases (cs-triage, meeting-notes) as well. If n8n's OpenAI node stabilizes, we can swap back — but today HTTP Request wins on production reliability.

Edge-case handling

  • Zero orders yesterday — both Postgres queries wrap total in COALESCE(sum(total), 0), so no NULL propagates. The AI produces a "revenue ₩0" summary and it posts to Slack normally (letting you see the fact that there were no sales at all).
  • OpenAI API errors — by default, HTTP Request fails the workflow on error. Immediately visible in the n8n Executions tab. In production, enable the node's Retry on Fail option to absorb transient rate limits.
  • Slack bot not invited to the channel — the Slack API returns not_in_channel and the workflow errors out. Confirm the invite before enabling.
  • Time zone — the cron uses the n8n instance's system time zone. Set TZ=Asia/Seoul on the n8n container to make the 06:00 KST schedule fire correctly.
30 min → 0 min
Daily report drafting
06:00 daily
Automatic posting
365 days
Without a miss
₩100/mo
GPT cost
The boss complimented me on the morning report. I didn't actually write it.Operations associate

Your operation belongs
in here, too.

Tell us the most repetitive task you have. We'll map an automation scenario for it.