{
  "name": "Extract & process invoices with Gemini AI, Google Sheets & Gmail notifications",
  "nodes": [
    {
      "id": "a6a71e48-04d8-4a73-af89-dc5ab7720788",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -256,
        672
      ]
    },
    {
      "id": "1f5025c5-043e-4934-8ba9-9964becf178c",
      "name": "Analyze image1",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        128,
        672
      ]
    },
    {
      "id": "f504934f-3551-4399-a610-f9f8ec1cd246",
      "name": "AI Agent1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        448,
        672
      ]
    },
    {
      "id": "f0999a88-8eb2-407f-8d50-6ca4118bb3df",
      "name": "Google Gemini Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        512,
        928
      ]
    },
    {
      "id": "0ee67ef8-d38c-4a78-9267-5e482ef7b7fd",
      "name": "Get data",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1280,
        672
      ]
    },
    {
      "id": "6c465765-d7ca-4f09-9720-8799132ec5d0",
      "name": "Make data in json structure format",
      "type": "n8n-nodes-base.set",
      "position": [
        912,
        672
      ]
    },
    {
      "id": "c25a3bdb-deef-4d9f-a2e3-2471bc1107fa",
      "name": "check if Data exist or not in table",
      "type": "n8n-nodes-base.if",
      "position": [
        1680,
        672
      ]
    },
    {
      "id": "0997e665-a8c5-4bdb-90f5-5d5304a0f355",
      "name": "Upload invoice to drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        80,
        912
      ]
    },
    {
      "id": "65f8bf39-6813-4def-8cac-274eb5db6c9e",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        352
      ],
      "parameters": {
        "width": 368,
        "height": 496,
        "content": "## Node 1: **When chat message received**\n\nThis is a *trigger node* that starts the workflow whenever a new chat message is received in n8n.\nIt supports file uploads, meaning users can directly send i"
      }
    },
    {
      "id": "bb06ce88-cbc3-4003-a2a8-3fb9b576d371",
      "name": "no missing field - new data add using payload 2 ",
      "type": "n8n-nodes-base.code",
      "position": [
        3152,
        480
      ]
    },
    {
      "id": "070e102e-3fd3-4caf-81b6-82eae65a3b00",
      "name": "If -  check missing field",
      "type": "n8n-nodes-base.if",
      "position": [
        2768,
        496
      ]
    },
    {
      "id": "84f5c157-36a7-491c-ba9e-52e5d3b08039",
      "name": "Send missing field error on mail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3440,
        976
      ]
    },
    {
      "id": "c33ae480-922e-4596-bd5a-dcd3a6b4aa93",
      "name": "Duplicate entry send mail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2080,
        992
      ]
    },
    {
      "id": "444d68a3-9a32-4caf-a930-2b4b83cc92d9",
      "name": "New data add using payload",
      "type": "n8n-nodes-base.code",
      "position": [
        2064,
        496
      ]
    },
    {
      "id": "5f78f6aa-9b9a-46b5-8d92-5b2d8cc89be2",
      "name": "Append data to sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3568,
        480
      ]
    },
    {
      "id": "5042aa5c-5d27-4e91-bb34-48adbb466148",
      "name": "Check Mandatory fields",
      "type": "n8n-nodes-base.code",
      "position": [
        2400,
        496
      ]
    },
    {
      "id": "e9f03e55-74ba-4576-8807-0b34490a809f",
      "name": "Send successful email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3968,
        480
      ]
    },
    {
      "id": "3a1e1818-7feb-4a7a-9d9d-a98b7bbb3c77",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        352
      ],
      "parameters": {
        "width": 384,
        "height": 512,
        "content": "# Node 3: AI Agent1\n\nThis node acts as an AI processing step that takes the raw extracted invoice text and restructures it into a strict **JSON format**.\nIt applies a *system message* that defines cle"
      }
    },
    {
      "id": "016dec77-8044-4bf1-91e2-04347f01b81e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        352
      ],
      "parameters": {
        "width": 352,
        "height": 496,
        "content": "## Node 2: **Analyze image1**\n\nThis node uses *Google Gemini (PaLM API)* to analyze the uploaded invoice image.\nIt takes the binary file (`data0`) and processes it through the **Gemini Vision Model** "
      }
    },
    {
      "id": "d04bddae-b8e8-4bdb-a12b-4cad195b739f",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        880
      ],
      "parameters": {
        "width": 384,
        "height": 544,
        "content": "\n\n\n\n\n   \n\n\n\n\n\n\n\n\n\n\n\n## Node 4: Google Gemini Chat Model1\n\nThis node provides the **language model backend** for the AI Agent.\nIt connects to Google Gemini (PaLM API) and powers the reasoning, formatti"
      }
    },
    {
      "id": "7e2078a0-b8ee-48dc-9649-06695fa7b10b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        352
      ],
      "parameters": {
        "width": 368,
        "height": 512,
        "content": "## Node 6: **Get data**\n\nThis node connects to a **Google Sheet** that acts as the *invoice database*.\nIt performs a lookup using the `Entry_ID` column and compares it with the current invoice’s `invo"
      }
    },
    {
      "id": "b147bb54-67f2-41fd-9f58-e68f58e82dfc",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        768,
        352
      ],
      "parameters": {
        "width": 368,
        "height": 512,
        "content": "## Node 5: **Make data in JSON structure format**\n\nThis node is a **Set node** that organizes the AI Agent’s output into a clean JSON object.\nIt assigns the extracted invoice data to a single field ca"
      }
    },
    {
      "id": "4fe6abc8-d092-4ae5-aab9-76b31d157e65",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1936,
        160
      ],
      "parameters": {
        "width": 336,
        "height": 496,
        "content": "## Node 8: **New data add using payload**\n\nThis node is a **Code node** that ensures proper handling of the invoice data before moving forward.\nIt first checks if the Google Sheets lookup returned any"
      }
    },
    {
      "id": "65ff906c-24b0-43fb-af3a-ed8b2382057f",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2288,
        160
      ],
      "parameters": {
        "width": 336,
        "height": 496,
        "content": "## Node 9: **Check Mandatory fields**\n\nThis is a **Code node** that validates the invoice data.\nIt checks if all *mandatory fields* (`invoice_id`, `shop_name`, `date`, `Total`, and `items`) are presen"
      }
    },
    {
      "id": "257b48c4-2f8d-4ead-9d45-37b5130151a6",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2640,
        160
      ],
      "parameters": {
        "width": 352,
        "height": 496,
        "content": "## Node 10: **If – check missing field**\n\nThis is an **If node** that decides the workflow path based on the validation status.\nIt checks the `status` field returned by the *Check Mandatory fields* no"
      }
    },
    {
      "id": "d36fab00-4dc9-44e9-b071-e77500233c3c",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3008,
        160
      ],
      "parameters": {
        "width": 400,
        "height": 496,
        "content": "## Node 11: **no missing field – new data add using payload 2**\n\nThis is a **Code node** that passes forward only the valid invoice JSON when the status is `\"ok\"`.\nIt retrieves the structured payload "
      }
    },
    {
      "id": "c1e60d32-3270-4440-ab23-dd8f0a3fe778",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3424,
        160
      ],
      "parameters": {
        "width": 384,
        "height": 496,
        "content": "## Node 12: **Append data to sheet**\n\nThis node writes the validated invoice data into the **Google Sheet**.\nIt uses the *append* operation to add a new row with mapped fields such as `Entry_ID`, `Dat"
      }
    },
    {
      "id": "7641cc35-64e1-439d-84bb-4631737d7dd8",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3824,
        160
      ],
      "parameters": {
        "width": 384,
        "height": 496,
        "content": "## Node 13: **Send successful email**\n\nThis node sends a confirmation email via **Gmail** once a new invoice is successfully added to the sheet.\nThe email includes key details like *Invoice ID, Compan"
      }
    },
    {
      "id": "89bd82ca-4f6b-42eb-8899-517915dfb83e",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1536,
        352
      ],
      "parameters": {
        "width": 384,
        "height": 512,
        "content": "## Node 7: **check if Data exist or not in table**\n\nThis is an **If node** that checks whether the invoice already exists in the Google Sheet.\nIt does this by verifying if the `Get data` node returned"
      }
    },
    {
      "id": "6b96884c-eefe-4ec5-a5ce-e148e2130901",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1936,
        672
      ],
      "parameters": {
        "width": 400,
        "height": 512,
        "content": "## Node 8.1: **Duplicate entry send mail**\n\nThis node sends an **email notification via Gmail** when an invoice already exists in the sheet.\nThe email is formatted in *HTML* and includes details like "
      }
    },
    {
      "id": "9b5aeb91-0f7f-465a-b774-bb1f5fed0869",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3264,
        672
      ],
      "parameters": {
        "width": 448,
        "height": 496,
        "content": "## Node 11.1: **Send missing field error on mail**\n\nThis node sends an **error notification email via Gmail** when mandatory fields are missing from the invoice.\nThe email subject highlights the error"
      }
    },
    {
      "id": "374ea423-b33d-4e4e-9a3e-ec3adbffbbbe",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -96,
        864
      ],
      "parameters": {
        "width": 448,
        "height": 480,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Node 2.1: **Upload invoice to drive**\n\nThis node uploads the original invoice file to **Google Drive** for safe storage and backup.\nIt takes the uploaded file (`data0`) and saves it"
      }
    }
  ],
  "connections": {
    "Get data": {
      "main": [
        [
          {
            "node": "check if Data exist or not in table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent1": {
      "main": [
        [
          {
            "node": "Make data in json structure format",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze image1": {
      "main": [
        [
          {
            "node": "AI Agent1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append data to sheet": {
      "main": [
        [
          {
            "node": "Send successful email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Mandatory fields": {
      "main": [
        [
          {
            "node": "If -  check missing field",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload invoice to drive": {
      "main": [
        []
      ]
    },
    "Google Gemini Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "If -  check missing field": {
      "main": [
        [
          {
            "node": "no missing field - new data add using payload 2 ",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send missing field error on mail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "New data add using payload": {
      "main": [
        [
          {
            "node": "Check Mandatory fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "Analyze image1",
            "type": "main",
            "index": 0
          },
          {
            "node": "Upload invoice to drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Make data in json structure format": {
      "main": [
        [
          {
            "node": "Get data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "check if Data exist or not in table": {
      "main": [
        [
          {
            "node": "New data add using payload",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Duplicate entry send mail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "no missing field - new data add using payload 2 ": {
      "main": [
        [
          {
            "node": "Append data to sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}