Files
n8n-masttro/workflows/lbPTAIqdSq9VCdp6_MoneyBot___Invoice_PDF_Download.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"
}
}