1200 lines
34 KiB
JSON
1200 lines
34 KiB
JSON
{
|
|
"id": "lbPTAIqdSq9VCdp6",
|
|
"name": "MoneyBot — Invoice PDF Download",
|
|
"active": true,
|
|
"activeVersionId": "b712991f-f70c-4420-b555-b898b7729dfd",
|
|
"createdAt": "2026-06-22T16:01:16.843Z",
|
|
"updatedAt": "2026-11-06T19:53:39.752Z",
|
|
"isArchived": false,
|
|
"versionId": "b712991f-f70c-4420-b555-b898b7729dfd",
|
|
"triggerCount": 2,
|
|
"nodes": [
|
|
{
|
|
"id": "55bb4c26-17ee-4f44-98cc-48836e4720da",
|
|
"name": "Webhook — Invoice PDF",
|
|
"type": "n8n-nodes-base.webhook",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-1296,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"httpMethod": "POST",
|
|
"path": "invoice-pdf",
|
|
"responseMode": "responseNode",
|
|
"options": {}
|
|
},
|
|
"webhookId": "moneybot-invoice-pdf"
|
|
},
|
|
{
|
|
"id": "440c6235-1b57-4916-8f41-e60d60eb3a40",
|
|
"name": "Set Params",
|
|
"type": "n8n-nodes-base.set",
|
|
"typeVersion": 3.4,
|
|
"position": [
|
|
-1088,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"assignments": {
|
|
"assignments": [
|
|
{
|
|
"id": "a1",
|
|
"name": "entity",
|
|
"value": "={{ $json.body.entity.toUpperCase() }}",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "a2",
|
|
"name": "invoiceId",
|
|
"value": "={{ $json.body.invoiceId }}",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "a3",
|
|
"name": "filename",
|
|
"value": "={{ ($json.body.filename && $json.body.filename.trim()) ? $json.body.filename.trim() : 'invoice_' + $json.body.entity.toUpperCase() + '_' + $json.body.invoiceId + '.pdf' }}",
|
|
"type": "string"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
}
|
|
},
|
|
{
|
|
"id": "f8bd399d-d04e-4d35-86b6-8447ed0376be",
|
|
"name": "Route by Entity",
|
|
"type": "n8n-nodes-base.switch",
|
|
"typeVersion": 3.2,
|
|
"position": [
|
|
-864,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"rules": {
|
|
"values": [
|
|
{
|
|
"conditions": {
|
|
"options": {
|
|
"caseSensitive": false,
|
|
"leftValue": "",
|
|
"typeValidation": "loose",
|
|
"version": 2
|
|
},
|
|
"conditions": [
|
|
{
|
|
"id": "r1",
|
|
"leftValue": "={{ $json.entity }}",
|
|
"rightValue": "MUS",
|
|
"operator": {
|
|
"type": "string",
|
|
"operation": "equals"
|
|
}
|
|
}
|
|
],
|
|
"combinator": "and"
|
|
},
|
|
"renameOutput": true,
|
|
"outputKey": "MUS"
|
|
},
|
|
{
|
|
"conditions": {
|
|
"options": {
|
|
"caseSensitive": false,
|
|
"leftValue": "",
|
|
"typeValidation": "loose",
|
|
"version": 2
|
|
},
|
|
"conditions": [
|
|
{
|
|
"id": "r2",
|
|
"leftValue": "={{ $json.entity }}",
|
|
"rightValue": "MMX",
|
|
"operator": {
|
|
"type": "string",
|
|
"operation": "equals"
|
|
}
|
|
}
|
|
],
|
|
"combinator": "and"
|
|
},
|
|
"renameOutput": true,
|
|
"outputKey": "MMX"
|
|
},
|
|
{
|
|
"conditions": {
|
|
"options": {
|
|
"caseSensitive": false,
|
|
"leftValue": "",
|
|
"typeValidation": "loose",
|
|
"version": 2
|
|
},
|
|
"conditions": [
|
|
{
|
|
"id": "r3",
|
|
"leftValue": "={{ $json.entity }}",
|
|
"rightValue": "MSAG",
|
|
"operator": {
|
|
"type": "string",
|
|
"operation": "equals"
|
|
}
|
|
}
|
|
],
|
|
"combinator": "and"
|
|
},
|
|
"renameOutput": true,
|
|
"outputKey": "MSAG"
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"fallbackOutput": "extra"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "5a0d0335-32ab-42ad-b670-ec5237c72ec2",
|
|
"name": "GET PDF — MUS",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-640,
|
|
-64
|
|
],
|
|
"parameters": {
|
|
"url": "=https://quickbooks.api.intuit.com/v3/company/9341452327761715/invoice/{{ $json.invoiceId }}/pdf?minorversion=65",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "quickBooksOAuth2Api",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "Accept",
|
|
"value": "application/pdf"
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"response": {
|
|
"response": {
|
|
"responseFormat": "file"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"credentials": {
|
|
"quickBooksOAuth2Api": {
|
|
"id": "i6dFL9yjAAhFxsmn",
|
|
"name": "QuickBooks Online MUS"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "07a459e4-fdfb-4b56-a289-f58422c17e81",
|
|
"name": "Build Base64",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-416,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"jsCode": "const buffer = await this.helpers.getBinaryDataBuffer(0, 'data');\nconst base64 = buffer.toString('base64');\nconst filename = $('Set Params').first().json.filename;\n\nreturn [{ json: { base64, filename } }];"
|
|
}
|
|
},
|
|
{
|
|
"id": "e90054e7-99d1-4283-9efc-ee4d6debb969",
|
|
"name": "Insert to Postgres",
|
|
"type": "n8n-nodes-base.postgres",
|
|
"typeVersion": 2.5,
|
|
"position": [
|
|
-208,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"operation": "executeQuery",
|
|
"query": "INSERT INTO moneybot_exports (file_id, filename, file_format, file_data)\nVALUES (gen_random_uuid(), $1, 'pdf', $2)\nRETURNING file_id",
|
|
"options": {
|
|
"queryReplacement": "={{ [$json.filename, $json.base64] }}"
|
|
}
|
|
},
|
|
"credentials": {
|
|
"postgres": {
|
|
"id": "WCNMtOftbLNqnKH7",
|
|
"name": "Postgres moneybot-exports"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "9dbce507-b985-4bf3-a840-7978fd667dd9",
|
|
"name": "Build Response",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
32,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"jsCode": "const fileId = $input.first().json.file_id;\nconst filename = $('Build Base64').first().json.filename;\nconst downloadUrl = `https://moneybot.masttro.com/webhook/08933a7d-ed33-4a7c-b652-7172b337471c?fileId=${fileId}`;\nconst message = `✅ [Download ${filename}](${downloadUrl})`;\n\nreturn [{ json: { file_id: fileId, downloadUrl, filename, message } }];"
|
|
}
|
|
},
|
|
{
|
|
"id": "e43a50aa-6b57-4909-845f-b4e40d7a8b50",
|
|
"name": "Respond with URL",
|
|
"type": "n8n-nodes-base.respondToWebhook",
|
|
"typeVersion": 1.1,
|
|
"position": [
|
|
240,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"respondWith": "json",
|
|
"responseBody": "={{ $json }}",
|
|
"options": {}
|
|
}
|
|
},
|
|
{
|
|
"id": "b797919b-ec15-4029-8fd1-653d1ff9f0f2",
|
|
"name": "GET PDF — MMX",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-640,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"url": "=https://quickbooks.api.intuit.com/v3/company/9341452328017372/invoice/{{ $json.invoiceId }}/pdf?minorversion=65",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "quickBooksOAuth2Api",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "Accept",
|
|
"value": "application/pdf"
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"response": {
|
|
"response": {
|
|
"responseFormat": "file"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"credentials": {
|
|
"quickBooksOAuth2Api": {
|
|
"id": "USLCXCphdJqcpr2C",
|
|
"name": "QuickBooks Online MMX"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "5d3f5fc9-b885-4462-a87c-e32eb9783134",
|
|
"name": "GET PDF — MSAG",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-640,
|
|
224
|
|
],
|
|
"parameters": {
|
|
"url": "=https://quickbooks.api.intuit.com/v3/company/9341452373926753/invoice/{{ $json.invoiceId }}/pdf?minorversion=65",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "quickBooksOAuth2Api",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "Accept",
|
|
"value": "application/pdf"
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"response": {
|
|
"response": {
|
|
"responseFormat": "file"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"credentials": {
|
|
"quickBooksOAuth2Api": {
|
|
"id": "Q0bvGHliYfQTGUWW",
|
|
"name": "QuickBooks Online MSAG"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "20262ccb-999b-4dbf-bd9f-46aa9fde124d",
|
|
"name": "Webhook — Download",
|
|
"type": "n8n-nodes-base.webhook",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-960,
|
|
496
|
|
],
|
|
"parameters": {
|
|
"path": "08933a7d-ed33-4a7c-b652-7172b337471c",
|
|
"responseMode": "responseNode",
|
|
"options": {}
|
|
},
|
|
"webhookId": "08933a7d-ed33-4a7c-b652-7172b337471c"
|
|
},
|
|
{
|
|
"id": "8eddeb9d-a02d-4a89-9ccc-ffc2ea34091f",
|
|
"name": "Fetch Export from Postgres",
|
|
"type": "n8n-nodes-base.postgres",
|
|
"typeVersion": 2.5,
|
|
"position": [
|
|
-736,
|
|
496
|
|
],
|
|
"parameters": {
|
|
"operation": "executeQuery",
|
|
"query": "SELECT filename, file_format, file_data FROM moneybot_exports WHERE file_id::text = $1 AND created_at > NOW() - INTERVAL '24 hours' LIMIT 1",
|
|
"options": {
|
|
"queryReplacement": "={{ [$json.query.fileId] }}"
|
|
}
|
|
},
|
|
"credentials": {
|
|
"postgres": {
|
|
"id": "WCNMtOftbLNqnKH7",
|
|
"name": "Postgres moneybot-exports"
|
|
}
|
|
},
|
|
"alwaysOutputData": true
|
|
},
|
|
{
|
|
"id": "103bde6b-0de7-4b36-ae31-c47d6a1b65a4",
|
|
"name": "Prepare Binary",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-512,
|
|
496
|
|
],
|
|
"parameters": {
|
|
"jsCode": "const rows = $input.all();\n\nif (!rows || rows.length === 0 || !rows[0].json.file_data) {\n const q = $('Webhook — Download').first().json.query || {};\n throw new Error('Export not found or expired for fileId=\"' + (q.fileId || '(missing)') + '\". Exports are retained for 24 hours after creation.');\n}\n\nconst row = rows[0].json;\n\nconst mimeType = row.file_format === 'pdf'\n ? 'application/pdf'\n : row.file_format === 'xlsx'\n ? 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n : 'text/csv';\n\nconst disposition = row.file_format === 'pdf' ? 'inline' : 'attachment';\n\nconst fileExtension = row.file_format === 'pdf'\n ? 'pdf'\n : row.file_format === 'xlsx'\n ? 'xlsx'\n : 'csv';\n\nreturn [{\n json: { filename: row.filename, disposition },\n binary: {\n data: {\n data: row.file_data,\n mimeType,\n fileName: row.filename,\n fileExtension\n }\n }\n}];"
|
|
}
|
|
},
|
|
{
|
|
"id": "99b761b8-1847-439a-a1b5-fd6b5c420775",
|
|
"name": "Respond to Webhook",
|
|
"type": "n8n-nodes-base.respondToWebhook",
|
|
"typeVersion": 1.1,
|
|
"position": [
|
|
-288,
|
|
496
|
|
],
|
|
"parameters": {
|
|
"respondWith": "binary",
|
|
"options": {
|
|
"responseHeaders": {
|
|
"entries": [
|
|
{
|
|
"name": "Content-Disposition",
|
|
"value": "={{ $json.disposition }}; filename=\"{{ $json.filename }}\""
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"connections": {
|
|
"Webhook — Invoice PDF": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Set Params",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Set Params": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Route by Entity",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Route by Entity": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "GET PDF — MUS",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "GET PDF — MMX",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "GET PDF — MSAG",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"GET PDF — MUS": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Build Base64",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Build Base64": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Insert to Postgres",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Insert to Postgres": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Build Response",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Build Response": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Respond with URL",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"GET PDF — MMX": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Build Base64",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"GET PDF — MSAG": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Build Base64",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Webhook — Download": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Fetch Export from Postgres",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Fetch Export from Postgres": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Prepare Binary",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Prepare Binary": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Respond to Webhook",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
}
|
|
},
|
|
"nodeGroups": [
|
|
{
|
|
"id": "c6995c45-c007-410e-a98d-6b1cf0781b27",
|
|
"name": "Fetch invoice PDF",
|
|
"nodeIds": [
|
|
"440c6235-1b57-4916-8f41-e60d60eb3a40",
|
|
"f8bd399d-d04e-4d35-86b6-8447ed0376be",
|
|
"5a0d0335-32ab-42ad-b670-ec5237c72ec2",
|
|
"b797919b-ec15-4029-8fd1-653d1ff9f0f2",
|
|
"5d3f5fc9-b885-4462-a87c-e32eb9783134",
|
|
"07a459e4-fdfb-4b56-a289-f58422c17e81"
|
|
],
|
|
"description": "Reads the entity and invoice id from the request and pulls that invoice PDF from the matching QuickBooks company."
|
|
},
|
|
{
|
|
"id": "088c6476-e407-48ae-b894-a2d2d9341fac",
|
|
"name": "Store and share PDF",
|
|
"nodeIds": [
|
|
"e90054e7-99d1-4283-9efc-ee4d6debb969",
|
|
"9dbce507-b985-4bf3-a840-7978fd667dd9",
|
|
"e43a50aa-6b57-4909-845f-b4e40d7a8b50"
|
|
],
|
|
"description": "Saves the PDF for 24 hours and replies to the caller with a download link."
|
|
},
|
|
{
|
|
"id": "bda07ef5-0656-46c3-a8b6-1b541f608cd5",
|
|
"name": "Serve file download",
|
|
"nodeIds": [
|
|
"8eddeb9d-a02d-4a89-9ccc-ffc2ea34091f",
|
|
"103bde6b-0de7-4b36-ae31-c47d6a1b65a4",
|
|
"99b761b8-1847-439a-a1b5-fd6b5c420775"
|
|
],
|
|
"description": "Looks up a stored file by id, rejects expired or unknown ids with a clear error, and streams the file back to the browser."
|
|
}
|
|
],
|
|
"settings": {
|
|
"binaryMode": "separate",
|
|
"callerPolicy": "workflowsFromSameOwner",
|
|
"errorWorkflow": "tJSgL4iy63ys2NCA",
|
|
"timeSavedMode": "fixed",
|
|
"availableInMCP": false,
|
|
"executionOrder": "v1"
|
|
},
|
|
"staticData": null,
|
|
"pinData": {},
|
|
"meta": null,
|
|
"tags": [],
|
|
"shared": [
|
|
{
|
|
"role": "workflow:owner",
|
|
"workflowId": "lbPTAIqdSq9VCdp6",
|
|
"projectId": "X4TTvIwW8wN0Iirz",
|
|
"createdAt": "2026-06-22T16:01:16.843Z",
|
|
"updatedAt": "2026-06-22T16:01:16.843Z"
|
|
}
|
|
],
|
|
"activeVersion": {
|
|
"versionId": "b712991f-f70c-4420-b555-b898b7729dfd",
|
|
"workflowId": "lbPTAIqdSq9VCdp6",
|
|
"nodes": [
|
|
{
|
|
"id": "55bb4c26-17ee-4f44-98cc-48836e4720da",
|
|
"name": "Webhook — Invoice PDF",
|
|
"type": "n8n-nodes-base.webhook",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-1296,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"httpMethod": "POST",
|
|
"path": "invoice-pdf",
|
|
"responseMode": "responseNode",
|
|
"options": {}
|
|
},
|
|
"webhookId": "moneybot-invoice-pdf"
|
|
},
|
|
{
|
|
"id": "440c6235-1b57-4916-8f41-e60d60eb3a40",
|
|
"name": "Set Params",
|
|
"type": "n8n-nodes-base.set",
|
|
"typeVersion": 3.4,
|
|
"position": [
|
|
-1088,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"assignments": {
|
|
"assignments": [
|
|
{
|
|
"id": "a1",
|
|
"name": "entity",
|
|
"value": "={{ $json.body.entity.toUpperCase() }}",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "a2",
|
|
"name": "invoiceId",
|
|
"value": "={{ $json.body.invoiceId }}",
|
|
"type": "string"
|
|
},
|
|
{
|
|
"id": "a3",
|
|
"name": "filename",
|
|
"value": "={{ ($json.body.filename && $json.body.filename.trim()) ? $json.body.filename.trim() : 'invoice_' + $json.body.entity.toUpperCase() + '_' + $json.body.invoiceId + '.pdf' }}",
|
|
"type": "string"
|
|
}
|
|
]
|
|
},
|
|
"options": {}
|
|
}
|
|
},
|
|
{
|
|
"id": "f8bd399d-d04e-4d35-86b6-8447ed0376be",
|
|
"name": "Route by Entity",
|
|
"type": "n8n-nodes-base.switch",
|
|
"typeVersion": 3.2,
|
|
"position": [
|
|
-864,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"rules": {
|
|
"values": [
|
|
{
|
|
"conditions": {
|
|
"options": {
|
|
"caseSensitive": false,
|
|
"leftValue": "",
|
|
"typeValidation": "loose",
|
|
"version": 2
|
|
},
|
|
"conditions": [
|
|
{
|
|
"id": "r1",
|
|
"leftValue": "={{ $json.entity }}",
|
|
"rightValue": "MUS",
|
|
"operator": {
|
|
"type": "string",
|
|
"operation": "equals"
|
|
}
|
|
}
|
|
],
|
|
"combinator": "and"
|
|
},
|
|
"renameOutput": true,
|
|
"outputKey": "MUS"
|
|
},
|
|
{
|
|
"conditions": {
|
|
"options": {
|
|
"caseSensitive": false,
|
|
"leftValue": "",
|
|
"typeValidation": "loose",
|
|
"version": 2
|
|
},
|
|
"conditions": [
|
|
{
|
|
"id": "r2",
|
|
"leftValue": "={{ $json.entity }}",
|
|
"rightValue": "MMX",
|
|
"operator": {
|
|
"type": "string",
|
|
"operation": "equals"
|
|
}
|
|
}
|
|
],
|
|
"combinator": "and"
|
|
},
|
|
"renameOutput": true,
|
|
"outputKey": "MMX"
|
|
},
|
|
{
|
|
"conditions": {
|
|
"options": {
|
|
"caseSensitive": false,
|
|
"leftValue": "",
|
|
"typeValidation": "loose",
|
|
"version": 2
|
|
},
|
|
"conditions": [
|
|
{
|
|
"id": "r3",
|
|
"leftValue": "={{ $json.entity }}",
|
|
"rightValue": "MSAG",
|
|
"operator": {
|
|
"type": "string",
|
|
"operation": "equals"
|
|
}
|
|
}
|
|
],
|
|
"combinator": "and"
|
|
},
|
|
"renameOutput": true,
|
|
"outputKey": "MSAG"
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"fallbackOutput": "extra"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "5a0d0335-32ab-42ad-b670-ec5237c72ec2",
|
|
"name": "GET PDF — MUS",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-640,
|
|
-64
|
|
],
|
|
"parameters": {
|
|
"url": "=https://quickbooks.api.intuit.com/v3/company/9341452327761715/invoice/{{ $json.invoiceId }}/pdf?minorversion=65",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "quickBooksOAuth2Api",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "Accept",
|
|
"value": "application/pdf"
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"response": {
|
|
"response": {
|
|
"responseFormat": "file"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"credentials": {
|
|
"quickBooksOAuth2Api": {
|
|
"id": "i6dFL9yjAAhFxsmn",
|
|
"name": "QuickBooks Online MUS"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "07a459e4-fdfb-4b56-a289-f58422c17e81",
|
|
"name": "Build Base64",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-416,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"jsCode": "const buffer = await this.helpers.getBinaryDataBuffer(0, 'data');\nconst base64 = buffer.toString('base64');\nconst filename = $('Set Params').first().json.filename;\n\nreturn [{ json: { base64, filename } }];"
|
|
}
|
|
},
|
|
{
|
|
"id": "e90054e7-99d1-4283-9efc-ee4d6debb969",
|
|
"name": "Insert to Postgres",
|
|
"type": "n8n-nodes-base.postgres",
|
|
"typeVersion": 2.5,
|
|
"position": [
|
|
-208,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"operation": "executeQuery",
|
|
"query": "INSERT INTO moneybot_exports (file_id, filename, file_format, file_data)\nVALUES (gen_random_uuid(), $1, 'pdf', $2)\nRETURNING file_id",
|
|
"options": {
|
|
"queryReplacement": "={{ [$json.filename, $json.base64] }}"
|
|
}
|
|
},
|
|
"credentials": {
|
|
"postgres": {
|
|
"id": "WCNMtOftbLNqnKH7",
|
|
"name": "Postgres moneybot-exports"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "9dbce507-b985-4bf3-a840-7978fd667dd9",
|
|
"name": "Build Response",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
32,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"jsCode": "const fileId = $input.first().json.file_id;\nconst filename = $('Build Base64').first().json.filename;\nconst downloadUrl = `https://moneybot.masttro.com/webhook/08933a7d-ed33-4a7c-b652-7172b337471c?fileId=${fileId}`;\nconst message = `✅ [Download ${filename}](${downloadUrl})`;\n\nreturn [{ json: { file_id: fileId, downloadUrl, filename, message } }];"
|
|
}
|
|
},
|
|
{
|
|
"id": "e43a50aa-6b57-4909-845f-b4e40d7a8b50",
|
|
"name": "Respond with URL",
|
|
"type": "n8n-nodes-base.respondToWebhook",
|
|
"typeVersion": 1.1,
|
|
"position": [
|
|
240,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"respondWith": "json",
|
|
"responseBody": "={{ $json }}",
|
|
"options": {}
|
|
}
|
|
},
|
|
{
|
|
"id": "b797919b-ec15-4029-8fd1-653d1ff9f0f2",
|
|
"name": "GET PDF — MMX",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-640,
|
|
80
|
|
],
|
|
"parameters": {
|
|
"url": "=https://quickbooks.api.intuit.com/v3/company/9341452328017372/invoice/{{ $json.invoiceId }}/pdf?minorversion=65",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "quickBooksOAuth2Api",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "Accept",
|
|
"value": "application/pdf"
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"response": {
|
|
"response": {
|
|
"responseFormat": "file"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"credentials": {
|
|
"quickBooksOAuth2Api": {
|
|
"id": "USLCXCphdJqcpr2C",
|
|
"name": "QuickBooks Online MMX"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "5d3f5fc9-b885-4462-a87c-e32eb9783134",
|
|
"name": "GET PDF — MSAG",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [
|
|
-640,
|
|
224
|
|
],
|
|
"parameters": {
|
|
"url": "=https://quickbooks.api.intuit.com/v3/company/9341452373926753/invoice/{{ $json.invoiceId }}/pdf?minorversion=65",
|
|
"authentication": "predefinedCredentialType",
|
|
"nodeCredentialType": "quickBooksOAuth2Api",
|
|
"sendHeaders": true,
|
|
"headerParameters": {
|
|
"parameters": [
|
|
{
|
|
"name": "Accept",
|
|
"value": "application/pdf"
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"response": {
|
|
"response": {
|
|
"responseFormat": "file"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"credentials": {
|
|
"quickBooksOAuth2Api": {
|
|
"id": "Q0bvGHliYfQTGUWW",
|
|
"name": "QuickBooks Online MSAG"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"id": "20262ccb-999b-4dbf-bd9f-46aa9fde124d",
|
|
"name": "Webhook — Download",
|
|
"type": "n8n-nodes-base.webhook",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-960,
|
|
496
|
|
],
|
|
"parameters": {
|
|
"path": "08933a7d-ed33-4a7c-b652-7172b337471c",
|
|
"responseMode": "responseNode",
|
|
"options": {}
|
|
},
|
|
"webhookId": "08933a7d-ed33-4a7c-b652-7172b337471c"
|
|
},
|
|
{
|
|
"id": "8eddeb9d-a02d-4a89-9ccc-ffc2ea34091f",
|
|
"name": "Fetch Export from Postgres",
|
|
"type": "n8n-nodes-base.postgres",
|
|
"typeVersion": 2.5,
|
|
"position": [
|
|
-736,
|
|
496
|
|
],
|
|
"parameters": {
|
|
"operation": "executeQuery",
|
|
"query": "SELECT filename, file_format, file_data FROM moneybot_exports WHERE file_id::text = $1 AND created_at > NOW() - INTERVAL '24 hours' LIMIT 1",
|
|
"options": {
|
|
"queryReplacement": "={{ [$json.query.fileId] }}"
|
|
}
|
|
},
|
|
"credentials": {
|
|
"postgres": {
|
|
"id": "WCNMtOftbLNqnKH7",
|
|
"name": "Postgres moneybot-exports"
|
|
}
|
|
},
|
|
"alwaysOutputData": true
|
|
},
|
|
{
|
|
"id": "103bde6b-0de7-4b36-ae31-c47d6a1b65a4",
|
|
"name": "Prepare Binary",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [
|
|
-512,
|
|
496
|
|
],
|
|
"parameters": {
|
|
"jsCode": "const rows = $input.all();\n\nif (!rows || rows.length === 0 || !rows[0].json.file_data) {\n const q = $('Webhook — Download').first().json.query || {};\n throw new Error('Export not found or expired for fileId=\"' + (q.fileId || '(missing)') + '\". Exports are retained for 24 hours after creation.');\n}\n\nconst row = rows[0].json;\n\nconst mimeType = row.file_format === 'pdf'\n ? 'application/pdf'\n : row.file_format === 'xlsx'\n ? 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n : 'text/csv';\n\nconst disposition = row.file_format === 'pdf' ? 'inline' : 'attachment';\n\nconst fileExtension = row.file_format === 'pdf'\n ? 'pdf'\n : row.file_format === 'xlsx'\n ? 'xlsx'\n : 'csv';\n\nreturn [{\n json: { filename: row.filename, disposition },\n binary: {\n data: {\n data: row.file_data,\n mimeType,\n fileName: row.filename,\n fileExtension\n }\n }\n}];"
|
|
}
|
|
},
|
|
{
|
|
"id": "99b761b8-1847-439a-a1b5-fd6b5c420775",
|
|
"name": "Respond to Webhook",
|
|
"type": "n8n-nodes-base.respondToWebhook",
|
|
"typeVersion": 1.1,
|
|
"position": [
|
|
-288,
|
|
496
|
|
],
|
|
"parameters": {
|
|
"respondWith": "binary",
|
|
"options": {
|
|
"responseHeaders": {
|
|
"entries": [
|
|
{
|
|
"name": "Content-Disposition",
|
|
"value": "={{ $json.disposition }}; filename=\"{{ $json.filename }}\""
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"connections": {
|
|
"Webhook — Invoice PDF": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Set Params",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Set Params": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Route by Entity",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Route by Entity": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "GET PDF — MUS",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "GET PDF — MMX",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"node": "GET PDF — MSAG",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"GET PDF — MUS": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Build Base64",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Build Base64": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Insert to Postgres",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Insert to Postgres": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Build Response",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Build Response": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Respond with URL",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"GET PDF — MMX": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Build Base64",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"GET PDF — MSAG": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Build Base64",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Webhook — Download": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Fetch Export from Postgres",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Fetch Export from Postgres": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Prepare Binary",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
},
|
|
"Prepare Binary": {
|
|
"main": [
|
|
[
|
|
{
|
|
"node": "Respond to Webhook",
|
|
"type": "main",
|
|
"index": 0
|
|
}
|
|
]
|
|
]
|
|
}
|
|
},
|
|
"nodeGroups": [
|
|
{
|
|
"id": "c6995c45-c007-410e-a98d-6b1cf0781b27",
|
|
"name": "Fetch invoice PDF",
|
|
"nodeIds": [
|
|
"440c6235-1b57-4916-8f41-e60d60eb3a40",
|
|
"f8bd399d-d04e-4d35-86b6-8447ed0376be",
|
|
"5a0d0335-32ab-42ad-b670-ec5237c72ec2",
|
|
"b797919b-ec15-4029-8fd1-653d1ff9f0f2",
|
|
"5d3f5fc9-b885-4462-a87c-e32eb9783134",
|
|
"07a459e4-fdfb-4b56-a289-f58422c17e81"
|
|
],
|
|
"description": "Reads the entity and invoice id from the request and pulls that invoice PDF from the matching QuickBooks company."
|
|
},
|
|
{
|
|
"id": "088c6476-e407-48ae-b894-a2d2d9341fac",
|
|
"name": "Store and share PDF",
|
|
"nodeIds": [
|
|
"e90054e7-99d1-4283-9efc-ee4d6debb969",
|
|
"9dbce507-b985-4bf3-a840-7978fd667dd9",
|
|
"e43a50aa-6b57-4909-845f-b4e40d7a8b50"
|
|
],
|
|
"description": "Saves the PDF for 24 hours and replies to the caller with a download link."
|
|
},
|
|
{
|
|
"id": "bda07ef5-0656-46c3-a8b6-1b541f608cd5",
|
|
"name": "Serve file download",
|
|
"nodeIds": [
|
|
"8eddeb9d-a02d-4a89-9ccc-ffc2ea34091f",
|
|
"103bde6b-0de7-4b36-ae31-c47d6a1b65a4",
|
|
"99b761b8-1847-439a-a1b5-fd6b5c420775"
|
|
],
|
|
"description": "Looks up a stored file by id, rejects expired or unknown ids with a clear error, and streams the file back to the browser."
|
|
}
|
|
],
|
|
"authors": "Michael Nolan (with n8n Assistant)",
|
|
"name": null,
|
|
"description": null,
|
|
"autosaved": false,
|
|
"createdAt": "2026-11-06T19:53:39.755Z",
|
|
"updatedAt": "2026-11-06T19:53:39.755Z"
|
|
}
|
|
} |