{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "2de76183-3907-4ff2-9afb-bfb2121915dc",
      "name": "Generate Random Meal in Mealie",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        704,
        1008
      ],
      "parameters": {
        "url": "http://<mealie ip address>:9925/api/households/mealplans/random",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "date",
              "value": "={{ $json.date }}"
            },
            {
              "name": "entryType",
              "value": "dinner"
            }
          ]
        },
        "nodeCredentialType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "7cee36dc-aa29-430d-ad5b-dfee585c22e1",
      "name": "Get Recipe From Mealie By Slug",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1168,
        1008
      ],
      "parameters": {
        "url": "=http://<mealie ip address>:9925/api/recipes/{{ $json.recipe.slug }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "1b52bdc4-8872-4be1-adff-7200990e3b08",
      "name": "Normalize Mealie Recipe Data",
      "type": "n8n-nodes-base.code",
      "position": [
        2272,
        1008
      ],
      "parameters": {
        "jsCode": "const recipes = $('Get Recipe From Mealie By Slug').all();\n\nconst mealPlanRecipes = recipes.map(item => {\n  const recipe = item.json;\n  return {\n    recipeId: recipe.id,\n    recipeIncrementQuantity: recipe.recipeServings ?? 1,\n    recipeIngredients: (recipe.recipeIngredient ?? []).map(ing => ({\n      quantity: ing.quantity ?? 0,\n      unit: ing.unit ?? null,\n      food: ing.food ?? null,\n      referencedRecipe: ing.referencedRecipe ?? null,\n      note: ing.note ?? \"\",\n      display: ing.display ?? \"\",\n      title: ing.title ?? null,\n      originalText: ing.originalText ?? null,\n      referenceId: ing.referenceId ?? null,\n    }))\n  };\n});\n\nreturn [{\n  json: {\n    recipes: mealPlanRecipes\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "bf165bc3-aec0-410f-9a49-1209f5f4477b",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        256,
        1008
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks"
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "5ca174ed-1ec2-4b61-959a-6af00cb047e2",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -464,
        0
      ],
      "parameters": {
        "width": 460,
        "height": 1200,
        "content": "## Try It Out!\n\n### This n8n template demonstrates how to automatically generate a full week of dinner meal plans in your self hosted Mealie instance and create a corresponding shopping list based on those planned meals.\n\n\nPerfect for anyone who wants hands off weekly planning. Set it once and let it build your dinners and prep your ingredient data every week.\n\n### How it works\n* A Schedule Trigger runs once per week to kick things off.\n* A Code node generates the next 7 calendar days starting from today.\n* For each day, we call the Mealie API to generate a random dinner entry.\n* Using the returned recipe slug, we fetch the full recipe details from Mealie.\n* A new shopping list is created in Mealie for the week.\n* The recipe data is normalized into a clean structure that includes servings and ingredient details, ready for shopping list aggregation or further processing.\n\n### What this gives you\n* Automatic weekly dinner planning\n* Structured ingredient data for every recipe\n* A named shopping list for the week\n* Clean normalized JSON that can easily be extended to:\n  * Aggregate ingredients across recipes\n  * Remove duplicates\n  * Scale quantities\n  * Export to external services\n\n### How to use\n* By default, this runs weekly using the Schedule Trigger. You can change the interval or replace it with:\n  * A Manual Trigger\n  * A Webhook\n  * A Form submission\n* Make sure your Mealie API endpoint and Bearer credentials are configured correctly.\n* Adjust the entryType field if you want breakfast or lunch instead of dinner.\n\n### Requirements\n* A running Mealie instance with API access enabled\n* HTTP Bearer credentials configured in n8n\n* Network access to your Mealie server\n\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f9925679-4535-48a4-a978-d2cfc0fc1e52",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": "#003D7A",
        "width": 416,
        "height": 496,
        "content": "## Pre-Requisite\nBefore using this workflow, you need a running **Mealie** instance with API access enabled.\n\nIf you have not installed Mealie yet, follow the official setup guide in the Mealie documentation. It walks through Docker setup, environment configuration, and API access.\n\n### After Mealie is running:\n* Go into the **four HTTP Request nodes** in this workflow and update the URLs so they point to your self-hosted Mealie IP address and port.  \n* Generate an API token inside Mealie.  \n* Update the **Mealie Auth Account** in n8n (the HTTP Bearer Auth credential) with this new token.  \n* Make sure each of the HTTP Request nodes uses the updated Mealie Auth Account.\n\n### Network Access\nEnsure your n8n instance can reach your Mealie server over the network. Once this is configured, the workflow should run without issues."
      },
      "typeVersion": 1
    },
    {
      "id": "7faf476e-97a3-47ab-a2ef-a0b0f3aaafab",
      "name": "Create New Shopping List in Mealie",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1760,
        1008
      ],
      "parameters": {
        "url": "http://<mealie ip address>:9925/api/households/shopping/lists",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"name\": \"Shopping List Week of {{ $('Generate Next 7 Days').item.json.date }}\"\n} ",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.4,
      "alwaysOutputData": false
    },
    {
      "id": "b8ee6180-2764-4869-a120-dcc2b578fef6",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        432,
        656
      ],
      "parameters": {
        "color": 4,
        "width": 432,
        "height": 480,
        "content": "## 1. Generate Dates for the Full Week and Request Random Dinners\n\nThese two nodes generate the next 7 calendar days starting from today and prepare them for meal planning. For each date, a request is sent to Mealie\u2019s random meal generator API to create a dinner entry, resulting in a full week of automatically scheduled dinners.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "55494358-8897-4329-a709-3d3aef68462f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        656
      ],
      "parameters": {
        "color": 4,
        "width": 448,
        "height": 480,
        "content": "## 4. Normalize Recipe Data and Add Ingredients to the Shopping List\n\nThis step prepares each recipe for shopping list creation and then pushes the data back to Mealie.\n\nThe Code node collects all fetched recipes and restructures them into a clean, standardized format. It extracts the recipe ID, serving quantity, and detailed ingredient data so everything is consistent and ready for submission.\n\nOnce normalized, the HTTP Request node sends the structured recipe payload to the newly created shopping list. Mealie then adds all associated ingredients to that list, completing the automation from meal planning to grocery preparation.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1b7d9ae7-30a0-49ac-a064-b9d1fab18fa9",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        992,
        656
      ],
      "parameters": {
        "color": 4,
        "width": 432,
        "height": 480,
        "content": "## 2. Fetch Full Recipe Details from Mealie\n\nOnce each random dinner is created, this node retrieves the complete recipe data using the recipe\u2019s slug. It sends an authenticated request to your Mealie instance and returns the full recipe object, including servings and ingredient details.\n\nThis ensures the workflow has structured, detailed data for each planned meal, which can then be normalized and used to build an accurate shopping list.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e338881f-04a1-46b9-8d8d-58a0478d7855",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        656
      ],
      "parameters": {
        "color": 4,
        "width": 432,
        "height": 480,
        "content": "## 3. Create a New Weekly Shopping List in Mealie\n\nThis node creates a new shopping list in your Mealie instance for the planned week. The list is dynamically named using the first date from the generated week, making it easy to identify later.\n\nThe request is authenticated using your Bearer token and runs once to ensure only a single shopping list is created for the entire workflow execution. This list becomes the destination for the aggregated ingredients from all planned dinners.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d02581bb-ef49-42ed-995c-dfda7c96faa8",
      "name": "Add Recipe(s) Ingredients To Shopping List in Mealie",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2480,
        1008
      ],
      "parameters": {
        "url": "=http://<mealie ip address>:9925/api/households/shopping/lists/{{$('Create New Shopping List in Mealie').item.json.id}}/recipe",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ $json.recipes }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "executeOnce": false,
      "typeVersion": 4.4
    },
    {
      "id": "97d2d432-0f2a-4820-bcde-e922d7b7c198",
      "name": "Generate Next 7 Days",
      "type": "n8n-nodes-base.code",
      "position": [
        480,
        1008
      ],
      "parameters": {
        "jsCode": "const days = [];\nconst today = new Date();\n\nfor (let i = 0; i < 7; i++) {\n  const date = new Date(today);\n  date.setDate(today.getDate() + i);\n\n  days.push({\n    json: {\n      date: date.toISOString().split(\"T\")[0],\n      dayOfWeek: date.toLocaleDateString(\"en-US\", { weekday: \"long\" }),\n    }\n  });\n}\n\nreturn days;"
      },
      "typeVersion": 2
    }
  ],
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Generate Next 7 Days",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Next 7 Days": {
      "main": [
        [
          {
            "node": "Generate Random Meal in Mealie",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Mealie Recipe Data": {
      "main": [
        [
          {
            "node": "Add Recipe(s) Ingredients To Shopping List in Mealie",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Random Meal in Mealie": {
      "main": [
        [
          {
            "node": "Get Recipe From Mealie By Slug",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Recipe From Mealie By Slug": {
      "main": [
        [
          {
            "node": "Create New Shopping List in Mealie",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create New Shopping List in Mealie": {
      "main": [
        [
          {
            "node": "Normalize Mealie Recipe Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}