This workflow follows the Execute Workflow Trigger → 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 →
{
"name": "LINE Image Handler",
"nodes": [
{
"parameters": {},
"id": "execute-workflow-trigger",
"name": "Execute Workflow Trigger",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"typeVersion": 1,
"position": [
250,
300
],
"notes": "\u89aa\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u304b\u3089\u547c\u3073\u51fa\u3055\u308c\u308b\u30c8\u30ea\u30ac\u30fc\uff08Image Event\u5c02\u7528\uff09"
},
{
"parameters": {
"documentId": {
"__rl": true,
"value": "16qhVQNDn_5Y1Ayw_H0ziUw1nu2b70o6IcRn1rr4Pa94",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "Master_User_Config",
"mode": "name"
},
"filtersUI": {
"values": [
{
"lookupColumn": "line_user_id",
"lookupValue": "={{ $('Execute Workflow Trigger').item.json.body.events[0].source.userId }}"
}
]
},
"options": {}
},
"id": "lookup-user-config",
"name": "\u9867\u5ba2\u30de\u30b9\u30bf\u30fc\u53c2\u7167",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.4,
"position": [
450,
300
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "LINE\u30e6\u30fc\u30b6\u30fcID\u304b\u3089\u9867\u5ba2\u8a2d\u5b9a\u3092\u53d6\u5f97"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "condition-drive-folder-exists",
"leftValue": "={{ $json.drive_folder_id }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
}
},
{
"id": "condition-sheet-exists",
"leftValue": "={{ $json.sheet_id }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "if-user-exists",
"name": "IF \u8a2d\u5b9a\u5b8c\u4e86",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
650,
300
],
"notes": "\u4eee\u767b\u9332\u30e6\u30fc\u30b6\u30fc\uff08drive_folder_id/sheet_id\u672a\u8a2d\u5b9a\uff09\u306f\u8a2d\u5b9a\u5f85\u3061\u30e1\u30c3\u30bb\u30fc\u30b8\u3078"
},
{
"parameters": {
"url": "=https://api-data.line.me/v2/bot/message/{{ $('Execute Workflow Trigger').item.json.body.events[0].message.id }}/content",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {}
},
"id": "get-image-node",
"name": "Get LINE Image",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
850,
200
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"notes": "LINE API\u304b\u3089\u753b\u50cf\u30d0\u30a4\u30ca\u30ea\u3092\u53d6\u5f97"
},
{
"parameters": {
"name": "={{ $now.format('yyyyMMdd_HHmmss') }}_{{ $('\u9867\u5ba2\u30de\u30b9\u30bf\u30fc\u53c2\u7167').item.json.line_user_id }}.jpg",
"driveId": {
"__rl": true,
"value": "My Drive",
"mode": "list"
},
"folderId": {
"__rl": true,
"value": "={{ $('\u9867\u5ba2\u30de\u30b9\u30bf\u30fc\u53c2\u7167').item.json.drive_folder_id }}",
"mode": "id"
},
"options": {}
},
"id": "gdrive-upload-node",
"name": "Google Drive Upload",
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
1050,
200
],
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "\u9867\u5ba2\u5225\u30d5\u30a9\u30eb\u30c0\u306b\u4fdd\u5b58\uff08\u52d5\u7684\u632f\u308a\u5206\u3051\uff09"
},
{
"parameters": {
"operation": "download",
"fileId": {
"__rl": true,
"value": "={{ $json.id }}",
"mode": "id"
},
"options": {}
},
"id": "google-drive-download",
"name": "Google Drive Download",
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
1150,
200
],
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u305f\u753b\u50cf\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u3066\u30d0\u30a4\u30ca\u30ea\u30c7\u30fc\u30bf\u3092\u53d6\u5f97"
},
{
"parameters": {
"jsCode": "// Google Drive Download\u30ce\u30fc\u30c9\u304b\u3089\u30d0\u30a4\u30ca\u30ea\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\nconst binaryPropertyName = Object.keys($input.item.binary)[0];\nconst mimeType = $input.item.binary[binaryPropertyName].mimeType || 'image/jpeg';\n\n// n8n 2.4.0\u306efilesystem\u30e2\u30fc\u30c9\u3067\u306fgetBinaryDataBuffer()\u3092\u4f7f\u7528\nconst binaryBuffer = await this.helpers.getBinaryDataBuffer(0, binaryPropertyName);\nconst base64String = binaryBuffer.toString('base64');\n\n// Google Drive\u306eURL\uff08\u8a3c\u6191\u7528\uff09\nconst driveFileId = $('Google Drive Upload').item.json.id;\nconst driveUrl = `https://drive.google.com/uc?export=view&id=${driveFileId}`;\n\n// Base64\u5f62\u5f0f\u3067data URI\u3092\u69cb\u7bc9\nconst base64Image = `data:${mimeType};base64,${base64String}`;\n\n// OpenAI API\u30ea\u30af\u30a8\u30b9\u30c8\u30dc\u30c7\u30a3\u3092\u69cb\u7bc9\nconst requestBody = {\n model: \"gpt-4o\",\n messages: [\n {\n role: \"system\",\n content: `\u3042\u306a\u305f\u306f\u7d4c\u7406\u306e\u5c02\u9580\u5bb6AI\u3067\u3059\u3002\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3055\u308c\u305f\u9818\u53ce\u66f8\u753b\u50cf\u304b\u3089JSON\u30c7\u30fc\u30bf\u3092\u62bd\u51fa\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n\n# \u30eb\u30fc\u30eb\n1. **transaction_date**: \u65e5\u4ed8\u3092 YYYY-MM-DD \u5f62\u5f0f\u3067\u62bd\u51fa\u3002\u8a18\u8f09\u304c\u306a\u3044\u5834\u5408\u306f null\u3002\n2. **merchant**: \u5e97\u8217\u540d\u30fb\u4f1a\u793e\u540d\u3092\u6b63\u78ba\u306b\u62bd\u51fa\u3002\n3. **amount**: \u5408\u8a08\u91d1\u984d\uff08\u6570\u5024\u306e\u307f\uff09\u3002\u30ab\u30f3\u30de\u3084\u5186\u30de\u30fc\u30af\u306f\u9664\u53bb\u3002\n4. **tax_amount**: \u6d88\u8cbb\u7a0e\u984d\uff08\u8a18\u8f09\u304c\u3042\u308c\u3070\uff09\u3002\n5. **invoice_number**: \"T\"\u304b\u3089\u59cb\u307e\u308b13\u6841\u306e\u767b\u9332\u756a\u53f7\u304c\u3042\u308c\u3070\u62bd\u51fa\u3002\u306a\u3051\u308c\u3070 null\u3002\n6. **description**: \u53d6\u5f15\u306e\u5185\u5bb9\uff08\u4f8b\uff1a\u99d0\u8eca\u5834\u4ee3\u3001\u98f2\u98df\u4ee3\uff09\u3002\u753b\u50cf\u5185\u306e\u6642\u9593\u60c5\u5831\u304c\u3042\u308c\u3070\u305d\u308c\u3082\u542b\u3081\u308b\u3002\n7. **category**: \u53d6\u5f15\u5185\u5bb9\u304b\u3089\u9069\u5207\u306a\u52d8\u5b9a\u79d1\u76ee\u3092\u63a8\u6e2c\u3057\u3066\u9078\u629e\u3002\n - \u99d0\u8eca\u5834\u30fb\u30bf\u30af\u30b7\u30fc \u2192 \"\u65c5\u8cbb\u4ea4\u901a\u8cbb\"\n - \u98f2\u98df\uff08\u6253\u3061\u5408\u308f\u305b\uff09 \u2192 \"\u4f1a\u8b70\u8cbb\"\n - \u6587\u623f\u5177\u30fb\u6d88\u8017\u54c1 \u2192 \"\u6d88\u8017\u54c1\u8cbb\"\n - \u66f8\u7c4d\u30fb\u30bb\u30df\u30ca\u30fc \u2192 \"\u7814\u4fee\u8cbb\"\n - \u305d\u306e\u4ed6 \u2192 \"\u96d1\u8cbb\"\n8. **tax_rate**: \u6d88\u8cbb\u7a0e\u7387\uff08\u4f8b\uff1a10 \u307e\u305f\u306f 8\uff09\u3002\u8efd\u6e1b\u7a0e\u7387\u306b\u6ce8\u610f\u3002\n\n# \u51fa\u529b\u5f62\u5f0f\nJSON\u306e\u307f\u3092\u51fa\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u8aac\u660e\u6587\u306f\u4e0d\u8981\u3067\u3059\u3002\n\n{\n \"transaction_date\": \"YYYY-MM-DD\",\n \"merchant\": \"\u5e97\u8217\u540d\",\n \"amount\": 1000,\n \"tax_amount\": 100,\n \"invoice_number\": \"T1234567890123\",\n \"description\": \"\u99d0\u8eca\u5834\u4ee3\uff0816:02-17:15\uff09\",\n \"category\": \"\u65c5\u8cbb\u4ea4\u901a\u8cbb\",\n \"tax_rate\": 10\n}`\n },\n {\n role: \"user\",\n content: [\n {\n type: \"text\",\n text: \"\u3053\u306e\u9818\u53ce\u66f8\u753b\u50cf\u304b\u3089\u60c5\u5831\u3092\u62bd\u51fa\u3057\u3066\u304f\u3060\u3055\u3044\u3002\"\n },\n {\n type: \"image_url\",\n image_url: {\n url: base64Image\n }\n }\n ]\n }\n ],\n max_tokens: 500,\n temperature: 0.2\n};\n\n// \u51fa\u529b\u30c7\u30fc\u30bf\nreturn {\n json: {\n requestBody: requestBody,\n driveUrl: driveUrl\n }\n};"
},
"id": "build-ocr-request-node",
"name": "OCR\u30ea\u30af\u30a8\u30b9\u30c8\u69cb\u7bc9",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1250,
200
],
"notes": "\u753b\u50cf\u3092Base64\u30a8\u30f3\u30b3\u30fc\u30c9\u3057\u3066OpenAI API\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u69cb\u7bc9"
},
{
"parameters": {
"method": "POST",
"url": "https://api.openai.com/v1/chat/completions",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "openAiApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json.requestBody }}",
"options": {}
},
"id": "ai-ocr-node",
"name": "AI-OCR\u51e6\u7406\uff08GPT-4o\uff09",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1450,
200
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"notes": "gpt-4o\u3067\u753b\u50cf\u304b\u3089\u69cb\u9020\u5316\u30c7\u30fc\u30bf\u62bd\u51fa"
},
{
"parameters": {
"operation": "read",
"documentId": {
"__rl": true,
"value": "={{ $('\u9867\u5ba2\u30de\u30b9\u30bf\u30fc\u53c2\u7167').item.json.sheet_id }}",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "\u52d8\u5b9a\u79d1\u76ee\u30de\u30b9\u30bf\u30fc",
"mode": "name"
},
"options": {
"returnAllMatches": true
}
},
"id": "get-knowledge-base-node",
"name": "\u52d8\u5b9a\u79d1\u76ee\u30de\u30b9\u30bf\u30fc\u53d6\u5f97",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.4,
"position": [
1650,
200
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "\u9867\u5ba2\u5225\u52d8\u5b9a\u79d1\u76ee\u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u3092\u53d6\u5f97",
"continueOnFail": true,
"alwaysOutputData": true
},
{
"parameters": {
"jsCode": "// AI-OCR\u7d50\u679c\u3092\u30d1\u30fc\u30b9\nlet content = $('AI-OCR\u51e6\u7406\uff08GPT-4o\uff09').item.json.choices[0].message.content;\ncontent = content.replace(/^```json\\s*\\n?/, '').replace(/\\n?```\\s*$/, '').trim();\nconst ocrResult = JSON.parse(content);\n\nconst merchant = ocrResult.merchant || '';\nconst description = ocrResult.description || '';\n\n// \u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u53d6\u5f97\uff08\u5168\u884c\uff09- \u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u8ffd\u52a0\nlet knowledgeBase = [];\ntry {\n const kbData = $('\u52d8\u5b9a\u79d1\u76ee\u30de\u30b9\u30bf\u30fc\u53d6\u5f97').all();\n // \u30c7\u30fc\u30bf\u304c\u5b58\u5728\u3057\u3001\u30a8\u30e9\u30fc\u3067\u306a\u3044\u5834\u5408\u306e\u307f\u4f7f\u7528\n if (kbData && Array.isArray(kbData) && kbData.length > 0) {\n // \u30a8\u30e9\u30fc\u30c7\u30fc\u30bf\uff08pairedItem\u304cnull\u306a\u3069\uff09\u3092\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\n knowledgeBase = kbData.filter(item => item && item.json && !item.error);\n }\n} catch (error) {\n // \u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u305f\u5834\u5408\u306f\u7a7a\u914d\u5217\u3068\u3057\u3066\u51e6\u7406\uff08AI\u63a8\u8ad6\u306b\u30d5\u30a9\u30fc\u30eb\u30d0\u30c3\u30af\uff09\n knowledgeBase = [];\n}\n\n// \u30de\u30c3\u30c1\u30f3\u30b0\u51e6\u7406\nlet matchedCategory = null;\nlet maxConfidence = 0;\nlet matchedRowId = null;\nlet matchedMerchantKeyword = null;\nlet matchedAccountCategory = null;\nlet matchedUsageCount = 0;\nlet matchedLastUsedDate = '';\nlet matchedConfidenceScore = 0;\n\nfor (let i = 0; i < knowledgeBase.length; i++) {\n const rule = knowledgeBase[i].json;\n const merchantKeyword = rule.merchant_keyword || '';\n const descriptionKeyword = rule.description_keyword || '';\n const confidence = parseInt(rule.confidence_score) || 0;\n const rowNumber = i + 2; // \u30d8\u30c3\u30c0\u30fc\u884c\u3092\u9664\u304f\uff081\u884c\u76ee=\u30d8\u30c3\u30c0\u30fc\u30012\u884c\u76ee=\u6700\u521d\u306e\u30c7\u30fc\u30bf\uff09\n \n // \u5e97\u8217\u540d\u3067\u306e\u5b8c\u5168\u4e00\u81f4\uff08\u6700\u512a\u5148\uff09\n if (merchantKeyword && merchant.includes(merchantKeyword)) {\n if (confidence > maxConfidence) {\n matchedCategory = rule.account_category;\n maxConfidence = confidence;\n matchedRowId = rowNumber;\n matchedMerchantKeyword = merchantKeyword;\n matchedAccountCategory = rule.account_category;\n matchedUsageCount = rule.usage_count || 0;\n matchedLastUsedDate = rule.last_used_date || '';\n matchedConfidenceScore = confidence;\n }\n }\n \n // \u53d6\u5f15\u5185\u5bb9\u3067\u306e\u90e8\u5206\u4e00\u81f4\n if (!matchedCategory && descriptionKeyword && description.includes(descriptionKeyword)) {\n if (confidence > maxConfidence) {\n matchedCategory = rule.account_category;\n maxConfidence = confidence;\n matchedRowId = rowNumber;\n matchedMerchantKeyword = merchantKeyword;\n matchedAccountCategory = rule.account_category;\n matchedUsageCount = rule.usage_count || 0;\n matchedLastUsedDate = rule.last_used_date || '';\n matchedConfidenceScore = confidence;\n }\n }\n}\n\n// \u7d50\u679c\u51fa\u529b\nreturn {\n json: {\n ...ocrResult,\n // \u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u30de\u30c3\u30c1\u512a\u5148\u3001\u306a\u3051\u308c\u3070AI\u63a8\u8ad6\n category: matchedCategory || ocrResult.category,\n match_source: matchedCategory ? 'knowledge_base' : 'ai_inference',\n matched_confidence: maxConfidence,\n matched_row_id: matchedRowId,\n // \u4f7f\u7528\u30c7\u30fc\u30bf\u66f4\u65b0\u7528\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u8ffd\u52a0\n merchant_keyword: matchedMerchantKeyword,\n account_category: matchedAccountCategory,\n usage_count: matchedUsageCount,\n last_used_date: matchedLastUsedDate,\n confidence_score: matchedConfidenceScore\n }\n};"
},
"id": "account-matching-node",
"name": "\u52d8\u5b9a\u79d1\u76ee\u5224\u5b9a\uff08\u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u512a\u5148\uff09",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1850,
200
],
"notes": "\u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u30de\u30c3\u30c1\u30f3\u30b0 \u2192 AI\u63a8\u8ad6\u30d5\u30a9\u30fc\u30eb\u30d0\u30c3\u30af"
},
{
"parameters": {
"jsCode": "// \u52d8\u5b9a\u79d1\u76ee\u5224\u5b9a\u7d50\u679c\u3092\u53d6\u5f97\nconst judgmentResult = $input.item.json;\nconst userConfig = $('\u9867\u5ba2\u30de\u30b9\u30bf\u30fc\u53c2\u7167').item.json;\nconst fileId = $('Google Drive Upload').item.json.id;\nconst driveUrl = `https://drive.google.com/uc?export=view&id=${fileId}`;\n\n// \u7a0e\u533a\u5206\u306e\u5224\u5b9a\nlet taxType = \"\";\nif (judgmentResult.invoice_number && judgmentResult.invoice_number.startsWith('T')) {\n taxType = judgmentResult.tax_rate === 10 ? \"\u8ab210% \u30a4\u30f3\u30dc\u30a4\u30b9\" : \"\u8ab28% \u30a4\u30f3\u30dc\u30a4\u30b9\";\n} else {\n taxType = judgmentResult.tax_rate === 10 ? \"\u8ab210% \u533a\u5206\u8a18\u8f09\" : \"\u8ab28% \u533a\u5206\u8a18\u8f09\";\n}\n\n// \u4f1a\u8a08\u30bd\u30d5\u30c8\u5225CSV\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u751f\u6210\nlet csvRow = \"\";\nif (userConfig.accounting_soft === \"freee\") {\n csvRow = [\n judgmentResult.transaction_date,\n judgmentResult.category,\n judgmentResult.amount,\n taxType,\n \"\u73fe\u91d1\",\n judgmentResult.amount,\n `${judgmentResult.merchant}\uff08${judgmentResult.description}\uff09`,\n \"\"\n ].join(\",\");\n} else if (userConfig.accounting_soft === \"moneyforward\") {\n csvRow = [\n judgmentResult.transaction_date,\n judgmentResult.category,\n \"\",\n judgmentResult.amount,\n \"\u73fe\u91d1\",\n \"\",\n judgmentResult.amount,\n taxType,\n `${judgmentResult.merchant}\uff08${judgmentResult.description}\uff09`\n ].join(\",\");\n}\n\n// \u51fa\u529b\u30c7\u30fc\u30bf\nreturn {\n json: {\n // \u5224\u5b9a\u7d50\u679c\uff08\u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u307e\u305f\u306fAI\u63a8\u8ad6\uff09\n ...judgmentResult,\n // \u8ffd\u52a0\u60c5\u5831\n customer_name: userConfig.customer_name,\n tax_type: taxType,\n evidence_url: driveUrl,\n csv_row: csvRow,\n status: \"Review_Required\",\n processed_at: new Date().toISOString(),\n sheet_id: userConfig.sheet_id\n }\n};"
},
"id": "transform-data-node",
"name": "\u30c7\u30fc\u30bf\u5909\u63db\u30fbCSV\u751f\u6210",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2050,
200
],
"notes": "\u7a0e\u533a\u5206\u5224\u5b9a\u30fbCSV\u751f\u6210\uff08\u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u5224\u5b9a\u7d50\u679c\u3092\u4f7f\u7528\uff09"
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"value": "={{ $('\u9867\u5ba2\u30de\u30b9\u30bf\u30fc\u53c2\u7167').item.json.sheet_id }}",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "\u4ed5\u8a33\u53f0\u5e33",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"schema": [
{
"id": "\u53d6\u5f15No",
"displayName": "\u53d6\u5f15No",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u53d6\u5f15\u65e5",
"displayName": "\u53d6\u5f15\u65e5",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u501f\u65b9\u52d8\u5b9a\u79d1\u76ee",
"displayName": "\u501f\u65b9\u52d8\u5b9a\u79d1\u76ee",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u501f\u65b9\u88dc\u52a9\u79d1\u76ee",
"displayName": "\u501f\u65b9\u88dc\u52a9\u79d1\u76ee",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u501f\u65b9\u90e8\u9580",
"displayName": "\u501f\u65b9\u90e8\u9580",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u501f\u65b9\u53d6\u5f15\u5148",
"displayName": "\u501f\u65b9\u53d6\u5f15\u5148",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u501f\u65b9\u7a0e\u533a\u5206",
"displayName": "\u501f\u65b9\u7a0e\u533a\u5206",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u501f\u65b9\u30a4\u30f3\u30dc\u30a4\u30b9",
"displayName": "\u501f\u65b9\u30a4\u30f3\u30dc\u30a4\u30b9",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u501f\u65b9\u91d1\u984d(\u5186)",
"displayName": "\u501f\u65b9\u91d1\u984d(\u5186)",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u8cb8\u65b9\u52d8\u5b9a\u79d1\u76ee",
"displayName": "\u8cb8\u65b9\u52d8\u5b9a\u79d1\u76ee",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u8cb8\u65b9\u88dc\u52a9\u79d1\u76ee",
"displayName": "\u8cb8\u65b9\u88dc\u52a9\u79d1\u76ee",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u8cb8\u65b9\u90e8\u9580",
"displayName": "\u8cb8\u65b9\u90e8\u9580",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u8cb8\u65b9\u53d6\u5f15\u5148",
"displayName": "\u8cb8\u65b9\u53d6\u5f15\u5148",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u8cb8\u65b9\u7a0e\u533a\u5206",
"displayName": "\u8cb8\u65b9\u7a0e\u533a\u5206",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u8cb8\u65b9\u30a4\u30f3\u30dc\u30a4\u30b9",
"displayName": "\u8cb8\u65b9\u30a4\u30f3\u30dc\u30a4\u30b9",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u8cb8\u65b9\u91d1\u984d(\u5186)",
"displayName": "\u8cb8\u65b9\u91d1\u984d(\u5186)",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u6458\u8981",
"displayName": "\u6458\u8981",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u30bf\u30b0",
"displayName": "\u30bf\u30b0",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "\u30e1\u30e2",
"displayName": "\u30e1\u30e2",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
}
],
"value": {
"\u53d6\u5f15No": "={{ $now.format('yyyyMMddHHmmss') }}",
"\u53d6\u5f15\u65e5": "={{ $json.transaction_date }}",
"\u501f\u65b9\u52d8\u5b9a\u79d1\u76ee": "={{ $json.category }}",
"\u501f\u65b9\u88dc\u52a9\u79d1\u76ee": "",
"\u501f\u65b9\u90e8\u9580": "",
"\u501f\u65b9\u53d6\u5f15\u5148": "={{ $json.merchant }}",
"\u501f\u65b9\u7a0e\u533a\u5206": "={{ $json.tax_type }}",
"\u501f\u65b9\u30a4\u30f3\u30dc\u30a4\u30b9": "={{ $json.invoice_number || '' }}",
"\u501f\u65b9\u91d1\u984d(\u5186)": "={{ $json.amount }}",
"\u8cb8\u65b9\u52d8\u5b9a\u79d1\u76ee": "\u73fe\u91d1",
"\u8cb8\u65b9\u88dc\u52a9\u79d1\u76ee": "",
"\u8cb8\u65b9\u90e8\u9580": "",
"\u8cb8\u65b9\u53d6\u5f15\u5148": "",
"\u8cb8\u65b9\u7a0e\u533a\u5206": "",
"\u8cb8\u65b9\u30a4\u30f3\u30dc\u30a4\u30b9": "",
"\u8cb8\u65b9\u91d1\u984d(\u5186)": "={{ $json.amount }}",
"\u6458\u8981": "={{ $json.merchant }}\uff08{{ $json.description || 'OCR\u81ea\u52d5\u51e6\u7406' }}\uff09",
"\u30bf\u30b0": "={{ $json.match_source === 'knowledge_base' ? '\u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9' : 'AI\u63a8\u8ad6' }}",
"\u30e1\u30e2": "={{ $json.evidence_url }} | Status: {{ $json.status }}"
},
"matchingColumns": []
},
"options": {}
},
"id": "append-sheet-node",
"name": "\u9867\u5ba2\u53f0\u5e33\u3078\u8a18\u5e33",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.4,
"position": [
2250,
200
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "\u9867\u5ba2\u5225\u30b9\u30d7\u30ec\u30c3\u30c9\u30b7\u30fc\u30c8\u306b\u884c\u8ffd\u52a0"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "condition-kb-match",
"leftValue": "={{ $json.match_source }}",
"rightValue": "knowledge_base",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"id": "if-kb-match-node",
"name": "IF \u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u30de\u30c3\u30c1",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
2450,
200
],
"notes": "\u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u30de\u30c3\u30c1\u306e\u5834\u5408\u306e\u307f\u4f7f\u7528\u30c7\u30fc\u30bf\u66f4\u65b0"
},
{
"parameters": {
"operation": "update",
"documentId": {
"__rl": true,
"value": "={{ $json.sheet_id }}",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "\u52d8\u5b9a\u79d1\u76ee\u30de\u30b9\u30bf\u30fc",
"mode": "name"
},
"columns": {
"mappingMode": "defineBelow",
"schema": [
{
"id": "merchant_keyword",
"displayName": "merchant_keyword",
"required": false,
"defaultMatch": true,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "account_category",
"displayName": "account_category",
"required": false,
"defaultMatch": true,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "usage_count",
"displayName": "usage_count",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "last_used_date",
"displayName": "last_used_date",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
},
{
"id": "confidence_score",
"displayName": "confidence_score",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": false
}
],
"value": {
"merchant_keyword": "={{ $json.merchant_keyword }}",
"account_category": "={{ $json.account_category }}",
"usage_count": "={{ parseInt($json.usage_count || 0) + 1 }}",
"last_used_date": "={{ $now.format('yyyy-MM-dd') }}",
"confidence_score": "={{ Math.min(100, parseInt($json.confidence_score || 0) + 5) }}"
},
"matchingColumns": [
"merchant_keyword",
"account_category"
]
},
"options": {
"range": "={{ 'A' + $json.matched_row_id + ':H' + $json.matched_row_id }}"
}
},
"id": "update-kb-usage-node",
"name": "\u4f7f\u7528\u30c7\u30fc\u30bf\u66f4\u65b0",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.4,
"position": [
2650,
200
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"notes": "usage_count +1, last_used_date\u66f4\u65b0, confidence_score +5"
},
{
"parameters": {
"jsCode": "// \u30c7\u30fc\u30bf\u5909\u63db\u30ce\u30fc\u30c9\u304b\u3089\u53d6\u5f97\u3057\u305f\u30c7\u30fc\u30bf\nconst data = $('\u30c7\u30fc\u30bf\u5909\u63db\u30fbCSV\u751f\u6210').item.json;\nconst userId = $('Execute Workflow Trigger').item.json.body.events[0].source.userId;\n\n// undefined/null\u5024\u3092\u9069\u5207\u306b\u51e6\u7406\u3057\u3066\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u69cb\u7bc9\nconst formatValue = (value, defaultText = '\uff08\u672a\u53d6\u5f97\uff09') => {\n return (value !== null && value !== undefined && value !== '') ? value : defaultText;\n};\n\nconst formatAmount = (amount) => {\n if (amount !== null && amount !== undefined) {\n return '\u00a5' + Number(amount).toLocaleString('ja-JP');\n }\n return '\uff08\u672a\u53d6\u5f97\uff09';\n};\n\n// \u5224\u5b9a\u5143\u3092\u8868\u793a\nconst matchInfo = data.match_source === 'knowledge_base' \n ? `\\n\\n\u5224\u5b9a\u5143: \u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\uff08\u4fe1\u983c\u5ea6: ${data.matched_confidence}%\uff09`\n : '\\n\\n\u5224\u5b9a\u5143: AI\u63a8\u8ad6';\n\n// LINE API\u30ea\u30af\u30a8\u30b9\u30c8\u30dc\u30c7\u30a3\u3092\u69cb\u7bc9\nconst lineMessage = {\n to: userId,\n messages: [\n {\n type: 'text',\n text: `\u9818\u53ce\u66f8\u3092\u51e6\u7406\u3057\u307e\u3057\u305f\u2705\n\n\u3010\u51e6\u7406\u5185\u5bb9\u3011\n\u65e5\u4ed8: ${formatValue(data.transaction_date)}\n\u652f\u6255\u5148: ${formatValue(data.merchant)}\n\u91d1\u984d: ${formatAmount(data.amount)}\n\u79d1\u76ee: ${formatValue(data.category)}${matchInfo}\n\n\u8a3c\u6191: ${formatValue(data.evidence_url, '\uff08\u30ea\u30f3\u30af\u306a\u3057\uff09')}`\n }\n ]\n};\n\nreturn {\n json: {\n lineRequestBody: lineMessage\n }\n};"
},
"id": "build-line-message-node",
"name": "LINE\u8fd4\u4fe1\u30e1\u30c3\u30bb\u30fc\u30b8\u69cb\u7bc9",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2850,
200
],
"notes": "\u5224\u5b9a\u5143\uff08\u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9/AI\uff09\u3092\u542b\u3080\u30e1\u30c3\u30bb\u30fc\u30b8\u69cb\u7bc9"
},
{
"parameters": {
"method": "POST",
"url": "https://api.line.me/v2/bot/message/push",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json.lineRequestBody }}",
"options": {}
},
"id": "line-reply-success",
"name": "LINE\u8fd4\u4fe1\uff08\u6210\u529f\uff09",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
3050,
200
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"notes": "\u51e6\u7406\u5b8c\u4e86\u3092LINE\u3067\u901a\u77e5"
},
{
"parameters": {
"method": "POST",
"url": "https://api.line.me/v2/bot/message/push",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ {\n \"to\": $('Execute Workflow Trigger').item.json.body.events[0].source.userId,\n \"messages\": [\n {\n \"type\": \"text\",\n \"text\": \"\u3054\u767b\u9332\u3042\u308a\u304c\u3068\u3046\u3054\u3056\u3044\u307e\u3059\u3002\\n\\n\u73fe\u5728\u3001\u7ba1\u7406\u8005\u304c\u8a2d\u5b9a\u4e2d\u3067\u3059\u3002\\n\u3057\u3070\u3089\u304f\u304a\u5f85\u3061\u304f\u3060\u3055\u3044\u3002\\n\\n\u8a2d\u5b9a\u5b8c\u4e86\u5f8c\u3001\u9818\u53ce\u66f8\u753b\u50cf\u3092\u9001\u4fe1\u3044\u305f\u3060\u3051\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002\"\n }\n ]\n} }}",
"options": {}
},
"id": "line-reply-user-error",
"name": "LINE\u8fd4\u4fe1\uff08\u8a2d\u5b9a\u5f85\u3061\uff09",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
850,
400
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"notes": "\u4eee\u767b\u9332\u30e6\u30fc\u30b6\u30fc\uff08\u8a2d\u5b9a\u672a\u5b8c\u4e86\uff09\u3078\u306e\u901a\u77e5"
}
],
"connections": {
"Execute Workflow Trigger": {
"main": [
[
{
"node": "\u9867\u5ba2\u30de\u30b9\u30bf\u30fc\u53c2\u7167",
"type": "main",
"index": 0
}
]
]
},
"\u9867\u5ba2\u30de\u30b9\u30bf\u30fc\u53c2\u7167": {
"main": [
[
{
"node": "IF \u8a2d\u5b9a\u5b8c\u4e86",
"type": "main",
"index": 0
}
]
]
},
"IF \u8a2d\u5b9a\u5b8c\u4e86": {
"main": [
[
{
"node": "Get LINE Image",
"type": "main",
"index": 0
}
],
[
{
"node": "LINE\u8fd4\u4fe1\uff08\u8a2d\u5b9a\u5f85\u3061\uff09",
"type": "main",
"index": 0
}
]
]
},
"Get LINE Image": {
"main": [
[
{
"node": "Google Drive Upload",
"type": "main",
"index": 0
}
]
]
},
"Google Drive Upload": {
"main": [
[
{
"node": "Google Drive Download",
"type": "main",
"index": 0
}
]
]
},
"Google Drive Download": {
"main": [
[
{
"node": "OCR\u30ea\u30af\u30a8\u30b9\u30c8\u69cb\u7bc9",
"type": "main",
"index": 0
}
]
]
},
"OCR\u30ea\u30af\u30a8\u30b9\u30c8\u69cb\u7bc9": {
"main": [
[
{
"node": "AI-OCR\u51e6\u7406\uff08GPT-4o\uff09",
"type": "main",
"index": 0
}
]
]
},
"AI-OCR\u51e6\u7406\uff08GPT-4o\uff09": {
"main": [
[
{
"node": "\u52d8\u5b9a\u79d1\u76ee\u30de\u30b9\u30bf\u30fc\u53d6\u5f97",
"type": "main",
"index": 0
}
]
]
},
"\u52d8\u5b9a\u79d1\u76ee\u30de\u30b9\u30bf\u30fc\u53d6\u5f97": {
"main": [
[
{
"node": "\u52d8\u5b9a\u79d1\u76ee\u5224\u5b9a\uff08\u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u512a\u5148\uff09",
"type": "main",
"index": 0
}
]
]
},
"\u52d8\u5b9a\u79d1\u76ee\u5224\u5b9a\uff08\u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u512a\u5148\uff09": {
"main": [
[
{
"node": "\u30c7\u30fc\u30bf\u5909\u63db\u30fbCSV\u751f\u6210",
"type": "main",
"index": 0
}
]
]
},
"\u30c7\u30fc\u30bf\u5909\u63db\u30fbCSV\u751f\u6210": {
"main": [
[
{
"node": "\u9867\u5ba2\u53f0\u5e33\u3078\u8a18\u5e33",
"type": "main",
"index": 0
}
]
]
},
"\u9867\u5ba2\u53f0\u5e33\u3078\u8a18\u5e33": {
"main": [
[
{
"node": "IF \u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u30de\u30c3\u30c1",
"type": "main",
"index": 0
}
]
]
},
"IF \u30ca\u30ec\u30c3\u30b8\u30d9\u30fc\u30b9\u30de\u30c3\u30c1": {
"main": [
[
{
"node": "\u4f7f\u7528\u30c7\u30fc\u30bf\u66f4\u65b0",
"type": "main",
"index": 0
}
],
[
{
"node": "LINE\u8fd4\u4fe1\u30e1\u30c3\u30bb\u30fc\u30b8\u69cb\u7bc9",
"type": "main",
"index": 0
}
]
]
},
"\u4f7f\u7528\u30c7\u30fc\u30bf\u66f4\u65b0": {
"main": [
[
{
"node": "LINE\u8fd4\u4fe1\u30e1\u30c3\u30bb\u30fc\u30b8\u69cb\u7bc9",
"type": "main",
"index": 0
}
]
]
},
"LINE\u8fd4\u4fe1\u30e1\u30c3\u30bb\u30fc\u30b8\u69cb\u7bc9": {
"main": [
[
{
"node": "LINE\u8fd4\u4fe1\uff08\u6210\u529f\uff09",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [
{
"name": "LINE Bot",
"id": "line-bot"
}
],
"triggerCount": 0,
"updatedAt": "2026-01-19T15:00:00.000Z",
"versionId": "1"
}
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.
googleDriveOAuth2ApigoogleSheetsOAuth2ApihttpHeaderAuthopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
LINE Image Handler. Uses executeWorkflowTrigger, googleSheets, httpRequest, googleDrive. Event-driven trigger; 17 nodes.
Source: https://github.com/AI-LandBase/landbase_ai_suite/blob/main/n8n/workflows/line-image-handler.json — 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.
Intelligent URL Validation - Validates PDF URLs before attempting download, extracting filenames from URLs and generating fallback names when needed, preventing wasted processing time Binary File Hand
PCN. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, itemLists. Event-driven trigger; 60 nodes.
The workflow automates the process of gathering extensive keyword data for a "Main Keyword." It starts by reading initial parameters from a Google Sheets template, creates a new dedicated Google Sheet
🔥 March Sale – n8n Community Members Get ideoGener8r for Just $27! (Reg. $47) Use Coupon Code: (Valid until 3/31/2025 for n8n community members)
📄 Documentation: Notion Guide