This workflow corresponds to n8n.io template #15973 — we link there as the canonical source.
This workflow follows the Agent → Error Trigger recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "3qIpy1a8SKR9OWwU",
"meta": {
"templateId": "ready-to-run-ai-workflow-v5",
"templateCredsSetupCompleted": true
},
"name": "Invoice + Payment Follow-up",
"tags": [],
"nodes": [
{
"id": "863c3e2f-f9d1-4f7e-95e8-7eb0850a2284",
"name": "Every Morning at 9am1",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-320,
2976
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 9
}
]
}
},
"typeVersion": 1.3
},
{
"id": "6264ee2e-0514-4d95-942b-536eef11e173",
"name": "Read All Invoices1",
"type": "n8n-nodes-base.googleSheets",
"position": [
-96,
2976
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1989760903,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas/edit#gid=1989760903",
"cachedResultName": "Client Invoices"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas/edit?usp=drivesdk",
"cachedResultName": "Client Invoices"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "dcdd88ae-3cef-43e5-8f84-655d786ef60a",
"name": "Filter Unpaid Invoices1",
"type": "n8n-nodes-base.if",
"position": [
128,
2976
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8b3d72bb-c3a1-4e69-a362-1d049f23e666",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json[\"Status\"] }}",
"rightValue": "Unpaid"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "e8224ab4-a277-4082-830a-4f9f8632e087",
"name": "Calculate Days Overdue1",
"type": "n8n-nodes-base.code",
"position": [
352,
2976
],
"parameters": {
"jsCode": "const items = $input.all();\nconst results = [];\n\nfor (const item of items) {\n if (!item.json[\"Due Date\"]) continue;\n\n let dueDate;\n const rawDate = item.json[\"Due Date\"];\n\n // Handle Google Sheets serial number\n if (typeof rawDate === 'number' || /^\\d{5}$/.test(String(rawDate))) {\n dueDate = new Date((rawDate - 25569) * 86400 * 1000);\n } else {\n dueDate = new Date(rawDate);\n }\n\n if (isNaN(dueDate.getTime())) {\n results.push({\n json: {\n ...item.json,\n daysOverdue: 0,\n isOverdue: false,\n isFirstReminder: false,\n isSecondReminder: false,\n isFinalNotice: false,\n dateError: `Could not parse date: ${rawDate}`\n }\n });\n continue;\n }\n\n dueDate.setHours(0, 0, 0, 0);\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n\n const diffTime = today - dueDate;\n const daysOverdue = Math.round(diffTime / (1000 * 60 * 60 * 24));\n\n // Read sent flags \u2014 handle both string \"TRUE\" and boolean true\n const firstSent = item.json[\"First Reminder Sent\"] === \"TRUE\" \n || item.json[\"First Reminder Sent\"] === true;\n const secondSent = item.json[\"Second Reminder Sent\"] === \"TRUE\" \n || item.json[\"Second Reminder Sent\"] === true;\n const finalSent = item.json[\"Final Notice Sent\"] === \"TRUE\" \n || item.json[\"Final Notice Sent\"] === true;\n\n // ONE email per run, highest priority wins\n let isFirstReminder = false;\n let isSecondReminder = false;\n let isFinalNotice = false;\n\n if (daysOverdue >= 30 && !finalSent) {\n isFinalNotice = true;\n } else if (daysOverdue >= 14 && !secondSent && firstSent) {\n isSecondReminder = true;\n } else if (daysOverdue >= 7 && !firstSent) {\n isFirstReminder = true;\n }\n\n results.push({\n json: {\n ...item.json,\n daysOverdue,\n isOverdue: daysOverdue > 0,\n isFirstReminder,\n isSecondReminder,\n isFinalNotice,\n parsedDueDate: dueDate.toISOString().split('T')[0]\n }\n });\n}\n\nreturn results;"
},
"typeVersion": 2
},
{
"id": "1b805585-0057-4633-8b15-e427ffa15d0e",
"name": "Route by Reminder Type1",
"type": "n8n-nodes-base.switch",
"position": [
576,
2944
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "7 day reminder",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a7f45efe-29ff-4d85-9185-bb420f3a9ca8",
"operator": {
"type": "boolean",
"operation": "true"
},
"leftValue": "={{ $json.isFirstReminder }}",
"rightValue": true
}
]
},
"renameOutput": true
},
{
"outputKey": "14 day reminder",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "c425adce-37fa-4042-a9a2-23987c08e497",
"operator": {
"type": "boolean",
"operation": "true"
},
"leftValue": "={{ $json.isSecondReminder }}",
"rightValue": true
}
]
},
"renameOutput": true
},
{
"outputKey": "Final notice",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "de3c732e-d8c3-487f-b433-508f65ed2bd1",
"operator": {
"type": "boolean",
"operation": "true"
},
"leftValue": "={{ $json.isFinalNotice }}",
"rightValue": true
}
]
},
"renameOutput": true
},
{
"outputKey": "Not due yet",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b172ae0c-992b-4c61-af42-297d78380512",
"operator": {
"type": "boolean",
"operation": "false"
},
"leftValue": "={{ $json.isOverdue }}",
"rightValue": false
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.4
},
{
"id": "e2e8acd3-8a50-4e61-a7c2-40ede540f1b8",
"name": "Extract First Email1",
"type": "n8n-nodes-base.set",
"position": [
1168,
2704
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "1",
"name": "email_body",
"type": "string",
"value": "={{ $json.output }}"
},
{
"id": "2",
"name": "Client Name",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Client Name\"] }}"
},
{
"id": "3",
"name": "Client Email",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Client Email\"] }}"
},
{
"id": "4",
"name": "Service",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Service\"] }}"
},
{
"id": "5",
"name": "Amount",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Amount\"] }}"
},
{
"id": "6",
"name": "daysOverdue",
"type": "number",
"value": "={{ $(\"Calculate Days Overdue1\").item.json.daysOverdue }}"
},
{
"id": "7",
"name": "Notes",
"type": "string",
"value": "={{ \"First reminder sent: \" + $now.toFormat(\"yyyy-MM-dd\") }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "09a5246b-97f5-4638-abcd-c7b8f956a837",
"name": "Send First Reminder Email1",
"type": "n8n-nodes-base.gmail",
"position": [
1376,
2704
],
"parameters": {
"sendTo": "={{ $json[\"Client Email\"] }}",
"message": "={{ $json.email_body }}",
"options": {},
"subject": "=Friendly reminder \u2014 Invoice for {{ $json[\"Service\"] }} due",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "9e10f86b-33fb-473e-ae1e-fb975708fd54",
"name": "Telegram - First Reminder Sent1",
"type": "n8n-nodes-base.telegram",
"position": [
1584,
2704
],
"parameters": {
"text": "=\ud83d\udce7 Payment reminder sent\n\nClient: {{ $json[\"Client Name\"] }}\nAmount: {{ $json[\"Amount\"] }}\nDays overdue: {{ $json.daysOverdue }}\nReminder type: First reminder",
"chatId": "123456789",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "0a41c2b9-6297-40ce-9e49-c579eed75fc4",
"name": "Update Sheet - First Reminder1",
"type": "n8n-nodes-base.googleSheets",
"position": [
1792,
2704
],
"parameters": {
"columns": {
"value": {
"Notes": "={{ \"First reminder sent: \" + $now.toFormat(\"yyyy-MM-dd\") }}",
"row_number": 0,
"Client Email": "={{ $('Extract First Email1').item.json['Client Email'] }}",
"First Reminder Sent": "TRUE"
},
"schema": [
{
"id": "Client Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Client Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Email",
"type": "string",
"display": true,
"required": false,
"displayName": "Client Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Service",
"type": "string",
"display": true,
"required": false,
"displayName": "Service",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Amount",
"type": "string",
"display": true,
"required": false,
"displayName": "Amount",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Invoice Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Invoice Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Due Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Due Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Notes",
"type": "string",
"display": true,
"required": false,
"displayName": "Notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "First Reminder Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "First Reminder Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Second Reminder Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Second Reminder Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Final Notice Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Final Notice Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Client Email"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1989760903,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas/edit#gid=1989760903",
"cachedResultName": "Client Invoices"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas/edit?usp=drivesdk",
"cachedResultName": "Client Invoices"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "aa933050-a033-4f2c-afca-c00bdafd93d5",
"name": "Extract Second Email1",
"type": "n8n-nodes-base.set",
"position": [
1168,
2944
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "1",
"name": "email_body",
"type": "string",
"value": "={{ $json.output }}"
},
{
"id": "2",
"name": "Client Name",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Client Name\"] }}"
},
{
"id": "3",
"name": "Client Email",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Client Email\"] }}"
},
{
"id": "4",
"name": "Service",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Service\"] }}"
},
{
"id": "5",
"name": "Amount",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Amount\"] }}"
},
{
"id": "6",
"name": "daysOverdue",
"type": "number",
"value": "={{ $(\"Calculate Days Overdue1\").item.json.daysOverdue }}"
},
{
"id": "7",
"name": "Notes",
"type": "string",
"value": "={{ \"Second reminder sent: \" + $now.toFormat(\"yyyy-MM-dd\") }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "797c7f93-c8c2-4d49-8ccc-3f497857392b",
"name": "Send Second Reminder Email1",
"type": "n8n-nodes-base.gmail",
"position": [
1376,
2944
],
"parameters": {
"sendTo": "={{ $json[\"Client Email\"] }}",
"message": "={{ $json.email_body }}",
"options": {},
"subject": "=Second notice \u2014 Payment overdue for {{ $json[\"Service\"] }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "740e6de6-2bcf-41ed-9faa-9dcd12267eca",
"name": "Telegram - Second Reminder Sent1",
"type": "n8n-nodes-base.telegram",
"position": [
1584,
2944
],
"parameters": {
"text": "=\ud83d\udce7 Payment reminder sent\n\nClient: {{ $('Extract Second Email1').item.json['Client Name'] }}\nAmount: {{ $('Extract Second Email1').item.json.Amount }}\nDays overdue: {{ $('Extract Second Email1').item.json.daysOverdue }}\nReminder type: Second reminder",
"chatId": "123456789",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "6171ae29-dd85-4b64-9d8d-e7392fa838f5",
"name": "Update Sheet - Second Reminder1",
"type": "n8n-nodes-base.googleSheets",
"position": [
1792,
2944
],
"parameters": {
"columns": {
"value": {
"Notes": "={{ \"Second reminder sent: \" + $now.toFormat(\"yyyy-MM-dd\") }}",
"Client Email": "={{ $('Extract Second Email1').item.json['Client Email'] }}",
"Second Reminder Sent": "TRUE"
},
"schema": [
{
"id": "Client Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Client Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Email",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Client Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Service",
"type": "string",
"display": true,
"required": false,
"displayName": "Service",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Amount",
"type": "string",
"display": true,
"required": false,
"displayName": "Amount",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Invoice Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Invoice Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Due Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Due Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Notes",
"type": "string",
"display": true,
"required": false,
"displayName": "Notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "First Reminder Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "First Reminder Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Second Reminder Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Second Reminder Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Final Notice Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Final Notice Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Client Email"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1989760903,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas/edit#gid=1989760903",
"cachedResultName": "Client Invoices"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas/edit?usp=drivesdk",
"cachedResultName": "Client Invoices"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "371159ae-1f8a-48ff-871f-3ea3f6ccc3d4",
"name": "Extract Final Email1",
"type": "n8n-nodes-base.set",
"position": [
1168,
3184
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "1",
"name": "email_body",
"type": "string",
"value": "={{ $json.output }}"
},
{
"id": "2",
"name": "Client Name",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Client Name\"] }}"
},
{
"id": "3",
"name": "Client Email",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Client Email\"] }}"
},
{
"id": "4",
"name": "Service",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Service\"] }}"
},
{
"id": "5",
"name": "Amount",
"type": "string",
"value": "={{ $(\"Calculate Days Overdue1\").item.json[\"Amount\"] }}"
},
{
"id": "6",
"name": "daysOverdue",
"type": "number",
"value": "={{ $(\"Calculate Days Overdue1\").item.json.daysOverdue }}"
},
{
"id": "7",
"name": "Notes",
"type": "string",
"value": "={{ \"Final notice sent: \" + $now.toFormat(\"yyyy-MM-dd\") }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ac495cdc-62c2-4054-9bdd-04e6e65562c9",
"name": "Send Final Notice Email1",
"type": "n8n-nodes-base.gmail",
"position": [
1376,
3184
],
"parameters": {
"sendTo": "={{ $json[\"Client Email\"] }}",
"message": "={{ $json.email_body }}",
"options": {},
"subject": "Final notice \u2014 Immediate payment required",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "42e6ffd9-bf85-41a1-96de-d1881c8e4b57",
"name": "Telegram - Final Notice Sent1",
"type": "n8n-nodes-base.telegram",
"position": [
1584,
3184
],
"parameters": {
"text": "=\ud83d\udce7 Payment reminder sent\n\nClient: {{ $('Extract Final Email1').item.json['Client Name'] }}\nAmount: {{ $('Extract Final Email1').item.json.Amount }}\nDays overdue: {{ $('Extract Final Email1').item.json.daysOverdue }}\nReminder type: Final notice",
"chatId": "123456789",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "7bbc6bf5-eacb-446a-b0a6-20bfac98b855",
"name": "Update Sheet - Final Notice1",
"type": "n8n-nodes-base.googleSheets",
"position": [
1792,
3184
],
"parameters": {
"columns": {
"value": {
"Notes": "={{ \"Final notice sent: \" + $now.toFormat(\"yyyy-MM-dd\") }}",
"row_number": 0,
"Client Email": "={{ $('Extract Final Email1').item.json['Client Email'] }}",
"Final Notice Sent": "TRUE"
},
"schema": [
{
"id": "Client Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Client Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Email",
"type": "string",
"display": true,
"required": false,
"displayName": "Client Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Service",
"type": "string",
"display": true,
"required": false,
"displayName": "Service",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Amount",
"type": "string",
"display": true,
"required": false,
"displayName": "Amount",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Invoice Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Invoice Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Due Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Due Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Notes",
"type": "string",
"display": true,
"required": false,
"displayName": "Notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "First Reminder Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "First Reminder Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Second Reminder Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Second Reminder Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Final Notice Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Final Notice Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Client Email"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1989760903,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas/edit#gid=1989760903",
"cachedResultName": "Client Invoices"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas/edit?usp=drivesdk",
"cachedResultName": "Client Invoices"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "171612d9-a367-4ad4-9d74-098d383b64a8",
"name": "Generate Invoice HTML",
"type": "n8n-nodes-base.html",
"position": [
-592,
912
],
"parameters": {
"html": "<!DOCTYPE html>\n<html>\n<head>\n<style>\nbody { font-family: Arial, sans-serif; margin: 40px; }\n.invoice-box { max-width: 800px; margin: auto; padding: 30px; border: 1px solid #eee; }\n.invoice-header { text-align: center; margin-bottom: 40px; }\n.invoice-details { margin-bottom: 30px; }\ntable { width: 100%; border-collapse: collapse; }\nth, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }\nth { background-color: #f8f8f8; }\n.total { font-size: 18px; font-weight: bold; }\n</style>\n</head>\n<body>\n<div class=\"invoice-box\">\n<div class=\"invoice-header\">\n<h1>INVOICE</h1>\n<p>Invoice Date: {{ $json[\"Invoice Date\"] }}</p>\n<p>Due Date: {{ $json[\"Due Date\"] }}</p>\n</div>\n<div class=\"invoice-details\">\n<p><strong>Bill To:</strong></p>\n<p>{{ $json[\"Client Name\"] }}<br>{{ $json[\"Client Email\"] }}</p>\n</div>\n<table>\n<tr><th>Service</th><th>Amount</th></tr>\n<tr><td>{{ $json[\"Service\"] }}</td><td>{{ $json.Currency ?? \"USD\" }} {{ $json[\"Amount\"] }}</td></tr>\n<tr><td class=\"total\">Total Due</td><td class=\"total\">{{ $json.Currency ?? \"USD\" }} {{ $json[\"Amount\"] }}</td></tr>\n</table>\n<p style=\"margin-top: 30px;\">Thank you for your business!</p>\n</div>\n</body>\n</html>"
},
"typeVersion": 1.2
},
{
"id": "1e88d10b-9a0b-41a0-b745-8d5dfa5c692f",
"name": "Send Initial Invoice",
"type": "n8n-nodes-base.gmail",
"position": [
432,
912
],
"parameters": {
"sendTo": "={{ $(\"New Invoice Created\").item.json[\"Client Email\"] }}",
"message": "={{ $json.output }}",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{
"property": "invoice_pdf"
}
]
}
},
"subject": "=Invoice for {{ $(\"New Invoice Created\").item.json[\"Service\"] }} - Due {{ $(\"New Invoice Created\").item.json[\"Due Date\"] }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "8ea62ada-06ef-4f3c-b17d-a07d1e569a61",
"name": "Update Sheet - Invoice Sent",
"type": "n8n-nodes-base.googleSheets",
"position": [
656,
912
],
"parameters": {
"columns": {
"value": {
"Notes": "={{ \"Invoice sent: \" + $now.toFormat(\"yyyy-MM-dd\") }}",
"Amount": "={{ $(\"New Invoice Created\").item.json[\"Amount\"] }}",
"Status": "Unpaid",
"Service": "={{ $(\"New Invoice Created\").item.json[\"Service\"] }}",
"Due Date": "={{ $(\"New Invoice Created\").item.json[\"Due Date\"] }}",
"Client Name": "={{ $(\"New Invoice Created\").item.json[\"Client Name\"] }}",
"Client Email": "={{ $(\"New Invoice Created\").item.json[\"Client Email\"] }}",
"Invoice Date": "={{ $(\"New Invoice Created\").item.json[\"Invoice Date\"] }}"
},
"schema": [
{
"id": "Client Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Client Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Email",
"type": "string",
"display": true,
"required": false,
"displayName": "Client Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Service",
"type": "string",
"display": true,
"required": false,
"displayName": "Service",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Amount",
"type": "string",
"display": true,
"required": false,
"displayName": "Amount",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Invoice Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Invoice Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Due Date",
"type": "string",
"display": true,
"required": false,
"displayName": "Due Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"display": true,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Notes",
"type": "string",
"display": true,
"required": false,
"displayName": "Notes",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "First Reminder Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "First Reminder Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Second Reminder Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Second Reminder Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Final Notice Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Final Notice Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Client Email"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1989760903,
"cachedResultName": "Client Invoices"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas",
"cachedResultName": "Client Invoices"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "6928c682-45ce-4b0c-822e-20b949f6f599",
"name": "Telegram - Mark as Paid",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
-1056,
1808
],
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2,
"alwaysOutputData": false
},
{
"id": "e813b278-da5f-4001-b47a-b09b46a763a8",
"name": "Check Paid Command",
"type": "n8n-nodes-base.if",
"position": [
-832,
1808
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a2ce688b-9997-4a4c-8842-5c989b71dae4",
"operator": {
"type": "string",
"operation": "startsWith"
},
"leftValue": "={{ $json.message?.text ?? \"\" }}",
"rightValue": "paid"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "6a4d0a37-0f19-4eca-af4f-3a68c3e5b4ee",
"name": "Extract Client Name",
"type": "n8n-nodes-base.code",
"position": [
-608,
1808
],
"parameters": {
"jsCode": "const text = $input.first().json.message.text;\nconst clientName = text.replace(/^paid\\s+/i, '').trim();\n\nreturn [{ json: { clientName: clientName, chatId: $input.first().json.message.chat.id } }];"
},
"typeVersion": 2
},
{
"id": "d2e25295-a1c1-45bb-8022-5be7d4bf4a31",
"name": "Find Client Invoice",
"type": "n8n-nodes-base.googleSheets",
"position": [
-384,
1808
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupValue": "={{ $json.clientName }}",
"lookupColumn": "Client Name"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1989760903,
"cachedResultName": "Client Invoices"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas",
"cachedResultName": "Client Invoices"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7,
"alwaysOutputData": true
},
{
"id": "93f2236e-790b-4add-b675-7d16d6aee733",
"name": "Mark as Paid in Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
64,
1712
],
"parameters": {
"columns": {
"value": {
"Notes": "={{ \"Marked paid: \" + $now.toFormat(\"yyyy-MM-dd\") }}",
"Amount": "={{ $json[\"Amount\"] }}",
"Status": "Paid",
"Service": "={{ $json[\"Service\"] }}",
"Due Date": "={{ $json[\"Due Date\"] }}",
"Client Name": "={{ $json[\"Client Name\"] }}",
"Client Email": "={{ $json[\"Client Email\"] }}",
"Invoice Date": "={{ $json[\"Invoice Date\"] }}"
},
"schema": [
{
"id": "Client Name",
"type": "string",
"displayName": "Client Name",
"canBeUsedToMatch": true
},
{
"id": "Client Email",
"type": "string",
"displayName": "Client Email",
"canBeUsedToMatch": true
},
{
"id": "Service",
"type": "string",
"displayName": "Service",
"canBeUsedToMatch": true
},
{
"id": "Amount",
"type": "string",
"displayName": "Amount",
"canBeUsedToMatch": true
},
{
"id": "Invoice Date",
"type": "string",
"displayName": "Invoice Date",
"canBeUsedToMatch": true
},
{
"id": "Due Date",
"type": "string",
"displayName": "Due Date",
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "string",
"displayName": "Status",
"canBeUsedToMatch": true
},
{
"id": "Notes",
"type": "string",
"displayName": "Notes",
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Client Email"
]
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1989760903,
"cachedResultName": "Client Invoices"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas",
"cachedResultName": "Client Invoices"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "b0522ab9-333e-4fb8-94b8-ec5f55236f7b",
"name": "Send Thank You Email",
"type": "n8n-nodes-base.gmail",
"position": [
288,
1712
],
"parameters": {
"sendTo": "={{ $json[\"Client Email\"] }}",
"message": "=Dear {{ $json[\"Client Name\"] }},\n\nThank you for your payment of {{ $json[\"Amount\"] }} for {{ $json[\"Service\"] }}. We have received your payment and your account is now settled.\n\nWe truly appreciate your business and look forward to working with you again!\n\nBest regards",
"options": {},
"subject": "Payment Received - Thank You!",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "f6349f11-87a5-4de0-9dec-e23a560b3b69",
"name": "Confirm to Owner",
"type": "n8n-nodes-base.telegram",
"position": [
512,
1712
],
"parameters": {
"text": "=\u2705 Marked as PAID\n\nClient: {{ $('Mark as Paid in Sheet').item.json['Client Name'] }}\nService: {{ $('Mark as Paid in Sheet').item.json.Service }}\nAmount: {{ $('Mark as Paid in Sheet').item.json.Amount }}\n\nThank you email sent automatically.",
"chatId": "={{ $(\"Extract Client Name\").item.json.chatId }}",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "3868a94f-734c-4e9a-ba48-34e363b0ab82",
"name": "Error Handler",
"type": "n8n-nodes-base.errorTrigger",
"position": [
-1824,
3456
],
"parameters": {},
"typeVersion": 1
},
{
"id": "027367e8-ecf7-49cd-a6b0-795c8770ad6c",
"name": "Send Error Alert",
"type": "n8n-nodes-base.telegram",
"position": [
-1600,
3456
],
"parameters": {
"text": "=\ud83d\udea8 WORKFLOW FAILED\n\nWorkflow: {{ $workflow.name }}\nNode: {{ $json.error.node.name }}\nError: {{ $json.error.message }}\nTime: {{ $now.toFormat(\"yyyy-MM-dd HH:mm:ss\") }}\n\nPlease check n8n immediately.",
"chatId": "123456789",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "da1839e3-2625-4ac4-8d8b-de1529e33f7e",
"name": "Sticky Note Main",
"type": "n8n-nodes-base.stickyNote",
"position": [
192,
208
],
"parameters": {
"color": 4,
"width": 450,
"height": 320,
"content": "\ud83d\udccb COMPLETE Invoice Automation System\n\n\ud83c\udd95 NEW INVOICE:\n\u2705 Auto-sends invoice PDF when row added\n\u2705 AI writes professional email\n\u2705 Updates sheet with sent date\n\n\ud83d\udcc5 DAILY REMINDERS (9am):\n\u2705 Day 7: Gentle reminder\n\u2705 Day 14: Firm reminder\n\u2705 Day 30: Final notice\n\u2705 Telegram notifications\n\n\ud83d\udcb0 MARK AS PAID:\n\u2705 Message bot: \"paid [client name]\"\n\u2705 Auto-updates sheet to Paid\n\u2705 Sends thank you email\n\n\ud83d\udea8 ERROR HANDLING:\n\u2705 Instant Telegram alerts on failures\n\u2705 Gemini auto-retries (3x)"
},
"typeVersion": 1
},
{
"id": "b007d66f-2e25-4584-9e3c-2222ff7a3ea9",
"name": "Sticky Note Setup",
"type": "n8n-nodes-base.stickyNote",
"position": [
2352,
208
],
"parameters": {
"color": 5,
"width": 400,
"height": 220,
"content": "\ud83d\udca1 SETUP INSTRUCTIONS\n\n1. Chat ID: Message @userinfobot on Telegram to get your chat ID\n\n2. Add Currency column to your Google Sheet (USD, GBP, INR, etc.)\n\n3. Duplicate Prevention: Reminders fire EXACTLY on days 7, 14, 30 (not ranges)\n\n4. Mark Paid: Message your bot \"paid Jane Smith\" to mark invoice as paid\n\n5. PDF Invoices: Automatically generated and attached to all emails"
},
"typeVersion": 1
},
{
"id": "7e051722-58e7-414b-b81f-5c78d3376dd9",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
-160,
1808
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "42252a7a-4fde-489a-9bdc-f3a8fa153a79",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json[\"Client Name\"] }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"id": "ca223e54-1820-4f66-9806-9c305f8e60bc",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
816,
2944
],
"parameters": {
"text": "=You are a professional billing assistant. Write a firm but professional \nsecond reminder email under 100 words.\n\nClient name: {{ $('Calculate Days Overdue1').item.json['Client Name'] }}\nService: {{ $('Calculate Days Overdue1').item.json.Service }}\nAmount due: {{ $('Calculate Days Overdue1').item.json.Amount }}\nDue date was: {{ $('Calculate Days Overdue1').item.json['Due Date'] }}\nDays overdue: {{ $('Calculate Days Overdue1').item.json.daysOverdue }}\n\nMention this is the second notice. Address the client by name.",
"options": {},
"promptType": "define"
},
"typeVersion": 3.1
},
{
"id": "872ecb54-4c8c-43f8-9724-1161a7dc474e",
"name": "Groq Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
"position": [
816,
3056
],
"parameters": {
"model": "llama-3.3-70b-versatile",
"options": {}
},
"credentials": {
"groqApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "f38714e5-a76a-4ce0-b5ed-d0c8432cb8d6",
"name": "AI Agent1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
816,
3184
],
"parameters": {
"text": "=You are a professional billing assistant. Write a firm final notice \nemail under 100 words.\n\nClient name: {{ $('Calculate Days Overdue1').item.json['Client Name'] }}\nService: {{ $('Calculate Days Overdue1').item.json.Service }}\nAmount due: {{ $('Calculate Days Overdue1').item.json.Amount }}\nDue date was: {{ $('Calculate Days Overdue1').item.json['Due Date'] }}\nDays overdue: {{ $('Calculate Days Overdue1').item.json.daysOverdue }}\n\nMention this is the final notice before further action. Address client by name.",
"options": {},
"promptType": "define"
},
"typeVersion": 3.1
},
{
"id": "a44f9abc-3ab4-4ae6-8187-c220709f9c96",
"name": "Groq Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
"position": [
816,
3296
],
"parameters": {
"model": "llama-3.3-70b-versatile",
"options": {}
},
"credentials": {
"groqApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "8735ac46-07c3-4125-b6ed-138292c0d98e",
"name": "AI Agent2",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
816,
2704
],
"parameters": {
"text": "=You are a professional billing assistant. Write a short polite payment \nreminder email under 100 words. Be warm, not aggressive.\n\nClient name: {{ $('Calculate Days Overdue1').item.json['Client Name'] }}\nService: {{ $('Calculate Days Overdue1').item.json.Service }}\nAmount due: {{ $('Calculate Days Overdue1').item.json.Amount }}\nDue date was: {{ $('Calculate Days Overdue1').item.json['Due Date'] }}\nDays overdue: {{ $('Calculate Days Overdue1').item.json.daysOverdue }}\n\nWrite a gentle first reminder. Address the client by name. ",
"options": {},
"promptType": "define"
},
"typeVersion": 3.1
},
{
"id": "00109042-f100-4f99-bebc-e6413761c26f",
"name": "Groq Chat Model2",
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
"position": [
832,
2816
],
"parameters": {
"model": "llama-3.3-70b-versatile",
"options": {}
},
"credentials": {
"groqApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "c3bb734b-dbc1-4283-8fe9-c6ea0a04c8da",
"name": "AI Agent3",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-144,
784
],
"parameters": {
"text": "=You are a professional billing assistant. Write a friendly invoice \nemail under 80 words.\n\nClient name: {{ $(\"New Invoice Created\").item.json[\"Client Name\"] }}\nService: {{ $(\"New Invoice Created\").item.json[\"Service\"] }}\nAmount: {{ $(\"New Invoice Created\").item.json[\"Amount\"] }}\nDue date: {{ $(\"New Invoice Created\").item.json[\"Due Date\"] }}\n\nThank them for their business and mention the invoice is attached.",
"options": {},
"promptType": "define"
},
"typeVersion": 3.1
},
{
"id": "24221496-32f5-49e0-95d6-726a0357bdf6",
"name": "Groq Chat Model3",
"type": "@n8n/n8n-nodes-langchain.lmChatGroq",
"position": [
-80,
1008
],
"parameters": {
"model": "llama-3.3-70b-versatile",
"options": {}
},
"credentials": {
"groqApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "ed1c9cdd-96e6-427f-a44a-6184a822d6ef",
"name": "New Invoice Created",
"type": "n8n-nodes-base.googleSheetsTrigger",
"position": [
-816,
912
],
"parameters": {
"event": "rowAdded",
"options": {},
"pollTimes": {
"item": [
{
"hour": 9
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1989760903,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas/edit#gid=1989760903",
"cachedResultName": "Client Invoices"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1PhXMdSOQqcIhkfQ9AHWAf60dTewFwaPZcwsyYZAFXas/edit?usp=drivesdk",
"cachedResultName": "Client Invoices"
}
},
"credentials": {
"googleSheetsTriggerOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "519b6b90-9fa8-4da2-be67-3d19a3f4d305",
"name": "Send a text message",
"type": "n8n-nodes-base.telegram",
"position": [
64,
1904
],
"parameters": {
"text": "=\u274c Client not found: {{ $('Extract Client Name').item.json.clientName }}\n\nPlease check the spelling and try again.\nType: paid [exact client name]",
"chatId": "123456789",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "cf737eef-e9c1-4209-a738-1b0ff6875b80",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
-368,
912
],
"parameters": {
"url": "https://api.pdfshift.io/v3/convert/pdf",
"method": "POST",
"options": {
"response": {
"response": {
"responseFormat": "file",
"outputPropertyName": "invoice_pdf"
}
}
},
"sendBody": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "source",
"value": "={{ $('Generate Invoice HTML').item.json.html }}"
},
{
"name": "landscape",
"value": "false"
},
{
"name": "use_print",
"value": "false"
}
]
},
"genericAuthType": "httpBasicAuth"
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "992b637d-b065-4502-867b-7fd15a5aa864",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
208,
912
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "6dfb984c-bddb-4e0a-9f7d-ab95341c4e4a",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1312,
576
],
"parameters": {
"width": 2240,
"height": 688,
"content": "# \ud83c\udd95 SECTION 1 \u2014 NEW INVOICE FLOW\n\n\n\n\n## TRIGGER: New row added to Google Sheet\n\n\n### WHAT HAPPENS AUTOMATICALLY:\n\n\n## \u2192 HTML invoice template generated instantly\n## \u2192 PDFShift converts HTML to real PDF\n## \u2192 Groq AI writes personalised email\n## \u2192 Gmail sends email with PDF attache
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleSheetsOAuth2ApigoogleSheetsTriggerOAuth2ApigroqApihttpBasicAuthtelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automates invoicing and payment follow-ups using Google Sheets, PDFShift, Groq (LLM), Gmail, and Telegram, sending initial invoices with PDF attachments, scheduling overdue reminders at 9am, and letting you mark invoices as paid via a Telegram command with…
Source: https://n8n.io/workflows/15973/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automates the process of generating, reviewing, and publishing blog posts across multiple platforms, now enhanced with support for RSS Feeds as a content source. It streamlines the manag
Arvifund - Supabase. Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 90 nodes.
Arvifund - Supabase (Fixed v2). Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 90 nodes.
Arvifund - Supabase (Fixed v4). Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 90 nodes.
Arvifund - Supabase (Fixed v3). Uses httpRequest, telegram, googleSheets, telegramTrigger. Event-driven trigger; 90 nodes.