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

고객 이탈 예측 → 리텐션 이메일 자동 발송

  • ▸마지막 활동일 기준으로 이탈 위험 고객 자동 식별
  • ▸이탈 위험도에 따른 맞춤 리텐션 메시지 생성
  • ▸Win-back 이메일 시퀀스 자동 발송

✅사전 준비

  • □고객 데이터베이스(Sheets/Airtable/CRM) 접근 권한
  • □마지막 로그인/구매일 데이터 필드 확인
  • □이탈 기준일 설정 (예: 30일/60일/90일 미활동)
  • □Gmail 또는 SendGrid API 설정

이탈 위험 고객 필터링 (Code 노드)

const customers = $input.all();
const now = new Date();

return customers
  .map(c => {
    const lastActive = new Date(c.json.last_active_date);
    const daysSince = Math.floor((now - lastActive) / (1000 * 60 * 60 * 24));
    let riskLevel = 'low';
    if (daysSince >= 90) riskLevel = 'high';
    else if (daysSince >= 60) riskLevel = 'medium';
    else if (daysSince >= 30) riskLevel = 'low_medium';
    return { json: { ...c.json, daysSince, riskLevel } };
  })
  .filter(c => c.json.daysSince >= 30);

리스크 레벨별 이메일 Switch

Node: Switch
Value: {{ $json.riskLevel }}

Case 'low_medium': 30일 미활동 → 새 기능 소개 이메일
Case 'medium': 60일 미활동 → 특별 할인 쿠폰 이메일
Case 'high': 90일 미활동 → 마지막 Win-back 이메일 + 설문
⚠️ 주의이탈 고객 이메일 발송 시 반드시 수신거부(Unsubscribe) 링크를 포함하고, 이미 수신거부한 고객은 필터링해야 합니다. 스팸 신고가 누적되면 도메인 평판이 하락합니다.
⚡

워크플로우 JSON

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

📥 n8n 임포트 방법
n8n 화면 우측 상단 메뉴 (⋮) → Import from JSON → 아래 JSON 전체 복사 후 붙여넣기 → Import 클릭
{
  "recipeId": "recipe066",
  "title": "경비 승인 Slack 버튼 워크플로우",
  "chapter": 6,
  "category": "재무 & 정산 자동화",
  "difficulty": "⭐⭐⭐",
  "estimatedTime": "50분",
  "usedApps": [
    "Google Forms",
    "Slack",
    "Google Sheets"
  ],
  "description": "직원이 구글 폼으로 경비 사전 승인을 신청하면, 팀장 Slack에 승인·반려 버튼이 포함된 메시지를 발송합니다. 팀장이 버튼을 클릭하면 결과가 Google Sheets에 자동 기록되고, 신청자에게 결과 이메일이 자동 발송됩니다.",
  "nodes": [
    {
      "id": "node1",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "name": "경비 신청 폼 제출 감지",
      "parameters": {
        "spreadsheetId": "={{$env.EXPENSE_REQUEST_SHEET_ID}}",
        "sheetName": "경비신청",
        "triggerOn": "rowAdded"
      }
    },
    {
      "id": "node2",
      "type": "n8n-nodes-base.slack",
      "name": "팀장 승인 요청 메시지 발송",
      "parameters": {
        "channel": "={{$env.MANAGER_SLACK_ID}}",
        "text": "💼 경비 승인 요청이 들어왔습니다.",
        "blocks": [
          {
            "type": "section",
            "text": {
              "type": "mrkdwn",
              "text": "*경비 승인 요청*\n신청자: {{$json['신청자']}}\n항목: {{$json['경비항목']}}\n금액: ₩{{$json['금액']}}\n사유: {{$json['사유']}}"
            }
          },
          {
            "type": "actions",
            "elements": [
              {
                "type": "button",
                "text": {
                  "type": "plain_text",
                  "text": "✅ 승인"
                },
                "style": "primary",
                "value": "approved",
                "action_id": "approve_expense"
              },
              {
                "type": "button",
                "text": {
                  "type": "plain_text",
                  "text": "❌ 반려"
                },
                "style": "danger",
                "value": "rejected",
                "action_id": "reject_expense"
              }
            ]
          }
        ]
      }
    },
    {
      "id": "node3",
      "type": "n8n-nodes-base.webhook",
      "name": "Slack 버튼 클릭 수신",
      "parameters": {
        "path": "expense-approval",
        "responseMode": "responseNode"
      }
    },
    {
      "id": "node4",
      "type": "n8n-nodes-base.googleSheets",
      "name": "승인 결과 시트 기록",
      "parameters": {
        "operation": "update",
        "spreadsheetId": "={{$env.EXPENSE_REQUEST_SHEET_ID}}",
        "sheetName": "경비신청",
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "승인여부": "={{$json['payload']['actions'][0]['value'] === 'approved' ? '승인' : '반려'}}",
            "처리일시": "={{$now.format('YYYY-MM-DD HH:mm')}}"
          }
        }
      }
    },
    {
      "id": "node5",
      "type": "n8n-nodes-base.gmail",
      "name": "신청자에게 결과 이메일 발송",
      "parameters": {
        "operation": "send",
        "to": "={{$json['신청자이메일']}}",
        "subject": "[경비 승인] {{$json['payload']['actions'][0]['value'] === 'approved' ? '승인' : '반려'}} 안내",
        "message": "안녕하세요!\n\n경비 승인 결과를 안내드립니다.\n\n항목: {{$json['경비항목']}}\n금액: ₩{{$json['금액']}}\n결과: {{$json['payload']['actions'][0]['value'] === 'approved' ? '✅ 승인' : '❌ 반려'}}\n처리일시: {{$now.format('YYYY-MM-DD HH:mm')}}\n\n감사합니다."
      }
    }
  ],
  "envVariables": {
    "EXPENSE_REQUEST_SHEET_ID": "Google Sheets 경비 신청 시트 ID",
    "MANAGER_SLACK_ID": "팀장 Slack DM ID"
  },
  "tips": [
    "Slack 버튼 클릭 수신을 위해 n8n Webhook 노드의 URL을 Slack App의 Interactivity Request URL에 등록해야 합니다.",
    "금액 기준으로 소액(10만 원 이하)은 자동 승인, 대형 건은 상위 결재자에게 추가 알림을 보내도록 IF 노드를 추가할 수 있어요.",
    "Slack App 생성 및 Interactivity 설정 방법은 QR코드 워크플로우 설명 페이지에서 확인할 수 있어요."
  ],
  "qrUrl": "www.koreaaitimes.com/books/n8n-vol2/recipe066"
}
← 이전 레시피☰ 목차다음 레시피 →