RECIPE 036
계약 만료 30일 전 자동 갱신 제안 이메일
- ▸Google Drive 특정 폴더의 파일을 다른 폴더 또는 Dropbox에 자동 백업할 수 있다
- ▸마지막 백업 이후 변경된 파일만 선택적으로 백업할 수 있다
- ▸백업 완료 후 결과를 Slack으로 리포트할 수 있다
✅사전 준비
- □Google Drive 자격증명 연결 완료 (원본 폴더)
- □백업 대상 서비스 자격증명 연결 완료 (Drive 다른 계정 또는 Dropbox)
- □Google Sheets에 백업 이력 저장용 시트 생성
- □Schedule Trigger: 매일 오전 2시 (Cron: 0 2 * * *)
변경 파일만 필터링 — Code 노드
const files = $('Drive File List').all().map(i => i.json);
const lastBackup = $('Sheets Last Backup').first().json.lastBackupTime;
const changed = files.filter(f =>
new Date(f.modifiedTime) > new Date(lastBackup)
);
return changed.map(f => ({ json: f }));Drive → Drive 복사 — HTTP Request
URL: https://www.googleapis.com/drive/v3/files/{{ $json.id }}/copy
Method: POST
Authentication: Google OAuth2
Body (JSON):
{
"name": "{{ $json.name }}",
"parents": ["BACKUP_FOLDER_ID"]
}Slack 백업 완료 리포트
✅ 백업 완료
백업 파일 수: {{ $input.all().length }}개
완료 시각: {{ $now.toFormat('yyyy-MM-dd HH:mm') }}
백업 위치: Google Drive /백업/{{ $now.toFormat('yyyyMMdd') }}/💡 TIPn8n 클라우드 실행 파일 크기 제한에 주의하세요. 대용량 파일(100MB 이상)은 Drive → Drive 직접 복사(서버사이드 복사)를 사용해야 메모리 초과 없이 처리할 수 있어요.
⚡
워크플로우 JSON
아래 JSON을 복사해 n8n에 바로 임포트하세요
📥 n8n 임포트 방법
n8n 화면 우측 상단 메뉴 (⋮) → Import from JSON → 아래 JSON 전체 복사 후 붙여넣기 → Import 클릭
n8n 화면 우측 상단 메뉴 (⋮) → Import from JSON → 아래 JSON 전체 복사 후 붙여넣기 → Import 클릭
{
"recipeId": "recipe036",
"title": "계약 만료 30일 전 자동 갱신 제안 이메일",
"chapter": 3,
"category": "영업 & 리드 관리 자동화",
"difficulty": "⭐⭐",
"estimatedTime": "30분",
"description": "계약 만료일 30일 전인 고객을 구글 시트에서 자동 필터링하여 갱신 안내 이메일을 발송하고, 담당 영업사원 Slack에 완료 알림을 보냅니다.",
"apps": [
"Google Sheets",
"Gmail",
"Slack"
],
"nodes": [
{
"id": "trigger_schedule",
"type": "trigger",
"name": "Schedule Trigger - 매일 오전 9시",
"service": "scheduleTrigger",
"config": {
"rule": "0 9 * * *"
}
},
{
"id": "sheets_read",
"type": "action",
"name": "Google Sheets - 계약 목록 읽기",
"service": "googleSheets",
"config": {
"operation": "readAllRows",
"documentId": "={{ $env.CONTRACT_SHEET_ID }}",
"sheetName": "계약목록"
}
},
{
"id": "function_filter",
"type": "function",
"name": "Function - 만료 30일 전 필터링",
"code": "const target = $now.plus({days: 30}).format('YYYY-MM-DD');\nreturn $input.all().filter(item => item.json['만료일'] === target);"
},
{
"id": "gmail_renewal",
"type": "action",
"name": "Gmail - 갱신 안내 이메일 발송",
"service": "gmail",
"config": {
"to": "={{ $json[\"고객_이메일\"] }}",
"subject": "서비스 계약 갱신 안내 - {{ $json[\"고객명\"] }}님",
"body": "안녕하세요, {{ $json[\"고객명\"] }}님.\n\n이용 중인 서비스 계약이 30일 후 만료될 예정입니다.\n갱신을 원하시면 담당자에게 연락해 주시거나 아래 링크를 통해 신청해 주세요.\n\n감사합니다."
}
},
{
"id": "slack_notify",
"type": "action",
"name": "Slack - 갱신 발송 완료 알림",
"service": "slack",
"config": {
"channel": "={{ $env.SLACK_SALES_CHANNEL }}",
"message": "📩 갱신 안내 이메일 발송 완료!\n고객: {{ $json[\"고객명\"] }}\n만료일: {{ $json[\"만료일\"] }}\n→ 팔로업 전화 준비해주세요."
}
}
],
"connections": [
{
"from": "trigger_schedule",
"to": "sheets_read"
},
{
"from": "sheets_read",
"to": "function_filter"
},
{
"from": "function_filter",
"to": "gmail_renewal"
},
{
"from": "gmail_renewal",
"to": "slack_notify"
}
],
"envVars": [
{
"key": "CONTRACT_SHEET_ID",
"description": "계약 목록 구글 시트 ID"
},
{
"key": "SLACK_SALES_CHANNEL",
"description": "영업팀 Slack 채널 ID"
}
],
"qrCodeUrl": "https://www.koreaaitimes.com/books/n8n-vol2/recipe036"
}