Recipe Automation Agent
This automation connects Notion, n8n, and AI models to organize recipes from various sources such as Instagram, YouTube, or websites. Whenever a new recipe link is added to a Notion database, the workflow automatically fetches the data, processes it using AI, and updates the recipe details back into Notion.
The purpose of this system is to extract ingredients and cooking steps automatically and to make future recipe suggestions based on available stock.
Shared 10/18/2025
123 views
Visual Workflow
JSON Code
{
"id": "PSwyAVtpyXUqSDU7",
"meta": {
"instanceId": "a8ced73792eedbc811b791fd4b05fbcb0142673384f7b7af1a52521102638462",
"templateCredsSetupCompleted": true
},
"name": "Recipe Maker",
"tags": [],
"nodes": [
{
"id": "50af05c2-7fea-4b96-9881-b8c32022b2f1",
"name": "Notion Trigger",
"type": "n8n-nodes-base.notionTrigger",
"position": [
0,
64
],
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"databaseId": {
"__rl": true,
"mode": "list",
"value": "284b6999-95ca-80c0-af5f-cd735e81ebb4",
"cachedResultUrl": "https://www.notion.so/284b699995ca80c0af5fcd735e81ebb4",
"cachedResultName": "Recipe Box"
}
},
"credentials": {
"notionApi": {
"id": "2Dw53KPRH0ARdlpU",
"name": "Notion account"
}
},
"typeVersion": 1
},
{
"id": "eede649f-bc4c-4f42-a663-9449349b5c96",
"name": "Fetch Recipe Data",
"type": "n8n-nodes-base.httpRequest",
"position": [
672,
-32
],
"parameters": {
"url": "={{ $json.recipeLink }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "ff478590-595a-44f7-bbf8-b8ca0161b5fc",
"name": "Code in JavaScript",
"type": "n8n-nodes-base.code",
"position": [
224,
64
],
"parameters": {
"jsCode": "const url = $input.first().json.URL\n\nlet source = \"website\"; // default\nif(url.includes(\"youtube.com\") || url.includes(\"youtu.be\")){\n source = \"youtube\";\n} else if(url.includes(\"instagram.com\") || url.includes(\"insta\")){\n source = \"instagram\";\n}\n\nreturn { json: { recipeLink: url, source } };\n"
},
"typeVersion": 2
},
{
"id": "2f8be347-db09-4b7a-9153-ba766e95a60c",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
448,
48
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Website",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "6087019a-4331-40d1-bf78-6a74bc16a24a",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.source }}",
"rightValue": "website"
}
]
},
"renameOutput": true
},
{
"outputKey": "Instagram",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8c3867ee-eed2-445f-9cd3-0921807f61b8",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.source }}",
"rightValue": "instagram"
}
]
},
"renameOutput": true
},
{
"outputKey": "Youtube",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "60d165bf-6373-44ab-a750-91537c53d35e",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.source }}",
"rightValue": "Youtube"
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "1c67a80d-aaf9-41e1-8a63-acb92b5a9fc4",
"name": "Code in JavaScript1",
"type": "n8n-nodes-base.code",
"position": [
896,
-32
],
"parameters": {
"jsCode": "// Get raw HTML from previous HTTP Request node\nlet html = $input.first().json.data ;\n\n// 1️⃣ Remove scripts and styles\nhtml = html.replace(/<script[\\s\\S]*?<\\/script>/gi, \"\")\n .replace(/<style[\\s\\S]*?<\\/style>/gi, \"\");\n\n// 2️⃣ Remove all remaining HTML tags\nlet text = html.replace(/<\\/?[^>]+(>|$)/g, \"\");\n\n// 3️⃣ Decode HTML entities (optional, like & → &)\ntext = text.replace(/ /gi, \" \")\n .replace(/&/gi, \"&\")\n .replace(/"/gi, '\"')\n .replace(/</gi, \"<\")\n .replace(/>/gi, \">\");\n\n// 4️⃣ Replace multiple spaces / newlines with a single space\ntext = text.replace(/\\s+/g, \" \").trim();\n\n// 5️⃣ Optional: truncate to avoid OpenAI 400 error\nconst maxLength = 15000; // safe limit\nif(text.length > maxLength){\n text = text.slice(0, maxLength);\n}\n\n// Return clean text\nreturn {\n json: {\n recipeText: text\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "ae5ac921-4071-4cf8-ab62-79e2532e58fb",
"name": "Message a model",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1120,
-32
],
"parameters": {
"text": "=You are an expert recipe analyzer.\nWhen given recipe text in the format of {{ $json.recipeText }}, return a JSON with:\n{\n \"ingredients\": [\"ingredient1\", \"ingredient2\", ...],\n \"steps\": [\"step1\", \"step2\", ...]\n}\nOnly return valid JSON.",
"prompt": "define",
"options": {},
"resource": "assistant",
"assistantId": {
"__rl": true,
"mode": "list",
"value": "asst_rTAdF9JiE96dkuoUP9DElMss",
"cachedResultName": "Recipe"
}
},
"credentials": {
"openAiApi": {
"id": "nBo5e7FgPo3rjkxs",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "bc8d4806-7a25-4c47-84b0-671419ae5f6c",
"name": "Code in JavaScript2",
"type": "n8n-nodes-base.code",
"position": [
1472,
-32
],
"parameters": {
"jsCode": "const raw = $input.first().json.output;\nreturn JSON.parse(raw);\n"
},
"typeVersion": 2
},
{
"id": "0a15d6f3-a19d-48a6-ba9f-2ec2ed7ed07f",
"name": "Update a database page",
"type": "n8n-nodes-base.notion",
"position": [
1696,
-32
],
"parameters": {
"pageId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Notion Trigger').item.json.id }}"
},
"options": {},
"resource": "databasePage",
"operation": "update",
"propertiesUi": {
"propertyValues": [
{
"key": "Ingredients|rich_text",
"text": {
"text": [
{
"text": "={{ $json.ingredients.map(i => \"• \" + i).join(\"\\n\") }}",
"annotationUi": {}
}
]
},
"richText": true
},
{
"key": "Steps|rich_text",
"text": {
"text": [
{
"text": "={{ $json.steps.join(\", \") }}",
"annotationUi": {}
}
]
},
"richText": true
}
]
}
},
"credentials": {
"notionApi": {
"id": "2Dw53KPRH0ARdlpU",
"name": "Notion account"
}
},
"typeVersion": 2.2
},
{
"id": "11b177fb-0684-412f-93a9-5ac926a4131a",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"position": [
672,
144
],
"parameters": {
"url": "=https://instagram120.p.rapidapi.com/api/instagram/mediaByShortcode",
"method": "POST",
"options": {},
"jsonBody": "={\n \"shortcode\": \"{{$json.recipeLink.split('/reel/')[1].split('/')[0]}}\"\n}\n",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "x-rapidapi-host",
"value": "instagram120.p.rapidapi.com"
},
{
"name": "x-rapidapi-key",
"value": "a565e031d8msh03f957b3f305a18p165b5fjsn8f5c6b1ac812"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "da9909d5-3e3e-48bc-b365-3ce225eeca91",
"name": "Code in JavaScript3",
"type": "n8n-nodes-base.code",
"position": [
880,
144
],
"parameters": {
"jsCode": "return {\n json: {\n caption: $input.first().json.meta.title|| \"\",\n videoUrl: $input.first().json.urls[0]|| \"\",\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "c553f2ff-b9cd-4339-9b60-5c3ea20d87ff",
"name": "Message a model1",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1088,
144
],
"parameters": {
"text": "={\n \"parameters\": {\n \"resource\": \"assistant\",\n \"operation\": \"messageAssistant\",\n \"assistantId\": \"YOUR_ASSISTANT_ID\",\n \"source\": \"connectedTriggerNode\",\n \"memory\": false,\n \"inputText\": \"Extract ingredients and steps from this content:\\n\\nVideo URL:{{ $json.videoUrl }} \\nCaption/Text: {{ $json.caption }}\"\n },\n \"name\": \"Extract Ingredients & Steps\",\n \"type\": \"n8n-nodes-base.openAi\",\n \"typeVersion\": 1,\n \"position\": [900, 400]\n}\n\nIf you cannot analyze the video or find no valid content, return as ingredients and steps can't fetch.\n",
"prompt": "define",
"options": {},
"resource": "assistant",
"assistantId": {
"__rl": true,
"mode": "list",
"value": "asst_QFJUX0nStBU7co6hg33iTlGM",
"cachedResultName": "Instagram recipe"
}
},
"credentials": {
"openAiApi": {
"id": "nBo5e7FgPo3rjkxs",
"name": "OpenAi account"
}
},
"typeVersion": 1.8
},
{
"id": "945c2c44-9a20-4175-b182-67c251327b40",
"name": "Code in JavaScript4",
"type": "n8n-nodes-base.code",
"position": [
1440,
144
],
"parameters": {
"jsCode": "// Get the raw output from the previous node\nconst raw = $input.first().json.output;\n\n// Parse it into a proper object\nconst data = JSON.parse(raw);\n\n// Convert ingredients and steps arrays into strings\nconst ingredientsText = data.ingredients.join(\"\\n\"); // each ingredient on a new line\nconst stepsText = data.steps.join(\"\\n\"); // each step on a new line\n\n// Return the final object to pass to Notion\nreturn [\n {\n json: {\n ingredients: ingredientsText,\n steps: stepsText,\n summary: data.summary,\n labels: data.labels\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "98ba4cd8-a9d7-41de-9532-7e47c7fffeb8",
"name": "Update a database page1",
"type": "n8n-nodes-base.notion",
"position": [
1648,
144
],
"parameters": {
"pageId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Notion Trigger').item.json.id }}"
},
"options": {},
"resource": "databasePage",
"operation": "update",
"propertiesUi": {
"propertyValues": [
{
"key": "Ingredients|rich_text",
"text": {
"text": [
{
"text": "={{ $json.ingredients }}",
"annotationUi": {}
}
]
},
"richText": true
},
{
"key": "Steps|rich_text",
"text": {
"text": [
{
"text": "={{ $json.steps }}",
"annotationUi": {}
}
]
},
"richText": true
}
]
}
},
"credentials": {
"notionApi": {
"id": "2Dw53KPRH0ARdlpU",
"name": "Notion account"
}
},
"typeVersion": 2.2
}
],
"active": false,
"pinData": {},
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1"
},
"versionId": "c660d16f-2df1-4e83-bc7b-2e3cfc4b59a3",
"connections": {
"Switch": {
"main": [
[
{
"node": "Fetch Recipe Data",
"type": "main",
"index": 0
}
],
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
],
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Code in JavaScript3",
"type": "main",
"index": 0
}
]
]
},
"Notion Trigger": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Message a model": {
"main": [
[
{
"node": "Code in JavaScript2",
"type": "main",
"index": 0
}
]
]
},
"Message a model1": {
"main": [
[
{
"node": "Code in JavaScript4",
"type": "main",
"index": 0
}
]
]
},
"Fetch Recipe Data": {
"main": [
[
{
"node": "Code in JavaScript1",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript1": {
"main": [
[
{
"node": "Message a model",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript2": {
"main": [
[
{
"node": "Update a database page",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript3": {
"main": [
[
{
"node": "Message a model1",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript4": {
"main": [
[
{
"node": "Update a database page1",
"type": "main",
"index": 0
}
]
]
},
"Update a database page": {
"main": [
[]
]
},
"Update a database page1": {
"main": [
[]
]
}
}
}