RECIPE 090
학습 진도 자동 추적 → 리마인더 발송
- ▸온라인 학습 플랫폼의 수강 진도를 주기적으로 수집
- ▸목표 진도 대비 현황을 자동 분석
- ▸학습 지연 수강생에게 맞춤 리마인더 자동 발송
✅사전 준비
- □학습 플랫폼 API 또는 수강 데이터 Google Sheets 연동
- □코스별 목표 완료일 및 주차별 목표 진도율 설정
- □Gmail 또는 Slack 알림 설정
- □개인화 메시지 템플릿 2~3가지 준비
진도율 계산 및 지연 분류
// Code 노드
const learners = $input.all();
const today = new Date();
return learners.map(l => {
const startDate = new Date(l.json.start_date);
const endDate = new Date(l.json.end_date);
const totalDays = (endDate - startDate) / 86400000;
const elapsedDays = (today - startDate) / 86400000;
const expectedProgress = Math.min((elapsedDays / totalDays) * 100, 100);
const actualProgress = l.json.completion_rate;
const gap = expectedProgress - actualProgress;
let status = 'on_track';
if (gap >= 20) status = 'critical';
else if (gap >= 10) status = 'behind';
return { json: { ...l.json, expectedProgress, gap, status } };
});리마인더 메시지 개인화
// Switch 노드로 status별 분기
// critical (20% 이상 지연)
제목: {{ $json.name }}님, 지금 바로 학습을 시작하세요!
내용: 현재 진도율이 목표보다 {{ $json.gap.toFixed(0) }}% 낮습니다.
이번 주 목표: {{ $json.this_week_lessons }} 강 완료
// behind (10~20% 지연)
제목: {{ $json.name }}님, 조금만 더 힘내세요!
내용: 현재 {{ $json.actualProgress.toFixed(0) }}% 완료! 주 3강만 들으면 목표 달성!!💡 TIPCron을 매주 월요일 오전 9시(`0 9 * * 1`)로 설정하면 한 주를 시작하는 시점에 리마인더를 보낼 수 있어 학습 동기 부여 효과가 가장 높습니다.
⚡
워크플로우 JSON
아래 JSON을 복사해 n8n에 바로 임포트하세요
📥 n8n 임포트 방법
n8n 화면 우측 상단 메뉴 (⋮) → Import from JSON → 아래 JSON 전체 복사 후 붙여넣기 → Import 클릭
n8n 화면 우측 상단 메뉴 (⋮) → Import from JSON → 아래 JSON 전체 복사 후 붙여넣기 → Import 클릭
{
"recipeId": "recipe090",
"title": "네이버 검색광고 일간 성과 리포트",
"chapter": 8,
"category": "국내 서비스 특화 레시피",
"difficulty": "⭐⭐",
"estimatedTime": "40분",
"usedApps": [
"네이버 검색광고 API",
"Google Sheets",
"Slack"
],
"description": "매일 오전 7시 네이버 검색광고 API로 전일 키워드별 노출수·클릭수·비용·전환수를 자동 수집해 Google Sheets에 누적 기록하고, 주요 지표 요약을 Slack으로 발송합니다.",
"apiGuide": {
"platform": "네이버 검색광고",
"issueUrl": "searchad.naver.com",
"steps": [
"네이버 검색광고 → 도구 → API 관리",
"이용 신청 (심사 필요, 1~2 영업일)",
"API 키 / 시크릿 발급",
"HMAC-SHA256 서명 인증 방식 사용 (Function 노드에서 처리)"
]
},
"nodes": [
{
"id": "node1",
"type": "n8n-nodes-base.scheduleTrigger",
"name": "매일 오전 7시 실행",
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 7 * * *"
}
]
}
}
},
{
"id": "node2",
"type": "n8n-nodes-base.code",
"name": "HMAC-SHA256 서명 생성",
"parameters": {
"jsCode": "const crypto = require('crypto');\nconst timestamp = Date.now().toString();\nconst method = 'GET';\nconst path = '/stats';\nconst message = timestamp + '.' + method + '.' + path;\nconst signature = crypto.createHmac('sha256', $env.NAVER_AD_SECRET_KEY).update(message).digest('base64');\nreturn [{ json: { timestamp, signature } }];"
}
},
{
"id": "node3",
"type": "n8n-nodes-base.httpRequest",
"name": "네이버 검색광고 성과 조회",
"parameters": {
"method": "GET",
"url": "https://api.naver.com/stats",
"headers": {
"X-Timestamp": "={{$json['timestamp']}}",
"X-API-KEY": "={{$env.NAVER_AD_API_KEY}}",
"X-Customer": "={{$env.NAVER_AD_CUSTOMER_ID}}",
"X-Signature": "={{$json['signature']}}"
},
"queryParameters": {
"dateFrom": "={{$now.minus({days: 1}).format('YYYYMMDD')}}",
"dateTo": "={{$now.minus({days: 1}).format('YYYYMMDD')}}",
"timeUnit": "DAY",
"fields": "clkCnt,impCnt,salesAmt,ctr"
}
}
},
{
"id": "node4",
"type": "n8n-nodes-base.googleSheets",
"name": "성과 시트 누적 기록",
"parameters": {
"operation": "appendOrUpdate",
"spreadsheetId": "={{$env.AD_REPORT_SHEET_ID}}",
"sheetName": "네이버광고성과",
"columns": {
"mappingMode": "defineBelow",
"value": {
"날짜": "={{$now.minus({days: 1}).format('YYYY-MM-DD')}}",
"노출수": "={{$json['data'][0]['impCnt']}}",
"클릭수": "={{$json['data'][0]['clkCnt']}}",
"CTR": "={{($json['data'][0]['ctr'] * 100).toFixed(2)}}%",
"광고비": "={{$json['data'][0]['salesAmt']}}"
}
}
}
},
{
"id": "node5",
"type": "n8n-nodes-base.slack",
"name": "일간 성과 요약 발송",
"parameters": {
"channel": "={{$env.MARKETING_SLACK_CHANNEL}}",
"text": "📊 어제 네이버 광고 성과 ({{$now.minus({days: 1}).format('MM/DD')}})\n\n총 노출: {{$node['네이버 검색광고 성과 조회'].json['data'][0]['impCnt'].toLocaleString()}}회\n총 클릭: {{$node['네이버 검색광고 성과 조회'].json['data'][0]['clkCnt'].toLocaleString()}}회\nCTR: {{($node['네이버 검색광고 성과 조회'].json['data'][0]['ctr'] * 100).toFixed(2)}}%\n총 비용: ₩{{$node['네이버 검색광고 성과 조회'].json['data'][0]['salesAmt'].toLocaleString()}}"
}
}
],
"envVariables": {
"NAVER_AD_API_KEY": "네이버 검색광고 API 키",
"NAVER_AD_SECRET_KEY": "네이버 검색광고 API 시크릿 키",
"NAVER_AD_CUSTOMER_ID": "네이버 광고 고객 ID",
"AD_REPORT_SHEET_ID": "Google Sheets 광고 성과 시트 ID",
"MARKETING_SLACK_CHANNEL": "마케팅팀 Slack 채널 ID"
},
"tips": [
"네이버 검색광고 API는 HMAC-SHA256 서명 인증이 필요합니다. Code 노드의 서명 생성 코드가 QR코드 템플릿에 포함되어 있어요.",
"레시피 013(구글 광고 성과 리포트)과 함께 운영하면 구글·네이버 광고 성과를 하나의 시트에서 통합 비교할 수 있어요.",
"CPA(전환당 비용)를 계산하려면 Code 노드에서 '광고비 / 전환수' 수식을 추가하세요."
],
"qrUrl": "www.koreaaitimes.com/books/n8n-vol2/recipe090"
}