n8n Workflow
Expert

Export and Analyze Google Keep Notes with AI and Google Sheets

Automate the process of exporting Google Keep notes from Google Drive, using AI to extract specific data like expenses, and organizing it into a Google Sheet for easy tracking and analysis.

Overview

Automatically processes Google Keep notes exported to Google Drive, uses OpenAI to extract expense data, and logs the structured information into a Google Sheet.

🧠 Description & Use Case

This workflow provides a powerful solution for anyone looking to export, process, and analyze their Google Keep notes. It automates the entire pipeline from fetching exported note files from Google Drive to using AI for data extraction and finally logging the structured information into a Google Sheet. The primary example demonstrated is for expense tracking, but it can be adapted for any data extraction task.

🔄 How It Works:

  1. Trigger & Fetch: The workflow is initiated manually. It then connects to your Google Drive and searches a specified folder (e.g., "Keep") for your exported note files.
  2. Batch Processing & Filtering: To handle a large number of notes efficiently, the Loop every 10 items node processes files in batches. The If extension is json node ensures only the correct Google Keep export files (.json) are handled.
  3. Download & Parse: Each valid JSON file is downloaded from Google Drive, and the Extract from File node parses its content, making the note's data (text, timestamps, etc.) available to the workflow.
  4. Content Filtering: The workflow applies two layers of filtering:
    • First, it checks if the note's content contains specific keywords like "dépensé" or "depense", targeting expense-related notes.
    • Second, it checks if the note is not archived, ensuring only active notes are processed.
  5. AI-Powered Data Extraction: For each note that passes the filters, the Put some AI treatment here agent sends the text content to OpenAI (gpt-4o-mini). The AI is prompted to extract the expense amount in euros and return only the number.
  6. Data Structuring: The Set the fields for export node organizes the information, combining the original note content, creation/edit timestamps, archived status, and the expense amount extracted by the AI into a clean, structured format.
  7. Log to Google Sheets: Finally, the Add to google sheet node takes this structured data and appends it as a new row to your designated spreadsheet, creating an automated ledger.

✅ Real-World Use Cases:

  • Automated Expense Tracking: Quickly jot down expenses in Google Keep (e.g., "Spent 15 euros on lunch") and have this workflow automatically create a detailed expense report in a spreadsheet.
  • Data Migration: Seamlessly move valuable information from the unstructured format of Google Keep into a structured, analyzable format in Google Sheets.
  • Information Archiving: Create a searchable and sortable database of your important notes, ideas, or reminders.
  • Task & Project Management: Adapt the AI prompt to extract action items, deadlines, or project details from notes and populate a project management spreadsheet.

Instructions

Basic steps

  1. Download workflow JSON
  2. Import into n8n
  3. Configure node parameters as needed
  4. Test and enable the workflow

💡 Tips

After importing, verify all connectors and credentials match your environment.

Preview

Workflow Visualization

19 nodes
100%
When clicking ‘Test workflow’manualTriggerExtract from FileextractFromFileIf is archived is falseifOpenAI Chat Model@n8n/langchain.lmChatOpenAiIf extension is jsonfilterSticky NotestickyNoteSearch in "Keep" foldergoogleDriveLoop every 10 itemssplitInBatchesDownload the filesgoogleDrivePut some AI treatment here if you need it@n8n/langchain.agentSet the fields for exportsetAdd to google sheetgoogleSheetsFilterifSticky Note1stickyNoteSticky Note2stickyNoteSticky Note3stickyNoteSticky Note4stickyNoteSticky Note5stickyNoteSticky Note6stickyNote

Nodes

1

When clicking ‘Test workflow’

manualTrigger

v1
2

Extract from File

extractFromFile

v1
3

If is archived is false

if

v2.2
4

OpenAI Chat Model

@n8n/langchain.lmChatOpenAi

v1.2
5

If extension is json

filter

v2.2
6

Sticky Note

stickyNote

v1
7

Search in "Keep" folder

googleDrive

v3
8

Loop every 10 items

splitInBatches

v3
9

Download the files

googleDrive

v3
10

Put some AI treatment here if you need it

@n8n/langchain.agent

v1.8
11

Set the fields for export

set

v3.4
12

Add to google sheet

googleSheets

v4.5
13

Filter

if

v2.2
14

Sticky Note1

stickyNote

v1
15

Sticky Note2

stickyNote

v1
16

Sticky Note3

stickyNote

v1
17

Sticky Note4

stickyNote

v1
18

Sticky Note5

stickyNote

v1
19

Sticky Note6

stickyNote

v1

Statistics

Total nodes:19
Disabled nodes:0
Node types:11
Connections:12
View full JSON structure
{
  "nodes": [
    {
      "id": "ee3cd6ff-40ba-40d4-bbbf-90244da4a272",
      "name": "When clicking ‘Test workflow’",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        0,
        -155
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "68584aab-c5f3-450a-a1e3-cddc8d64082d",
      "name": "Extract from File",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        1100,
        -280
      ],
      "parameters": {
        "options": {},
        "operation": "fromJson"
      },
      "typeVersion": 1
    },
    {
      "id": "e23a67a1-44df-4b83-a80a-9383f4432c7d",
      "name": "If is archived is false",
      "type": "n8n-nodes-base.if",
      "position": [
        1540,
        -280
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e051d2f2-7c22-4864-bbe7-4832cc54acaa",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.isArchived }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "313764d0-f115-46d3-a2e3-1fde647f7d85",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1848,
        -60
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "1IOLtYX7aTspCAN8",
          "name": "OpenAI Pollup"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "81fcc7a0-955d-4930-b203-8e98d57e3c4c",
      "name": "If extension is json",
      "type": "n8n-nodes-base.filter",
      "position": [
        660,
        -280
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "7b80be39-b5cc-4f96-8529-75559aaece38",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.name.split('.').pop(); }}",
              "rightValue": "=json"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1c8c81ea-d0ae-4925-ae4b-05482c1b5fa2",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -340,
        -380
      ],
      "parameters": {
        "color": 4,
        "width": 260,
        "height": 440,
        "content": "## How to export your Google keep notes \n* Google has a dedicated service for exporting your google data, called [Google Takeout](https://takeout.google.com/), you'll have to login  it. \n* Click on \"Deselect all\" then select only Google Keep and click on \"Next\". \n- Select the destination (use \"Send download link via mail\" as you'll have to uncompress a zip file before to send it again to Google Drive)\n- Upload to Google Drive all json files from your uncompresed file, to specific directory and you are ready to start!\n"
      },
      "typeVersion": 1
    },
    {
      "id": "31eb6398-cca0-4ed1-910a-470fa49c9727",
      "name": "Search in \"Keep\" folder",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        220,
        -155
      ],
      "parameters": {
        "limit": 2,
        "filter": {
          "folderId": {
            "__rl": true,
            "mode": "list",
            "value": "1BggjRVCqyDnECK_mB2M-PYareptQv99P",
            "cachedResultUrl": "https://drive.google.com/drive/folders/1BggjRVCqyDnECK_mB2M-PYareptQv99P",
            "cachedResultName": "Keep"
          },
          "whatToSearch": "files"
        },
        "options": {},
        "resource": "fileFolder"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "veQ5hnnOES56fTcI",
          "name": "Google Drive account good"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "653d04b2-4020-4254-a8f5-53e15228adb7",
      "name": "Loop every 10 items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        440,
        -155
      ],
      "parameters": {
        "options": {},
        "batchSize": 10
      },
      "typeVersion": 3
    },
    {
      "id": "c1171bd7-5e2d-49e6-a52b-6e9282cb093d",
      "name": "Download the files",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        880,
        -280
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "veQ5hnnOES56fTcI",
          "name": "Google Drive account good"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "4d9caff3-2ac8-40fc-91a4-1b395e693141",
      "name": "Put some AI treatment here if you need it",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "notes": "Yu can use this AI Agent to process a number or anything you need from your notes",
      "position": [
        1760,
        -280
      ],
      "parameters": {
        "text": "=Extract the amount in euros of the input. output just the amount and nothing else. \nHere is the input:{{ $json.data.textContent }}",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 1.8
    },
    {
      "id": "d97c4e02-4b1a-479f-8492-e601c553ac57",
      "name": "Set the fields for export",
      "type": "n8n-nodes-base.set",
      "position": [
        2136,
        -280
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d05409ea-b739-47bd-9c07-0dea40b83de1",
              "name": "textContent",
              "type": "string",
              "value": "={{ $('If is archived is false').item.json.data.textContent }}"
            },
            {
              "id": "acbe202e-de95-4a47-a90b-78556fec4650",
              "name": "Edited",
              "type": "string",
              "value": "={{ new Date($('If is archived is false').item.json.data.userEditedTimestampUsec / 1000).toLocaleString() }}"
            },
            {
              "id": "13f00e53-75fd-4db5-9a22-b5e329c72b47",
              "name": "Created",
              "type": "string",
              "value": "={{ new Date($('If is archived is false').item.json.data.createdTimestampUsec / 1000).toLocaleString() }}"
            },
            {
              "id": "7e58e874-5238-4fb6-8b00-ea947c59ec4b",
              "name": "isArchived",
              "type": "boolean",
              "value": "={{ $('If is archived is false').item.json.data.isArchived }}"
            },
            {
              "id": "721f31d8-4944-4a63-878e-71816eee755c",
              "name": "Amount",
              "type": "string",
              "value": "={{ $json.output }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "0f8d9b1f-f5de-477f-ad50-eeb89bcf8dc7",
      "name": "Add to google sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2356,
        -155
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "textContent",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "textContent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Edited",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Edited",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Created",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Created",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "isArchived",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "isArchived",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1rjgyHw6XU4NTRCx4eXuQ0AIXhY3mWqxg1NiAhrSnuzE/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1rjgyHw6XU4NTRCx4eXuQ0AIXhY3mWqxg1NiAhrSnuzE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1rjgyHw6XU4NTRCx4eXuQ0AIXhY3mWqxg1NiAhrSnuzE/edit?usp=drivesdk",
          "cachedResultName": "googl keep export (10/05/25)"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "gdLmm513ROUyH6oU",
          "name": "Google Sheets account"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "31141cf2-94d6-45ad-8632-18001a6d4d36",
      "name": "Filter",
      "type": "n8n-nodes-base.if",
      "position": [
        1320,
        -280
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "11bacf5f-6675-4681-b205-5e5293eaae02",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.data.textContentHtml }}",
              "rightValue": "dépensé"
            },
            {
              "id": "c40da1df-559c-4278-bde1-cdb8e65c8428",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.data.textContentHtml }}",
              "rightValue": "depense"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c4c941f5-6579-4f4f-9916-cdd496498760",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2300,
        -360
      ],
      "parameters": {
        "color": 5,
        "height": 360,
        "content": "## Create an empty google sheet file\n\nThat will get your entries from the notes "
      },
      "typeVersion": 1
    },
    {
      "id": "3ab60239-85cf-4c84-94d3-659fdfef4316",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        140,
        -300
      ],
      "parameters": {
        "color": 5,
        "height": 360,
        "content": "## Set the directory Where you put the files"
      },
      "typeVersion": 1
    },
    {
      "id": "49546099-e072-4183-a14e-fff80928920d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1240,
        -480
      ],
      "parameters": {
        "color": 5,
        "height": 360,
        "content": "## Filter the files\n\nIf you need the content to contain a word, or after a certain date.\n\nIf you don't need to filter it, just remove the node"
      },
      "typeVersion": 1
    },
    {
      "id": "195923a2-faf9-40c3-95c0-08fdc078e291",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1720,
        -500
      ],
      "parameters": {
        "color": 5,
        "width": 320,
        "height": 560,
        "content": "## Process each file with AI\n\nIf you need the extract some information from the contextq, you can do it here. If you don't need it, just delete the node"
      },
      "typeVersion": 1
    },
    {
      "id": "07b3570a-72cf-480b-b3b8-fb461b57822d",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -340,
        80
      ],
      "parameters": {
        "color": 4,
        "width": 380,
        "height": 300,
        "content": "## Setup\n* Export your Google Keep notes (see \"how to export your Google Keep notes\")\n\n- Connect Google Drive, OpenAI, and Google Sheets in n8n.\n\n- Set the correct folder path for your notes in the “Search in ‘Keep’ folder” node.\n\n- Point the Google Sheet node to your spreadsheet"
      },
      "typeVersion": 1
    },
    {
      "id": "48e1cff2-2748-4d15-91b4-d5ee2f5d9581",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -340,
        -500
      ],
      "parameters": {
        "width": 720,
        "height": 100,
        "content": "## Contact me\n### If you need some help with this workflow: Write to me: [[email protected]](mailto:[email protected])\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Filter": {
      "main": [
        [
          {
            "node": "If is archived is false",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Put some AI treatment here if you need it",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Download the files": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add to google sheet": {
      "main": [
        [
          {
            "node": "Loop every 10 items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop every 10 items": {
      "main": [
        [],
        [
          {
            "node": "If extension is json",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If extension is json": {
      "main": [
        [
          {
            "node": "Download the files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If is archived is false": {
      "main": [
        [
          {
            "node": "Put some AI treatment here if you need it",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search in \"Keep\" folder": {
      "main": [
        [
          {
            "node": "Loop every 10 items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set the fields for export": {
      "main": [
        [
          {
            "node": "Add to google sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Test workflow’": {
      "main": [
        [
          {
            "node": "Search in \"Keep\" folder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Put some AI treatment here if you need it": {
      "main": [
        [
          {
            "node": "Set the fields for export",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Actions

Share
Categories:
Tags:
manualtriggersplitinbatchesifsetgooglesheetsstickynotegoogledriveextractfromfilefilter

Technical Specs

Complexity:
Expert
Node Count:
19 nodes
Published:11 months ago
Updated:9 days ago

Compatibility

Platform:
N8N Cloud & Self-hosted
Min Version:
N8N v1.0.0+
Supports cloud and self-hosted deployment

License

This workflow template follows MIT license, you can freely use, modify and distribute.

Please comply with relevant third-party service terms when using.

Related Workflows