{
  "name": "AI Auto-Save Gmail Receipts",
  "tags": [],
  "nodes": [
    {
      "id": "8fdd8f41-acfd-4430-bdfe-b9a43ea81dcc",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        0,
        -640
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "a8c74ce2-0665-4c34-8e06-1a412f249be4",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1100,
        -640
      ],
      "parameters": {
        "text": "=You are an expert assistant that extracts receipt fields for tax tracking.\n\nHere is the full receipt text:\n{{ $json.text }}\n\nExtract and return a single JSON object with the following fields:\n- \"date\": Format as YYYY-MM-DD.\n- \"merchant\": Name of business or company issuing the receipt. If a value is missing, return `null`.\n- \"category\": Infer based on context (e.g. Meals, Software, Travel, Office Supplies).\n- \"description\": A short summary of the service or item purchased (e.g. \u201cDomain name renewal for 2 years\u201d). If a value is missing, return `null`.\n- \"subtotal\": Value before GST. Extract only if clearly labeled.If a value is missing, return 0.\n- \"tax\": The Goods and Services Tax amount (labelled as GST or Tax). Return 0 if not present.If a value is missing, return 0.\n- \"total\": Final amount paid (after tax). If a value is missing, return 0.\n- \"id\": {{ $json.id }}\n- \"threadId\": {{ $json.threadId }}\n\n\n\nRespond ONLY with a JSON object, like this:\n{\n  \"date\": \"2025-03-12\",\n  \"merchant\": \"Vendor\",\n  \"category\": \"Software\",\n  \"description\": \"Subscribe for 2 years\",\n  \"subtotal\": 45.32,\n  \"tax\": 4.53,\n  \"total\": 49.85\n}\n",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "1b97d088-fcaf-45dd-9d86-acb381984cc0",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1128,
        -420
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4",
          "cachedResultName": "gpt-4"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "5084e1bc-349b-4806-8954-c97a3d26d333",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1248,
        -420
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"date\": {\n      \"type\": \"string\",\n      \"format\": \"date\"\n    },\n    \"merchant\": {\n      \"type\": \"string\"\n    },\n    \"category\": {\n      \"type\": \"string\"\n    },\n    \"description\": {\n      \"type\": \"string\"\n    },\n    \"subtotal\": {\n      \"type\": \"number\"\n    },\n    \"tax\": {\n      \"type\": \"number\"\n    },\n    \"total\": {\n      \"type\": \"number\"\n    },\n    \"id\": {\n      \"type\": \"string\"\n    }\n    ,\n    \"threadId\": {\n      \"type\": \"string\"\n    }\n  },\n  \"required\": [\"date\", \"merchant\", \"category\", \"description\", \"subtotal\", \"tax\", \"total\", \"id\", \"threadId\"]\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "174f31ac-0849-47aa-8ff1-751d74e952e1",
      "name": "Get Emails with Receipts",
      "type": "n8n-nodes-base.gmail",
      "position": [
        220,
        -640
      ],
      "parameters": {
        "simple": false,
        "filters": {
          "q": "has:attachment",
          "labelIds": [
            "Label_3361902760602362460"
          ],
          "readStatus": "unread"
        },
        "options": {},
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "8fcc7b91-267b-4572-9948-b7a4215cbf44",
      "name": "Get Required Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        660,
        -440
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d9d2348c-eca4-4255-a6a9-de29ca06f2c6",
              "name": "id",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "8685f151-93c4-4eca-8378-ea6ec7b03631",
              "name": "threadId",
              "type": "string",
              "value": "={{ $json.threadId }}"
            },
            {
              "id": "695604d2-438d-4168-9747-f46a84f289ad",
              "name": "textAsHtml",
              "type": "string",
              "value": "={{ $json.textAsHtml }}"
            },
            {
              "id": "4fe59ba7-e736-4911-8080-f0cbb94db73d",
              "name": "subject",
              "type": "string",
              "value": "={{ $json.subject }}"
            },
            {
              "id": "288351d6-9248-4e84-b96d-006f14d0f6c3",
              "name": "date",
              "type": "string",
              "value": "={{ $json.date }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "04b2b190-b370-411c-844c-2d8275aa1579",
      "name": "Download Attachment",
      "type": "n8n-nodes-base.gmail",
      "position": [
        440,
        -640
      ],
      "parameters": {
        "simple": false,
        "options": {
          "downloadAttachments": true
        },
        "messageId": "={{ $json.id }}",
        "operation": "get"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "34256129-d04a-4e01-86cc-6a5b2108b954",
      "name": "Append to Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1476,
        -740
      ],
      "parameters": {
        "columns": {
          "value": {
            "Tax": "{{ $json.output.tax}}",
            "Date": "={{ $json.output.date }}",
            "Total": "={{ $json.output.total }}",
            "Merchant": "={{ $json.output.merchant }}",
            "Subtotal": "={{ $json.output.subtotal }}",
            "Category ": "={{ $json.output.category }}",
            "Description": "={{ $json.output.description }}"
          },
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Merchant",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Merchant",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Category ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Category ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Description",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Subtotal",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Subtotal",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Total",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Tax",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Tax",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "__YOUR_SHEETNAME__",
          "cachedResultUrl": "__PLACEHOLDER__",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "__YOUR_DOCUMENTID__",
          "cachedResultUrl": "__PLACEHOLDER__",
          "cachedResultName": "Receipts"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6,
      "alwaysOutputData": true
    },
    {
      "id": "1288f2c7-732b-4e35-9d4d-4b20c5f61171",
      "name": "Merge Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        880,
        -640
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition",
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "e67ccaae-5bbc-4023-abbc-c9733d11198c",
      "name": "Upload File",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        660,
        -840
      ],
      "parameters": {
        "name": "={{ \n  (() => {\n    const date = $json.date.slice(0, 10).replace(/-/g, '');\n    const sender = ($json.from?.value?.[0]?.name || 'Unknown').trim();\n    const cleanSender = sender\n      .replace(/[^a-zA-Z0-9]/g, '_')   // replace non-alphanumeric\n      .replace(/_+/g, '_')             // collapse repeated _\n      .replace(/^_+|_+$/g, '');        // trim leading/trailing _\n    return `${date}_${cleanSender}`;\n  })()\n}}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive",
          "cachedResultUrl": "__PLACEHOLDER__",
          "cachedResultName": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "url",
          "value": "__YOUR_FOLDERID__"
        },
        "inputDataFieldName": "attachment_0"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "36288b85-6591-4f4a-8637-bf21c8aea23e",
      "name": "Extract Data from Invoice",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        660,
        -640
      ],
      "parameters": {
        "options": {},
        "operation": "pdf",
        "binaryPropertyName": "attachment_0"
      },
      "typeVersion": 1
    },
    {
      "id": "b9494f63-29ae-42fa-b4ce-6509119d234b",
      "name": "Mark Email as Read",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1476,
        -540
      ],
      "parameters": {
        "messageId": "={{ $json.output.id }}",
        "operation": "markAsRead"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "c482e032-f3f4-49d5-81b0-c2ef7f191b13",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        520,
        -1000
      ],
      "parameters": {
        "width": 380,
        "height": 320,
        "content": "### \ud83d\udce4 Upload Receipt to Google Drive\nThis node saves the PDF attachment from the email to your Google Drive.\n- Double-click to choose the destination folder\n- Make sure Google Drive credentials are set up in **Credentials > Google Drive**\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f724e9e1-0de2-4db8-b221-ed5692dc0ab4",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -120,
        -840
      ],
      "parameters": {
        "width": 320,
        "height": 400,
        "content": "### \ud83d\udd52 Entry Point \u2013 Auto-Run This Flow\nThis node controls when the flow is triggered (currently 8am daily).\n- You can change the schedule from cron to manual\n- Starts the chain of pulling emails, extracting data, and saving to Drive + Sheets\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "0ebecebd-a40a-4c41-bba3-12866c150052",
  "connections": {
    "AI Agent": {
      "main": [
        [
          {
            "node": "Append to Google Sheet",
            "type": "main",
            "index": 0
          },
          {
            "node": "Mark Email as Read",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Data": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload File": {
      "main": [
        [
          {
            "node": "Merge Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get Emails with Receipts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Download Attachment": {
      "main": [
        [
          {
            "node": "Upload File",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Required Fields",
            "type": "main",
            "index": 0
          },
          {
            "node": "Extract Data from Invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Required Fields": {
      "main": [
        [
          {
            "node": "Merge Data",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Append to Google Sheet": {
      "main": [
        []
      ]
    },
    "Get Emails with Receipts": {
      "main": [
        [
          {
            "node": "Download Attachment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Extract Data from Invoice": {
      "main": [
        [
          {
            "node": "Merge Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    }
  }
}