Workflow: develop a modular n8n workflow that supports Splitout Schedule Create Webhook
Integrations: aggregate, html, httpRequest, if, merge, microsoftExcel, microsoftOutlook, noOp, removeDuplicates, scheduleTrigger, set, splitInBatches, splitOut, stickyNote

{"meta": {"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9", "templateCredsSetupCompleted": true}, "nodes": [{"id": "c3a9ba81-3a7e-4afe-be8b-cf482cbb88c2", "name": "Schedule Trigger", "type": "n8n-nodes-base.scheduleTrigger", "position": [-1040, -540], "parameters": {"rule": {"interval": [{"triggerAtHour": 6}]}}, "typeVersion": 1.2}, {"id": "f63d035c-5a7b-4cf4-8730-5fa7dff6f94b", "name": "Get Subscribers", "type": "n8n-nodes-base.microsoftExcel", "position": [-860, -540], "parameters": {"options": {}, "resource": "worksheet", "workbook": {"__rl": true, "mode": "id", "value": "="}, "operation": "readRows", "worksheet": {"__rl": true, "mode": "id", "value": "="}}, "credentials": {"microsoftExcelOAuth2Api": {"id": "56tIUYYVARBe9gfX", "name": "Microsoft Excel account"}}, "typeVersion": 2.1}, {"id": "e93aa8de-5c68-4a01-ae60-beb141e0a430", "name": "Get Unique Categories", "type": "n8n-nodes-base.set", "position": [-400, -160], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "fe138128-50d5-469f-8c0b-0af8c873f198", "name": "categories", "type": "array", "value": "={{ $input.all().flatMap(item => item.json.categories).unique() }}"}]}}, "executeOnce": true, "typeVersion": 3.4}, {"id": "a874ae4e-d67e-4019-9e5c-03ea677468ae", "name": "OpenAI Chat Model", "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "position": [760, 80], "parameters": {"model": {"__rl": true, "mode": "list", "value": "gpt-4o-mini"}, "options": {}}, "credentials": {"openAiApi": {"id": "8gccIjcuf3gvaoEr", "name": "OpenAi account"}}, "typeVersion": 1.2}, {"id": "bc9c7578-3b6f-45fb-9f93-94637774d125", "name": "Aggregate", "type": "n8n-nodes-base.aggregate", "position": [1180, 40], "parameters": {"options": {}, "aggregate": "aggregateAllItemData"}, "typeVersion": 1}, {"id": "ae83c9e2-a267-463c-a606-b4d101f93f92", "name": "Collect Fields", "type": "n8n-nodes-base.set", "position": [980, -60], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "4a266505-4b88-41cf-bf22-f38c705c27e5", "name": "workflow_id", "type": "number", "value": "={{ $('Workflows to Items').item.json.workflow.id }}"}, {"id": "df3348e2-b6ec-4c38-a146-c38be9b830bc", "name": "workflow_name", "type": "string", "value": "={{ $('Workflows to Items').item.json.workflow.name }}"}, {"id": "b4646059-748f-407a-b829-d6605d5ab683", "name": "workflow_desc", "type": "string", "value": "={{ $json.response.text }}"}, {"id": "eac0d9ab-9445-4bc2-9e64-160fe44b9ace", "name": "workflow_created_at", "type": "string", "value": "={{ $('Workflows to Items').item.json.workflow.createdAt }}"}, {"id": "24a3c0cb-224c-4ce6-b59e-38b10ab2c02f", "name": "author_id", "type": "number", "value": "={{ $('Workflows to Items').item.json.workflow.user.id }}"}, {"id": "a2b8a52f-be72-484c-aa86-582b73be1859", "name": "author_name", "type": "string", "value": "={{ $('Workflows to Items').item.json.workflow.user.name }}"}, {"id": "ae735511-8c7c-4bef-b6ac-cfe3d4b87b4f", "name": "author_username", "type": "string", "value": "={{ $('Workflows to Items').item.json.workflow.user.username }}"}, {"id": "2dc1f59f-a854-4322-85df-c5998f782dcd", "name": "category", "type": "string", "value": "={{ $('For Each Category').item.json.category }}"}]}}, "typeVersion": 3.4}, {"id": "8ca1ea7e-9098-4e82-919b-ba98ae7d7574", "name": "Categories to Items", "type": "n8n-nodes-base.splitOut", "position": [-220, -160], "parameters": {"options": {"destinationFieldName": "category"}, "fieldToSplitOut": "categories"}, "typeVersion": 1}, {"id": "eb6d74b8-f1ed-4ab2-8c5f-7e6c6361b055", "name": "For Each Category", "type": "n8n-nodes-base.splitInBatches", "position": [320, -160], "parameters": {"options": {}}, "typeVersion": 3}, {"id": "8640ffac-9df6-4154-bcd5-dfa90c3843d4", "name": "Workflows to Items", "type": "n8n-nodes-base.splitOut", "position": [500, -60], "parameters": {"options": {"destinationFieldName": "workflow"}, "fieldToSplitOut": "workflows"}, "typeVersion": 1}, {"id": "4456a43b-df26-4bb8-a62d-b9f05eff4479", "name": "Workflow Summarizer", "type": "@n8n/n8n-nodes-langchain.chainLlm", "position": [660, -60], "parameters": {"text": "=## Description\n```\n{{ $json.workflow.description.replaceAll('#', '') }}\n```", "messages": {"messageValues": [{"message": "=You have received a description of a n8n template from the official template gallery. Your task is to summarize the description into one or two sentences. The summary should loosely follow the structure of:\n* identify the goal of the template\n* describe the method or approached implemented\n* highlight which important n8n nodes were used\n\neg. \"Obtain real-time crypto market insights using an AI-powered workflow with CoinMarketCap APIs through Telegram\""}]}, "promptType": "define"}, "typeVersion": 1.5}, {"id": "5f4a5921-c954-4523-8925-90401d8dbf22", "name": "Merge", "type": "n8n-nodes-base.merge", "position": [660, -460], "parameters": {"mode": "chooseBranch"}, "typeVersion": 3.1}, {"id": "f95fb28c-875c-4105-aa83-9fea257ea440", "name": "Fetch Latest 10 per Category", "type": "n8n-nodes-base.httpRequest", "position": [-40, -160], "parameters": {"url": "=https://n8n.io/api/product-api/workflows/search", "options": {}, "sendQuery": true, "queryParameters": {"parameters": [{"name": "category", "value": "={{$json.category }}"}, {"name": "rows", "value": "10"}, {"name": "sort", "value": "createdAt:desc"}, {"name": "page", "value": "1"}]}}, "typeVersion": 4.2}, {"id": "4dda6cbc-e53f-452d-b257-df9ef18abd75", "name": "No Operation, do nothing", "type": "n8n-nodes-base.noOp", "position": [1560, -460], "parameters": {}, "typeVersion": 1}, {"id": "881337d8-3ca8-43d2-931f-9cfec16cc367", "name": "Get Relevant Workflows", "type": "n8n-nodes-base.set", "position": [1380, -280], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "fbd0ad94-e5aa-4082-81f5-d7b2e08dfbcf", "name": "workflows", "type": "array", "value": "={{\n$json.categories\n  .flatMap(cat =>\n    $('Flatten Workflows').first().json.workflows.filter(item => item.category === cat)\n  )\n}}"}]}}, "typeVersion": 3.4}, {"id": "b3ad0e26-e495-4dae-bfdd-f65961178acc", "name": "Flatten Workflows", "type": "n8n-nodes-base.set", "position": [500, -280], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "17a82dd9-3fcf-44d9-b5da-bf89a1f53d59", "name": "workflows", "type": "array", "value": "={{\n$input.all().flatMap(item => item.json.data)\n}}"}]}}, "executeOnce": true, "typeVersion": 3.4}, {"id": "05f72731-f8b0-4d8f-ba78-66ef8fbaf059", "name": "Remove Already Seen", "type": "n8n-nodes-base.removeDuplicates", "position": [1740, -280], "parameters": {"options": {}, "operation": "removeItemsSeenInPreviousExecutions", "dedupeValue": "={{ $('For Each Subscriber').item.json.name.toSnakeCase() }}_{{ $json.workflow_id }}"}, "typeVersion": 2}, {"id": "3904d2a2-9a95-4e11-883e-b2e88c6a884f", "name": "Workflow to Items", "type": "n8n-nodes-base.splitOut", "position": [1560, -280], "parameters": {"options": {}, "fieldToSplitOut": "workflows"}, "typeVersion": 1}, {"id": "d416dee7-df0f-4579-a25f-6baed16453e8", "name": "Combine Workflows", "type": "n8n-nodes-base.aggregate", "position": [1920, -280], "parameters": {"options": {}, "aggregate": "aggregateAllItemData"}, "typeVersion": 1}, {"id": "3797dd21-3144-47e8-9359-841b97073001", "name": "Has New Workflows?", "type": "n8n-nodes-base.if", "position": [1380, -600], "parameters": {"options": {}, "conditions": {"options": {"version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "and", "conditions": [{"id": "08403b2a-4ae6-4cf5-aa88-cc49441e3c56", "operator": {"type": "array", "operation": "lengthGt", "rightType": "number"}, "leftValue": "={{ $json.data }}", "rightValue": 0}]}}, "typeVersion": 2.2}, {"id": "0cd6ce35-c083-4db6-bc87-9d21e70a3bab", "name": "With User Reference", "type": "n8n-nodes-base.set", "position": [2100, -280], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "d69921eb-b518-4614-af63-e67a521ee373", "name": "name", "type": "string", "value": "={{ $('For Each Subscriber').item.json.name }}"}, {"id": "01ee6e0a-9d03-42f6-ad46-68b9df861679", "name": "email", "type": "string", "value": "={{ $('For Each Subscriber').item.json.email }}"}, {"id": "5263e512-1b24-43c8-9033-6547dab2811b", "name": "categories", "type": "array", "value": "={{ $('For Each Subscriber').item.json.categories }}"}]}, "includeOtherFields": true}, "typeVersion": 3.4}, {"id": "b3a616c7-615f-49ff-8e6f-530324a98be4", "name": "Generate HTML Template", "type": "n8n-nodes-base.html", "position": [1740, -720], "parameters": {"html": "<h1>New Workflows for {{ $now.format('DD') }}</h1>\n{{\n$json.categories\n  .filter(cat =>\n    $json.data.filter(item => item.category === cat).length > 0\n  )\n  .map(category => `\n    <h2>${category.toSentenceCase()}</h2>\n    <ul>\n    ${$json.data\n      .filter(workflow => workflow.category === category)\n      .map(workflow => `\n      <li>\n        <a href=\"https://n8n.io/workflows/${workflow.workflow_id}\">\n          <h3>${workflow.workflow_name}</h3>\n        </a>\n        <p>\n          by\n          <a href=\"https://n8n.io/creators/${workflow.author_username}\">\n            ${workflow.author_name}\n          </a>\n          &middot;\n          created on ${DateTime.fromISO(workflow.workflow_created_at).toFormat('DD')}\n        </p>\n        <p>${workflow.workflow_desc}</p>\n      </li>\n    `).join('\\n')}\n    </ul>\n  `)\n  .join('\\n')\n}}"}, "typeVersion": 1.2}, {"id": "0c9865c7-9352-4fda-a943-34c8f524de6c", "name": "Parse Rows", "type": "n8n-nodes-base.set", "position": [-660, -540], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "d89dfc07-3c1f-4fbc-9a52-3748797a4840", "name": "name", "type": "string", "value": "={{ $json.name }}"}, {"id": "c622ceca-2e6d-4bab-bb08-235f704c7e2f", "name": "email", "type": "string", "value": "={{ $json.email }}"}, {"id": "9fca8e33-330a-4e4d-b461-251cd7e5c620", "name": "categories", "type": "array", "value": "={{ $json.categories.split(',') }}"}]}}, "typeVersion": 3.4}, {"id": "f5fbd7f2-65e5-4dd7-8e43-38a8a99e3321", "name": "Send Daily Digest", "type": "n8n-nodes-base.microsoftOutlook", "position": [1920, -720], "webhookId": "8cd83f97-1e5f-4280-9a9d-26d1ee05c45e", "parameters": {"subject": "=New Workflows for {{ $now.format('DD') }}", "bodyContent": "={{\n$json.html\n  .replaceAll('\\n', '')\n  .replaceAll('  ', '')\n  .trim()\n}}", "toRecipients": "={{ $('Has New Workflows?').item.json.email }}", "additionalFields": {"from": "=no-reply <no-reply@example.com>", "replyTo": "=no-reply <no-reply@example.com>", "bodyContentType": "html"}}, "credentials": {"microsoftOutlookOAuth2Api": {"id": "EWg6sbhPKcM5y3Mr", "name": "Microsoft Outlook account"}}, "typeVersion": 2}, {"id": "e81ba3a0-e3f6-4231-8870-8ef03edf41e1", "name": "Append Category", "type": "n8n-nodes-base.set", "position": [140, -160], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "b965dee8-f3b5-419b-b39a-79bf2b7d04c1", "name": "category", "type": "string", "value": "={{ $('Categories to Items').item.json.category }}"}]}, "includeOtherFields": true}, "typeVersion": 3.4}, {"id": "e1c2c743-a560-47e8-b906-a2e8fd17622f", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [-1060, -740], "parameters": {"color": 7, "width": 440, "content": "## 1. Get Subscribers from Excel\n[Learn more about the Excel node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.microsoftexcel)\n\nExcel can be an easy way to store a simple list of subscribers who will receive our daily digest. We can also specify only the categories they are interested in."}, "typeVersion": 1}, {"id": "e10a23be-2af7-4b92-9b5f-df855e6ee349", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [-400, -420], "parameters": {"color": 7, "width": 620, "height": 220, "content": "## 2. Fetch Latest Templates from n8n\n[Learn more about the HTTP Request node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest)\n\nUsing the HTTP request node, we can call the n8n.io template search API to the latest published templates. However, to save on resources, we only want to fetch from categories relevant to our subscribers. To do so:\n1) We only want to fetch latest templates from unique categories amongst all subscribers\n2) Do this fetching once to later reference for all subscribers"}, "typeVersion": 1}, {"id": "0ee0b2ca-0247-4471-a6f5-920fd8e67f96", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [500, 260], "parameters": {"color": 7, "width": 580, "height": 180, "content": "## 3. Generate AI Summary For Each Template\n[Read more about the Basic LLM node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm)\n\nWhen building our email digest, we'd rather have a shortened and summarized version of each template's description for easier scanning and reading. We can use AI to accomplish this and merge it with the template object."}, "typeVersion": 1}, {"id": "ab234694-2878-440b-aeb5-37573ebe517e", "name": "Sticky Note3", "type": "n8n-nodes-base.stickyNote", "position": [1680, -60], "parameters": {"color": 7, "width": 580, "height": 200, "content": "## 4. Filter Relevant Templates for Subscriber\n[Read more about the Split Out node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitout)\n\nFor each subscriber, we want to filter out our freshly collected n8n.io templates by the categories relevant to the subscriber as defined in the Excel sheet. A \"Remove duplicates\" node can be used to keep track of duplicate templates - as templates can have more than one category and appear twice!"}, "typeVersion": 1}, {"id": "460a8b3d-c125-41c3-95c5-afdfe63c7561", "name": "Sticky Note4", "type": "n8n-nodes-base.stickyNote", "position": [1740, -960], "parameters": {"color": 7, "width": 580, "height": 200, "content": "## 5. Generate Daily Digest and Send Via Outlook\n[Read more about the Outlook node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.microsoftoutlook)\n\nFinally, we can construct our digest's content using the HTML node and customise it by subscriber as necessary. The Outlook node is then used to send the digest to the subscriber."}, "typeVersion": 1}, {"id": "c79a2775-6276-41df-a9f0-64017e88a8c7", "name": "Sticky Note5", "type": "n8n-nodes-base.stickyNote", "position": [-500, 0], "parameters": {"color": 5, "width": 200, "height": 120, "content": "### Execute Once\nThis node has been set to execute once rather than for each subscriber."}, "typeVersion": 1}, {"id": "5290822e-b63b-4b73-8511-6a12e2387656", "name": "Sticky Note6", "type": "n8n-nodes-base.stickyNote", "position": [-940, -360], "parameters": {"color": 5, "width": 280, "height": 120, "content": "### Columns\n- name *(text)*\n- email *(text)*\n- categories *(text, comma-delimited)*"}, "typeVersion": 1}, {"id": "56acbd11-7fa5-44b8-b031-fcdeb6e44839", "name": "For Each Subscriber", "type": "n8n-nodes-base.splitInBatches", "position": [1180, -460], "parameters": {"options": {}}, "typeVersion": 3}, {"id": "6aef7efc-1bc7-4a1d-b0cb-459484b3d179", "name": "Sticky Note7", "type": "n8n-nodes-base.stickyNote", "position": [-1600, -1400], "parameters": {"width": 500, "height": 1000, "content": "## Try It Out!\n### This n8n template builds a newsletter (\"daily digest\") delivery service which pulls and summarises the latest n8n.io template in select categories defined by subscribers.\n\nIt's scheduled to run once a day and sends the newsletter directly to subscriber via a nicely formatted email. If you've had trouble keeping up with the latest and greatest templates beign published daily, this workflow can save you a lot of time!\n\n### How it works\n* A scheduled trigger pulls a list of subscribers (email and category preferences) from an Excel workbook.\n* We work out unique categories amongst all subscribers and only fetch the latest n8n website templates from these categories to save on resources and optimise the number of API calls we make.\n* The fetched templates are summarised via AI to produce a short description which is more suitable for our email format.\n* For each subscriber, we filter and collect only the templates relevant to their category preferences (as defined in the Excel) and ensure that duplicate templates or those which have been \"seen before\" are omitted.\n* A HTML node is then used to generate the email newsletter. HTML emails are the perfect format since we can add links back to the template.\n* Finally, we use the Outlook node to send the email digest to the subscriber.\n\n### How to use\n* Populate your Excel sheet with 3 columns: name, email and categories. Categories is a comma-delimited list of categories which match the n8n template website. The available categories are AI, SecOps, Sales, IT Ops, Marketing, Engineering, DevOps, Building Blocks, Design, Finance, HR, Other, Product and Support.\n* To subscribe a new user, simply add their email to the Excel sheet with at least one category.\n* To unsubscribe a user, remove them from the sheet.\n* If you're not interested in paid templates, you may want to filter them out after fetching them.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!"}, "typeVersion": 1}], "pinData": {}, "connections": {"Merge": {"main": [[{"node": "For Each Subscriber", "type": "main", "index": 0}]]}, "Aggregate": {"main": [[{"node": "For Each Category", "type": "main", "index": 0}]]}, "Parse Rows": {"main": [[{"node": "Get Unique Categories", "type": "main", "index": 0}, {"node": "Merge", "type": "main", "index": 0}]]}, "Collect Fields": {"main": [[{"node": "Aggregate", "type": "main", "index": 0}]]}, "Append Category": {"main": [[{"node": "For Each Category", "type": "main", "index": 0}]]}, "Get Subscribers": {"main": [[{"node": "Parse Rows", "type": "main", "index": 0}]]}, "Schedule Trigger": {"main": [[{"node": "Get Subscribers", "type": "main", "index": 0}]]}, "Combine Workflows": {"main": [[{"node": "With User Reference", "type": "main", "index": 0}]]}, "Flatten Workflows": {"main": [[{"node": "Merge", "type": "main", "index": 1}]]}, "For Each Category": {"main": [[{"node": "Flatten Workflows", "type": "main", "index": 0}], [{"node": "Workflows to Items", "type": "main", "index": 0}]]}, "OpenAI Chat Model": {"ai_languageModel": [[{"node": "Workflow Summarizer", "type": "ai_languageModel", "index": 0}]]}, "Workflow to Items": {"main": [[{"node": "Remove Already Seen", "type": "main", "index": 0}]]}, "Has New Workflows?": {"main": [[{"node": "Generate HTML Template", "type": "main", "index": 0}], [{"node": "No Operation, do nothing", "type": "main", "index": 0}]]}, "Workflows to Items": {"main": [[{"node": "Workflow Summarizer", "type": "main", "index": 0}]]}, "Categories to Items": {"main": [[{"node": "Fetch Latest 10 per Category", "type": "main", "index": 0}]]}, "For Each Subscriber": {"main": [[{"node": "Has New Workflows?", "type": "main", "index": 0}], [{"node": "Get Relevant Workflows", "type": "main", "index": 0}]]}, "Remove Already Seen": {"main": [[{"node": "Combine Workflows", "type": "main", "index": 0}]]}, "With User Reference": {"main": [[{"node": "For Each Subscriber", "type": "main", "index": 0}]]}, "Workflow Summarizer": {"main": [[{"node": "Collect Fields", "type": "main", "index": 0}]]}, "Get Unique Categories": {"main": [[{"node": "Categories to Items", "type": "main", "index": 0}]]}, "Generate HTML Template": {"main": [[{"node": "Send Daily Digest", "type": "main", "index": 0}]]}, "Get Relevant Workflows": {"main": [[{"node": "Workflow to Items", "type": "main", "index": 0}]]}, "Fetch Latest 10 per Category": {"main": [[{"node": "Append Category", "type": "main", "index": 0}]]}}}