발행일: 2026-10-06(화) 11:44
← 목차로 돌아가기|하루 30분 n8n 시리즈 ② 실무 자동화 레시피 100
RECIPE 050

월간 고객 응대 성과 리포트 자동 생성

  • ▸영어 뉴스 RSS 피드를 자동으로 수집할 수 있다
  • ▸OpenAI로 영문 기사를 한국어로 번역 및 요약할 수 있다
  • ▸정리된 내용을 매일 아침 이메일 또는 Slack으로 자동 발송할 수 있다

✅사전 준비

  • □OpenAI API 자격증명 연결 완료
  • □영어 뉴스 RSS URL 준비 (TechCrunch, The Verge, Wired 등)
  • □Gmail 또는 Slack 자격증명 연결 완료
  • □Schedule Trigger: 평일 오전 7시 (Cron: 0 7 * * 1-5)

주요 영어 뉴스 RSS URL

TechCrunch:  https://techcrunch.com/feed/
The Verge:   https://www.theverge.com/rss/index.xml
Wired:       https://www.wired.com/feed/rss
Hacker News: https://hnrss.org/frontpage
MIT Tech:    https://www.technologyreview.com/feed/

번역 + 요약 — OpenAI 프롬프트

Model: gpt-4o-mini

Prompt:
다음 영문 뉴스 기사 제목과 요약을 한국어로 번역하고,
한국 IT 독자 관점에서 왜 중요한지 한 줄로 설명해줘.

형식:
- 제목(번역): ...
- 핵심 내용: ...
- 왜 중요한가: ...

원문 제목: {{ $json.title }}
원문 요약: {{ $json.contentSnippet?.slice(0, 500) }}

뉴스레터 HTML 조립 — Code 노드

const items = $input.all();
const rows = items.map((i, idx) => {
  const lines = i.json.message.content.split('\n').filter(Boolean);
  return `<div style='margin-bottom:20px;padding:16px;background:#f8f9fa;border-radius:8px'>
    <b>${idx + 1}. </b>${lines.join('<br>')}
    <br><a href='${i.json.link}' style='font-size:12px;color:#666'>원문 읽기 ↗</a>
  </div>`;
}).join('');

return [{ json: {
  html: `<div style='max-width:600px;font-family:sans-serif'>
    <h2>🌍 오늘의 글로벌 IT 뉴스</h2>
    <p style='color:#666'>${new Date().toLocaleDateString('ko-KR')}</p>
    ${rows}
  </div>`,
} }];
💡 TIP기사 5~7개가 뉴스레터 읽기 적당한 분량입니다. RSS 피드에서 SplitInBatches로 상위 5개만 잘라내면 OpenAI 비용도 줄이고 가독성도 높일 수 있어요.
⚡

워크플로우 JSON

아래 JSON을 복사해 n8n에 바로 임포트하세요

📥 n8n 임포트 방법
n8n 화면 우측 상단 메뉴 (⋮) → Import from JSON → 아래 JSON 전체 복사 후 붙여넣기 → Import 클릭
{
  "recipeId": "recipe050",
  "title": "월간 고객 응대 성과 리포트 자동 생성",
  "chapter": 4,
  "category": "고객 응대 자동화",
  "difficulty": "⭐⭐",
  "estimatedTime": "35분",
  "usedApps": [
    "Zendesk API",
    "Google Sheets",
    "Slack"
  ],
  "description": "매월 1일 오전 9시에 Zendesk에서 지난 달 티켓 처리 건수·평균 응답 시간·CSAT 점수를 수집하여 Google Sheets에 월별 누적 기록하고 Slack 채널에 요약 리포트를 발송합니다.",
  "nodes": [
    {
      "id": "trigger_schedule",
      "type": "trigger",
      "service": "Schedule",
      "name": "매월 1일 오전 9시",
      "config": {
        "interval": "monthly",
        "dayOfMonth": 1,
        "time": "09:00"
      }
    },
    {
      "id": "get_ticket_stats",
      "type": "action",
      "service": "HTTP Request",
      "name": "Zendesk 지난달 통계 조회",
      "config": {
        "method": "GET",
        "url": "https://{{$env.ZENDESK_DOMAIN}}.zendesk.com/api/v2/reports/overview.json",
        "authentication": "basicAuth",
        "username": "{{$env.ZENDESK_EMAIL}}/token",
        "password": "{{$env.ZENDESK_API_TOKEN}}",
        "queryParams": {
          "start_time": "{{$now.minus({months: 1}).startOf('month').toUnixInteger()}}",
          "end_time": "{{$now.minus({months: 1}).endOf('month').toUnixInteger()}}"
        }
      }
    },
    {
      "id": "get_csat",
      "type": "action",
      "service": "HTTP Request",
      "name": "CSAT 점수 조회",
      "config": {
        "method": "GET",
        "url": "https://{{$env.ZENDESK_DOMAIN}}.zendesk.com/api/v2/satisfaction_ratings.json",
        "authentication": "basicAuth",
        "username": "{{$env.ZENDESK_EMAIL}}/token",
        "password": "{{$env.ZENDESK_API_TOKEN}}",
        "queryParams": {
          "start_time": "{{$now.minus({months: 1}).startOf('month').toUnixInteger()}}",
          "end_time": "{{$now.minus({months: 1}).endOf('month').toUnixInteger()}}"
        }
      }
    },
    {
      "id": "calc_metrics",
      "type": "action",
      "service": "Function",
      "name": "지표 계산",
      "config": {
        "code": "const stats = $node['get_ticket_stats'].json;\nconst csatData = $node['get_csat'].json['satisfaction_ratings'];\n\nconst totalTickets = stats.tickets_solved || 0;\nconst avgReplyTime = Math.round((stats.avg_reply_time_in_minutes || 0));\n\nconst goodRatings = csatData.filter(r => r.score === 'good').length;\nconst csatScore = csatData.length > 0 \n  ? Math.round((goodRatings / csatData.length) * 100) \n  : 0;\n\nconst lastMonth = new Date();\nlastMonth.setMonth(lastMonth.getMonth() - 1);\nconst monthLabel = `${lastMonth.getFullYear()}년 ${lastMonth.getMonth() + 1}월`;\n\nreturn [{ json: { monthLabel, totalTickets, avgReplyTime, csatScore, totalRatings: csatData.length } }];"
      }
    },
    {
      "id": "record_sheet",
      "type": "action",
      "service": "Google Sheets",
      "name": "월간 시트 기록",
      "config": {
        "operation": "appendRow",
        "spreadsheetId": "{{$env.CS_REPORT_SHEET_ID}}",
        "sheetName": "월간성과",
        "row": {
          "기준월": "{{$json['monthLabel']}}",
          "총처리건수": "{{$json['totalTickets']}}",
          "평균응답시간(분)": "{{$json['avgReplyTime']}}",
          "CSAT점수(%)": "{{$json['csatScore']}}",
          "응답건수": "{{$json['totalRatings']}}"
        }
      }
    },
    {
      "id": "send_report",
      "type": "action",
      "service": "Slack",
      "name": "Slack 리포트 발송",
      "config": {
        "operation": "sendMessage",
        "channel": "{{$env.CS_SLACK_CHANNEL}}",
        "message": "📊 {{$json['monthLabel']}} 고객 응대 성과 리포트\n\n🎫 총 처리 건수: {{$json['totalTickets']}}건\n⏱ 평균 첫 응답 시간: {{$json['avgReplyTime']}}분\n😊 고객 만족도(CSAT): {{$json['csatScore']}}% ({{$json['totalRatings']}}건 응답)\n\n👉 상세 리포트 보기: {{$env.CS_REPORT_SHEET_URL}}"
      }
    }
  ],
  "edges": [
    {
      "from": "trigger_schedule",
      "to": "get_ticket_stats"
    },
    {
      "from": "trigger_schedule",
      "to": "get_csat"
    },
    {
      "from": "get_ticket_stats",
      "to": "calc_metrics"
    },
    {
      "from": "get_csat",
      "to": "calc_metrics"
    },
    {
      "from": "calc_metrics",
      "to": "record_sheet"
    },
    {
      "from": "record_sheet",
      "to": "send_report"
    }
  ],
  "tips": [
    "get_ticket_stats와 get_csat 노드는 병렬로 실행하고 Merge 노드로 합친 뒤 calc_metrics에 넘기면 실행 시간을 단축할 수 있어요.",
    "전월 대비 CSAT 증감률을 계산하려면 시트에서 이전 달 값을 함께 읽어와 비교하는 단계를 추가하세요.",
    "Zendesk 대신 채널톡을 사용하는 경우 레시피 048에서 누적한 Google Sheets 데이터를 집계 소스로 활용하세요."
  ],
  "qrUrl": "www.koreaaitimes.com/books/n8n-vol2/recipe050"
}
← 이전 레시피☰ 목차다음 레시피 →