This workflow corresponds to n8n.io template #14148 — 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 →
{
"id": "rVTVIVdaRJ36Ss9J",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "AI Handwritten Memo Organizer copy",
"tags": [],
"nodes": [
{
"id": "d966c63b-0c81-4ae4-b39f-cea2e1bc262b",
"name": "LINE_Receive_Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-352,
-352
],
"parameters": {
"path": "=e89b4943-1f2e-4d37-84ad-0fce0b78175e",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "24b6f4c9-f787-4a76-b810-73f8ce3c13d0",
"name": "LINE_Check_MessageType",
"type": "n8n-nodes-base.if",
"position": [
112,
-352
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "58a4dbd8-8eed-400c-b94a-7083131e133a",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('LINE_Receive_Webhook').item.json.body.events[0].message.type }}",
"rightValue": "image"
},
{
"id": "69e0a667-2629-4538-9bb6-518274328f8b",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"id": "65504c18-86a1-43b4-ba30-73034b424a3c",
"name": "LINE_Download_ImageContent",
"type": "n8n-nodes-base.httpRequest",
"position": [
560,
-368
],
"parameters": {
"url": "=https://api-data.line.me/v2/bot/message/{{ $('LINE_Receive_Webhook').item.json.body.events[0].message.id }}/content",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "=Authorization",
"value": "=Bearer {{ $('Config_Set_Environment').item.json.LINE_ACCESS_TOKEN }}"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "d818cc9f-74b8-4df2-832e-8c4ad0bea0f0",
"name": "Binary_Restore_From_LINE",
"type": "n8n-nodes-base.code",
"position": [
944,
-368
],
"parameters": {
"jsCode": "const item = $input.first();\n\n// Restore binary data\nitem.binary = $node[\"LINE_Download_ImageContent\"].binary;\n\nreturn [item];"
},
"typeVersion": 2
},
{
"id": "6560682c-aea1-40ff-8883-07e6346da25c",
"name": "Drive_Upload_Image",
"type": "n8n-nodes-base.googleDrive",
"position": [
752,
-368
],
"parameters": {
"name": "={{ $('LINE_Receive_Webhook').item.json.body.events[0].message.id }}.jpg",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "1xR4KZbVauD6_J0t5YbPBvFSS1dxPLuWu",
"cachedResultUrl": "https://drive.google.com/drive/folders/1xR4KZbVauD6_J0t5YbPBvFSS1dxPLuWu",
"cachedResultName": "LINE_PIC"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "e70fef6c-4191-4ec8-8676-2f1d9692b9be",
"name": "AI_OCR_Analyze_Image",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
1152,
-368
],
"parameters": {
"text": "=You are a high-precision OCR engine.\n\nPlease read the text written in the image as accurately as possible.\nIf the text cannot be read, you must output the following JSON and terminate the process:\n{\n\"title\": \"\",\n\"category\": \"\",\n\"summary\": \"The text could not be recognized.\",\n\"tags\":[]\n}\n\nIf the text can be read, generate the following based on the summarized content:\n\nTitle\n\nCategory\n\nSummary\n\nTags (up to 3 important keywords)\n\n\u3010Rules\u3011\n\nThe category should be a short, easy-to-group term.\n\nTags must be single words with no duplicates.\n\nAvoid overly abstract tags (e.g., important, memo).\n\n\u3010Important\u3011\n\nOutput must be pure JSON only\n\nNo explanations or preface text\n\nDo not output anything other than JSON\n\nOutput the following fields in JSON format:\n\n{\n\"title\": \"\",\n\"category\": \"\",\n\"summary\": \"\",\n\"tags\":[]\n}",
"batching": {},
"messages": {
"messageValues": [
{
"type": "HumanMessagePromptTemplate",
"messageType": "imageBinary"
}
]
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "63af5fcc-e079-48c2-9548-f47f5bd5459d",
"name": "AI_Model_Gemini",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1200,
-176
],
"parameters": {
"options": {
"topP": 1,
"temperature": 0,
"maxOutputTokens": 2048
}
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "629c2e2c-9fe6-4dc0-9055-a62c83a02091",
"name": "Data_Parse_OCR_JSON",
"type": "n8n-nodes-base.code",
"position": [
1600,
-368
],
"parameters": {
"jsCode": "let raw = $json[\"text\"] || \"\";\n\nraw = raw.replace(/```json\\s*/i, \"\").replace(/```/g, \"\").trim();\n\n// Extract only the JSON part\nconst match = raw.match(/\\{[\\s\\S]*\\}/);\nif (match) {\n raw = match[0];\n}\n\n// parsed\nlet parsed;\ntry {\n parsed = JSON.parse(raw);\n} catch (e) {\n parsed = {\n title: \"\",\n category: \"\",\n summary: raw.slice(0, 100),\n tags: []\n };\n}\n\n// Add patterns\n\nif (!parsed.title || typeof parsed.title !== \"string\") {\n parsed.title = \"No title\";\n}\n\nif (!parsed.category || typeof parsed.category !== \"string\") {\n parsed.category = \"Uncategorized\";\n}\n\nif (!parsed.summary || typeof parsed.summary !== \"string\") {\n parsed.summary = \"No summary\";\n}\n\nif (!Array.isArray(parsed.tags)) {\n parsed.tags = [];\n}\n\n// Sanitize the contents of the tags as well\nparsed.tags = parsed.tags\n .filter(tag => typeof tag === \"string\")\n .slice(0, 3);\n\n// Original item\nconst item = $input.first();\n\n// Merge\nitem.json = {\n ...item.json,\n ...parsed\n};\n\n// Preserve binary data\nitem.binary = $input.first().binary;\n\nreturn [item];"
},
"typeVersion": 2
},
{
"id": "490147c4-3b25-4868-89db-410367e97af5",
"name": "AI_Check_OCR_Failure",
"type": "n8n-nodes-base.if",
"position": [
1888,
-368
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0cad7233-7daa-4bff-bde7-08f254669175",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.summary }}",
"rightValue": "=The text could not be recognized."
}
]
}
},
"typeVersion": 2.3
},
{
"id": "8ce58f94-0c8f-4796-8082-7fa7af4f1eaf",
"name": "LINE_Reply_NoImage",
"type": "n8n-nodes-base.httpRequest",
"position": [
320,
-176
],
"parameters": {
"url": "=https://api.line.me/v2/bot/message/reply",
"method": "POST",
"options": {},
"jsonBody": "={\n \"replyToken\": \"{{$node['LINE_Receive_Webhook'].json.body.events[0].replyToken }}\",\n \"messages\": [\n {\n \"type\": \"text\",\n \"text\": \"If you send a handwritten memo, I will summarize its contents.\"\n }\n ]\n}\n",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "=Authorization",
"value": "=Bearer {{$node[\"Config_Set_Environment\"].json.LINE_ACCESS_TOKEN }}"
},
{
"name": "=Content-type",
"value": "=application/json"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "77b6636b-89a7-4ca7-9266-80ab17312250",
"name": "Sheets_Get_Metadata",
"type": "n8n-nodes-base.httpRequest",
"position": [
2272,
-352
],
"parameters": {
"url": "=https://sheets.googleapis.com/v4/spreadsheets/{{ $('Config_Set_Environment').item.json.GOOGLE_SHEETS_ID }}",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleOAuth2Api"
},
"credentials": {
"googleOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "3c6d4ce3-d628-4973-a921-f8df9bfce102",
"name": "Sheets_Check_Category_Exists",
"type": "n8n-nodes-base.code",
"position": [
2480,
-352
],
"parameters": {
"jsCode": "// Category obtained via OCR\nconst category = $('Data_Parse_OCR_JSON').first().json.category;\n\n// List of sheets retrieved via the Sheets API\nconst sheets = $json.sheets || [];\n\n// Create a list of sheet names\nconst sheetNames = sheets.map(s => s.properties.title);\n\n// Match check\nconst exists = sheetNames.includes(category);\n\nreturn [\n {\n json: {\n category: category,\n sheetExists: exists,\n sheetNames: sheetNames\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "cea2f7b2-3ec4-4602-8840-f17011641121",
"name": "Sheets_Branch_Category",
"type": "n8n-nodes-base.if",
"position": [
2688,
-352
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7865df36-eede-4198-ad62-2942a8471bfa",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.sheetExists }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.3
},
{
"id": "9fd98944-f097-420e-9f18-9a1c8e2a6404",
"name": "Sheets_Create_Category",
"type": "n8n-nodes-base.googleSheets",
"position": [
2832,
-240
],
"parameters": {
"title": "={{ $('Sheets_Check_Category_Exists').item.json.category }}",
"options": {},
"operation": "create",
"documentId": {
"__rl": true,
"mode": "list",
"value": "1eFUe4xD5Xgd5BbQ2kT_QzKQzF3EspnuXdpYYv8p46HM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1eFUe4xD5Xgd5BbQ2kT_QzKQzF3EspnuXdpYYv8p46HM/edit?usp=drivesdk",
"cachedResultName": "OCR_data"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "835f1e29-373f-41b8-bdf0-b0235c7bd4ac",
"name": "Sheets_Append_Row",
"type": "n8n-nodes-base.googleSheets",
"position": [
3344,
-368
],
"parameters": {
"columns": {
"value": {
"date": "={{$now.format(\"yyyy-MM-dd HH:mm:ss\")}}",
"tags": "={{ $node['Data_Parse_OCR_JSON'].json.tags.join(',') }}",
"title": "={{ $node['Data_Parse_OCR_JSON'].json.title }}",
"webUrl": "={{ $('Drive_Upload_Image').item.json.webViewLink }}",
"summary": "={{ $node['Data_Parse_OCR_JSON'].json.summary }}"
},
"schema": [
{
"id": "date",
"type": "string",
"display": true,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "title",
"type": "string",
"display": true,
"required": false,
"displayName": "title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "summary",
"type": "string",
"display": true,
"required": false,
"displayName": "summary",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "webUrl",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "webUrl",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "tags",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "tags",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "={{ $('Sheets_Check_Category_Exists').item.json.category }}"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1eFUe4xD5Xgd5BbQ2kT_QzKQzF3EspnuXdpYYv8p46HM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1eFUe4xD5Xgd5BbQ2kT_QzKQzF3EspnuXdpYYv8p46HM/edit?usp=drivesdk",
"cachedResultName": "OCR_data"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "b9403280-7d7c-49be-9267-17fbfabcd74e",
"name": "LINE_Push_Completion_Message",
"type": "n8n-nodes-base.httpRequest",
"position": [
3696,
-368
],
"parameters": {
"url": "=https://api.line.me/v2/bot/message/push",
"method": "POST",
"options": {},
"jsonBody": "={\n \"to\":\"{{ $('LINE_Receive_Webhook').item.json.body.events[0].source.userId }}\",\n \"messages\": [\n {\n \"type\": \"text\",\n \"text\": \"The text has been summarized and saved.\\n SheetsName\u300c{{$node['Sheets_Check_Category_Exists'].json.category}}\u300d\\nTitle\u300c{{$json.title}}\u300d\\n Tags\u300c{{ $json.tags }}\u300d\"\n }\n ]\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "=Authorization",
"value": "=Bearer {{ $('Config_Set_Environment').item.json.LINE_ACCESS_TOKEN }}"
},
{
"name": "=Content-type",
"value": "=application/json"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "6cec1e96-0f19-43e4-92b5-4a4719ce0018",
"name": "Data_Prepare_Sheet_Row",
"type": "n8n-nodes-base.set",
"position": [
3040,
-240
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "da4e2d84-d288-4ab4-85bb-d77cc5d36181",
"name": "date",
"type": "string",
"value": "={{$now.format(\"yyyy-MM-dd HH:mm:ss\")}}"
},
{
"id": "2326e8d4-3fd1-4693-82c5-f20e277d883e",
"name": "title",
"type": "string",
"value": "={{ $node['Data_Parse_OCR_JSON'].json.title }}"
},
{
"id": "bf464c30-98cd-4489-9a87-8838bc0f3c54",
"name": "summary",
"type": "string",
"value": "={{ $node['Data_Parse_OCR_JSON'].json.summary }}"
},
{
"id": "edcd36c7-75db-4b3d-899a-56a1022b822e",
"name": "webUrl",
"type": "string",
"value": "={{ $node['Drive_Upload_Image'].json.webViewLink }}"
},
{
"id": "dd39e3b3-caaa-466b-8b4c-a40885fbf357",
"name": "tags",
"type": "string",
"value": "={{ $node['Data_Parse_OCR_JSON'].json.tags.join(',') }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "e69bd4e7-c264-44d1-adcc-a8ef27d5a369",
"name": "Config_Set_Environment",
"type": "n8n-nodes-base.set",
"position": [
-128,
-352
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "aa8b0c5c-df21-49f6-a885-eff8ad142d3d",
"name": "LINE_ACCESS_TOKEN",
"type": "string",
"value": "=YOUR_ACCESS_TOKEN"
},
{
"id": "98ad89fb-a6a2-463d-adc8-7c3ce9125170",
"name": "GOOGLE_SHEETS_ID",
"type": "string",
"value": "YOUR_GOOGLE_SHEETS_ID"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "01086742-e02d-431b-a8e2-894cc045908e",
"name": "LINE_Reply_Processing",
"type": "n8n-nodes-base.httpRequest",
"position": [
320,
-368
],
"parameters": {
"url": "=https://api.line.me/v2/bot/message/reply",
"method": "POST",
"options": {},
"jsonBody": "={\n \"replyToken\": \"{{$node['LINE_Receive_Webhook'].json.body.events[0].replyToken }}\",\n \"messages\": [\n {\n \"type\": \"text\",\n \"text\": \"Processing\u2026\"\n }\n ]\n}\n",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "=Authorization",
"value": "=Bearer {{$node[\"Config_Set_Environment\"].json.LINE_ACCESS_TOKEN }}"
},
{
"name": "=Content-type",
"value": "=application/json"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "265726ac-ccc0-4a59-8831-01d9066621a2",
"name": "LINE_Push_NoSummary",
"type": "n8n-nodes-base.httpRequest",
"position": [
2064,
-528
],
"parameters": {
"url": "=https://api.line.me/v2/bot/message/push",
"method": "POST",
"options": {},
"jsonBody": "={\n \"to\":\"{{ $('LINE_Receive_Webhook').item.json.body.events[0].source.userId }}\",\n \"messages\": [\n {\n \"type\": \"text\",\n \"text\": \"The image could not be read.\\n\u2022 The text may be too small.\\n\u2022 Please retake the photo in a well-lit environment.\"\n }\n ]\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "=Authorization",
"value": "=Bearer {{ $('Config_Set_Environment').item.json.LINE_ACCESS_TOKEN }}"
},
{
"name": "=Content-type",
"value": "=application/json"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "6e3926bb-93e7-4571-a552-f8fefbca4dfc",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
496,
-608
],
"parameters": {
"color": 7,
"width": 608,
"height": 416,
"content": "## Image Handling\n\nProcesses the incoming image:\n\n\u2022 Downloads image from LINE API\n\u2022 Uploads image to Google Drive\n\u2022 Restores binary data\n\nEnsures persistent storage for later use."
},
"typeVersion": 1
},
{
"id": "b4988f99-7b80-4e3e-b80f-2e3fc284e400",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1136,
-720
],
"parameters": {
"width": 688,
"height": 960,
"content": "## AI Handwritten Memo Organizer \u2013 Overview\nThis workflow receives handwritten memo images sent via LINE and automatically extracts, summarizes, and organizes the content using AI.\n\n## Step-by-step process:\n1.\tUser sends a handwritten memo image via LINE\n2.\tWebhook receives the image\n3.\tImmediate reply is sent: \u201cProcessing\u2026\u201d\n4.\tImage is saved to Google Drive\n5.\tAI performs OCR and generates structured data (title, category, summary, tags)\n6.\tThe JSON response is safely parsed with error handling\n7.\tOCR failure is detected if text cannot be properly extracted\nIf OCR fails:\n\u2192 User is notified with guidance for retaking the image\nIf OCR succeeds:\n\u2192 Check if the category sheet exists in Google Sheets\n\u2192 If not, create a new sheet\n\u2192 Save the data (title, summary, tags, date, image URL)\n8.\tCompletion message is sent to the user via LINE\n\n## Setup Steps\n1.\tCreate a LINE Messaging API channel and obtain the Channel Access Token\n2.\tCreate a Google Spreadsheet for storing memo data\n3.\tCreate a Google Drive folder to store uploaded images\n4.\tSet the following values in the Config node:\no\tLINE_ACCESS_TOKEN\no\tGOOGLE_SHEETS_ID\n5.\tSet the Webhook URL in the LINE Developers Console\n\n## Key points:\n\u2022 Immediate response improves user experience\n\u2022 JSON parsing includes fallback handling for malformed AI output\n\u2022 OCR failure is detected and handled safely\n\u2022 Data is automatically categorized into separate sheets\n\u2022 Tags are generated to enable future search functionality\n \n## Notes:\n\u2022 If a non-image message is sent, the user is prompted to send an image\n\u2022 If text cannot be extracted, the data will not be saved\n\u2022 The AI output may not always be perfectly accurate\n\u2022 This workflow is designed for memo organization, not critical data processing\n"
},
"typeVersion": 1
},
{
"id": "7801b3d3-d0eb-4711-a946-a457acf5f17c",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-416,
-608
],
"parameters": {
"color": 7,
"width": 896,
"height": 608,
"content": "## LINE Input & Validation\n\nReceives messages via LINE Webhook.\n\n\u2022 Validates that the input is an image\n\u2022 Non-image messages are rejected with guidance\n\u2022 Ensures only valid data enters the workflow\n\u2022 Sends an instant reply: \u201cProcessing\u2026\u201d\n\nThis step prevents invalid processing early."
},
"typeVersion": 1
},
{
"id": "ac47a850-0fe3-4aef-a804-aa5b43abdfce",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1120,
-656
],
"parameters": {
"color": 7,
"width": 400,
"height": 608,
"content": "## OCR & AI Processing\n\nExtracts and structures data from the image:\n\n\u2022 Performs OCR on handwritten content\n\u2022 Generates structured JSON:\n - title\n - category\n - summary\n - tags\n\nTransforms unstructured data into usable format."
},
"typeVersion": 1
},
{
"id": "41e2fac1-ece2-4101-a4f3-20f2cb2c3aa8",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1536,
-656
],
"parameters": {
"color": 7,
"width": 272,
"height": 464,
"content": "## JSON Parsing\n\nSafely parses AI output:\n\n\u2022 Removes invalid wrappers (e.g. ```json)\n\u2022 Extracts JSON content\n\u2022 Handles malformed responses with fallback\n\nPrevents workflow crashes from AI inconsistencies."
},
"typeVersion": 1
},
{
"id": "cba9d1aa-eb5f-4538-a89c-4fd282e7e43a",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1840,
-752
],
"parameters": {
"color": 7,
"width": 368,
"height": 592,
"content": "## OCR Failure Detection\n\nValidates OCR result quality:\n\n\u2022 Detects missing or invalid summary\n\u2022 Stops workflow if text is not recognized\n\nPrevents saving incorrect data."
},
"typeVersion": 1
},
{
"id": "e9b8bc3f-5148-49a4-970d-02e19fb0cc44",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
2224,
-608
],
"parameters": {
"color": 7,
"width": 976,
"height": 544,
"content": "## Sheet Management\n\nManages Google Sheets structure:\n\n\u2022 Checks if category sheet exists\n\u2022 Creates new sheet if needed\n\nEnables scalable data organization."
},
"typeVersion": 1
},
{
"id": "4739a0a1-b1e0-4acd-b023-0b9d3ba244d7",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
3216,
-624
],
"parameters": {
"color": 7,
"width": 320,
"height": 416,
"content": "## Data Storage\n\nStores structured data:\n\n\u2022 Title\n\u2022 Summary\n\u2022 Tags\n\u2022 Date\n\u2022 Image URL\n\nAll data is appended to the correct sheet."
},
"typeVersion": 1
},
{
"id": "ac129a5a-5345-48b4-972d-66b07fc042dd",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
3552,
-576
],
"parameters": {
"color": 7,
"width": 304,
"height": 384,
"content": "## Completion Response\n\nSends results back to user:\n\n\u2022 Confirms successful processing\n\u2022 Provides organized output\n\nCloses the workflow clearly."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "aedf2830-81f7-4919-96a1-ea92f40160fd",
"connections": {
"AI_Model_Gemini": {
"ai_languageModel": [
[
{
"node": "AI_OCR_Analyze_Image",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Sheets_Append_Row": {
"main": [
[
{
"node": "LINE_Push_Completion_Message",
"type": "main",
"index": 0
}
]
]
},
"Drive_Upload_Image": {
"main": [
[
{
"node": "Binary_Restore_From_LINE",
"type": "main",
"index": 0
}
]
]
},
"Data_Parse_OCR_JSON": {
"main": [
[
{
"node": "AI_Check_OCR_Failure",
"type": "main",
"index": 0
}
]
]
},
"Sheets_Get_Metadata": {
"main": [
[
{
"node": "Sheets_Check_Category_Exists",
"type": "main",
"index": 0
}
]
]
},
"AI_Check_OCR_Failure": {
"main": [
[
{
"node": "LINE_Push_NoSummary",
"type": "main",
"index": 0
}
],
[
{
"node": "Sheets_Get_Metadata",
"type": "main",
"index": 0
}
]
]
},
"AI_OCR_Analyze_Image": {
"main": [
[
{
"node": "Data_Parse_OCR_JSON",
"type": "main",
"index": 0
}
]
]
},
"LINE_Receive_Webhook": {
"main": [
[
{
"node": "Config_Set_Environment",
"type": "main",
"index": 0
}
]
]
},
"LINE_Reply_Processing": {
"main": [
[
{
"node": "LINE_Download_ImageContent",
"type": "main",
"index": 0
}
]
]
},
"Config_Set_Environment": {
"main": [
[
{
"node": "LINE_Check_MessageType",
"type": "main",
"index": 0
}
]
]
},
"Data_Prepare_Sheet_Row": {
"main": [
[
{
"node": "Sheets_Append_Row",
"type": "main",
"index": 0
}
]
]
},
"LINE_Check_MessageType": {
"main": [
[
{
"node": "LINE_Reply_Processing",
"type": "main",
"index": 0
}
],
[
{
"node": "LINE_Reply_NoImage",
"type": "main",
"index": 0
}
]
]
},
"Sheets_Branch_Category": {
"main": [
[
{
"node": "Sheets_Append_Row",
"type": "main",
"index": 0
}
],
[
{
"node": "Sheets_Create_Category",
"type": "main",
"index": 0
}
]
]
},
"Sheets_Create_Category": {
"main": [
[
{
"node": "Data_Prepare_Sheet_Row",
"type": "main",
"index": 0
}
]
]
},
"Binary_Restore_From_LINE": {
"main": [
[
{
"node": "AI_OCR_Analyze_Image",
"type": "main",
"index": 0
}
]
]
},
"LINE_Download_ImageContent": {
"main": [
[
{
"node": "Drive_Upload_Image",
"type": "main",
"index": 0
}
]
]
},
"Sheets_Check_Category_Exists": {
"main": [
[
{
"node": "Sheets_Branch_Category",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
googleDriveOAuth2ApigoogleOAuth2ApigooglePalmApigoogleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow receives handwritten memo images sent via LINE and automatically extracts, summarizes, and organizes the content using AI. User sends a handwritten memo image via LINE Webhook receives the image Immediate reply is sent: “Processing…” Image is saved to Google Drive…
Source: https://n8n.io/workflows/14148/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
ANIS_HUB 1. Uses gmail, googleDrive, googleSheets, httpRequest. Webhook trigger; 89 nodes.
Resume Screening & Behavioral Interviews with Gemini, Elevenlabs, & Notion ATS copy. Uses outputParserStructured, chainLlm, googleDrive, stickyNote. Webhook trigger; 67 nodes.
Candidate Engagement | Resume Screening | AI Voice Interviews | Applicant Insights
Categories: Accounting Automation • OCR Processing • AI Data Extraction • Business Tools
This workflow converts handwritten memo images sent via LINE into structured, searchable knowledge using AI.Users simply send a handwritten memo photo. The workflow automatically performs OCR, summari