This workflow corresponds to n8n.io template #15357 — we link there as the canonical source.
This workflow follows the Agent → Form Trigger 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 →
{
"id": "rIwXNYqvJQCZSchw",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Claude Customer Insights from Website and Reddit with AI",
"tags": [],
"nodes": [
{
"id": "c6254ab3-ca2e-47ee-8c70-9627b2b5a965",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
1008
],
"parameters": {
"color": 2,
"width": 3632,
"height": 528,
"content": "## 1. Getting website info\n\n### What happens here\n\n- The workflow starts from a simple form with a **website URL**\n- It fetches the homepage and extracts readable website text\n- It also checks navigation links and selects a few useful internal pages\n- Those pages are fetched too, then merged into one cleaner website text source\n\n### Why this matters\n\nA homepage alone is usually not enough.\n\nThis step pulls better context from pages like:\n- product\n- features\n- solutions\n- customers\n- about\n\n### Output\n\n- homepage text\n- selected internal page text\n- cleaned website content ready for analysis"
},
"typeVersion": 1
},
{
"id": "97849f12-3cd2-4077-8112-be13d5c2aea8",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
1552
],
"parameters": {
"color": 5,
"width": 4592,
"height": 608,
"content": "## 2. Creating website insights and getting posts\n\n### What happens here\n\n- AI analyzes the website text and extracts structured brand info such as:\n - product summary\n - customer groups\n - pain points\n - solution\n - features\n - benefits\n - brand voice\n - business type\n\n- Then it creates a couple of targeted Reddit search phrases based on the product and market\n- The workflow searches Reddit using those phrases and collects matching posts\n- Low-quality or empty results are filtered out\n\n### Why this matters\n\nThis step turns raw website copy into a usable product understanding, then uses that understanding \nto find real conversations from potential customers.\n\n### Output\n\n- structured website insights\n- targeted Reddit search terms\n- relevant Reddit posts for the same market/problem space"
},
"typeVersion": 1
},
{
"id": "44a4a036-ac11-458e-8fe5-a1dcf26dc658",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
2176
],
"parameters": {
"color": 2,
"width": 3632,
"height": 688,
"content": "## 3. Adding comments + generating Reddit insights\n\n### What happens here\n\n- Relevant Reddit posts are checked and filtered further\n- The workflow pulls comments from selected threads\n- Posts and comments are combined into one research input\n- AI then extracts insight signals such as:\n - customer pain points\n - trigger events\n - aspirations\n - interesting quotes\n - content ideas\n\n- Final outputs are merged with the original website insights\n\n### Why this matters\n\nWebsite copy tells you how the brand talks.\n\nReddit tells you how customers talk.\n\nThis step combines both, so the output is much closer to real market language and real buyer frustration.\n\n### Output\n\n- Reddit pain points\n- trigger moments\n- aspirations\n- useful quotes\n- combined customer insight output for messaging and ad creation"
},
"typeVersion": 1
},
{
"id": "a73c1770-a2ec-47db-8f89-5df76c84e31c",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
144
],
"parameters": {
"color": 4,
"width": 656,
"height": 320,
"content": "## What this workflow does\n\nThis workflow takes a **website URL** and turns it into structured **customer and market insights**.\n\nIt first extracts product and audience context from the website, then uses that context to find relevant Reddit discussions, pull comments, and turn all of it into messaging-ready insight signals you can use for **ads, positioning, landing pages, hooks, and market research**.\n\nThis is also a core part of how **Blumpo** works behind the scenes. One of the biggest problems with AI-generated ads is that the output is only as good as the input. If the context is weak, generic, or based only on website copy, the result usually feels generic too. This workflow helps solve that by combining **brand context from the site** with **real customer language from Reddit**, so the final insights are much closer to what people actually care about, struggle with, and respond to.\n\nIf you want the more complete version of this idea, **Blumpo** takes this further by combining website extraction, customer insight mining, and ad generation into one workflow."
},
"typeVersion": 1
},
{
"id": "d1007986-f798-4112-9b79-849af2747a42",
"name": "Return",
"type": "n8n-nodes-base.set",
"position": [
2912,
2432
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "7cc8ead6-b2a4-4902-92a2-bd605ed08556",
"name": "reddit_customer_pain_points",
"type": "array",
"value": "={{ $json.parsed_output[0].topPainPoints }}"
},
{
"id": "e8ec0084-603e-4a6a-99c3-df451a1dd24f",
"name": "reddit_trigger_events",
"type": "array",
"value": "={{ $json.parsed_output[0].triggerEvents }}"
},
{
"id": "36605df8-5d75-457d-8513-85976621037c",
"name": "reddit_aspirations",
"type": "array",
"value": "={{ $json.parsed_output[0].aspirations }}"
},
{
"id": "34c9e801-5fa9-4a14-8383-d24c560fc744",
"name": "reddit_interesting_quotes",
"type": "array",
"value": "={{ $json.parsed_output[0].interestingQuotes }}"
},
{
"id": "5f5f704f-1a82-413e-8555-1fb99066f01b",
"name": "customer_group",
"type": "array",
"value": "={{ $('Product description').item.json.output.customer_group }}"
},
{
"id": "1f5b10b2-f99c-40bf-a53b-54d21fb3ff3c",
"name": "key_features",
"type": "array",
"value": "={{ $('Product description').item.json.output.key_features }}"
},
{
"id": "03afb8d3-0476-4c17-823c-8e19de1f0073",
"name": "key_benefits",
"type": "array",
"value": "={{ $('Product description').item.json.output.key_benefits }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "b0c7c8e5-772e-4e12-b7f6-697006a5cbb6",
"name": "Reddit2",
"type": "n8n-nodes-base.reddit",
"position": [
1664,
1616
],
"parameters": {
"limit": 30,
"keyword": "={{ $json.output['1'] }}",
"location": "allReddit",
"operation": "search",
"additionalFields": {
"sort": "relevance"
}
},
"credentials": {
"redditOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "15d5d094-f443-4117-94ac-5d427b98c6a9",
"name": "Reddit3",
"type": "n8n-nodes-base.reddit",
"position": [
1664,
1808
],
"parameters": {
"limit": 20,
"keyword": "={{ $json.output['2'] }}",
"location": "allReddit",
"operation": "search",
"additionalFields": {
"sort": "top"
}
},
"credentials": {
"redditOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "469660ee-2455-4ee0-8ae5-c6f12133aca7",
"name": "Edit Fields3",
"type": "n8n-nodes-base.set",
"position": [
1136,
1664
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "459f7155-9016-433e-a261-8afb0c8c9048",
"name": "Product Name",
"type": "string",
"value": "={{ $json.output.brand_name }}"
},
{
"id": "54f1ea1f-3c9b-4665-9247-3b7bd2745e5e",
"name": "Brand description",
"type": "string",
"value": "={{ $json.output.product_summary }}"
},
{
"id": "9368fd1f-0a3f-4492-afbe-bee8fec41733",
"name": "Customer group",
"type": "string",
"value": "={{ $json.output.customer_group }}"
},
{
"id": "7863c1ca-1e0f-4c43-a5c4-c0cf70ea9ebe",
"name": "Problems",
"type": "string",
"value": "={{ $json.output.problems }}"
},
{
"id": "33b349a1-f41a-4305-9372-9f9e0fa07a4c",
"name": "Solution",
"type": "string",
"value": "={{ $json.output.solution }}"
},
{
"id": "89bdeb11-5b39-4a2b-8fd3-c34e0dc5ad7d",
"name": "Key features",
"type": "string",
"value": "={{ $json.output.key_features }}"
},
{
"id": "9b4d9030-c132-41aa-be9c-a1dfd5cb9f55",
"name": "Key benefits",
"type": "string",
"value": "={{ $json.output.key_benefits }}"
},
{
"id": "e95ed425-cf31-4bfc-8347-2236f729a94c",
"name": "industry",
"type": "string",
"value": "={{ $json.output.industry }}"
},
{
"id": "0400c5f4-f32c-4c54-a0eb-fbec30f873a4",
"name": "output.business_type",
"type": "string",
"value": "={{ $json.output.business_type }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "cf337b8a-6649-40d6-bb98-08e5e192d79d",
"name": "Insights creation1",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueErrorOutput",
"position": [
2288,
2448
],
"parameters": {
"text": "={{ $json.prompt }}",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"retryOnFail": true,
"typeVersion": 2.2,
"waitBetweenTries": 800
},
{
"id": "953cf4cf-c100-4be8-be0e-89e250ed7b17",
"name": "Merge Searches",
"type": "n8n-nodes-base.merge",
"position": [
1872,
1696
],
"parameters": {},
"typeVersion": 3,
"alwaysOutputData": true
},
{
"id": "357943b0-c80a-4062-a8af-1e045cad779c",
"name": "Remove Empty",
"type": "n8n-nodes-base.function",
"position": [
2064,
1696
],
"parameters": {
"functionCode": "return items.filter(i => i.json && Object.keys(i.json).length > 0);"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "930b0f3e-c6cc-4555-a52e-8568adb5ac2c",
"name": "Aggregate Posts",
"type": "n8n-nodes-base.aggregate",
"position": [
2480,
1696
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"renameField": true,
"outputFieldName": "posts",
"fieldToAggregate": "selftext"
},
{
"renameField": true,
"outputFieldName": "titles",
"fieldToAggregate": "title"
},
{
"renameField": true,
"outputFieldName": "subreddits",
"fieldToAggregate": "subreddit"
},
{
"renameField": true,
"outputFieldName": "ids",
"fieldToAggregate": "id"
}
]
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "92890902-4bc7-460f-812f-3b0ba91aed61",
"name": "Count Posts",
"type": "n8n-nodes-base.set",
"position": [
2736,
1696
],
"parameters": {
"fields": {
"values": [
{
"name": "count_posts",
"stringValue": "={{ $json.posts.length }}"
}
]
},
"options": {}
},
"typeVersion": 3,
"alwaysOutputData": true
},
{
"id": "4bd1e9da-aabd-466a-a83a-ea1987144bdb",
"name": "Split Relevance",
"type": "n8n-nodes-base.splitOut",
"position": [
3712,
1696
],
"parameters": {
"options": {},
"fieldToSplitOut": "output"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "9690fc49-93aa-46cb-8b88-14dcce80e605",
"name": "Attach Metadata",
"type": "n8n-nodes-base.function",
"position": [
3856,
1696
],
"parameters": {
"functionCode": "const original = $item(0).$node[\"Count Posts\"].json;\nreturn items.map(i => {\n const idx = i.json.post_index;\n i.json.title = original.titles[idx];\n i.json.post = original.posts[idx];\n i.json.subreddit = original.subreddits[idx];\n i.json.id = original.ids[idx];\n return i;\n});"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "70a60556-1607-476c-a99a-55f0337a0788",
"name": "If1",
"type": "n8n-nodes-base.if",
"position": [
2272,
1712
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "db9c6872-7518-49da-8b7e-cfc36a963c99",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.ups }}",
"rightValue": 1
},
{
"id": "619d8c83-743b-485d-b2dd-34e328c93b69",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.selftext }}",
"rightValue": ""
},
{
"id": "2c8060a7-feb3-4d65-9bf1-eb86b8a33968",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.score }}",
"rightValue": 1
},
{
"id": "95904be4-85a5-4faa-927f-854ceda311ce",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.num_comments }}",
"rightValue": 1
},
{
"id": "3f9fe2d7-9f74-4b9a-bf4a-303c78c5424c",
"operator": {
"type": "boolean",
"operation": "false",
"singleValue": true
},
"leftValue": "={{ $json.is_video }}",
"rightValue": "false"
},
{
"id": "a7e6cbbf-8bff-43b5-bf2e-55c0817aed31",
"operator": {
"type": "boolean",
"operation": "false",
"singleValue": true
},
"leftValue": "={{ $json.over_18 }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2,
"alwaysOutputData": true
},
{
"id": "20d898f8-8f3c-49d6-a1ae-cf3be624e805",
"name": "Check relevance of posts",
"type": "@n8n/n8n-nodes-langchain.agent",
"maxTries": 4,
"position": [
3392,
1696
],
"parameters": {
"text": "={{ $json.prompt }}",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"retryOnFail": true,
"typeVersion": 2.2,
"alwaysOutputData": true
},
{
"id": "bd5a7170-09c2-4140-b8e8-2d1abd6e9d40",
"name": "Structured Output Parser1",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
3536,
1952
],
"parameters": {
"jsonSchemaExample": "[\n { \"post_index\": 0, \"isRelevant\": true },\n { \"post_index\": 1, \"isRelevant\": false },\n { \"post_index\": 2, \"isRelevant\": true }\n]"
},
"typeVersion": 1.3
},
{
"id": "1c1bd2f5-4290-4546-96da-9c81c754cdb9",
"name": "Filter",
"type": "n8n-nodes-base.filter",
"position": [
4032,
1696
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "1f340911-74cf-4b8d-9a83-c1a20ce3abd4",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.isRelevant }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.3,
"alwaysOutputData": true
},
{
"id": "e208b70c-1b80-46a7-be0c-3ea4b1333e16",
"name": "Prompt",
"type": "n8n-nodes-base.set",
"position": [
2944,
1696
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "b47fa569-8189-43e8-8c17-6d8fb03fbe3d",
"name": "prompt",
"type": "string",
"value": "=You are a content relevance classifier.\n\nProduct description:\n{{ $('Edit Fields3').item.json['Brand description'] }}\n\nReddit posts (array):\n{{ $json.posts }}\nYour task is to classify ALL posts at once.\n\nA post is relevant if it discusses the same customer group, problems, workflows, situations, or pain points described in the product description.\n\nIMPORTANT:\n- The array contains exactly {{ $json.count_posts }} posts.\n- You must output exactly {{ $json.count_posts }} results.\n- No more, no fewer.\n"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "76d5b469-5259-4cbf-b1fc-1198d2573a0b",
"name": "If2",
"type": "n8n-nodes-base.if",
"position": [
3152,
1696
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "525947e5-bea2-442c-a3d8-58ba3e24c52a",
"operator": {
"type": "number",
"operation": "lt"
},
"leftValue": "={{ $json.prompt.length }}",
"rightValue": 600000
}
]
}
},
"typeVersion": 2.3
},
{
"id": "4c6e80a1-85c9-4f04-b212-b232c703d440",
"name": "set posts",
"type": "n8n-nodes-base.set",
"position": [
3088,
1920
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "ff4ed2c9-f816-4d62-8228-75216276bc3e",
"name": "posts",
"type": "array",
"value": "={{ $('Count Posts').item.json.posts.slice(0,-4) }}"
},
{
"id": "2c725363-a765-446e-9ab4-e14ed1548081",
"name": "titles",
"type": "array",
"value": "={{ $('Count Posts').item.json.titles.slice(0,-4) }}"
},
{
"id": "433519cf-b972-4a05-a02b-36dd1c9699bb",
"name": "subreddits",
"type": "array",
"value": "={{ $('Count Posts').item.json.subreddits.slice(0,-4) }}"
},
{
"id": "55c9c2d2-f622-4ca4-8108-1b7f6bb30d81",
"name": "ids",
"type": "array",
"value": "={{ $('Count Posts').item.json.ids.slice(0,-4) }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "920fe4bd-6162-4b1d-9e49-5ed0493b98c2",
"name": "prompt",
"type": "n8n-nodes-base.set",
"position": [
1856,
2528
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "ca4d7637-fdbc-4ec1-b6ed-cf3f6685b813",
"name": "prompt",
"type": "string",
"value": "=You are a senior B2B SaaS marketing strategist extracting actionable, brand-aligned messaging insights from Reddit posts.\n\nUse the brand\u2019s website outputs as your primary context.\nReddit posts are only used to supplement and refine what is already known \u2014 not to contradict it, replace it, or generalize beyond it.\n\nYou must only extract insights that are relevant to this specific product, customer group, and problem\u2013solution space.\n\nBRAND WEBSITE DATA (PRIMARY CONTEXT)\n\nBrand Name:\n{{ $('Product description').item.json.message.content.brand_name }}\nProduct Summary:\n{{ $('Product description').item.json.message.content.product_summary }}\nCustomer Group:\n{{ $('Product description').item.json.message.content.customer_group }}\nProblems:\n{{ $('Product description').item.json.message.content.problems }}\nSolution (How the product solves those problems):\n{{ $('Product description').item.json.message.content.solution }}\n\nKey Features:\n{{ $('Product description').item.json.message.content.key_features }}\n\nKey Benefits / Differentiators:\n{{ $('Product description').item.json.message.content.key_benefits }}\n\nREDDIT POSTS (SECONDARY CONTEXT)\n\nposts: {{ $json.posts }}\ncomments:{{ $json.comments }}\n\nTASK\n\nAnalyze the Reddit posts through the lens of the brand\u2019s product.\n\nExtract only insights that match or extend the brand\u2019s:\n\ncustomer group\n\nproblems\n\nsolution\n\nfeatures\n\nbenefits\n\nproduct category\n\nIf something in Reddit is off-topic or unrelated, ignore it completely.\n\nAvoid generalizations, empty arrays, filler, invented pain points, or insights not grounded in the post.\n\nEvery field must contain specific, actionable, ad-useful messaging signals.\n\n\nFIELD DEFINITIONS & REQUIREMENTS\n\ntopPainPoints \u2192 10+ short evidence-based frustrations directly relevant to the product category AND consistent with the website\u2019s problems list.\n\ntriggerEvents \u2192 10+ specific situations that cause the ICP to look for the product (only if reflected in Reddit).\n\naspirations \u2192 10+ brief desired outcomes aligned with what the product actually delivers.\n\ninterestingQuotes \u2192 5-10 vivid phrases taken from the posts (loose paraphrasing allowed).\n\ncontentIdeas \u2192 1\u20133 ad angles or topics based on user insights.\n\nEach field must contain at least one non-empty string.\nIf no actionable insight found or post is irrelevant here put null\n\nVALIDATION RULES\n\nOutput valid JSON only:\n[\n {\n \"topPainPoints\": [\"\"],\n \"triggerEvents\": [\"\"],\n \"aspirations\": [\"\"],\n \"interestingQuotes\": [\"\", \"\"]\n }\n]\n"
}
]
}
},
"typeVersion": 3.4,
"alwaysOutputData": true
},
{
"id": "dee48fc4-5107-4288-8cf4-153548777ac3",
"name": "If4",
"type": "n8n-nodes-base.if",
"position": [
2048,
2496
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "5adc7687-941f-4eb3-b3c2-be47fbfa1c7c",
"operator": {
"type": "number",
"operation": "lt"
},
"leftValue": "={{ $json.prompt.length }}",
"rightValue": 600000
}
]
}
},
"typeVersion": 2.3,
"alwaysOutputData": true
},
{
"id": "8bbfceb1-5d8e-4f17-8616-2d27a085e2c9",
"name": "ai parser",
"type": "n8n-nodes-base.code",
"onError": "continueRegularOutput",
"position": [
2704,
2432
],
"parameters": {
"jsCode": "function isPlainObject(value) {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction stripCodeFences(text) {\n if (typeof text !== 'string') return text;\n\n return text\n .replace(/^\\s*```json\\s*/i, '')\n .replace(/^\\s*```\\s*/i, '')\n .replace(/\\s*```\\s*$/i, '')\n .trim();\n}\n\nfunction extractJsonFromMixedText(text) {\n if (typeof text !== 'string') return null;\n\n const trimmed = text.trim();\n\n const fencedMatch = trimmed.match(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/i);\n if (fencedMatch && fencedMatch[1]) {\n return fencedMatch[1].trim();\n }\n\n const starts = [];\n const arrStart = trimmed.indexOf('[');\n const objStart = trimmed.indexOf('{');\n\n if (arrStart !== -1) starts.push(arrStart);\n if (objStart !== -1) starts.push(objStart);\n\n if (starts.length === 0) return null;\n\n const start = Math.min(...starts);\n const openChar = trimmed[start];\n const closeChar = openChar === '[' ? ']' : '}';\n\n let depth = 0;\n let inString = false;\n let escaped = false;\n\n for (let i = start; i < trimmed.length; i++) {\n const ch = trimmed[i];\n\n if (inString) {\n if (escaped) {\n escaped = false;\n } else if (ch === '\\\\') {\n escaped = true;\n } else if (ch === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (ch === '\"') {\n inString = true;\n continue;\n }\n\n if (ch === openChar) depth++;\n if (ch === closeChar) depth--;\n\n if (depth === 0) {\n return trimmed.slice(start, i + 1).trim();\n }\n }\n\n return null;\n}\n\nfunction cleanString(value) {\n if (typeof value !== 'string') return value;\n\n return value\n .replace(/^\\uFEFF/, '')\n .replace(/\\r/g, '')\n .replace(/\\t/g, ' ')\n .replace(/\\n+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction parseJsonIfPossible(value) {\n if (typeof value !== 'string') return value;\n\n const cleaned = stripCodeFences(value);\n\n try {\n return JSON.parse(cleaned);\n } catch (e) {\n const extracted = extractJsonFromMixedText(value);\n if (!extracted) return null;\n\n try {\n return JSON.parse(extracted);\n } catch (e2) {\n return null;\n }\n }\n}\n\nfunction extractCandidate(value) {\n if (Array.isArray(value)) {\n return value;\n }\n\n if (typeof value === 'string') {\n const parsed = parseJsonIfPossible(value);\n if (parsed) return extractCandidate(parsed);\n return null;\n }\n\n if (isPlainObject(value)) {\n const wrapperKeys = [\n 'output',\n 'text',\n 'response',\n 'content',\n 'message',\n 'result',\n 'data',\n 'completion'\n ];\n\n for (const key of wrapperKeys) {\n if (key in value) {\n const nested = extractCandidate(value[key]);\n if (nested) return nested;\n }\n }\n }\n\n return null;\n}\n\nfunction normalizeStringArray(value) {\n if (value === null || value === undefined) {\n return [];\n }\n\n if (Array.isArray(value)) {\n return value\n .map((v) => (typeof v === 'string' ? cleanString(v) : ''))\n .filter((v) => typeof v === 'string' && v.length > 0);\n }\n\n if (typeof value === 'string') {\n const cleaned = cleanString(value);\n return cleaned ? [cleaned] : [];\n }\n\n return [];\n}\n\nreturn $input.all().map((item, index) => {\n const source = item.json;\n const candidate = extractCandidate(source);\n\n if (!candidate) {\n throw new Error(`Item ${index}: Could not extract valid JSON array from AI output`);\n }\n\n if (!Array.isArray(candidate)) {\n throw new Error(`Item ${index}: Parsed AI output must be an array`);\n }\n\n if (candidate.length === 0) {\n throw new Error(`Item ${index}: Parsed AI output array cannot be empty`);\n }\n\n const normalized = candidate.map((entry, entryIndex) => {\n if (!isPlainObject(entry)) {\n throw new Error(`Item ${index}: entry ${entryIndex} must be an object`);\n }\n\n return {\n topPainPoints: normalizeStringArray(entry.topPainPoints),\n triggerEvents: normalizeStringArray(entry.triggerEvents),\n aspirations: normalizeStringArray(entry.aspirations),\n interestingQuotes: normalizeStringArray(entry.interestingQuotes),\n contentIdeas: normalizeStringArray(entry.contentIdeas),\n };\n });\n\n return {\n json: {\n parsed_output: normalized\n }\n };\n});"
},
"typeVersion": 2
},
{
"id": "ee6df972-71a9-4e8d-a784-1fd76d93653f",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
4384,
1680
],
"parameters": {
"maxItems": 20
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "28f91743-045f-4a90-ae67-58e1fe96d81a",
"name": "set post and comments",
"type": "n8n-nodes-base.set",
"position": [
2160,
2672
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f867cfe0-ae47-4f97-b630-5687c538aabf",
"name": "posts",
"type": "array",
"value": "={{ $('Aggregate').item.json.post.slice(0,-4) }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "01b3c59f-e348-4041-8814-501e7763538c",
"name": "If3",
"type": "n8n-nodes-base.if",
"position": [
4208,
1696
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "eadf647c-6f06-42d5-97ca-1d39c02148a2",
"operator": {
"type": "object",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{$json}}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3,
"alwaysOutputData": true
},
{
"id": "51a7f5be-157d-43b7-978f-c41b205573e4",
"name": "Anthropic Chat Model4",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
2272,
2624
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-5-20250929",
"cachedResultName": "Claude Sonnet 4.5"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "e98baa2f-318a-42f9-bc24-881fe93fed25",
"name": "Anthropic Chat Model5",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
3392,
1936
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-5-20250929",
"cachedResultName": "Claude Sonnet 4.5"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "8686fdd6-c696-4eff-bde6-c5aa238253dc",
"name": "Get many comments in a post",
"type": "n8n-nodes-base.reddit",
"position": [
1120,
2432
],
"parameters": {
"limit": 10,
"postId": "={{ $json['post ID'] }}",
"resource": "postComment",
"operation": "getAll",
"subreddit": "={{ $json.subreddit }}"
},
"credentials": {
"redditOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "a8122fba-dbad-4ddd-9ddf-ff244f977201",
"name": "Aggregate3",
"type": "n8n-nodes-base.aggregate",
"position": [
1216,
2592
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"renameField": true,
"outputFieldName": "posts",
"fieldToAggregate": "originalPost"
}
]
}
},
"typeVersion": 1
},
{
"id": "3d4bacb5-038d-444e-951f-264ea009e7aa",
"name": "Merge2",
"type": "n8n-nodes-base.merge",
"position": [
1648,
2528
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2,
"alwaysOutputData": true
},
{
"id": "efa13ed7-de72-4028-b013-ac46bfd2ccc7",
"name": "Edit Fields2",
"type": "n8n-nodes-base.set",
"position": [
832,
2480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "17c9b4d6-c2df-4966-b261-6ec31f246157",
"name": "subreddit",
"type": "string",
"value": "={{ $json.subreddit }}"
},
{
"id": "2f903f1a-2543-46ae-83c8-5cea7b18f371",
"name": "originalPost",
"type": "string",
"value": "={{ $json.post }}"
},
{
"id": "c3f8f5b4-e828-4a95-9a06-d25f0b8e8838",
"name": "title",
"type": "string",
"value": "={{ $json.title }}"
},
{
"id": "04472799-7652-47b8-927d-99472de7ac7b",
"name": "post ID",
"type": "string",
"value": "={{ $json.id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "0fb72edb-1bd9-46e4-9d34-7e4f77d56cc2",
"name": "Aggregate4",
"type": "n8n-nodes-base.aggregate",
"position": [
1296,
2448
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"renameField": true,
"outputFieldName": "comments",
"fieldToAggregate": "body"
}
]
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "d4b3d165-2eb6-4a26-b770-6b7dd7750f5c",
"name": "Text extract2",
"type": "n8n-nodes-base.markdown",
"position": [
2000,
1024
],
"parameters": {
"html": "={{ $('Fetch Homepage1').item.json.data }}",
"options": {
"ignore": "a,img"
}
},
"typeVersion": 1
},
{
"id": "fd0f612e-82d3-4d57-9c97-e2dd955b7215",
"name": "HTML1",
"type": "n8n-nodes-base.html",
"onError": "continueRegularOutput",
"position": [
1424,
1264
],
"parameters": {
"options": {},
"operation": "extractHtmlContent",
"extractionValues": {
"values": [
{
"key": "navLinks",
"attribute": "href",
"cssSelector": "nav a, header nav a, .menu a, .navbar a, .main-menu a, #menu a",
"returnArray": true,
"returnValue": "attribute"
}
]
}
},
"typeVersion": 1.2,
"alwaysOutputData": true
},
{
"id": "76d7bc4c-bcb0-48cf-8e8d-2217b14d6b6a",
"name": "Get website (text)1",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
2416,
1264
],
"parameters": {
"url": "={{ $json.URLs }}",
"options": {}
},
"typeVersion": 4.2,
"alwaysOutputData": true
},
{
"id": "e9f011f5-9bd1-44a0-99fb-ec1299755c31",
"name": "Text extract3",
"type": "n8n-nodes-base.markdown",
"onError": "continueRegularOutput",
"position": [
2592,
1264
],
"parameters": {
"html": "={{ $json.data }}",
"options": {
"ignore": "a,img"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "ab1d1643-4a06-4722-bcca-69d09f37c4db",
"name": "Merge3",
"type": "n8n-nodes-base.merge",
"position": [
2928,
1136
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "d20a0941-0d43-4ec6-8533-dd7993b5a5d3",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
3152,
1136
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "data"
}
]
}
},
"typeVersion": 1
},
{
"id": "7b6f2801-39e2-4935-bea5-fb9c7e069c65",
"name": "Structured Output Parser4",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1776,
1424
],
"parameters": {
"jsonSchemaExample": "[\n \"/first-handle/\",\n \"/second-handle/\",\n \"/third-handle/\",\n \"/fourth-handle/\"\n]"
},
"typeVersion": 1.3
},
{
"id": "5a88c1e7-f5ea-45e5-871d-f63374110b64",
"name": "Split Out1",
"type": "n8n-nodes-base.splitOut",
"position": [
2000,
1264
],
"parameters": {
"options": {},
"fieldToSplitOut": "output"
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "1ded7c6e-8ab3-4190-a3e7-1366e8c1ff8e",
"name": "Aggregate5",
"type": "n8n-nodes-base.aggregate",
"position": [
2768,
1264
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "data"
}
]
}
},
"typeVersion": 1
},
{
"id": "987375a6-508b-4592-bc47-e3ca06a73bb2",
"name": "Anthropic Chat Model6",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
1648,
1424
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-5-20250929",
"cachedResultName": "Claude Sonnet 4.5"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "5c7df785-9355-42d8-8bdc-8d6cecca4f49",
"name": "Fetch Homepage1",
"type": "n8n-nodes-base.httpRequest",
"position": [
1200,
1120
],
"parameters": {
"url": "={{ $json.Website }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "91a2683f-314a-4e60-9d77-7263f8fecb35",
"name": "Base inputs1",
"type": "n8n-nodes-base.set",
"position": [
976,
1120
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "ed0f1505-82b6-4393-a0d8-088055137ec9",
"name": "Website",
"type": "string",
"value": "={{ $('Form Input').item.json.Website.startsWith(\"https\") ? $('Form Input').item.json.Website : \"https://\" + $json.Website }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "53e6a941-e0dc-495d-bd6b-ab16f6eb5390",
"name": "Extract Website Copy1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1648,
1024
],
"parameters": {
"text": "=Identify Language of the dommain:\nInput domain:\n\n{{ $('Base inputs1').item.json.Website }}\n- Identify the top-level domain (TLD), including multi-part endings like .com.pl or .co.uk.\n\n- If the TLD corresponds to a specific country, output that country\u2019s dominant language.\n\n- If the TLD is generic or not tied to a country (e.g., .com, .co, .io, .ai, .net, .org, .app, .dev, .tech), DEFAULT to English.\n\n- If unsure or ambiguous, DEFAULT to English. \n\nReturn only the language as a plain string.\nExample: \"English\"\nNo JSON. No arrays. No extra text.",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2,
"alwaysOutputData": true
},
{
"id": "527e969d-c3f0-4682-940c-4b885e7735dc",
"name": "Extract Sub-Website Copy1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1648,
1264
],
"parameters": {
"text": "=From the list of website handles, select up to 4 handles that will likely contain the most valuable marketing insights, brand tone, and product messaging.\nExclude the main homepage.\n\nList:\n{{ $json.navLinks }}\nPRIORITIZE HANDLES LIKE:\n/product/, /features/, /solutions/, /platform/, /pricing/, /customers/, /use-cases/, /blog/, /resources/, /why-us/, /about/\n\nIGNORE:\ncareers, legal, login, language variants (/de/, /fr/), support pages.\n\nOUTPUT FORMAT (strict):\n\n[\n \"/first-handle/\",\n \"/second-handle/\",\n \"/third-handle/\",\n \"/fourth-handle/\"\n]",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2,
"alwaysOutputData": true
},
{
"id": "e549ba69-89bd-4ddc-ab2d-cf234d52e8b8",
"name": "Map websites1",
"type": "n8n-nodes-base.set",
"onError": "continueRegularOutput",
"position": [
2224,
1264
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "d82fe5ee-9427-493d-8a0e-5e96ae17bf4c",
"name": "URLs",
"type": "string",
"value": "={{ $json.output }}"
}
]
}
},
"typeVersion": 3.4,
"alwaysOutputData": true
},
{
"id": "5ed7e247-1f9d-4001-8343-abfe9cdb618f",
"name": "Clean text1",
"type": "n8n-nodes-base.code",
"position": [
3344,
1120
],
"parameters": {
"jsCode": "// 1) Get array of text blocks from the Aggregate node\nlet arr = $json.data || [];\n\n// 2) Join all text pieces into one long text string\nlet txt = arr.join(\" \");\n\n// 3) Remove markdown headings\ntxt = txt.replace(/^#{1,6}\\s*/gm, \"\");\n\n// 4) Remove tabs and newlines\ntxt = txt.replace(/[\\t\\r]+/g, \" \");\ntxt = txt.replace(/\\n+/g, \" \");\n\n// 5) Remove leftover markdown bullets, dashes, stars\ntxt = txt.replace(/[*\u2022\\-+]{1,2}\\s*/g, \"\");\n\n// 6) Remove multiple spaces\ntxt = txt.replace(/\\s{2,}/g, \" \").trim();\n\n// 7) JSON-escape without wrapping in quotes\nlet jsonSafe = JSON.stringify(txt).slice(1, -1);\n\nreturn {\n json_safe: jsonSafe\n};\n"
},
"typeVersion": 2
},
{
"id": "89dd07bb-8b54-42b9-8c5e-2d70472e58ae",
"name": "Anthropic Chat Model7",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
1632,
1152
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-5-20250929",
"cachedResultName": "Claude Sonnet 4.5"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "bb7b7d3f-f031-4a63-a781-d1def7ec792b",
"name": "Form Input",
"type": "n8n-nodes-base.formTrigger",
"position": [
784,
1120
],
"parameters": {
"options": {},
"formTitle": "Data input",
"formFields": {
"values": [
{
"fieldLabel": "Website",
"requiredField": true
}
]
}
},
"typeVersion": 2.2
},
{
"id": "d22c61da-3593-4cfd-a254-bb37740e561a",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1488,
1888
],
"parameters": {
"jsonSchemaExample": " {\n \"1\": \"string\",\n\"2\": \"string\"\n }"
},
"typeVersion": 1.3
},
{
"id": "eefd28b9-1c35-4a31-84ea-267808021fe7",
"name": "Structured Output Parser2",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
960,
1888
],
"parameters": {
"jsonSchemaExample": "{\n\"brand_name\": \"\",\n\"product_summary\": \"\",\n\"customer_group\": [],\n\"industry\":\"\",\n\"problems\": [],\n\"solution\": \"\",\n\"key_features\": [],\n\"key_benefits\": [],\n\"business_type\": \"\"\n}"
},
"typeVersion": 1.3
},
{
"id": "08e52245-a341-4cea-bb29-d89491431d66",
"name": "Anthropic Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
768,
1888
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-5-20250929",
"cachedResultName": "Claude Sonnet 4.5"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "1624770f-b6d2-4201-a4a0-6d72c3be66c6",
"name": "Anthropic Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
1280,
1872
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-5-20250929",
"cachedResultName": "Claude Sonnet 4.5"
},
"options": {}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "7320d3b6-29c0-4882-be3b-0105d6ad5a96",
"name": "Product description",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueErrorOutput",
"position": [
784,
1680
],
"parameters": {
"text": "=You are a brand analyst.\n\nYour task is to extract structured information strictly from the provided website text.\n\nYou must maximize the amount of information extracted, but:\n\nDo not invent facts.\nDo not guess or rely on prior knowledge.\nOnly return elements that are directly supported by explicit text or strongly implied within the same paragraph or section.\nIf any element cannot be found, return \"Unknown\" or [].\n\nUse short, clear phrasing.\nNever include marketing fluff \u2014 only what the text clearly states.\n\nWEBSITE TEXT\n{{ $json.json_safe }}\n\nTASKS\n\nProduct / Brand Name\nExtract only if clearly visible in the text. Capitalize first letter. If multiple appear, pick the most prominent. If unsure \u2192 \"Unknown\". Look at the website URL if needed to confirm the brand name.\n\nProduct Summary\n1\u20132 neutral, factual sentences describing what the product does, based ONLY on the text.\n\nCustomer Group\nIdentify the four most relevant customer groups (ICPs) that the product is designed for based on the provided information, list them all each after ,\n\nIndustry\nSet the core industry in which the company operates.\n\nProblems\nList the core pain points described or clearly implied.\n\nSolution\nShort, factual explanation of how the product solves the problems.\n\nKey Features\nExtract main functional capabilities. Do not turn benefits into features.\n\nKey Benefits / Differentiators\nExtract value outcomes explicitly stated.\n\nBusiness type\nAnalyze the provided brand data (website text, product, customer, and offering) to determine which business model it most closely fits.\n\n\nOUTPUT FORMAT (Valid JSON Only)\n\n{\n\"brand_name\": \"\",\n\"product_summary\": \"\",\n\"customer_group\": [],\n\"industry\":\"\",\n\"problems\": [],\n\"solution\": \"\",\n\"key_features\": [],\n\"key_benefits\": [],\n\"business_type\": \"\"\n}\n\nReturn ONLY this JSON object. No explanations, no markdown, no extra text.",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"retryOnFail": true,
"typeVersion": 2.2,
"waitBetweenTries": 800
},
{
"id": "e1fc2747-caaf-4ccc-8ceb-d117751ec9f1",
"name": "Setting keywords for Reddit1",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueErrorOutput",
"position": [
1312,
1680
],
"parameters": {
"text": "=You are a marketing strategist and Reddit researcher.\n\nYour task is to identify two **the most natural Reddit search phrase (1\u20133 words)** that real users would type when discussing frustrations, pain points, or needs related to the product below.\n\n---\n\n### PRODUCT DESCRIPTION\n{{ $json['Brand description'] }}\n---\n\n### INSTRUCTIONS\n- Think like a real Reddit user posting or searching about this type of product. \n- The phrases must sound like something someone would actually type into Reddit search or include in a post title. \n- It should describe the *tool, feature, or category name* \u2014 not just the general topic or industry. \n- Include descriptive context words that make it **specific and useful** (e.g., \u201ctask management tool\u201d instead of \u201ctask management\u201d, \u201cCRM platform\u201d instead of \u201cCRM\u201d). \n- If the brand is B2B SaaS, prefer product-like or problem-solving phrasing: \u201cautomation software\u201d, \u201cproject tracking app\u201d, \u201cworkflow tool\u201d, etc. \n- Avoid vague, high-level phrases like \u201cwork\u201d, \u201cproductivity\u201d, \u201cmanagement\u201d, \u201cbusiness\u201d. \n- Keep it lowercase, short (max 3 words), and natural for Reddit.\n- create 2 keywords, phrases (number 1 and number 2)\n- keep both specific for the product market so it doenst go too broad\n\n---\n\n### OUTPUT\nReturn **only** 2 separate keywords or short phrases \u2014 nothing else, no punctuation, no explanations.\n {\n \"1\": \"string\",\n\"2\": \"string\"\n }",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"retryOnFail": true,
"typeVersion": 2.2,
"waitBetweenTries": 800
},
{
"id": "98bfea5b-1dca-4c42-85fb-a9e85f51186c",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
480
],
"parameters": {
"width": 656,
"height": 416,
"content": "## Setup before running\n\n### Required credentials\n\n- **Anthropic account** \nUsed for website analysis, keyword generation, relevance checking, and final insight creation\n\n- **Reddit account** \nUsed to search posts and pull comments from relevant threads\n\n### Form input required\n\n- **Website** \u2014 required\n\n### Important checks\n\n- Make sure the submitted website includes the correct homepage\n- Check that your Reddit credential is connected and working\n- Review the prompts if you want to make the workflow more broad or more niche\n- If sharing publicly, remove private credentials and regenerate webhook references"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "204d1820-9b43-473b-8e08-1e1f6059839e",
"connections": {
"If1": {
"main": [
[
{
"node": "Aggregate Posts",
"type": "main",
"index": 0
}
]
]
},
"If2": {
"main": [
[
{
"node": "Check relevance of posts",
"type": "main",
"index": 0
}
],
[
{
"node": "set posts",
"type": "main",
"index": 0
}
]
]
},
"If3": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
],
[]
]
},
"If4": {
"main": [
[
{
"node": "Insights creation1",
"type": "main",
"index": 0
}
],
[
{
"node": "set post and comments",
"type": "main",
"index": 0
}
]
]
},
"HTML1": {
"main": [
[
{
"node": "Extract Sub-Website Copy1",
"type": "main",
"index": 0
}
]
]
},
"Limit": {
"main": [
[
{
"node": "Edit Fields2",
"type": "main",
"index": 0
}
]
]
},
"Filter": {
"main": [
[
{
"node": "If3",
"type": "main",
"index": 0
}
]
]
},
"Merge2": {
"main": [
[
{
"node": "prompt",
"type": "main",
"index": 0
}
]
]
},
"Merge3": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Prompt": {
"main": [
[
{
"node": "If2",
"type": "main",
"index": 0
}
]
]
},
"Return": {
"main": [
[]
]
},
"prompt": {
"main": [
[
{
"node": "If4",
"type": "main",
"index": 0
}
]
]
},
"Reddit2": {
"main": [
[
{
"node": "Merge Searches",
"type": "main",
"index": 0
}
]
]
},
"Reddit3": {
"main": [
[
{
"node": "Merge Searches",
"type": "main",
"index": 1
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "Clean text1",
"type": "main",
"index": 0
}
]
]
},
"ai parser": {
"main": [
[
{
"node": "Return",
"type": "main",
"index": 0
}
]
]
},
"set posts": {
"main": [
[
{
"node": "Count Posts",
"type": "main",
"index": 0
}
]
]
},
"Aggregate3": {
"main": [
[
{
"node": "Merge2",
"type": "main",
"index": 1
}
]
]
},
"Aggregate4": {
"main": [
[
{
"node": "Merge2",
"type": "main",
"index": 0
}
]
]
},
"Aggregate5": {
"main": [
[
{
"node": "Merge3",
"type": "main",
"index": 1
}
]
]
},
"Form Input": {
"main": [
[
{
"node": "Base inputs1",
"type": "main",
"index": 0
}
]
]
},
"Split Out1": {
"main": [
[
{
"node": "Map websites1",
"type": "main",
"index": 0
}
]
]
},
"Clean text1": {
"main": [
[
{
"node": "Product description",
"type": "main",
"index": 0
}
]
]
},
"Count Posts": {
"main": [
[
{
"node": "Prompt",
"type": "main",
"index": 0
}
]
]
},
"Base inputs1": {
"main": [
[
{
"node": "Fetch Homepage1",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields2": {
"main": [
[
{
"node": "Aggregate3",
"type": "main",
"index": 0
},
{
"node": "Get many comments in a post",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields3": {
"main": [
[
{
"node": "Setting keywords for Reddit1",
"type": "main",
"index": 0
}
]
]
},
"Remove Empty": {
"main": [
[
{
"node": "If1",
"type": "main",
"index": 0
}
]
]
},
"Map websites1": {
"main": [
[
{
"node": "Get website (text)1",
"type": "main",
"index": 0
}
]
]
},
"Text extract2": {
"main": [
[
{
"node": "Merge3",
"type": "main",
"index": 0
}
]
]
},
"Text extract3": {
"main": [
[
{
"node": "Aggregate5",
"type": "main",
"index": 0
}
]
]
},
"Merge Searches": {
"main": [
[
{
"node": "Remove Empty",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Posts": {
"main": [
[
{
"node": "Count Posts",
"type": "main",
"index": 0
}
]
]
},
"Attach Metadata": {
"main": [
[
{
"node": "Filter",
"type": "main",
"index": 0
}
]
]
},
"Fetch Homepage1": {
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.
anthropicApiredditOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow is designed for marketers, founders, agencies, and product teams who want to understand how real customers talk about a product category, market, or problem space.
Source: https://n8n.io/workflows/15357/ — 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.
This workflow streamlines academic paper development through a multi-agent AI architecture that collects references, drafts individual sections autonomously, compiles the manuscript, and exports a pro
This workflow is designed for marketers, founders, agencies, and content teams who want to generate static ad creatives faster from minimal brand input.
This workflow turns Reddit pain points into emotionally-driven comic-style ads using AI. It takes in a product description, scrapes Reddit for real user pain points, filters relevant posts using AI, g
Creators, agencies, and marketers who need short-form vertical video at scale. Anyone who wants to turn a topic into an edited “talking shorts” style clip without opening a video editor.
This workflow is designed for ecommerce brands, marketers, agencies, and content teams who want to generate static product ads faster from minimal product input.