cosmolocal-website/n8n-workflows/04-follow-up-reminders.json

231 lines
6.7 KiB
JSON

{
"name": "Follow-up Reminders — Stale Contacts",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 9,
"triggerAtMinute": 0,
"triggerAtDay": 1
}
]
}
},
"id": "weekly-schedule",
"name": "Weekly Check (Monday 9 AM)",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [240, 300]
},
{
"parameters": {
"method": "GET",
"url": "https://crm.cosmolocal.world/api/v1/objects/people",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer {{ $env.TWENTY_API_KEY }}"
}
]
},
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "limit",
"value": "100"
}
]
},
"options": {}
},
"id": "fetch-all-contacts",
"name": "Fetch All Contacts",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [460, 300]
},
{
"parameters": {
"fieldToSplitOut": "data.people",
"options": {}
},
"id": "split-contacts",
"name": "Split Into Items",
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [680, 300]
},
{
"parameters": {
"jsCode": "const items = $input.all();\nconst staleItems = [];\nconst now = new Date();\nconst STALE_DAYS = 14;\n\nfor (const item of items) {\n const updatedAt = new Date(item.json.updatedAt);\n const daysSinceUpdate = Math.floor((now - updatedAt) / (1000 * 60 * 60 * 24));\n \n if (daysSinceUpdate >= STALE_DAYS) {\n staleItems.push({\n json: {\n ...item.json,\n daysSinceUpdate,\n email: item.json.emails?.primaryEmail || 'N/A',\n fullName: `${item.json.name?.firstName || ''} ${item.json.name?.lastName || ''}`.trim() || 'Unknown'\n }\n });\n }\n}\n\nreturn staleItems.length > 0 ? staleItems : [{ json: { noStaleContacts: true } }];"
},
"id": "filter-stale",
"name": "Filter Stale Contacts (14+ days)",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [900, 300]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "has-stale",
"leftValue": "={{ $json.noStaleContacts }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "notTrue"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "if-has-stale",
"name": "Any Stale Contacts?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [1120, 300]
},
{
"parameters": {
"jsCode": "const items = $input.all();\nconst count = items.length;\n\nconst tableRows = items.map(i => `<tr><td style=\"padding:8px;border:1px solid #e7e5e4\">${i.json.fullName}</td><td style=\"padding:8px;border:1px solid #e7e5e4\">${i.json.email}</td><td style=\"padding:8px;border:1px solid #e7e5e4\">${i.json.daysSinceUpdate}</td></tr>`).join('');\n\nreturn [{\n json: {\n subject: `[Cosmolocal CRM] ${count} contact${count !== 1 ? 's' : ''} need${count === 1 ? 's' : ''} follow-up`,\n htmlBody: `<h2>Stale Contact Report</h2><p>The following ${count} contact${count !== 1 ? 's have' : ' has'} not been updated in 14+ days:</p><table style=\"border-collapse:collapse;width:100%\"><tr style=\"background:#f5f5f4\"><th style=\"padding:8px;text-align:left;border:1px solid #e7e5e4\">Name</th><th style=\"padding:8px;text-align:left;border:1px solid #e7e5e4\">Email</th><th style=\"padding:8px;text-align:left;border:1px solid #e7e5e4\">Days Stale</th></tr>${tableRows}</table><p style=\"margin-top:16px\"><a href=\"https://crm.cosmolocal.world\">Open CRM</a> to follow up.</p><p style=\"color:#78716c;font-size:12px\">Automated by n8n — automate.cosmolocal.world</p>`,\n count\n }\n}];"
},
"id": "build-report",
"name": "Build Report Email",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1340, 240]
},
{
"parameters": {
"fromEmail": "={{ $env.N8N_SMTP_SENDER }}",
"toEmail": "***REDACTED_EMAIL***",
"subject": "={{ $json.subject }}",
"emailType": "html",
"html": "={{ $json.htmlBody }}",
"options": {}
},
"id": "send-reminder-email",
"name": "Send Reminder to Team",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2.1,
"position": [1560, 240],
"credentials": {
"smtp": {
"id": "mailcow-smtp",
"name": "Mailcow SMTP"
}
}
},
{
"parameters": {},
"id": "no-stale-contacts",
"name": "No Stale Contacts — Done",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [1340, 420]
}
],
"connections": {
"Weekly Check (Monday 9 AM)": {
"main": [
[
{
"node": "Fetch All Contacts",
"type": "main",
"index": 0
}
]
]
},
"Fetch All Contacts": {
"main": [
[
{
"node": "Split Into Items",
"type": "main",
"index": 0
}
]
]
},
"Split Into Items": {
"main": [
[
{
"node": "Filter Stale Contacts (14+ days)",
"type": "main",
"index": 0
}
]
]
},
"Filter Stale Contacts (14+ days)": {
"main": [
[
{
"node": "Any Stale Contacts?",
"type": "main",
"index": 0
}
]
]
},
"Any Stale Contacts?": {
"main": [
[
{
"node": "Build Report Email",
"type": "main",
"index": 0
}
],
[
{
"node": "No Stale Contacts — Done",
"type": "main",
"index": 0
}
]
]
},
"Build Report Email": {
"main": [
[
{
"node": "Send Reminder to Team",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [
{
"name": "cosmolocal"
},
{
"name": "crm"
}
],
"pinData": {}
}