AutomationFlowsAI & RAG › Whatsapp Receipt OCR & AI Data Extraction with Twilio, Llamaparse & Gemini

Whatsapp Receipt OCR & AI Data Extraction with Twilio, Llamaparse & Gemini

ByGabriela Macovei @gabrielamacovei on n8n.io

Categories: Accounting Automation • OCR Processing • AI Data Extraction • Business Tools

Webhook trigger★★★★★ complexityAI-powered41 nodesHTTP RequestOpenRouter ChatGoogle Gemini ChatGoogle DriveGoogle SheetsChain LlmOutput Parser Structured
AI & RAG Trigger: Webhook Nodes: 41 Complexity: ★★★★★ AI nodes: yes Added:

This workflow corresponds to n8n.io template #11332 — we link there as the canonical source.

This workflow follows the Chainllm → Google Drive 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 →

Download .json
{
  "id": "yCdDUcDhcFqoAyg3",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "[creator submission] OCR LLamaParse WhatsApp twilio  gemini open router g sheets",
  "tags": [],
  "nodes": [
    {
      "id": "3d154638-8a76-4006-9eb8-cb4c4ac551e4",
      "name": "Webhook3",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -3264,
        1024
      ],
      "parameters": {
        "path": "5c87f92e-eba8-4f8e-825e-73a0bce05186",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2.1
    },
    {
      "id": "4723f47e-4192-4f08-bc71-a0063ba19870",
      "name": "If5",
      "type": "n8n-nodes-base.if",
      "position": [
        -1264,
        224
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b738ff6d-2da2-4681-a8c8-5cf2b6558562",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "=SUCCESS"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "71f84019-8a7b-42e2-abed-7375903f4cfc",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        -1040,
        384
      ],
      "parameters": {
        "amount": 2
      },
      "typeVersion": 1.1
    },
    {
      "id": "34ff5654-e5b8-4975-b61e-be81eae87085",
      "name": "HTTP Request28",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1536,
        224
      ],
      "parameters": {
        "url": "=https://api.cloud.llamaindex.ai/api/v1/parsing/job/{{ $json.id }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "d8d24b43-a3c2-4db8-b25e-9e7c54f6dfc7",
      "name": "HTTP Request29",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1776,
        224
      ],
      "parameters": {
        "url": "https://api.cloud.llamaindex.ai/api/v1/parsing/upload",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "parse_mode",
              "value": "parse_page_with_agent"
            },
            {
              "name": "model",
              "value": "anthropic-sonnet-4.0"
            },
            {
              "name": "high_res_ocr",
              "value": "true"
            },
            {
              "name": "adaptive_long_table",
              "value": "true"
            },
            {
              "name": "outlined_table_extraction",
              "value": "true"
            },
            {
              "name": "output_tables_as_HTML",
              "value": "false"
            },
            {
              "name": "preset",
              "value": "invoice"
            },
            {
              "name": "file",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "c21433f2-c6be-4889-9229-229632e1e814",
      "name": "HTTP Request17",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1424,
        -48
      ],
      "parameters": {
        "url": "https://messaging.twilio.com/v2/Indicators/Typing.json",
        "method": "POST",
        "options": {
          "timeout": 180000
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "messageId",
              "value": "={{ $('Webhook3').item.json.body.MessageSid }}"
            },
            {
              "name": "channel",
              "value": "whatsapp"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "authorization",
              "value": "Basic QUNkMzgyNTA5NGIyZDM1NzNmMTBiMTM4NDQ5ZWNkNmRiMzpZT1VSX0FVVEhfVE9LRU5fSEVSRQ=="
            }
          ]
        },
        "nodeCredentialType": "twilioApi"
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 1500
    },
    {
      "id": "a717a933-8de0-41ae-bec6-3a92dfd5a776",
      "name": "HTTP Request18",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -96,
        -96
      ],
      "parameters": {
        "url": "https://messaging.twilio.com/v2/Indicators/Typing.json",
        "method": "POST",
        "options": {
          "timeout": 180000
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "messageId",
              "value": "={{ $('Webhook3').item.json.body.MessageSid }}"
            },
            {
              "name": "channel",
              "value": "whatsapp"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "authorization",
              "value": "Basic QUNkMzgyNTA5NGIyZDM1NzNmMTBiMTM4NDQ5ZWNkNmRiMzpZT1VSX0FVVEhfVE9LRU5fSEVSRQ=="
            }
          ]
        },
        "nodeCredentialType": "twilioApi"
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 1500
    },
    {
      "id": "845b9bb8-0f4e-402d-987c-c0f76e1a11d8",
      "name": "HTTP Request30",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1008,
        96
      ],
      "parameters": {
        "url": "=https://api.cloud.llamaindex.ai/api/v1/parsing/job/{{ $json.id }}/result/markdown",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "cc3ac676-a194-4e2e-bac1-da7a4c55a6fa",
      "name": "OpenRouter Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        -400,
        400
      ],
      "parameters": {
        "model": "anthropic/claude-sonnet-4.5",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "25322de5-1b5e-4066-a8fb-b1fc7620f87e",
      "name": "HTTP Request5",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2208,
        1216
      ],
      "parameters": {
        "url": "={{ $('Webhook3').item.json.body.MediaUrl0 }}",
        "options": {
          "timeout": 180000
        },
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "twilioApi"
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 2000
    },
    {
      "id": "447bb8ac-e92e-495d-99dd-e3c9f38d798c",
      "name": "Google Gemini Chat Model5",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -560,
        400
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-pro"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6adfe435-d353-4a01-a812-5514d2a553ee",
      "name": "Upload file2",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1776,
        1264
      ],
      "parameters": {
        "name": "={{ $('Webhook3').item.json.body.MessageSid }}{{ $binary.data.fileName }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "82128d99-a421-4d1f-bbea-f2cf6a145eee",
      "name": "Append row in sheet2",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -2432,
        1216
      ],
      "parameters": {
        "columns": {
          "value": {
            "MessageSid": "={{ $('Webhook3').item.json.body.MessageSid }}"
          },
          "schema": [
            {
              "id": "Phone number",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "MessageSid",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "MessageSid",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Vendor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Cost",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Cost",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tax",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Tax",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Currency",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Link to Picture (Google Drive)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Link to Picture (Google Drive)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ABN",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ABN",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status Data accuracy ? Yes / No / Not confirmet yet",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Status Data accuracy ? Yes / No / Not confirmet yet",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ID quick reply",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ID quick reply",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 573969032,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY/edit#gid=573969032",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY/edit?usp=drivesdk",
          "cachedResultName": "OCR created from n8n"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "43bbff2d-f8cc-43cf-bb2b-0f7a879be4d2",
      "name": "Update row in sheet4",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2224,
        1264
      ],
      "parameters": {
        "columns": {
          "value": {
            "MessageSid": "={{ $('Webhook3').item.json.body.MessageSid }}",
            "Link to Picture (Google Drive)": "={{ $('Upload file2').item.json.webViewLink }}"
          },
          "schema": [
            {
              "id": "Phone number",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "MessageSid",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "MessageSid",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Vendor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Cost",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Cost",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tax",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Tax",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Currency",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Link to Picture (Google Drive)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Link to Picture (Google Drive)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ABN",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ABN",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status Data accuracy ? Yes / No / Not confirmet yet",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Status Data accuracy ? Yes / No / Not confirmet yet",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ID quick reply",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ID quick reply",
              "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": [
            "MessageSid"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 573969032,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY/edit#gid=573969032",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY/edit?usp=drivesdk",
          "cachedResultName": "OCR created from n8n"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "45ebc70d-7607-49c3-bbba-2a9121b7d168",
      "name": "Update row in sheet5",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 5,
      "position": [
        1520,
        160
      ],
      "parameters": {
        "columns": {
          "value": {
            "ABN": "={{ $json.ABN }}",
            "Tax": "={{ $json.Tax }}",
            "Cost": "={{ $json.cost }}",
            "Date": "={{ $json.date }}",
            "Vendor": "={{ $json.vendor }}",
            "Currency": "={{ $json.currency }}",
            "MessageSid": "={{ $('Webhook3').item.json.body.MessageSid }}",
            "Status Data accuracy ? Yes / No / Not confirmet yet": "Not confirmed yet"
          },
          "schema": [
            {
              "id": "Phone number",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "MessageSid",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "MessageSid",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Vendor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Cost",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Cost",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tax",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Tax",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Currency",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Link to Picture (Google Drive)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Link to Picture (Google Drive)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ABN",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "ABN",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status Data accuracy ? Yes / No / Not confirmet yet",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Status Data accuracy ? Yes / No / Not confirmet yet",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ID quick reply",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ID quick reply",
              "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": [
            "MessageSid"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 573969032,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY/edit#gid=573969032",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY/edit?usp=drivesdk",
          "cachedResultName": "OCR created from n8n"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "alwaysOutputData": true,
      "waitBetweenTries": 4000
    },
    {
      "id": "9495e485-9e5c-408c-b6cd-45f266d9514c",
      "name": "HTTP Request6",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1744,
        160
      ],
      "parameters": {
        "url": "https://api.twilio.com/2010-04-01/Accounts/ACYOUR_TWILIO_ACCOUNT_SID/Messages.json",
        "method": "POST",
        "options": {
          "timeout": 180000
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "From",
              "value": "whatsapp:+1234567890"
            },
            {
              "name": "To",
              "value": "={{ $('Webhook3').item.json.body.From }}"
            },
            {
              "name": "Body",
              "value": "=Processed File: {{ $('Webhook3').item.json.body.MessageSid }}\nVendor: {{ $('Merge2').item.json.vendor }}\nCost: {{ $('Merge2').item.json.cost }}\nTax: {{ $('Merge2').item.json.Tax }}\nDate: {{ $('Merge2').item.json.date }}\nABN: {{ $('Basic LLM Chain3').item.json.output.ABN }}"
            }
          ]
        },
        "nodeCredentialType": "twilioApi"
      },
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 1500
    },
    {
      "id": "b3dd632d-178d-4699-abd7-c9980c8d69b8",
      "name": "Basic LLM Chain3",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "maxTries": 2,
      "position": [
        -496,
        112
      ],
      "parameters": {
        "text": "=You are an LLM that extracts structured data from OCR\u2019d Australian receipts and invoices.\n\nInput OCR text is:\n{{ $json.markdown }}\n\n\nGlobal rules:\n- Read the **entire** OCR text before deciding any value.\n- If a field cannot be confidently determined, output it as an empty string, except `Tax`, which must follow the rules below.\n- Never fabricate values.\n- Do not output this tag: ```json\n\n---\n\n## Tax field (GST / TAX / VAT)\n\n`Tax` must be **exactly one** of:\n\n- A numeric string like `\"3.61\"` (no currency symbol)\n- `\"Included in total cost\"`\n- `\"Unidentified\"`\n- `\"Not found\"`\n\nFollow these rules **in order of priority**:\n\n### 1. Explicit \u201ctax included\u201d + numeric amount (highest priority)\n\nIf you find text that:\n- states GST/tax is **included**, **and**\n- gives a **specific numeric tax amount** near that statement,\n\nthen:\n\n- `Tax = \"<that numeric amount>\"` (no currency symbol)\n\nExamples:\n- `10% GST tax included, $131` \u2192 `\"131\"`\n- `9% Tax Included, $3.61` \u2192 `\"3.61\"`\n- `Tax Included, $3.61` \u2192 `\"3.61\"`\n\n### 2. Included in total, no numeric amount\n\nIf **any** text says that tax/GST is **included in the total** (e.g. `Gst Included In Total`, `prices include GST`),\nand **no specific tax amount appears anywhere**, then:\n\n- `Tax = \"Included in total cost\"`\n\nDo **not** treat ABN/ADN/company numbers as tax.\n\n### 3. Separate total GST/tax amount (not per item)\n\nOtherwise, search for a **single total GST/tax amount** for the whole receipt:\n\n- Appears near `GST`, `TAX`, `VAT`, `TOTAL GST`, etc.\n- Usually has 2 decimal places.\n- Typically much smaller than the total/subtotal (e.g. ~10%).\n\n**OCR sanity rule:**\n- If a large amount appears next to `GST` and a smaller, plausible tax amount is on a nearby line, prefer the **smaller nearby amount**.\n\nIf a clear total tax amount is found:\n\n- `Tax = \"<that numeric amount>\"` (string, no currency symbol)\n\n### 4. Only per-item GST \u2192 `\"Unidentified\"`\n\nSet `Tax = \"Unidentified\"` when **all** of the following are true:\n\n1. GST is indicated **only at item level**, not as a single total line.  \n   - For example: items with markers such as `T`, `T1`, `G`, `GST`, or similar, where some items have the marker and some do not.\n2. There is **no separate total GST/tax amount** shown as a standalone numeric value (e.g. no `GST 1.75`, `TOTAL GST 2.50`, `TAX 0.95` line).\n3. There is **no statement** that GST/tax is included in the total.\n\nIn this case, **do not** guess or calculate total GST from item-level data.\n\n### 5. No reliable tax info \u2192 `\"Not found\"`\n\nSet `Tax = \"Not found\"` if:\n\n- No clear total GST/tax numeric amount is present, **and**\n- No statement indicates tax is included in the total, **and**\n- There are **no clear per-item GST markers** that make it obvious GST is applied only on some items.\n\nUse `\"Not found\"` when tax info is missing or too unclear, not when per-item GST is visible (that is `\"Unidentified\"`).\n\n### 6. What is NOT tax\n\nNever treat the following as tax:\n\n- Service charges or service fees\n- Product prices\n- ABN / ADN or any business/company ID\n- Any other registration or reference number\n\n---\n\n## Vendor field\n\n`Vendor` = merchant/store providing the goods or services.\n\nRules:\n\n- Prefer the merchant name from the receipt header or footer.\n- Do **not** set `Vendor` to a bank or card issuer that appears only in payment details, logos, or \u201cprocessed by\u201d text.\n- If both a merchant and a bank are present, always choose the merchant.\n- Only use a bank name as `Vendor` if it is clearly a bank-service document (e.g. bank fees, loan interest, account statement/invoice).\n- If you cannot confidently identify a non-bank merchant and the document does not clearly relate to banking services, set:\n  - `Vendor = \"\"`\n\n### Vendor normalisation and spelling correction\n\n- If OCR slightly misspells a known brand (from the lists below), correct it and output the **canonical brand name**.\n  - Example: `Woolverths Online`, `Woolwoths Online` \u2192 `Vendor = \"Woolworths Online\"`.\n- If the same merchant appears multiple times with different spellings, choose the most complete and best-spelled version, correcting obvious OCR errors.\n- If a merchant name is not in the lists but clearly represents a store/merchant, use that name as `Vendor` in its clearest form (with obvious corrections), not a bank name.\n\nTreat the following (and clear abbreviations/variants) as **banks**, not merchants, unless clearly issuing the invoice for banking services:\n\nCommonwealth Bank of Australia (CommBank), Westpac, National Australia Bank (NAB), ANZ, Macquarie Bank, ING, HSBC, Citibank/Citi, Bendigo Bank, Suncorp, Bank of Queensland (BOQ), Bankwest, St.George, BankSA, Bank of Melbourne, UBank, ME Bank, AMP Bank, Rabobank, Great Southern Bank, Heritage Bank, Newcastle Permanent, IMB Bank, Judo Bank, Virgin Money (Australia), RACQ Bank, Teachers Mutual Bank, Bank Australia, MyState Bank, Bank of Sydney.\n\n### Known Australian Retail Vendors (canonical forms)\n\nUse these to help identify and normalise `Vendor`:\n\n**Supermarkets & Grocery**\n- Woolworths  \n- White Lotus  \n- Coles  \n- ALDI  \n- IGA (Metcash)  \n- FoodWorks  \n- Costco  \n- Harris Farm Markets  \n- Drakes Supermarkets  \n- Foodland  \n- Spudshed  \n\n**Discount / Variety & Department Stores**\n- Kmart  \n- Spocket  \n- Big W  \n- apexcool.com  \n- Target  \n- Myer  \n- David Jones  \n- The Reject Shop  \n- Best & Less  \n- Daiso  \n- TK Maxx  \n\n**Electronics & Appliances**\n- JB Hi-Fi  \n- apexcool.com  \n- The Good Guys  \n- apexcool.com  \n- Harvey Norman  \n- Officeworks  \n- Bing Lee  \n- Retravision  \n- Betta Home Living  \n\n**Hardware, Auto & Outdoor**\n- Bunnings Warehouse  \n- roymorgan.com  \n- Mitre 10  \n- Home Hardware  \n- Total Tools  \n- Supercheap Auto  \n- Repco  \n- Autobarn  \n- Anaconda  \n- Kathmandu  \n\n**Pharmacy & Health / Beauty**\n- Chemist Warehouse  \n- apexcool.com  \n- Priceline Pharmacy  \n- TerryWhite Chemmart  \n- Amcal  \n- Guardian Pharmacy  \n- My Chemist  \n- Blooms The Chemist  \n\n**Fashion, Footwear & Accessories**\n- Cotton On  \n- Country Road  \n- Witchery  \n- Just Jeans  \n- Peter Alexander  \n- Sportsgirl  \n- Jay Jays  \n- H&M  \n- Zara  \n- Uniqlo  \n- City Beach  \n- Kathmandu  \n- Platypus Shoes  \n- Foot Locker  \n- Williams Shoes  \n- Pandora  \n- Michael Hill  \n\n**Homewares, Furniture & Misc**\n- IKEA  \n- Freedom  \n- Fantastic Furniture  \n- Temple & Webster  \n- Adairs  \n- Bed Bath N\u2019 Table  \n- Pillow Talk  \n- Spotlight  \n- Lincraft  \n- Baby Bunting  \n- Petbarn  \n- Petstock  \n\n**Fuel & Service Stations**\n- BP  \n- Shell  \n- Ampol  \n- Caltex  \n- 7-Eleven  \n- United Petroleum  \n- Puma Energy  \n- EG (including EG Ampol / former Woolworths Petrol)  \n- Coles Express  \n- Costco Fuel  \n- Metro Petroleum  \n\nWhen OCR text is close to one of these names, output the canonical form exactly.\n\n---\n\n## ABN field\n\n`ABN` = Australian Business Number of the **vendor**.\n\n### How to extract ABN (very important \u2013 follow in this order):\n\n1. **Look for an explicit ABN label**\n   - Search the entire text (including inside HTML tables) for:\n     - `ABN`, `A.B.N.`, `ABN:`, `A.B.N:`, or obvious OCR variants like `ADN`, `A.D.N.`\n   - If you find a row, line, or table cell where a **header/label** is `ABN` and the **value** on the same line/row is a number, then:\n     - That number **is the ABN**, even if other numeric IDs (PAYID, phone, etc.) also appear elsewhere.\n\n   Examples:\n   - In an HTML table like:\n     <table>\n       <thead><tr><th>Field</th><th>Value</th></tr></thead>\n       <tbody>\n         <tr><td>ABN</td><td>608 044 257</td></tr>\n       </tbody>\n     </table>\n\n\n     You MUST output:\n     \"ABN\": \"608044257\"\n\n   - If there is both `ABN 608 044 257` and a `PAYID : 603 044 257`, you still choose the number on the **ABN** line.\n\n2. **Normalise the digits**\n   - ABNs have **11 digits**.\n   - They may include spaces, dashes or dots:\n     - `608 044 257` \u2192 `608044257`\n     - `60-804-4257` \u2192 `608044257` (if OCR spacing is off but it is clearly the ABN line).\n   - Remove ALL spaces and punctuation and return **exactly 11 digits** as a string.\n\n3. **Only use \"Not found\" when there is no ABN label**\n   - `\"ABN\": \"Not found\"` is allowed **only if**:\n     - There is **no** `ABN`/`A.B.N.`/`ADN` label anywhere, and\n     - There is no obvious ABN-like number near the company header/footer.\n   - The existence of other numbers (PAYID, phone, account, etc.) does **not** justify `\"Not found\"` if there is a clear ABN label.\n\n4. **What is NOT ABN**\n   - Do **not** treat as ABN:\n     - `PAYID`, `BSB`, `Account`, `Invoice No`, `Transaction No`, `Phone`, `Customer ID`, etc.\n   - If a number appears near these labels and not near `ABN`, ignore it for the ABN field.\n\n**Summary:**  \nIf a line, cell, or row explicitly says `ABN` and contains an 11-digit number (with or without spaces), you MUST output that number (normalised to digits only). Do **not** return `\"Not found\"` in that case.\n\n\n---\nDo not output this tag: ```json\n\n",
        "batching": {},
        "promptType": "define",
        "needsFallback": true,
        "hasOutputParser": true
      },
      "retryOnFail": false,
      "typeVersion": 1.7,
      "waitBetweenTries": 2000
    },
    {
      "id": "a4292084-421c-480b-bec0-9d040d7961d7",
      "name": "Structured Output Parser3",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -128,
        432
      ],
      "parameters": {
        "autoFix": true,
        "jsonSchemaExample": "{\n  \"vendor\": \"Vendor / merchant name (not the bank). Correct obvious OCR misspellings. Use \\\"Not found\\\" if you can't confidently identify it.\",\n  \"cost\": \"Total amount paid including GST/tax. Numeric string with no currency symbol, e.g. \\\"20.50\\\". Use \\\"0\\\" if unknown.\",\n  \"Tax\": \"GST/tax amount. Either a numeric string (e.g. \\\"3.61\\\") or exactly one of: \\\"Included in total cost\\\", \\\"Unidentified\\\", \\\"Not found\\\".\",\n  \"date\": \"Transaction date as DD/MM/YYYY (with leading zeros). Use \\\"Not found\\\" if missing or unclear.\",\n  \"currency\": \"Currency on the receipt, e.g. \\\"AUD\\\", \\\"USD\\\", or \\\"$\\\". Prefer the 3-letter code when available.\",\n  \"ABN\": \"11-digit Australian Business Number with no spaces or punctuation, or \\\"Not found\\\" if you can't confidently find one.\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "057914d2-ad00-4edd-a192-7d5083e67ec3",
      "name": "Code4",
      "type": "n8n-nodes-base.code",
      "position": [
        272,
        144
      ],
      "parameters": {
        "jsCode": "// n8n Code node\n\nfunction expandYear(year) {\n  if (isNaN(year)) return NaN;\n  if (year < 100) {\n    // Pivot rule:\n    // 00\u201349 => 2000\u20132049\n    // 50\u201399 => 1950\u20131999\n    return year >= 50 ? 1900 + year : 2000 + year;\n  }\n  return year;\n}\n\nfunction isValidDate(y, m, d) {\n  if (!y || !m || !d) return false;\n  const date = new Date(y, m - 1, d);\n  return (\n    date.getFullYear() === y &&\n    date.getMonth() === m - 1 &&\n    date.getDate() === d\n  );\n}\n\nfunction normalizeDate(dateStr) {\n  if (!dateStr) return '';\n\n  let cleaned = String(dateStr).trim();\n  if (!cleaned) return '';\n\n  // 1) Remove ISO-style time: 2023-02-28T10:30:00Z -> 2023-02-28\n  cleaned = cleaned.replace(/T.*$/, '');\n\n  // 2) Remove trailing time part if present\n  cleaned = cleaned.replace(/\\s+\\d{1,2}:\\d{2}(:\\d{2})?\\s*(AM|PM|am|pm)?$/, '');\n\n  cleaned = cleaned.trim();\n  if (!cleaned) return '';\n\n  // Month names \u2192 let JS parse (e.g. \"21 MAR 2023\")\n  if (/[a-zA-Z]/.test(cleaned)) {\n    const d = new Date(cleaned);\n    if (!isNaN(d.getTime())) {\n      const dd = String(d.getDate()).padStart(2, '0');\n      const mm = String(d.getMonth() + 1).padStart(2, '0');\n      const yyyy = String(d.getFullYear());\n      return `${dd}/${mm}/${yyyy}`;\n    }\n    return cleaned;\n  }\n\n  // Normal numeric separators: / - .\n  const parts = cleaned.split(/[\\/\\-\\.]/).map(p => p.trim());\n  if (parts.length !== 3) {\n    const d = new Date(cleaned);\n    if (!isNaN(d.getTime())) {\n      const dd = String(d.getDate()).padStart(2, '0');\n      const mm = String(d.getMonth() + 1).padStart(2, '0');\n      const yyyy = String(d.getFullYear());\n      return `${dd}/${mm}/${yyyy}`;\n    }\n    return cleaned;\n  }\n\n  let [p1, p2, p3] = parts.map(p => parseInt(p, 10));\n\n  // Case 1: YYYY-MM-DD\n  if (parts[0].length === 4 && !isNaN(p1) && !isNaN(p2) && !isNaN(p3)) {\n    const y = p1;\n    const m = p2;\n    const d = p3;\n    if (isValidDate(y, m, d)) {\n      const dd = String(d).padStart(2, '0');\n      const mm = String(m).padStart(2, '0');\n      const yyyy = String(y);\n      return `${dd}/${mm}/${yyyy}`;\n    }\n  }\n\n  // Case 2: DD/MM/YYYY or MM/DD/YYYY (last part is year)\n  if (!isNaN(p1) && !isNaN(p2) && !isNaN(p3)) {\n    let year = expandYear(p3);\n\n    // Prefer DD/MM for ambiguity\n    let y = year;\n    let m = p2;\n    let d = p1;\n    if (isValidDate(y, m, d)) {\n      const dd = String(d).padStart(2, '0');\n      const mm = String(m).padStart(2, '0');\n      const yyyy = String(y);\n      return `${dd}/${mm}/${yyyy}`;\n    }\n\n    // Fallback: MM/DD\n    m = p1;\n    d = p2;\n    if (isValidDate(y, m, d)) {\n      const dd = String(d).padStart(2, '0');\n      const mm = String(m).padStart(2, '0');\n      const yyyy = String(y);\n      return `${dd}/${mm}/${yyyy}`;\n    }\n  }\n\n  const d = new Date(dateStr);\n  if (!isNaN(d.getTime())) {\n    const dd = String(d.getDate()).padStart(2, '0');\n    const mm = String(d.getMonth() + 1).padStart(2, '0');\n    const yyyy = String(d.getFullYear());\n    return `${dd}/${mm}/${yyyy}`;\n  }\n\n  return cleaned;\n}\n\n// Helper to support both old & new shapes:\n// - \"White Lotus\"\n// - { description: \"White Lotus\" }\n// - { value: \"White Lotus\" }\nfunction extractField(field) {\n  if (field == null) return '';\n  if (typeof field === 'string') return field;\n  if (typeof field === 'object') {\n    if (typeof field.description === 'string') return field.description;\n    if (typeof field.value === 'string') return field.value;\n  }\n  return String(field);\n}\n\nreturn items.map(item => {\n  const out = item.json.output || item.json;\n\n  const vendor   = extractField(out.vendor);\n  const cost     = extractField(out.cost);\n  const tax      = extractField(out.Tax);\n  const dateRaw  = extractField(out.date);\n  const currency = extractField(out.currency);\n  const abn      = extractField(out.ABN);\n\n  const normalizedDate = normalizeDate(dateRaw);\n\n  return {\n    json: {\n      vendor,\n      cost,\n      Tax: tax,\n      date: normalizedDate,\n      currency,\n      ABN: abn,\n    },\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "3b0550c1-4a1e-4faa-ad60-1d9ec442e1a5",
      "name": "HTTP Request7",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2656,
        1216
      ],
      "parameters": {
        "url": "https://messaging.twilio.com/v2/Indicators/Typing.json",
        "method": "POST",
        "options": {
          "timeout": 180000
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "messageId",
              "value": "={{ $json.body.MessageSid }}"
            },
            {
              "name": "channel",
              "value": "whatsapp"
            }
          ]
        },
        "nodeCredentialType": "twilioApi"
      },
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 1500
    },
    {
      "id": "ada46948-8237-4c9d-b3a8-c49527eb3bd9",
      "name": "Code5",
      "type": "n8n-nodes-base.code",
      "position": [
        1072,
        96
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  const cost = parseFloat(item.json.cost);\n\n  if (!isNaN(cost)) {\n    // Calculate tax as cost / 11\n    item.json.Tax = (cost / 11).toFixed(2);\n  }\n\n  // vendor, cost, date, currency stay exactly the same\n  return item;\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "7dafcd20-9587-4155-bd7b-e350974aa75e",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        848,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "6a90a778-0adc-4148-b62f-7b8ff79623bd",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.Tax }}",
              "rightValue": "cost"
            },
            {
              "id": "1c13573b-87d2-4f1f-9c3f-d1a343b70baf",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.Tax }}",
              "rightValue": "found"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4230f3ac-57a9-4803-b304-c9c89d8c3fa5",
      "name": "Merge2",
      "type": "n8n-nodes-base.merge",
      "position": [
        1296,
        160
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "5efbcb46-320d-4b4e-b381-ebad2c70b760",
      "name": "Merge3",
      "type": "n8n-nodes-base.merge",
      "position": [
        2512,
        736
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "3d82e7e7-4c4c-45e7-b114-1e93561fdd36",
      "name": "Share file1",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        2000,
        1264
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "share",
        "permissionsUi": {
          "permissionsValues": {
            "role": "reader",
            "type": "anyone"
          }
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "44718e64-3da1-4ef6-b1bb-c106928e1ef5",
      "name": "HTTP Request19",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1968,
        160
      ],
      "parameters": {
        "url": "https://api.twilio.com/2010-04-01/Accounts/ACYOUR_TWILIO_ACCOUNT_SID/Messages.json",
        "method": "POST",
        "options": {
          "timeout": 180000
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "ContentSid",
              "value": "HX94b61b9296c53e6067dc659bd25f40ae"
            },
            {
              "name": "From",
              "value": "MG5bb9305483a311ba7e698fc25714f90c"
            },
            {
              "name": "To",
              "value": "={{ $('Webhook3').item.json.body.From }}"
            }
          ]
        },
        "nodeCredentialType": "twilioApi"
      },
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "52bc56ad-05e0-4f96-8835-ea91d828a9a5",
      "name": "Switch1",
      "type": "n8n-nodes-base.switch",
      "position": [
        -2880,
        1008
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "d91d24d7-a887-4b5f-83e5-4ebeb06a2406",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.body.ButtonPayload || 'none' }}",
                    "rightValue": "1"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "2",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "d0629fc3-cce8-4d57-b536-dc6ff66f4f09",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.body.ButtonPayload || 'none' }}",
                    "rightValue": "2"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "68fc79d7-aeac-4dbe-80c3-eff2a9f87f54",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.body.ButtonPayload || 'none' }}",
                    "rightValue": "none"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.3
    },
    {
      "id": "ceae7c32-f29e-4eea-b9b0-be58615eaa71",
      "name": "HTTP Request20",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2672,
        208
      ],
      "parameters": {
        "url": "https://api.twilio.com/2010-04-01/Accounts/ACYOUR_TWILIO_ACCOUNT_SID/Messages.json",
        "method": "POST",
        "options": {
          "timeout": 180000
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "From",
              "value": "whatsapp:+1234567890"
            },
            {
              "name": "To",
              "value": "={{ $('Webhook3').item.json.body.From }}"
            },
            {
              "name": "Body",
              "value": "=Thank you for confirming!"
            }
          ]
        },
        "nodeCredentialType": "twilioApi"
      },
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 1500
    },
    {
      "id": "c3d5c9f6-725f-46d1-89f4-11269309d6a2",
      "name": "HTTP Request21",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2656,
        464
      ],
      "parameters": {
        "url": "https://api.twilio.com/2010-04-01/Accounts/ACYOUR_TWILIO_ACCOUNT_SID/Messages.json",
        "method": "POST",
        "options": {
          "timeout": 180000
        },
        "sendBody": true,
        "contentType": "form-urlencoded",
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "From",
              "value": "whatsapp:+1234567890"
            },
            {
              "name": "To",
              "value": "={{ $('Webhook3').item.json.body.From }}"
            },
            {
              "name": "Body",
              "value": "=Please re-upload the receipt file."
            }
          ]
        },
        "nodeCredentialType": "twilioApi"
      },
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 1500
    },
    {
      "id": "083d882a-b5df-4523-bc8f-52cb9b9ba65c",
      "name": "Update row in sheet9",
      "type": "n8n-nodes-base.googleSheets",
      "disabled": true,
      "maxTries": 5,
      "position": [
        -2352,
        208
      ],
      "parameters": {
        "columns": {
          "value": {
            "ID quick reply": "={{ $('Webhook3').item.json.body.OriginalRepliedMessageSid }}",
            "Status Data accuracy ? Yes / No / Not confirmet yet": "YES"
          },
          "schema": [
            {
              "id": "Phone number",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "MessageSid",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "MessageSid",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Vendor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Cost",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Cost",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tax",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Tax",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Currency",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Link to Picture (Google Drive)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Link to Picture (Google Drive)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ABN",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ABN",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status Data accuracy ? Yes / No / Not confirmet yet",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Status Data accuracy ? Yes / No / Not confirmet yet",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ID quick reply",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "ID quick reply",
              "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": [
            "ID quick reply"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 573969032,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY/edit#gid=573969032",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/10qYwN3SJ5kNS64BneV8k7BubXzDfuULc5G0_aMarGlY/edit?usp=drivesdk",
          "cachedResultName": "OCR created from n8n"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "alwaysOutputData": true,
      "waitBetweenTries": 4000
    },
    {
      "id": "1048ad77-4811-402e-884e-05deabefd1e0",
      "name": "Update row in sheet10",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 5,
      "position": [
        -2352,
        464
      ],
      "parameters": {
        "columns": {
          "value": {
            "ID quick reply": "={{ $('Webhook3').item.json.body.OriginalRepliedMessageSid }}",
            "Status Data accuracy ? Yes / No / Not confirmet yet": "NO"
          },
          "schema": [
            {
              "id": "MessageSid",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "MessageSid",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Vendor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Cost",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Cost",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tax",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Tax",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Currency",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Link to Picture (Google Drive)",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Link to Picture (Google Drive)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "ABN",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "ABN",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status Data accuracy ? Yes / No / Not confirm

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Categories: Accounting Automation • OCR Processing • AI Data Extraction • Business Tools

Source: https://n8n.io/workflows/11332/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Resume Screening & Behavioral Interviews with Gemini, Elevenlabs, & Notion ATS copy. Uses outputParserStructured, chainLlm, googleDrive, stickyNote. Webhook trigger; 67 nodes.

Output Parser Structured, Chain Llm, Google Drive +9
AI & RAG

Candidate Engagement | Resume Screening | AI Voice Interviews | Applicant Insights

Output Parser Structured, Chain Llm, Google Drive +9
AI & RAG

ANIS_HUB 1. Uses gmail, googleDrive, googleSheets, httpRequest. Webhook trigger; 89 nodes.

Gmail, Google Drive, Google Sheets +3
AI & RAG

This comprehensive workflow automates the complete financial document processing pipeline using AI. Upload invoices via chat, drop expense receipts into a folder, or add bank statements - the system a

Chat Trigger, HTTP Request, Google Sheets +8
AI & RAG

Tired of grinding out YouTube content? This n8n workflow turns AI into your personal video factory—creating engaging, faceless shorts on autopilot. Perfect for creators, marketers, or side-hustlers lo

HTTP Request, Google Drive, Google Sheets +6