{ "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 contactList = items.map(item => \n `- **${item.json.fullName}** (${item.json.email}) — ${item.json.daysSinceUpdate} days since last update`\n).join('\\n');\n\nconst count = items.length;\n\nreturn [{\n json: {\n subject: `[Cosmolocal CRM] ${count} contact${count !== 1 ? 's' : ''} need${count === 1 ? 's' : ''} follow-up`,\n htmlBody: `

Stale Contact Report

The following ${count} contact${count !== 1 ? 's have' : ' has'} not been updated in 14+ days:

${items.map(i => ``).join('')}
NameEmailDays Stale
${i.json.fullName}${i.json.email}${i.json.daysSinceUpdate}

Open CRM to follow up.

Automated by n8n — automate.cosmolocal.world

`,\n count\n }\n}];" }, "id": "build-report", "name": "Build Report Email", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [1340, 240] }, { "parameters": { "method": "POST", "url": "https://api.resend.com/emails", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Authorization", "value": "Bearer {{ $env.RESEND_API_KEY }}" }, { "name": "Content-Type", "value": "application/json" } ] }, "sendBody": true, "specifyBody": "json", "jsonBody": "={\n \"from\": \"CRM Bot \",\n \"to\": [\"hello@cosmolocal.world\"],\n \"subject\": \"{{ $json.subject }}\",\n \"html\": \"{{ $json.htmlBody }}\"\n}", "options": {} }, "id": "send-reminder-email", "name": "Send Reminder to Team", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [1560, 240] }, { "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": {} }