-
Notifications
You must be signed in to change notification settings - Fork 6.4k
Expand file tree
/
Copy pathSend Escalating WhatsApp Invoice Reminders from Google Sheets (Hebrew).json
More file actions
1 lines (1 loc) · 8.43 KB
/
Copy pathSend Escalating WhatsApp Invoice Reminders from Google Sheets (Hebrew).json
File metadata and controls
1 lines (1 loc) · 8.43 KB
1
{"name": "Send Escalating WhatsApp Invoice Reminders from Google Sheets (Hebrew)", "nodes": [{"parameters": {"content": "## Send Escalating WhatsApp Invoice Reminders from Google Sheets (Hebrew)\n\n### How it works\n\nThis workflow runs every morning at 09:00 to check a Google Sheet for open invoices. It calculates whether each invoice is exactly 7, 14, or 30 days overdue and builds the matching Hebrew reminder message. Matching reminders are sent through a WAHA WhatsApp HTTP endpoint, then the invoice row is updated in Google Sheets to record the sent reminder.\n\n### Setup steps\n\n- Configure Google Sheets credentials in n8n and point the read node to the spreadsheet and sheet containing open invoices.\n- Ensure the invoice sheet includes the fields expected by the code node, such as due date, customer phone number, invoice details, and reminder status columns.\n- Update the WAHA HTTP request URL from https://YOUR-WAHA-SERVER/api/sendText to your actual WAHA server endpoint and configure any required authentication headers.\n- Verify the schedule trigger timezone so 09:00 matches the intended local morning time.\n- Test with sample invoices that are exactly 7, 14, and 30 days overdue to confirm message formatting and row updates.\n\n### Customization\n\nAdjust the code node to change overdue tiers, Hebrew message wording, phone-number formatting, or filtering rules. The schedule can also be changed if reminders should be sent at a different time or frequency.", "width": 460, "height": 920}, "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [-572, -340], "id": "942e28de-3ca6-4c5d-8708-66a258636010", "name": "Sticky Note"}, {"parameters": {"content": "## Schedule and read invoices\n\nStarts the workflow every morning at 09:00 and pulls the current list of open invoices from Google Sheets. These two left-side nodes form the intake cluster for the daily reminder run.", "width": 416, "height": 484, "color": 7}, "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [-48, -300], "id": "aa4a7373-a32c-40ca-b95a-7bb261c6a466", "name": "Sticky Note1"}, {"parameters": {"content": "## Calculate reminder tier\n\nFilters the invoice data to the items that are exactly 7, 14, or 30 days overdue and prepares the appropriate Hebrew WhatsApp reminder message for each matching invoice.", "width": 192, "height": 524, "color": 7}, "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [400, -340], "id": "061dc03e-5177-45a9-a065-4685aea1e7c7", "name": "Sticky Note2"}, {"parameters": {"content": "## Send and record reminders\n\nSends each prepared reminder through the WAHA WhatsApp API, then updates Google Sheets to mark that the reminder was sent.", "width": 416, "height": 484, "color": 7}, "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [624, -300], "id": "8f463d5b-06b7-4e9d-b161-7c513ee8898f", "name": "Sticky Note3"}, {"id": "schedule-daily-t2", "name": "When Each Day at 09:00", "type": "n8n-nodes-base.scheduleTrigger", "position": [0, 0], "parameters": {"rule": {"interval": [{"field": "days", "triggerAtHour": 9, "triggerAtMinute": 0}]}}, "typeVersion": 1.3}, {"id": "sheets-read-invoices-t2", "name": "Read Invoices from Sheets", "type": "n8n-nodes-base.googleSheets", "position": [224, 0], "parameters": {"options": {"returnAllMatches": "returnAllMatches"}, "resource": "sheet", "filtersUI": {"values": [{"lookupValue": "open", "lookupColumn": "Status"}]}, "operation": "read", "sheetName": {"__rl": true, "mode": "list", "value": "", "cachedResultName": "Invoices"}, "documentId": {"__rl": true, "mode": "list", "value": "", "cachedResultName": "Invoices spreadsheet"}, "authentication": "oAuth2", "combineFilters": "AND"}, "typeVersion": 4.7}, {"id": "code-compute-tier-t2", "name": "Calculate Overdue Tier", "type": "n8n-nodes-base.code", "position": [448, 0], "parameters": {"mode": "runOnceForAllItems", "jsCode": "// Keeps only invoices that are EXACTLY 7, 14 or 30 days overdue today,\n// so each invoice gets at most one reminder per tier (no daily spam).\n// Each tier has its own Hebrew message - edit the texts freely.\n\nconst REMINDERS = {\n 7: (inv) => 'היי ' + inv.name + ', תזכורת ידידותית: חשבונית מספר ' + inv.id + ' על סך ' + inv.amount + ' ₪ ממתינה לתשלום כבר שבוע. נשמח להסדרה בהקדם, תודה!',\n 14: (inv) => 'שלום ' + inv.name + ', חשבונית מספר ' + inv.id + ' על סך ' + inv.amount + ' ₪ פתוחה כבר 14 יום. נודה לטיפולך. אם התשלום כבר בוצע, אפשר להתעלם מהודעה זו.',\n 30: (inv) => 'שלום ' + inv.name + ', תזכורת אחרונה: חשבונית מספר ' + inv.id + ' על סך ' + inv.amount + ' ₪ פתוחה מזה 30 יום. נבקש להסדיר את התשלום עוד היום. לשאלות אנחנו זמינים כאן.',\n};\n\nfunction parseDate(v) {\n if (!v) return null;\n const s = String(v).trim();\n let d = DateTime.fromISO(s);\n if (!d.isValid) d = DateTime.fromFormat(s, 'dd/MM/yyyy');\n if (!d.isValid) d = DateTime.fromFormat(s, 'd/M/yyyy');\n if (!d.isValid) d = DateTime.fromFormat(s, 'MM/dd/yyyy');\n return d.isValid ? d.startOf('day') : null;\n}\n\nfunction toChatId(phone) {\n let digits = String(phone ?? '').replace(/\\D/g, '');\n if (digits.startsWith('0')) digits = '972' + digits.slice(1);\n if (!digits.startsWith('972')) digits = '972' + digits;\n return digits + '@c.us';\n}\n\nconst out = [];\nfor (const item of $input.all()) {\n const row = item.json;\n const due = parseDate(row.DueDate);\n if (!due) continue;\n const daysOverdue = Math.floor($today.diff(due, 'days').days);\n const buildMessage = REMINDERS[daysOverdue];\n if (!buildMessage) continue; // not exactly 7/14/30 days overdue today\n\n const inv = { id: row.InvoiceID ?? '', name: row.CustomerName ?? '', amount: row.Amount ?? '' };\n\n out.push({\n json: {\n InvoiceID: inv.id,\n CustomerName: inv.name,\n Amount: inv.amount,\n daysOverdue,\n tier: 'reminder-' + daysOverdue,\n chatId: toChatId(row.Phone),\n message: buildMessage(inv),\n },\n });\n}\nreturn out;", "language": "javaScript"}, "typeVersion": 2}, {"id": "http-send-reminder-t2", "name": "Post WhatsApp Reminder", "type": "n8n-nodes-base.httpRequest", "position": [672, 0], "parameters": {"url": "https://YOUR-WAHA-SERVER/api/sendText", "method": "POST", "options": {"batching": {"batch": {"batchSize": 1, "batchInterval": 3000}}}, "sendBody": true, "contentType": "json", "specifyBody": "keypair", "authentication": "genericCredentialType", "bodyParameters": {"parameters": [{"name": "session", "value": "default"}, {"name": "chatId", "value": "={{ $json.chatId }}"}, {"name": "text", "value": "={{ $json.message }}"}]}, "genericAuthType": "httpHeaderAuth"}, "typeVersion": 4.4}, {"id": "sheets-mark-sent-t2", "name": "Update Sent Status in Sheets", "type": "n8n-nodes-base.googleSheets", "position": [896, 0], "parameters": {"columns": {"value": {"InvoiceID": "={{ $('Calculate Overdue Tier').item.json.InvoiceID }}", "LastReminder": "={{ $('Calculate Overdue Tier').item.json.tier }}", "LastReminderDate": "={{ $now.toFormat('yyyy-MM-dd') }}"}, "schema": [{"id": "InvoiceID", "type": "string", "display": true, "required": false, "displayName": "InvoiceID", "defaultMatch": true, "canBeUsedToMatch": true}, {"id": "LastReminder", "type": "string", "display": true, "required": false, "displayName": "LastReminder", "defaultMatch": false, "canBeUsedToMatch": false}, {"id": "LastReminderDate", "type": "string", "display": true, "required": false, "displayName": "LastReminderDate", "defaultMatch": false, "canBeUsedToMatch": false}], "mappingMode": "defineBelow", "matchingColumns": ["InvoiceID"]}, "options": {}, "resource": "sheet", "operation": "update", "sheetName": {"__rl": true, "mode": "list", "value": "", "cachedResultName": "Invoices"}, "documentId": {"__rl": true, "mode": "list", "value": "", "cachedResultName": "Invoices spreadsheet"}, "authentication": "oAuth2"}, "typeVersion": 4.7}], "active": false, "pinData": {}, "settings": {"executionOrder": "v1"}, "connections": {"Read Invoices from Sheets": {"main": [[{"node": "Calculate Overdue Tier", "type": "main", "index": 0}]]}, "When Each Day at 09:00": {"main": [[{"node": "Read Invoices from Sheets", "type": "main", "index": 0}]]}, "Post WhatsApp Reminder": {"main": [[{"node": "Update Sent Status in Sheets", "type": "main", "index": 0}]]}, "Calculate Overdue Tier": {"main": [[{"node": "Post WhatsApp Reminder", "type": "main", "index": 0}]]}}}