This workflow corresponds to n8n.io template #9760 — we link there as the canonical source.
This workflow follows the Agent → Datatable 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": "iwPkwhyyDLOePuom",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Generate Invoices and Send Reminders for Customers with Jotform, QuickBooks and Gmail",
"tags": [],
"nodes": [
{
"id": "9c594f0d-b9d7-4329-8017-90bbc445cc43",
"name": "Receive form submission",
"type": "n8n-nodes-base.webhook",
"position": [
-464,
0
],
"parameters": {
"path": "ebee0263-fc61-414f-a9cc-faf3269ce30d",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "20ea495b-ef6e-4bb4-a3a4-8fa95b17a77d",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
320,
0
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "bfa24559-7702-4ebf-909d-c5c2a60ad817",
"operator": {
"type": "object",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json }}",
"rightValue": 0
},
{
"id": "b4301cfe-a22a-490f-a72b-50d266bc1c5e",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.Id }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "16ccee04-eefb-4e38-a5d4-3c65e26f779f",
"name": "Get the product",
"type": "n8n-nodes-base.quickbooks",
"position": [
1248,
0
],
"parameters": {
"limit": 1,
"filters": {
"query": "=WHERE name = '{{ $json.item.name }}'"
},
"resource": "item",
"operation": "getAll"
},
"credentials": {
"quickBooksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "51fda0e5-2c6e-40cc-a967-76426f4bcf36",
"name": "Create the invoice",
"type": "n8n-nodes-base.quickbooks",
"position": [
1856,
0
],
"parameters": {
"Line": [
{
"Amount": 1,
"itemId": "={{ $json.item.id }}",
"DetailType": "SalesItemLineDetail",
"Description": "Jotform submission"
}
],
"resource": "invoice",
"operation": "create",
"CustomerRef": "={{ $json.customer.id }}",
"additionalFields": {}
},
"credentials": {
"quickBooksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "2e729c72-459b-4448-892c-4f7b14af1eb6",
"name": "Send the invoice",
"type": "n8n-nodes-base.quickbooks",
"position": [
2160,
0
],
"parameters": {
"email": "={{ $('Add item id').item.json.customer.email }}",
"resource": "invoice",
"invoiceId": "={{ $json.Id }}",
"operation": "send"
},
"credentials": {
"quickBooksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "9fb60975-4ab2-465d-b0c3-27669702b49f",
"name": "Check if the customer exists",
"type": "n8n-nodes-base.quickbooks",
"position": [
112,
0
],
"parameters": {
"limit": 1,
"filters": {
"query": "=Where PrimaryEmailAddr = '{{ $json.customer.email }}'"
},
"operation": "getAll"
},
"credentials": {
"quickBooksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "465941dd-9b14-4651-bff1-d5c62a6b52aa",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-544,
-112
],
"parameters": {
"color": 7,
"width": 256,
"height": 320,
"content": "## Receive Submission\nReceives the product/service form submission from Jotform"
},
"typeVersion": 1
},
{
"id": "fd542ca6-d362-4d9d-8469-0a0493d8092e",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
64,
-112
],
"parameters": {
"color": 7,
"width": 400,
"height": 320,
"content": "## Check If Customer exists \nChecks if the customer exists in QBO or not"
},
"typeVersion": 1
},
{
"id": "10412197-c39a-4b71-a8ae-f025c30c6a88",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
512,
-336
],
"parameters": {
"color": 7,
"width": 304,
"height": 336,
"content": "## Customer Exists\nNow since the customer exists we will update the customer details like updating the billing details with the new one"
},
"typeVersion": 1
},
{
"id": "77b8565e-bd0a-4fd7-a23c-7bdd2c94cd42",
"name": "Create the customer",
"type": "n8n-nodes-base.quickbooks",
"position": [
608,
176
],
"parameters": {
"operation": "create",
"displayName": "=",
"additionalFields": {
"BillAddr": {
"details": {
"City": "={{ $('Format data').item.json.address.city }}",
"Line1": "={{ $('Format data').item.json.address.line1 }}",
"PostalCode": "={{ $('Format data').item.json.address.postalZipCode }}"
}
},
"GivenName": "={{ $('Format data').item.json.customer.name }}",
"PrimaryPhone": "={{ $('Format data').item.json.customer.phone }}",
"PrimaryEmailAddr": "={{ $('Format data').item.json.customer.email }}"
}
},
"credentials": {
"quickBooksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "aa96c6e2-418b-45d1-848d-cef54e891550",
"name": "Update the customer",
"type": "n8n-nodes-base.quickbooks",
"position": [
608,
-192
],
"parameters": {
"operation": "update",
"customerId": "={{ $json.Id }}",
"updateFields": {
"BillAddr": {
"details": {
"City": "={{ $('Format data').item.json.address.city }}",
"Line1": "={{ $('Format data').item.json.address.line1 }}",
"PostalCode": "={{ $('Format data').item.json.address.postalZipCode }}"
}
},
"GivenName": "={{ $('Format data').item.json.customer.name }}",
"PrimaryPhone": "={{ $('Format data').item.json.customer.phone }}"
}
},
"credentials": {
"quickBooksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "a27bb89f-7797-4e4e-b104-0b739d05ee0d",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
512,
48
],
"parameters": {
"color": 7,
"width": 304,
"height": 320,
"content": "## Customer Doesn't Exist\nNow since the customer doesn't exist we will create new customer"
},
"typeVersion": 1
},
{
"id": "3c029901-edd6-4085-a4b9-578adecf5164",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1168,
-112
],
"parameters": {
"color": 7,
"width": 256,
"height": 320,
"content": "## Get The Item\nGets the selected product/service from QBO"
},
"typeVersion": 1
},
{
"id": "4c978dba-767e-4327-a1b2-2626fac272a7",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1776,
-112
],
"parameters": {
"color": 7,
"width": 256,
"height": 320,
"content": "## Create The Invoice\nCreates a new invoice for that customer"
},
"typeVersion": 1
},
{
"id": "7eb0c556-eeb0-47ff-bc78-8050056f6dbe",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
2080,
-112
],
"parameters": {
"color": 7,
"width": 256,
"height": 320,
"content": "## Send The Invoice\nSends the newly created invoice for that customer(via email)"
},
"typeVersion": 1
},
{
"id": "cb13f312-4f56-45ad-b462-fe120cd79c62",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1664,
-416
],
"parameters": {
"width": 1072,
"height": 1280,
"content": "## Generate Invoices and Send Reminders for Customers with Jotform, QuickBooks and Gmail\nThis workflow automates the entire process of receiving a product/service order, checking or creating a customer in **QuickBooks Online (QBO)**, generating an invoice, emailing it \u2014 all triggered by a form submission (via **Jotform**), and sending invoice reminders.\n\n## How It Works\n### 1- Receive Submission\n* Triggered when a user submits a form.\n* Collects data like customer details, selected product/service, etc.\n\n### 2- Check If Customer Exists\n* Searches QBO to determine if the customer already exists.\n* \u2705 **If Customer Exists:** **Update** customer details (e.g., billing address).\n* \u274c **If Customer Doesn\u2019t Exist:** **Create** a new customer in QBO.\n\n### 3- Get The Item\n* Retrieves the selected product or service from QBO.\n\n### 4- Create The Invoice\n* Generates a new invoice for the customer using the item selected.\n\n### 5- Send The Invoice\n* Automatically sends the invoice via email to the customer.\n\n### 6- Store The Invoice In DB\n* Stores the needed invoice details in the DB.\n\n### 7- Send Reminders\n* Every day at 8 AM, the automation checks each invoice to decide whether to:\n * send a reminder email,\n * skip and send it later, or\n * delete the invoice from the DB (if it's paid or all reminders have been sent).\n\n## Who Can Benefit from This Workflow?\n* **Freelancers**\n* **Service Providers**\n* **Consultants & Coaches**\n* **Small Businesses**\n* **E-commerce or Custom Product Sellers**\n\n## Requirements\n- Jotform webhook setup, more info [here](https://www.jotform.com/help/245-how-to-setup-a-webhook-with-jotform/)\n- QuickBooks Online credentials, more info [here](https://developer.intuit.com/app/developer/qbo/docs/get-started/get-client-id-and-client-secret)\n- Email setup, update email nodes (`Send reminder email` & `Send reminders sent summary`), more info about Gmail setup [here](https://docs.n8n.io/integrations/builtin/credentials/google)\n- Create data table with the following columns:\n * invoiceId (string)\n * remainingAmount (number)\n * currency (string)\n * remindersSent (number)\n * lastSentAt (date time)\n- Update `Add reminders config` node so update the data table id and intervals in days (default is after 2 days, then after 3 days and finally after 5 days )\n- LLM model credentials"
},
"typeVersion": 1
},
{
"id": "f4d77f45-9142-4c1c-b125-e8e5f24ed59d",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-240,
-112
],
"parameters": {
"color": 7,
"width": 256,
"height": 320,
"content": "## Format Data\nFormats the data thus making it easier to be used in other nodes"
},
"typeVersion": 1
},
{
"id": "b66c8925-e5af-4ad3-83bf-8b8db88fa5bc",
"name": "Format data",
"type": "n8n-nodes-base.code",
"position": [
-160,
0
],
"parameters": {
"jsCode": "function extractAddressData(text) {\n const regex = /Street Address:\\s*([^<]+)<br>Street Address Line 2:\\s*([^<]+)<br>City:\\s*([^<]+)<br>State \\/ Province:\\s*([^<]+)<br>Postal \\/ Zip Code:\\s*([^<]+)<br>Country:\\s*([^<]+)<br>/;\n const matches = text.match(regex);\n \n if (matches) {\n return {\n line1: matches[1].trim(),\n line2: matches[2].trim(),\n city: matches[3].trim(),\n stateProvince: matches[4].trim(),\n postalZipCode: matches[5].trim(),\n country: matches[6].trim()\n };\n }\n \n return {\n line1: null,\n line2: null,\n city: null,\n stateProvince: null,\n postalZipCode: null,\n country: null\n }\n}\n\nreturn {\n address: extractAddressData($input.first().json.body.billingAddress),\n customer: {\n name: $input.first().json.body.name,\n email: $input.first().json.body.email,\n phone: $input.first().json.body.phone\n },\n item: {\n name: $input.first().json.body.itemName\n }\n}"
},
"typeVersion": 2
},
{
"id": "3ef848b5-f0c9-4e48-994a-1ec16d130c27",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
864,
-112
],
"parameters": {
"color": 7,
"width": 256,
"height": 320,
"content": "## Add Customer Id\nAdds customer id to the data"
},
"typeVersion": 1
},
{
"id": "a475fc3d-1d1b-406e-92ae-f8d982232b33",
"name": "Add customer id",
"type": "n8n-nodes-base.code",
"position": [
944,
0
],
"parameters": {
"jsCode": "return {\n ...$('Format data').first().json,\n customer: {\n ...$('Format data').first().json.customer,\n id: $input.first().json.Id\n }\n}"
},
"typeVersion": 2
},
{
"id": "d521cb5a-a497-4b2b-be64-0b2b0a755696",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1472,
-112
],
"parameters": {
"color": 7,
"width": 256,
"height": 320,
"content": "## Add Item Id\nAdds item (service/product) id to the data"
},
"typeVersion": 1
},
{
"id": "e5bdb990-3b56-4f97-beba-499d3e063961",
"name": "Add item id",
"type": "n8n-nodes-base.code",
"position": [
1552,
0
],
"parameters": {
"jsCode": "return {\n ...$('Add customer id').first().json,\n item: {\n ...$('Add customer id').first().json.item,\n id: $input.first().json.Id\n }\n}"
},
"typeVersion": 2
},
{
"id": "9370f28d-d910-4e28-8001-414529a51f18",
"name": "Add reminders config",
"type": "n8n-nodes-base.set",
"position": [
960,
704
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={\n \"dataTableId\": \"\",\n \"reminderIntervalsInDays\": [2, 3, 5],\n isInvoiceTrigger: {{ $json[\"Day of week\"] ? false : true }}\n}\n "
},
"typeVersion": 3.4
},
{
"id": "f1e1bc2a-c99e-461d-88fd-d87bfcff3a34",
"name": "Insert invoice id to DB",
"type": "n8n-nodes-base.dataTable",
"position": [
1664,
512
],
"parameters": {
"columns": {
"value": {
"currency": "={{ $('Send the invoice').item.json.CurrencyRef.value }}",
"invoiceId": "={{ $('Send the invoice').item.json.Id }}",
"remindersSent": 0,
"remainingAmount": "={{ $('Send the invoice').item.json.Balance }}"
},
"schema": [
{
"id": "invoiceId",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "invoiceId",
"defaultMatch": false
},
{
"id": "remainingAmount",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "remainingAmount",
"defaultMatch": false
},
{
"id": "currency",
"type": "string",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "currency",
"defaultMatch": false
},
{
"id": "remindersSent",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "remindersSent",
"defaultMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {
"optimizeBulk": false
},
"dataTableId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Add reminders config').item.json.dataTableId }}"
}
},
"typeVersion": 1
},
{
"id": "aabb6827-0dd5-4332-a36c-cc35f150956a",
"name": "Get Invoices",
"type": "n8n-nodes-base.dataTable",
"position": [
1664,
880
],
"parameters": {
"operation": "get",
"returnAll": true,
"dataTableId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Add reminders config').item.json.dataTableId }}"
}
},
"typeVersion": 1
},
{
"id": "15f3089c-ebc8-4cad-85c0-67fc5bbf2802",
"name": "Get the invoice",
"type": "n8n-nodes-base.quickbooks",
"position": [
2368,
1104
],
"parameters": {
"resource": "invoice",
"invoiceId": "={{ $json.invoiceId }}"
},
"credentials": {
"quickBooksOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "0f498328-0b7b-41d9-8f7a-edc45f92438a",
"name": "If2",
"type": "n8n-nodes-base.if",
"position": [
1312,
704
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "82853a4e-d488-49cd-8e36-ba1a737c519b",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.isInvoiceTrigger }}",
"rightValue": "0"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "e84c641c-5316-47fa-bd3c-827487d437a9",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2736,
544
],
"parameters": {
"text": "={{ $('Get today's sent reminders').all() }}",
"options": {
"systemMessage": "=You are an AI assistant that generates a daily reminder summary for invoices. You will receive a list of invoice data and your task is to summarize how many reminders have been sent for each invoice today.\n\nInput Data:\nThe input data is a list of invoices with the following fields:\n- remainingAmount: The remaining amount the customer still needs to pay.\n- currency: The currency of the remaining amount (e.g., USD, EUR).\n- remindersSent: The total number of reminders that have been sent for this invoice.\n\nGoal:\n1- Summarize the reminders sent today:\n- Count how many reminders have been sent for all invoices provided in the input.\n\n2- Generate a professional HTML email summary:\n- Use the information from the invoices to create a summary in HTML format.\n- Include a greeting for the team (e.g., \"Sales Team\", \"Finance Team\").\n- Display a total count of reminders sent today.\n- Include invoice-level details such as invoiceId, remainingAmount, currency, and remindersSent.\n\nFormatting Guidelines:\n1- The summary should always be structured as an HTML email.\n2- The summary should be clear, readable, and professional.\n3- You may choose the layout that feels most appropriate, but always include:\n - A greeting (e.g., \"Dear Team,\").\n - A total number of reminders sent today.\n - A list of invoices with invoiceId, remainingAmount, currency, and remindersSent.\n4- Closing with generic sign-off.\n\nExample input:\n[\n {\n \"id\": 70,\n \"createdAt\": \"2025-10-10T16:50:54.851Z\",\n \"updatedAt\": \"2025-10-15T16:50:54.851Z\",\n \"invoiceId\": \"158\",\n \"remainingAmount\": 10,\n \"currency\": \"USD\",\n \"remindersSent\": 5\n },\n {\n \"id\": 80,\n \"createdAt\": \"2025-10-12T17:50:54.851Z\",\n \"updatedAt\": \"2025-10-15T16:50:54.851Z\",\n \"invoiceId\": \"160\",\n \"remainingAmount\": 30,\n \"currency\": \"EUR\",\n \"remindersSent\": 3\n }\n]\n\nExample of Expected Output:\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Reminder Summary for Today</title>\n <style>\n body { font-family: Arial, sans-serif; color: #333; line-height: 1.6; }\n .table { width: 100%; margin-top: 20px; border-collapse: collapse; }\n .table th, .table td { border: 1px solid #ddd; padding: 8px; text-align: left; }\n .table th { background-color: #f2f2f2; }\n .summary { font-size: 16px; margin-top: 20px; }\n </style>\n</head>\n<body>\n <div class=\"content\">\n <p>Dear Sales Team,</p>\n \n <p>Here is a summary of the reminders sent today:</p>\n \n <div class=\"summary\">\n <strong>Total reminders sent today: 2</strong>\n </div>\n\n <table class=\"table\">\n <thead>\n <tr>\n <th>Invoice ID</th>\n <th>Remaining Amount</th>\n <th>Currency</th>\n <th>Total Reminders Sent</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>158</td>\n <td>$10.00</td>\n <td>USD</td>\n <td>5</td>\n </tr>\n <tr>\n <td>160</td>\n <td>\u20ac30.00</td>\n <td>EUR</td>\n <td>3</td>\n </tr>\n </tbody>\n </table>\n\n <p>If you need further details, feel free to reach out!</p>\n\n <p>Best regards,<br>AI Assistant</p>\n </div>\n</body>\n</html>"
},
"promptType": "define"
},
"executeOnce": true,
"typeVersion": 2.2
},
{
"id": "93a4aa27-13ca-4989-a617-5211f3856ed9",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2736,
752
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "06381d7b-8067-4216-8ecb-a84876693bf3",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
2672,
1120
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "send now",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "df179cc3-60b8-4b49-9fb7-0adabcc3e394",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.Balance > 0 && DateTime.fromISO($('Loop over invoices').item.json.updatedAt).plus($('Add reminders config').item.json.reminderIntervalsInDays[$('Loop over invoices').item.json.remindersSent], 'days').format('yyyy-MM-dd') == $now.format('yyyy-MM-dd') }}",
"rightValue": ""
}
]
},
"renameOutput": true
},
{
"outputKey": "already paid ",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cf03d75d-6560-42ed-8293-3d5e9399b9e3",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.Balance == 0 }}",
"rightValue": ""
}
]
},
"renameOutput": true
},
{
"outputKey": "send later",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "81cb838e-79c8-4c92-964f-f7f5cd44a498",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": true,
"rightValue": ""
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.3
},
{
"id": "242fe315-78c9-4bb5-8a53-2d6485574d54",
"name": "Schedule reminders trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
608,
704
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 8
}
]
}
},
"typeVersion": 1.2
},
{
"id": "add99766-9f1f-4309-96b7-6e26d5503185",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
512,
576
],
"parameters": {
"color": 7,
"width": 304,
"height": 320,
"content": "## Schedule Trigger\nSchedules reminders trigger daily at 8 AM"
},
"typeVersion": 1
},
{
"id": "fb8287f4-0b04-4adc-914d-875c5ff04e7c",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
864,
528
],
"parameters": {
"color": 7,
"width": 304,
"height": 368,
"content": "## Add Reminders Config\nAdds reminders config details like `intervals in days` so first reminder will be sent after 2 days, second one after 3 days and final one after 5 days"
},
"typeVersion": 1
},
{
"id": "c07d8400-4ef0-40e4-bff2-22555692077d",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
1216,
528
],
"parameters": {
"color": 7,
"width": 304,
"height": 368,
"content": "## Check Trigger\nChecks if the previous node has been executed by the above workflow or by the schedule trigger"
},
"typeVersion": 1
},
{
"id": "2c40665a-11db-454b-951f-e28890b633bd",
"name": "Sticky Note14",
"type": "n8n-nodes-base.stickyNote",
"position": [
1568,
352
],
"parameters": {
"color": 7,
"width": 304,
"height": 336,
"content": "## Insert Invoice To DB\nInserts newly created invoice needed details to DB so customer will be notified later on about the invoice"
},
"typeVersion": 1
},
{
"id": "397c3156-6843-4596-8b1e-ac2dbe795b2e",
"name": "Sticky Note15",
"type": "n8n-nodes-base.stickyNote",
"position": [
1568,
736
],
"parameters": {
"color": 7,
"width": 304,
"height": 336,
"content": "## Get All Invoices\nGets all the invoices from DB"
},
"typeVersion": 1
},
{
"id": "d23e89a3-885d-4251-8f24-9baece741836",
"name": "Sticky Note16",
"type": "n8n-nodes-base.stickyNote",
"position": [
1920,
752
],
"parameters": {
"color": 7,
"width": 304,
"height": 320,
"content": "## Loop Over Invoices\nLoops over invoices one by one"
},
"typeVersion": 1
},
{
"id": "8621a71b-9813-4232-9a44-15c62332e75a",
"name": "Loop over invoices",
"type": "n8n-nodes-base.splitInBatches",
"position": [
2016,
880
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "4c21d69d-5111-45bf-b76f-b5834379c1cc",
"name": "Sticky Note17",
"type": "n8n-nodes-base.stickyNote",
"position": [
2272,
544
],
"parameters": {
"color": 7,
"width": 304,
"height": 352,
"content": "## Get Sent Reminders\nGets today's sent reminders from DB"
},
"typeVersion": 1
},
{
"id": "3270e7c4-c153-4341-a9f9-2f2c299264a6",
"name": "Sticky Note18",
"type": "n8n-nodes-base.stickyNote",
"position": [
2272,
944
],
"parameters": {
"color": 7,
"width": 304,
"height": 368,
"content": "## Get Invoice Details\nGets the invoice details from QBO so we know whether or not any changes have been made or not"
},
"typeVersion": 1
},
{
"id": "c12c85f8-ea33-471b-80ff-491db349e784",
"name": "Get today's sent reminders",
"type": "n8n-nodes-base.dataTable",
"position": [
2368,
688
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "lastSentAt",
"keyValue": "={{ $now.startOf('day').toUTC().toString() }}",
"condition": "gte"
}
]
},
"matchType": "allConditions",
"operation": "get",
"returnAll": true,
"dataTableId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Add reminders config').item.json.dataTableId }}"
}
},
"executeOnce": true,
"typeVersion": 1
},
{
"id": "2139421b-bd22-47a6-98d7-7ad641207c7f",
"name": "Sticky Note19",
"type": "n8n-nodes-base.stickyNote",
"position": [
2624,
416
],
"parameters": {
"color": 7,
"width": 592,
"height": 480,
"content": "## Summarize Sent Reminders & Send An Email\nSummarizes today's sent reminders using AI and send a summery email to the team like sales team or finance team"
},
"typeVersion": 1
},
{
"id": "11869e18-01a0-4e33-906e-3d6b7b59d40c",
"name": "Increase sent reminders",
"type": "n8n-nodes-base.dataTable",
"position": [
3136,
1072
],
"parameters": {
"columns": {
"value": {
"lastSentAt": "={{ $now.toISO() }}",
"remindersSent": "={{ $('Loop over invoices').item.json.remindersSent + 1 }} "
},
"schema": [
{
"id": "invoiceId",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "invoiceId",
"defaultMatch": false
},
{
"id": "remainingAmount",
"type": "number",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "remainingAmount",
"defaultMatch": false
},
{
"id": "currency",
"type": "string",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "currency",
"defaultMatch": false
},
{
"id": "remindersSent",
"type": "number",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "remindersSent",
"defaultMatch": false
},
{
"id": "lastSentAt",
"type": "dateTime",
"display": true,
"removed": false,
"readOnly": false,
"required": false,
"displayName": "lastSentAt",
"defaultMatch": false
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"filters": {
"conditions": [
{
"keyName": "invoiceId",
"keyValue": "={{ $('Loop over invoices').item.json.invoiceId }}"
}
]
},
"options": {},
"matchType": "allConditions",
"operation": "update",
"dataTableId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Add reminders config').item.json.dataTableId }}"
}
},
"typeVersion": 1
},
{
"id": "17e76636-622c-49c1-8993-cbb15022b41a",
"name": "Delete invoice",
"type": "n8n-nodes-base.dataTable",
"position": [
3616,
1232
],
"parameters": {
"filters": {
"conditions": [
{
"keyValue": "={{ $('Loop over invoices').item.json.id }}"
}
]
},
"options": {},
"matchType": "allConditions",
"operation": "deleteRows",
"dataTableId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Add reminders config').item.json.dataTableId }}"
}
},
"typeVersion": 1
},
{
"id": "34b07269-37f5-4946-8af7-83b200f31c81",
"name": "If3",
"type": "n8n-nodes-base.if",
"position": [
3344,
1072
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f7c9422b-bfd2-4006-9d81-d2332e95532a",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.remindersSent >= $('Add reminders config').item.json.reminderIntervalsInDays.length }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2.2
},
{
"id": "32b570e6-b5fb-46bd-96f0-6815e30cf4b2",
"name": "Sticky Note20",
"type": "n8n-nodes-base.stickyNote",
"position": [
2624,
944
],
"parameters": {
"color": 7,
"width": 1184,
"height": 480,
"content": "## Send Reminders Logic\nThe logic that decides whether or not to send a reminder email now, skip it and send it later or delete the invoice/s from DB (because all the reminders have been sent or the invoice has been paid)"
},
"typeVersion": 1
},
{
"id": "c358be7d-4f13-406c-b713-189474fa8583",
"name": "Send reminder email",
"type": "n8n-nodes-base.gmail",
"position": [
2928,
1072
],
"parameters": {
"sendTo": "={{ $json.BillEmail.Address }}",
"message": "=<!DOCTYPE html>\n<html>\n<head>\n <style>\n body {\n font-family: Arial, sans-serif;\n color: #333;\n line-height: 1.6;\n }\n .container {\n width: 100%;\n max-width: 600px;\n margin: 0 auto;\n padding: 20px;\n border: 1px solid #f1f1f1;\n border-radius: 5px;\n background-color: #f9f9f9;\n }\n .header {\n text-align: center;\n background-color: #007bff;\n color: white;\n padding: 10px;\n border-radius: 5px;\n }\n .footer {\n text-align: center;\n color: #777;\n font-size: 0.8em;\n margin-top: 20px;\n }\n .button {\n background-color: #28a745;\n color: white;\n text-decoration: none;\n padding: 10px 20px;\n border-radius: 5px;\n display: inline-block;\n margin-top: 20px;\n }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h2>Invoice Reminder: {{ $json.DocNumber }}</h2>\n </div>\n \n <p>Dear,</p>\n \n <p>This is a friendly reminder that your invoice with us is due soon. We kindly ask you to review and complete the payment as soon as possible to avoid any delays.</p>\n \n <p><strong>Invoice Number:</strong> {{ $json.DocNumber }}</p>\n <p><strong>Due Date:</strong> {{ $json.DueDate }}</p>\n \n <p>Please click the button below to view and pay your invoice:</p>\n \n <a href=\"{{ $json.InvoiceLink }}\" class=\"button\">View & Pay Invoice</a>\n \n <p>Thank you for your prompt attention to this matter. If you have any questions or need assistance, feel free to contact us.</p>\n \n <p>Best regards, <br>\n [Your Company Name] <br>\n [Your Contact Information]</p>\n \n <div class=\"footer\">\n <p>© {{ $now.year }} [Your Company Name]. All rights reserved.</p>\n </div>\n </div>\n</body>\n</html>\n",
"options": {},
"subject": "=Friendly Reminder: Your Invoice is Due Soon \u2013 {{ $json.DocNumber }}"
},
"typeVersion": 2.1
},
{
"id": "91131646-c435-4151-b683-6de0053e4d43",
"name": "Send reminders sent summary",
"type": "n8n-nodes-base.gmail",
"position": [
3008,
544
],
"parameters": {
"sendTo": "user@example.com",
"message": "={{ $json.output }}",
"options": {},
"subject": "=Summary of today's reminders sent"
},
"typeVersion": 2.1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "43348de3-c2ce-4b0c-b6f3-49341f180347",
"connections": {
"If": {
"main": [
[
{
"node": "Update the customer",
"type": "main",
"index": 0
}
],
[
{
"node": "Create the customer",
"type": "main",
"index": 0
}
]
]
},
"If2": {
"main": [
[
{
"node": "Insert invoice id to DB",
"type": "main",
"index": 0
}
],
[
{
"node": "Get Invoices",
"type": "main",
"index": 0
}
]
]
},
"If3": {
"main": [
[
{
"node": "Delete invoice",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop over invoices",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "Send reminder email",
"type": "main",
"index": 0
}
],
[
{
"node": "Delete invoice",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop over invoices",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Send reminders sent summary",
"type": "main",
"index": 0
}
]
]
},
"Add item id": {
"main": [
[
{
"node": "Create the invoice",
"type": "main",
"index": 0
}
]
]
},
"Format data": {
"main": [
[
{
"node": "Check if the customer exists",
"type": "main",
"index": 0
}
]
]
},
"Get Invoices": {
"main": [
[
{
"node": "Loop over invoices",
"type": "main",
"index": 0
}
]
]
},
"Delete invoice": {
"main": [
[
{
"node": "Loop over invoices",
"type": "main",
"index": 0
}
]
]
},
"Add customer id": {
"main": [
[
{
"node": "Get the product",
"type": "main",
"index": 0
}
]
]
},
"Get the invoice": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Get the product": {
"main": [
[
{
"node": "Add item id",
"type": "main",
"index": 0
}
]
]
},
"Send the invoice": {
"main": [
[
{
"node": "Add reminders config",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Create the invoice": {
"main": [
[
{
"node": "Send the invoice",
"type": "main",
"index": 0
}
]
]
},
"Loop over invoices": {
"main": [
[
{
"node": "Get today's sent reminders",
"type": "main",
"index": 0
}
],
[
{
"node": "Get the invoice",
"type": "main",
"index": 0
}
]
]
},
"Create the customer": {
"main": [
[
{
"node": "Add customer id",
"type": "main",
"index": 0
}
]
]
},
"Send reminder email": {
"main": [
[
{
"node": "Increase sent reminders",
"type": "main",
"index": 0
}
]
]
},
"Update the customer": {
"main": [
[
{
"node": "Add customer id",
"type": "main",
"index": 0
}
]
]
},
"Add reminders config": {
"main": [
[
{
"node": "If2",
"type": "main",
"index": 0
}
]
]
},
"Increase sent reminders": {
"main": [
[
{
"node": "If3",
"type": "main",
"index": 0
}
]
]
},
"Insert invoice id to DB": {
"main": [
[]
]
},
"Receive form submission": {
"main": [
[
{
"node": "Format data",
"type": "main",
"index": 0
}
]
]
},
"Get today's sent reminders": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Schedule reminders trigger": {
"main": [
[
{
"node": "Add reminders config",
"type": "main",
"index": 0
}
]
]
},
"Check if the customer exists": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
openAiApiquickBooksOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automates the entire process of receiving a product/service order, checking or creating a customer in QuickBooks Online (QBO), generating an invoice, emailing it — all triggered by a form submission (via Jotform), and sending invoice reminders. Receive Submission…
Source: https://n8n.io/workflows/9760/ — 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 enterprise resource planning (ERP) operations across Engineering, Finance, HR, and Admin departments for operations managers, ERP administrators, and business process owners wh
This workflow automates the entire process of receiving a product/service order, checking or creating a customer in QuickBooks Online (QBO), generating an invoice, emailing it — all triggered by a for
This workflow automates the entire process of receiving a product/service order, checking or creating a customer in QuickBooks Online (QBO), generating an invoice, emailing it — all triggered by a for
JoinDAn8n. Uses httpRequest, dataTable, emailReadImap, lmChatOpenAi. Webhook trigger; 37 nodes.
This workflow automates credit operations onboarding by running KYC verification, credit bureau checks, identity validation, and sanctions screening through a single AI-powered agent. Built for credit