Exportar n8n
Este es unPersonal Productivity, Multimodal AIflujo de automatización del dominio deautomatización que contiene 17 nodos.Utiliza principalmente nodos como If, Set, Code, Switch, Webhook. Registrar calorías de alimentos de imágenes en Google Sheets usando LINE y OpenAI Vision
- •Punto final de HTTP Webhook (n8n generará automáticamente)
- •Pueden requerirse credenciales de autenticación para la API de destino
- •Credenciales de API de Google Sheets
- •Clave de API de OpenAI
Nodos utilizados (17)
Categoría
{
"id": "HzZvyjb6riqHb2FR",
"meta": {
"instanceId": "9101df148a9ab5ba09dd343a0c584806dbd6c3b74e74be8e97699184269b6877"
},
"name": "export n8n",
"tags": [],
"nodes": [
{
"id": "74a3253b-68d1-4745-85a1-70f5fa3260a9",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
-592,
48
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "80b1a421-efcd-487e-8c18-925496da9b0c",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.body.events[0].message.type }}",
"rightValue": "text"
}
]
}
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "c124e4cd-78b0-4ce1-bf72-26806f7211e8",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.body.events[0].message.type }}",
"rightValue": "image"
}
]
}
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"typeVersion": 3.2
},
{
"id": "adf17e8b-4e45-4ad4-90e9-208b5bf6207f",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
160,
-160
],
"parameters": {
"text": "={{ $json.text }}",
"options": {
"systemMessage": "=You are an AI assistant. Your job is to respond to user messages."
},
"promptType": "define"
},
"typeVersion": 2.1
},
{
"id": "ef15eb25-64d9-4c30-becc-7f338d46ce55",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
32,
48
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"id": "mO23EZGRXh9cFi9G",
"name": "OpenAi account 2"
}
},
"typeVersion": 1.2
},
{
"id": "17e136f4-34f7-42c8-9793-19d13610aa49",
"name": "Analizar imagen",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
-96,
272
],
"parameters": {
"text": "=Estimate calories only if the item in this image is a food item, and output the calories in the following simple JSON format:\n\n[{\n\"dishName\": \"result\",\n\"calories\": \"result\",\n}]\n\nDo not output anything but this JSON only if it is food.",
"modelId": {
"__rl": true,
"mode": "list",
"value": "chatgpt-4o-latest",
"cachedResultName": "CHATGPT-4O-LATEST"
},
"options": {},
"resource": "image",
"inputType": "base64",
"operation": "analyze"
},
"credentials": {
"openAiApi": {
"id": "mO23EZGRXh9cFi9G",
"name": "OpenAi account 2"
}
},
"typeVersion": 1.8
},
{
"id": "0359b260-8639-475b-8d47-cc76e004f027",
"name": "Editar campos1",
"type": "n8n-nodes-base.set",
"position": [
576,
272
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6e9a99a3-62b1-4121-b7d7-148eaebbe9ba",
"name": "output",
"type": "string",
"value": "={{ $json.message }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "0535be0a-4aac-48a8-8909-41abca4944a0",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
176,
48
],
"parameters": {
"sessionKey": "={{ $('LINE webhook').item.json.body.events[0].source.userId }}",
"sessionIdType": "customKey"
},
"typeVersion": 1.3
},
{
"id": "2851ca68-76c5-4b97-910d-2d4fa729754f",
"name": "Code",
"type": "n8n-nodes-base.code",
"position": [
352,
608
],
"parameters": {
"jsCode": "const inputData = $input.all();\nconst results = [];\n\nfor (let i = 0; i < inputData.length; i++) {\n try {\n\n let aiResponse = inputData[i].json.output || inputData[i].json.text || inputData[i].json.content || '';\n \n if (!aiResponse) {\n console.log(`アイテム ${i}: 空の応答をスキップ`);\n continue;\n }\n \n // 文字列の前後の空白を削除\n aiResponse = aiResponse.trim();\n \n // JSONの前後にある不要なテキストを削除\n // ```json や ``` で囲まれている場合の処理\n if (aiResponse.includes('```json')) {\n const jsonStart = aiResponse.indexOf('```json') + 7;\n const jsonEnd = aiResponse.indexOf('```', jsonStart);\n if (jsonEnd !== -1) {\n aiResponse = aiResponse.substring(jsonStart, jsonEnd).trim();\n }\n } else if (aiResponse.includes('```')) {\n const jsonStart = aiResponse.indexOf('```') + 3;\n const jsonEnd = aiResponse.indexOf('```', jsonStart);\n if (jsonEnd !== -1) {\n aiResponse = aiResponse.substring(jsonStart, jsonEnd).trim();\n }\n }\n \n // JSONの開始と終了を見つける\n const jsonStartIndex = aiResponse.indexOf('[');\n const jsonEndIndex = aiResponse.lastIndexOf(']');\n \n if (jsonStartIndex !== -1 && jsonEndIndex !== -1 && jsonEndIndex > jsonStartIndex) {\n const jsonString = aiResponse.substring(jsonStartIndex, jsonEndIndex + 1);\n \n try {\n // JSONをパース\n const parsedData = JSON.parse(jsonString);\n \n // 配列でない場合は配列に変換\n const dataArray = Array.isArray(parsedData) ? parsedData : [parsedData];\n \n // 各アイテムを処理\n dataArray.forEach((item, index) => {\n // 必要なフィールドが存在することを確認\n if (item && typeof item === 'object') {\n const processedItem = {\n dishName: item.dishName || item.dish_name || item.name || 'Unknown',\n calories: item.calories || item.calorie || item.cal || 0,\n // 元のデータも保持(デバッグ用)\n originalIndex: i,\n itemIndex: index,\n timestamp: new Date().toISOString()\n };\n \n // カロリーが数値でない場合は数値に変換を試行\n if (typeof processedItem.calories === 'string') {\n const numericCalories = parseInt(processedItem.calories.replace(/[^\\d]/g, ''));\n processedItem.calories = isNaN(numericCalories) ? 0 : numericCalories;\n }\n \n results.push({ json: processedItem });\n }\n });\n \n } catch (parseError) {\n console.log(`アイテム ${i}: JSON解析エラー - ${parseError.message}`);\n console.log(`問題のあるJSON文字列: ${jsonString}`);\n \n // JSONが無効な場合でも、手動でデータを抽出を試行\n const manualExtract = extractDataManually(aiResponse);\n if (manualExtract) {\n results.push({ json: manualExtract });\n }\n }\n } else {\n console.log(`アイテム ${i}: 有効なJSON構造が見つかりません`);\n \n // 手動でデータを抽出を試行\n const manualExtract = extractDataManually(aiResponse);\n if (manualExtract) {\n results.push({ json: manualExtract });\n }\n }\n \n } catch (error) {\n console.log(`アイテム ${i}: 処理エラー - ${error.message}`);\n \n // エラーが発生した場合でもデフォルト値で処理を継続\n results.push({\n json: {\n dishName: 'Error',\n calories: 0,\n error: error.message,\n originalIndex: i,\n timestamp: new Date().toISOString()\n }\n });\n }\n}\n\n// 手動でデータを抽出する関数\nfunction extractDataManually(text) {\n try {\n const dishMatch = text.match(/\"dishName\"\\s*:\\s*\"([^\"]+)\"/i) || \n text.match(/\"dish_name\"\\s*:\\s*\"([^\"]+)\"/i) ||\n text.match(/\"name\"\\s*:\\s*\"([^\"]+)\"/i);\n \n const caloriesMatch = text.match(/\"calories\"\\s*:\\s*\"?(\\d+)\"?/i) ||\n text.match(/\"calorie\"\\s*:\\s*\"?(\\d+)\"?/i) ||\n text.match(/\"cal\"\\s*:\\s*\"?(\\d+)\"?/i);\n \n if (dishMatch || caloriesMatch) {\n return {\n dishName: dishMatch ? dishMatch[1] : 'Unknown',\n calories: caloriesMatch ? parseInt(caloriesMatch[1]) : 0,\n extractedManually: true,\n timestamp: new Date().toISOString()\n };\n }\n } catch (error) {\n console.log('手動抽出エラー:', error.message);\n }\n return null;\n}\n\n// 結果が空の場合のデフォルト処理\nif (results.length === 0) {\n console.log('処理可能なデータが見つかりませんでした');\n results.push({\n json: {\n dishName: 'No Data',\n calories: 0,\n error: 'No valid data found',\n timestamp: new Date().toISOString()\n }\n });\n}\n\nconsole.log(`処理完了: ${results.length} 件のアイテムを変換しました`);\nreturn results;"
},
"typeVersion": 2
},
{
"id": "bff30c01-da43-463d-940e-b396d8237c61",
"name": "Agregar fila en hoja",
"type": "n8n-nodes-base.googleSheets",
"position": [
608,
608
],
"parameters": {
"columns": {
"value": {
"cal": "={{ $json.calories }}",
"date": "={{ $now.format('yyyy-MM-dd') }}",
"menu": "={{ $json.dishName }}"
},
"schema": [
{
"id": "date",
"type": "string",
"display": true,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "menu",
"type": "string",
"display": true,
"required": false,
"displayName": "menu",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "cal",
"type": "string",
"display": true,
"required": false,
"displayName": "cal",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1178520345,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1upzLlUvmXYgALLtUR6WEHUtxh064mDNrBVM-b3Of_vg/edit#gid=1178520345",
"cachedResultName": "11_test"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1upzLlUvmXYgALLtUR6WEHUtxh064mDNrBVM-b3Of_vg",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1upzLlUvmXYgALLtUR6WEHUtxh064mDNrBVM-b3Of_vg/edit?usp=drivesdk",
"cachedResultName": "kote2 n8n sheet"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "XH1Umk2FssMX8K1X",
"name": "Google Sheets account"
}
},
"typeVersion": 4.6
},
{
"id": "1bf7ef0f-1e8d-4e61-b3bd-aaaefcf15366",
"name": "Code1",
"type": "n8n-nodes-base.code",
"position": [
352,
272
],
"parameters": {
"jsCode": "// n8n Code node - AIエージェントからのJSON文字列をLINEメッセージに変換\nconst inputData = $input.all();\nconst results = [];\n\nfor (let i = 0; i < inputData.length; i++) {\n try {\n // AIエージェントからの出力を取得\n let aiResponse = inputData[i].json.output || inputData[i].json.text || inputData[i].json.content || '';\n \n // 空の場合はスキップ\n if (!aiResponse) {\n console.log(`アイテム ${i}: 空の応答をスキップ`);\n continue;\n }\n \n // 文字列の前後の空白を削除\n aiResponse = aiResponse.trim();\n \n // JSONデータを抽出する\n const menuItems = extractMenuData(aiResponse);\n \n if (menuItems && menuItems.length > 0) {\n // LINEメッセージを生成\n const lineMessage = generateLineMessage(menuItems);\n \n results.push({\n json: {\n message: lineMessage,\n menuCount: menuItems.length,\n totalCalories: menuItems.reduce((sum, item) => sum + item.calories, 0),\n timestamp: new Date().toISOString(),\n originalIndex: i\n }\n });\n \n console.log(`アイテム ${i}: ${menuItems.length}個のメニューを処理しました`);\n } else {\n // 食品が検出されなかった場合\n results.push({\n json: {\n message: \"画像から食品を検出できませんでした。\",\n menuCount: 0,\n totalCalories: 0,\n timestamp: new Date().toISOString(),\n originalIndex: i\n }\n });\n \n console.log(`アイテム ${i}: 食品が検出されませんでした`);\n }\n \n } catch (error) {\n console.log(`アイテム ${i}: 処理エラー - ${error.message}`);\n \n // エラーが発生した場合のデフォルトメッセージ\n results.push({\n json: {\n message: \"画像の解析でエラーが発生しました。もう一度お試しください。\",\n menuCount: 0,\n totalCalories: 0,\n error: error.message,\n timestamp: new Date().toISOString(),\n originalIndex: i\n }\n });\n }\n}\n\n// JSONデータを抽出する関数\nfunction extractMenuData(text) {\n const menuItems = [];\n \n try {\n // JSONの前後にある不要なテキストを削除\n let cleanText = text;\n \n // ```json や ``` で囲まれている場合の処理\n if (cleanText.includes('```json')) {\n const jsonStart = cleanText.indexOf('```json') + 7;\n const jsonEnd = cleanText.indexOf('```', jsonStart);\n if (jsonEnd !== -1) {\n cleanText = cleanText.substring(jsonStart, jsonEnd).trim();\n }\n } else if (cleanText.includes('```')) {\n const jsonStart = cleanText.indexOf('```') + 3;\n const jsonEnd = cleanText.indexOf('```', jsonStart);\n if (jsonEnd !== -1) {\n cleanText = cleanText.substring(jsonStart, jsonEnd).trim();\n }\n }\n \n // JSONの開始と終了を見つける\n const jsonStartIndex = cleanText.indexOf('[');\n const jsonEndIndex = cleanText.lastIndexOf(']');\n \n if (jsonStartIndex !== -1 && jsonEndIndex !== -1 && jsonEndIndex > jsonStartIndex) {\n const jsonString = cleanText.substring(jsonStartIndex, jsonEndIndex + 1);\n \n try {\n // JSONをパース\n const parsedData = JSON.parse(jsonString);\n \n // 配列でない場合は配列に変換\n const dataArray = Array.isArray(parsedData) ? parsedData : [parsedData];\n \n // 各アイテムを処理\n dataArray.forEach((item) => {\n if (item && typeof item === 'object') {\n const dishName = item.dishName || item.dish_name || item.name || 'Unknown';\n let calories = item.calories || item.calorie || item.cal || 0;\n \n // カロリーが文字列の場合は数値に変換\n if (typeof calories === 'string') {\n const numericCalories = parseInt(calories.replace(/[^\\d]/g, ''));\n calories = isNaN(numericCalories) ? 0 : numericCalories;\n }\n \n // 有効なデータのみ追加\n if (dishName !== 'Unknown' && calories > 0) {\n menuItems.push({\n dishName: dishName,\n calories: calories\n });\n }\n }\n });\n \n } catch (parseError) {\n console.log('JSON解析エラー:', parseError.message);\n // 手動でデータを抽出を試行\n const manualExtract = extractDataManually(text);\n if (manualExtract) {\n menuItems.push(manualExtract);\n }\n }\n } else {\n // 手動でデータを抽出を試行\n const manualExtract = extractDataManually(text);\n if (manualExtract) {\n menuItems.push(manualExtract);\n }\n }\n \n } catch (error) {\n console.log('データ抽出エラー:', error.message);\n }\n \n return menuItems;\n}\n\n// 手動でデータを抽出する関数\nfunction extractDataManually(text) {\n try {\n const dishMatch = text.match(/\"dishName\"\\s*:\\s*\"([^\"]+)\"/i) || \n text.match(/\"dish_name\"\\s*:\\s*\"([^\"]+)\"/i) ||\n text.match(/\"name\"\\s*:\\s*\"([^\"]+)\"/i);\n \n const caloriesMatch = text.match(/\"calories\"\\s*:\\s*\"?(\\d+)\"?/i) ||\n text.match(/\"calorie\"\\s*:\\s*\"?(\\d+)\"?/i) ||\n text.match(/\"cal\"\\s*:\\s*\"?(\\d+)\"?/i);\n \n if (dishMatch && caloriesMatch) {\n const calories = parseInt(caloriesMatch[1]);\n if (!isNaN(calories) && calories > 0) {\n return {\n dishName: dishMatch[1],\n calories: calories\n };\n }\n }\n } catch (error) {\n console.log('手動抽出エラー:', error.message);\n }\n return null;\n}\n\n// LINEメッセージを生成する関数\nfunction generateLineMessage(menuItems) {\n if (!menuItems || menuItems.length === 0) {\n return \"画像から食品を検出できませんでした。\";\n }\n \n let message = \"カロリー計算:\\n\";\n \n // 各メニューアイテムを追加\n menuItems.forEach((item) => {\n message += `・${item.dishName}(${item.calories}kcal)\\n`;\n });\n \n message += \"シートに記入しました\";\n \n return message;\n}\n\n// 結果が空の場合のデフォルト処理\nif (results.length === 0) {\n console.log('処理可能なデータが見つかりませんでした');\n results.push({\n json: {\n message: \"画像の処理でエラーが発生しました。もう一度お試しください。\",\n menuCount: 0,\n totalCalories: 0,\n timestamp: new Date().toISOString()\n }\n });\n}\n\nconsole.log(`LINE メッセージ生成完了: ${results.length} 件のメッセージを生成しました`);\nreturn results;"
},
"typeVersion": 2
},
{
"id": "56bfb625-6b6b-480d-a81d-55ad8a629c57",
"name": "LINE webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-1040,
144
],
"webhookId": "0980b700-284e-4e52-a33e-71e087eea37f",
"parameters": {
"path": "0980b700-284e-4e52-a33e-71e087eea37f",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2
},
{
"id": "9e59d336-a880-42aa-b69c-66b445208d1c",
"name": "verificación de usuario",
"type": "n8n-nodes-base.if",
"position": [
-800,
144
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "28c9bc55-ef1b-4fee-8c22-a48b88a82c34",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.body.events[0].source.userId }}",
"rightValue": "{your id}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "11ddcfb0-a2e8-4002-ba64-bff77a4bf066",
"name": "descarga de imágenes",
"type": "n8n-nodes-base.httpRequest",
"position": [
-368,
272
],
"parameters": {
"url": "=https://api-data.line.me/v2/bot/message/{{ $json.body.events[0].message.id }}/content",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer {channel access toaken}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "b40c936c-5273-493a-822f-36b44de906b3",
"name": "solo mensaje",
"type": "n8n-nodes-base.set",
"position": [
-128,
-160
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "8504cdbe-9904-4e83-aee9-362f02a25014",
"name": "text",
"type": "string",
"value": "={{ $json.body.events[0].message.text }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "599b110f-7771-4497-a41f-b231c3ebc3b8",
"name": "enviar LINE",
"type": "n8n-nodes-base.httpRequest",
"position": [
1184,
128
],
"parameters": {
"url": "https://api.line.me/v2/bot/message/reply",
"method": "POST",
"options": {},
"jsonBody": "={\n \"replyToken\": \"{{ $('LINE webhook').item.json.body.events[0].replyToken }}\",\n \"messages\": [\n {\n \"type\": \"text\",\n \"text\":{{ JSON.stringify($json.output) }}\n }\n ]\n} ",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer +pLP8YfaojvZ8MzTsryZHngxknOchb4z7RDnDKzh+n2QLxlZKm36+S2yc0WRNrNztHO98iNh1wa+4Vlo73PuRwIrK7q15L493jCEEbRiyv4OKzmHI5hX9PCssHyD9LRZlTdlDfF6M3Vg9Vs1zfAkRgdB04t89/1O/w1cDnyilFU="
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "978b63a0-fab0-445f-8f1b-0ab3b92f22b1",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1504,
-64
],
"parameters": {
"width": 368,
"height": 560,
"content": "## LINE Food Image Calorie Logger to Google Sheets\n\nThis workflow allows a LINE user to send either text or an image of food to a connected LINE bot.\n\n- **Text message** → The AI agent responds directly via LINE. \n- **Image message** → The workflow downloads it from LINE’s API, analyzes it using OpenAI’s Vision model, estimates calories **only if the image contains food**, and formats the result into JSON. \n- Detected dishes and calories are appended to a Google Sheet, and a confirmation message is sent back to the user via LINE.\n\n### Key Features\n- Integrates **LINE Messaging API** webhook with n8n\n- Uses **OpenAI Vision** to detect food and estimate calories\n- Automatically logs results into **Google Sheets**\n- Sends **real-time feedback** to the LINE user\n\n### How to Use\n1. Set up a LINE Messaging API channel and get your **channel access token**.\n2. Add your **OpenAI API credentials** in n8n.\n3. Replace placeholders for `{channel access token}`, `{your id}`, and **Google Sheet IDs** with your own.\n4. Activate the workflow and send a food image or text message to your LINE bot.\n"
},
"typeVersion": 1
},
{
"id": "78855553-f504-4ee0-913e-1b1c933f0cae",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
192
],
"parameters": {
"color": 4,
"width": 704,
"height": 272,
"content": "## message to LINE"
},
"typeVersion": 1
},
{
"id": "e2180426-a161-4483-a630-63eb54cf0d29",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
512
],
"parameters": {
"color": 3,
"width": 704,
"height": 272,
"content": "## write to Google Sheets"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "a7eb22fe-627c-4d1a-aaee-a05a9fb4eb81",
"connections": {
"2851ca68-76c5-4b97-910d-2d4fa729754f": {
"main": [
[
{
"node": "bff30c01-da43-463d-940e-b396d8237c61",
"type": "main",
"index": 0
}
]
]
},
"1bf7ef0f-1e8d-4e61-b3bd-aaaefcf15366": {
"main": [
[
{
"node": "0359b260-8639-475b-8d47-cc76e004f027",
"type": "main",
"index": 0
}
]
]
},
"74a3253b-68d1-4745-85a1-70f5fa3260a9": {
"main": [
[
{
"node": "b40c936c-5273-493a-822f-36b44de906b3",
"type": "main",
"index": 0
}
],
[
{
"node": "11ddcfb0-a2e8-4002-ba64-bff77a4bf066",
"type": "main",
"index": 0
}
]
]
},
"adf17e8b-4e45-4ad4-90e9-208b5bf6207f": {
"main": [
[
{
"node": "599b110f-7771-4497-a41f-b231c3ebc3b8",
"type": "main",
"index": 0
}
]
]
},
"0359b260-8639-475b-8d47-cc76e004f027": {
"main": [
[
{
"node": "599b110f-7771-4497-a41f-b231c3ebc3b8",
"type": "main",
"index": 0
}
]
]
},
"56bfb625-6b6b-480d-a81d-55ad8a629c57": {
"main": [
[
{
"node": "9e59d336-a880-42aa-b69c-66b445208d1c",
"type": "main",
"index": 0
}
]
]
},
"b40c936c-5273-493a-822f-36b44de906b3": {
"main": [
[
{
"node": "adf17e8b-4e45-4ad4-90e9-208b5bf6207f",
"type": "main",
"index": 0
}
]
]
},
"17e136f4-34f7-42c8-9793-19d13610aa49": {
"main": [
[
{
"node": "2851ca68-76c5-4b97-910d-2d4fa729754f",
"type": "main",
"index": 0
},
{
"node": "1bf7ef0f-1e8d-4e61-b3bd-aaaefcf15366",
"type": "main",
"index": 0
}
]
]
},
"0535be0a-4aac-48a8-8909-41abca4944a0": {
"ai_memory": [
[
{
"node": "adf17e8b-4e45-4ad4-90e9-208b5bf6207f",
"type": "ai_memory",
"index": 0
}
]
]
},
"11ddcfb0-a2e8-4002-ba64-bff77a4bf066": {
"main": [
[
{
"node": "17e136f4-34f7-42c8-9793-19d13610aa49",
"type": "main",
"index": 0
}
]
]
},
"ef15eb25-64d9-4c30-becc-7f338d46ce55": {
"ai_languageModel": [
[
{
"node": "adf17e8b-4e45-4ad4-90e9-208b5bf6207f",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"9e59d336-a880-42aa-b69c-66b445208d1c": {
"main": [
[
{
"node": "74a3253b-68d1-4745-85a1-70f5fa3260a9",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Avanzado - Productividad personal, IA Multimodal
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
kote2
@kote2I share practical examples and ideas for AI automation using tools like n8n, explained in a way that’s easy for beginners to understand. While Dify is currently more well-known in Japan, n8n complements it and is expected to gain even more attention in the future. This channel aims to be a practical guide you can rely on when that wave of popularity arrives. That said, I’m still learning too—so let’s learn and grow together!
Compartir este flujo de trabajo