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 클릭
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"
}