{
  "name": "Invoice Automation - Cookie Based + Gemini Extraction",
  "nodes": [
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "83a8af90-25d4-4632-9eb0-f6cf15ec8ec2",
              "name": "Time",
              "value": "={{ $now }}",
              "type": "string"
            },
            {
              "id": "237db538-3cc6-454a-aa67-39e27eadc264",
              "name": "UserEmail",
              "value": "={{ $json.From }}",
              "type": "string"
            },
            {
              "id": "b461c65d-d2ab-45bf-b765-db25db86640d",
              "name": "EmailBody",
              "value": "={{ $json.snippet }}",
              "type": "string"
            },
            {
              "id": "c8cf08a7-04a8-4bc4-908e-3cae9275bd3a",
              "name": "ThreadID",
              "value": "={{ $json.threadId }}",
              "type": "string"
            },
            {
              "id": "55c3add7-1a57-47e3-a247-c60a37e41ddd",
              "name": "InvoiceURL",
              "value": "={{ $json.invoiceurl }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "c4cb7ce6-416a-43c2-851a-743e279f2724",
      "name": "Set Config",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -1760,
        80
      ]
    },
    {
      "parameters": {
        "url": "={{ $json.InvoiceURL }}/api/invoices/pending",
        "options": {}
      },
      "id": "0cc0ae15-3865-4f23-bbf0-aac48690d709",
      "name": "Get Pending Invoices List",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -1536,
        80
      ]
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "e50a6f0b-9f41-4d57-acfd-86e1fff6d8c8",
      "name": "Loop Over Invoices",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        -1312,
        80
      ]
    },
    {
      "parameters": {
        "url": "={{ $json.invoiceUrl }}",
        "options": {}
      },
      "id": "5e1fbcc3-89af-43fd-8150-c3b09b7062e2",
      "name": "Download Invoice (Authenticated)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -1088,
        0
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "1JOSSyVd_o3Pus3t_E6npbvKRatCbFN1lNDB2zm4Tqy0",
          "mode": "list",
          "cachedResultName": "Applicaiton",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JOSSyVd_o3Pus3t_E6npbvKRatCbFN1lNDB2zm4Tqy0/edit?usp=drivesdk"
        },
        "sheetName": {
          "__rl": true,
          "value": "gid=0",
          "mode": "list",
          "cachedResultName": "Sheet1",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1JOSSyVd_o3Pus3t_E6npbvKRatCbFN1lNDB2zm4Tqy0/edit#gid=0"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {},
          "matchingColumns": [],
          "schema": [
            {
              "id": "Email",
              "displayName": "Email",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Company Name",
              "displayName": "Company Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "HR Name",
              "displayName": "HR Name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Industry",
              "displayName": "Industry",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Location",
              "displayName": "Location",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Contact Number",
              "displayName": "Contact Number",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "displayName": "Status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "id": "16d060b2-1442-40ef-872f-b79eb5fd48a4",
      "name": "Append to Master Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        -416,
        0
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "QDrPKGFrmtgC4hP2",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "5aa0058b-fd63-4628-b1df-3a32cb079e12",
              "leftValue": false,
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "d8428321-df69-4db8-96fd-d2658b1f7148",
      "name": "Check if Duplicate/Fake",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -192,
        80
      ]
    },
    {
      "parameters": {
        "sendTo": "useremail@gmail.com",
        "subject": "⚠️ Duplicate/Fake Invoice Detected",
        "message": "={{ $json.duplicate }}",
        "options": {}
      },
      "id": "b8348ae4-2b55-4f6d-8ba7-2ae3275c9bf6",
      "name": "Send Alert Email",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        32,
        80
      ],
      "webhookId": "18f09f4f-0c61-4a7c-8e01-8c7c0ac67e14",
      "credentials": {
        "gmailOAuth2": {
          "id": "r0vKGU4IGeUiOAWh",
          "name": "Gmail account"
        }
      }
    },
    {
      "parameters": {
        "resource": "image",
        "operation": "analyze",
        "modelId": {
          "__rl": true,
          "value": "models/gemini-3.5-flash",
          "mode": "list",
          "cachedResultName": "models/gemini-3.5-flash"
        },
        "text": "=system_prompt: |\n  You are an expert invoice data extraction AI specialized in analyzing Indian business invoices (tax invoices, GST invoices, commercial invoices).\n\n  Your task is to thoroughly analyze the provided invoice image or PDF and extract every possible piece of information with high accuracy.\n\n  Follow these strict rules:\n\n  1. Read the entire document carefully, including headers, footers, tables, small text, and any stamps or signatures.\n  2. Extract information exactly as it appears. Do not make up or assume any values.\n  3. If a field is not present or cannot be clearly read, return null for that field.\n  4. For monetary values, extract only the number (no currency symbols or commas). Keep the currency separately.\n  5. For dates, always convert to YYYY-MM-DD format. If only month/year is available, use the first day of the month.\n  6. For line items, extract every single item mentioned in the invoice.\n  7. Be extremely careful with tax calculations (CGST, SGST, IGST, Cess). Extract both rate and amount.\n  8. Return the output ONLY in clean, valid JSON format. Do not add any explanation, markdown, or extra text outside the JSON.\n\n  Extract the following fields with maximum detail:\n\n  ### Invoice Header Information\n  - invoiceNumber: Invoice number / Bill number\n  - invoiceDate: Date of invoice (YYYY-MM-DD)\n  - dueDate: Due date, if mentioned\n  - invoiceType: Type of invoice (Tax Invoice, Commercial Invoice, etc.)\n\n  ### Seller / Vendor Details\n  - sellerName: Full name of the seller/supplier\n  - sellerAddress: Complete address\n  - sellerGSTIN: GST Identification Number\n  - sellerPAN: PAN number, if available\n  - sellerState: State name and code\n  - sellerContact: Phone, email, or mobile number\n\n  ### Buyer / Bill To Details\n  - buyerName: Full name of the buyer\n  - buyerAddress: Complete address\n  - buyerGSTIN: GST Identification Number of buyer\n  - buyerState: State name and code\n\n  ### Line Items (Array)\n  For each line item, extract:\n  - itemDescription: Full description of the item/service\n  - hsnSacCode: HSN or SAC code\n  - quantity: Quantity\n  - unit: Unit of measurement (Nos, Kg, etc.)\n  - rate: Rate per unit\n  - taxableAmount: Taxable value before tax\n  - cgstRate: CGST rate (in %)\n  - cgstAmount: CGST amount\n  - sgstRate: SGST rate (in %)\n  - sgstAmount: SGST amount\n  - igstRate: IGST rate (in %)\n  - igstAmount: IGST amount\n  - cessRate: Cess rate (if any)\n  - cessAmount: Cess amount\n  - totalAmount: Total amount for that line item\n\n  ### Tax Summary\n  - totalTaxableValue: Total taxable value of all items\n  - totalCGST: Total CGST amount\n  - totalSGST: Total SGST amount\n  - totalIGST: Total IGST amount\n  - totalCess: Total Cess amount\n  - totalTaxAmount: Grand total of all taxes\n  - grandTotal: Final grand total amount (including all taxes)\n  - amountInWords: Amount in words as written on invoice\n\n  ### Payment & Bank Details\n  - bankName: Bank name\n  - accountNumber: Bank account number\n  - ifscCode: IFSC code\n  - paymentTerms: Payment terms mentioned\n\n  ### Other Important Fields\n  - poNumber: Purchase Order number / Reference number\n  - poDate: Purchase Order date\n  - ewayBillNumber: E-way bill number, if present\n  - reverseCharge: Is Reverse Charge applicable? (Yes/No)\n  - placeOfSupply: Place of Supply\n  - termsAndConditions: Any terms and conditions mentioned\n  - authorizedSignatory: Name of the person who signed\n  - digitalSignature: Whether digital signature is present (Yes/No)\n  - notes: Any additional notes or remarks on the invoice\n\n  ### Quality & Verification\n  - extractionConfidence: Your confidence level in extraction (High / Medium / Low)\n  - issuesFound: List any issues you noticed (blurry text, missing fields, calculation mismatch, etc.)\n\n  Output Format:\n  Return ONLY a valid JSON object following the structure above. Do not wrap it in markdown code blocks. Do not add any text before or after the JSON.\n",
        "inputType": "binary",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "typeVersion": 1.2,
      "position": [
        -864,
        0
      ],
      "id": "6e4799a6-d56a-42ee-b0ae-69eb35ffc010",
      "name": "Analyze an image",
      "credentials": {
        "googlePalmApi": {
          "id": "WBXnwvDXaFeNpY1j",
          "name": "Ra1mu"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// =============================================\n// n8n Code Node: Process Gemini Invoice Output\n// =============================================\n// This node cleans and structures the output from Gemini\n// so it can be cleanly written to Google Sheets or database.\n\nconst geminiOutput = items[0].json;\n\n// Step 1: Clean Gemini output (sometimes it returns markdown or extra text)\nlet rawText = '';\n\nif (typeof geminiOutput === 'string') {\n  rawText = geminiOutput;\n} else if (geminiOutput.text) {\n  rawText = geminiOutput.text;\n} else if (geminiOutput.content) {\n  rawText = geminiOutput.content;\n} else {\n  rawText = JSON.stringify(geminiOutput);\n}\n\n// Remove markdown code blocks if present\nrawText = rawText.replace(/```json/g, '').replace(/```/g, '').trim();\n\n// Step 2: Try to parse JSON\nlet invoiceData;\ntry {\n  invoiceData = JSON.parse(rawText);\n} catch (error) {\n  // If parsing fails, return error object\n  return [{\n    json: {\n      error: true,\n      message: \"Failed to parse Gemini output as JSON\",\n      rawOutput: rawText,\n      processedAt: new Date().toISOString()\n    }\n  }];\n}\n\n// Step 3: Create clean structured object for Google Sheets\nconst cleanInvoice = {\n  // Invoice Header\n  invoiceNumber: invoiceData.invoiceNumber || null,\n  invoiceDate: invoiceData.invoiceDate || null,\n  dueDate: invoiceData.dueDate || null,\n  invoiceType: invoiceData.invoiceType || null,\n\n  // Seller Details\n  sellerName: invoiceData.sellerName || null,\n  sellerGSTIN: invoiceData.sellerGSTIN || null,\n  sellerPAN: invoiceData.sellerPAN || null,\n  sellerState: invoiceData.sellerState || null,\n\n  // Buyer Details\n  buyerName: invoiceData.buyerName || null,\n  buyerGSTIN: invoiceData.buyerGSTIN || null,\n  buyerState: invoiceData.buyerState || null,\n\n  // Financial Summary\n  totalTaxableValue: invoiceData.totalTaxableValue || null,\n  totalCGST: invoiceData.totalCGST || null,\n  totalSGST: invoiceData.totalSGST || null,\n  totalIGST: invoiceData.totalIGST || null,\n  totalCess: invoiceData.totalCess || null,\n  totalTaxAmount: invoiceData.totalTaxAmount || null,\n  grandTotal: invoiceData.grandTotal || null,\n  amountInWords: invoiceData.amountInWords || null,\n\n  // Other Important Fields\n  poNumber: invoiceData.poNumber || null,\n  ewayBillNumber: invoiceData.ewayBillNumber || null,\n  reverseCharge: invoiceData.reverseCharge || null,\n  placeOfSupply: invoiceData.placeOfSupply || null,\n\n  // Line Items (store as JSON string - best for Google Sheets)\n  lineItemsCount: invoiceData.lineItems ? invoiceData.lineItems.length : 0,\n  lineItemsJSON: invoiceData.lineItems ? JSON.stringify(invoiceData.lineItems) : null,\n\n  // Quality & Metadata\n  extractionConfidence: invoiceData.extractionConfidence || null,\n  issuesFound: invoiceData.issuesFound ? JSON.stringify(invoiceData.issuesFound) : null,\n\n  // Processing Metadata\n  processedAt: new Date().toISOString(),\n  source: \"n8n + Gemini 1.5 Flash\",\n  status: \"Pending Review\"\n};\n\n// Return clean object\nreturn [{\n  json: cleanInvoice\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -640,
        0
      ],
      "id": "86af267e-4e2d-46a0-8d18-84f3871b7d36",
      "name": "Code in JavaScript"
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "filters": {}
      },
      "type": "n8n-nodes-base.gmailTrigger",
      "typeVersion": 1.4,
      "position": [
        -1984,
        80
      ],
      "id": "dc0089f9-3654-4311-8253-9a4f0a02d2e6",
      "name": "Gmail Trigger",
      "credentials": {
        "gmailOAuth2": {
          "id": "r0vKGU4IGeUiOAWh",
          "name": "Gmail account"
        }
      }
    }
  ],
  "pinData": {},
  "connections": {
    "Set Config": {
      "main": [
        [
          {
            "node": "Get Pending Invoices List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Pending Invoices List": {
      "main": [
        [
          {
            "node": "Loop Over Invoices",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Invoices": {
      "main": [
        [],
        [
          {
            "node": "Download Invoice (Authenticated)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append to Master Sheet": {
      "main": [
        [
          {
            "node": "Check if Duplicate/Fake",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if Duplicate/Fake": {
      "main": [
        [
          {
            "node": "Send Alert Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Loop Over Invoices",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Invoice (Authenticated)": {
      "main": [
        [
          {
            "node": "Analyze an image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze an image": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Append to Master Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail Trigger": {
      "main": [
        [
          {
            "node": "Set Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate"
  },
  "versionId": "73f855db-6377-43af-8323-2d3a5e9a8d0f",
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "a79a30e2bf6d9bd5386655f231311e7478158b2e6a5b818dd047ab6052ecfea0"
  },
  "nodeGroups": [],
  "id": "4YyfhTlzyFk9t9KF",
  "tags": [
    {
      "name": "invoic",
      "id": "dfGIMfTptOn5nQXp",
      "updatedAt": "2026-07-11T17:40:49.184Z",
      "createdAt": "2026-07-11T17:40:49.184Z"
    },
    {
      "name": "invoice",
      "id": "bwGPTSkU5ET2V46N",
      "updatedAt": "2026-07-11T17:40:52.710Z",
      "createdAt": "2026-07-11T17:40:52.710Z"
    },
    {
      "name": "emaiautomation",
      "id": "EQ8ujcCFSCV8RGbt",
      "updatedAt": "2026-07-11T17:40:57.912Z",
      "createdAt": "2026-07-11T17:40:57.912Z"
    },
    {
      "name": "body",
      "id": "qHKLReRV63KDUTfQ",
      "updatedAt": "2026-07-11T17:41:01.032Z",
      "createdAt": "2026-07-11T17:41:01.032Z"
    }
  ]
}