{"prompt": "How would you build: Ai Overview Analyzer?", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 5\n- Node Types: @n8n/n8n-nodes-langchain.agent, @n8n/n8n-nodes-langchain.memoryBufferWindow, @n8n/n8n-nodes-langchain.lmChatOpenAi, @n8n/n8n-nodes-langchain.toolWorkflow, @n8n/n8n-nodes-langchain.chatTrigger\n\n**Logic Flow**:\n1. **Trigger**: @n8n/n8n-nodes-langchain.chatTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"AI Overview Analyzer\",\n \"nodes\": [\n {\n \"parameters\": {\n \"options\": {}\n },\n \"type\": \"@n8n/n8n-nodes-langchain.chatTrigger\",\n \"typeVersion\": 1.3,\n \"position\": [\n 0,\n 0\n ],\n \"id\": \"72ac6c8d-a373-4d71-849a-75ed6716b9b1\",\n \"name\": \"When chat message received\",\n \"webhookId\": \"715bcc67-a6b6-4334-8141-83c123f35917\"\n },\n {\n \"parameters\": {\n \"contextWindowLength\": 10\n },\n \"type\": \"@n8n/n8n-nodes-langchain.memoryBufferWindow\",\n \"typeVersion\": 1.3,\n \"position\": [\n 304,\n 240\n ],\n \"id\": \"f16346fd-e166-4d5e-973e-0db4412d20e6\",\n \"name\": \"Simple Memory\"\n },\n {\n \"parameters\": {\n \"model\": {\n \"__rl\": true,\n \"value\": \"gpt-4.1\",\n \"mode\": \"list\",\n \"cachedResultName\": \"gpt-4.1\"\n },\n \"options\": {\n \"temperature\": 0\n }\n },\n \"type\": \"@n8n/n8n-nodes-langchain.lmChatOpenAi\",\n \"typeVersion\": 1.2,\n \"position\": [\n 144,\n 240\n ],\n \"id\": \"7887d008-b881-4387-91cb-cd824bbd553f\",\n \"name\": \"GPT-4.1\",\n \"credentials\": {\n \"openAiApi\": {\n \"id\": \"RAj3VxCHt0rIwBTk\",\n \"name\": \"OpenAI\"\n }\n }\n },\n {\n \"parameters\": {\n \"description\": \"Call this tool to get the AI Overview from Google.\",\n \"workflowId\": {\n \"__rl\": true,\n \"value\": \"4ViOjawp2E5PbJsu\",\n \"mode\": \"list\",\n \"cachedResultName\": \"Analyze AI Overview\"\n },\n \"workflowInputs\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"gl\": \"={{ $fromAI('country') }}\",\n \"q\": \"={{ $fromAI('query') }}\",\n \"location\": \"={{ $fromAI('location') }}\",\n \"hl\": \"={{ $fromAI('host_language') }}\"\n },\n \"matchingColumns\": [],\n \"schema\": [\n {\n \"id\": \"gl\",\n \"displayName\": \"gl\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"q\",\n \"displayName\": \"q\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"location\",\n \"displayName\": \"location\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"hl\",\n \"displayName\": \"hl\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": false\n }\n },\n \"type\": \"@n8n/n8n-nodes-langchain.toolWorkflow\",\n \"typeVersion\": 2.2,\n \"position\": [\n 464,\n 240\n ],\n \"id\": \"38bb6138-e3c9-4850-aa4b-bc5b5d28f2ed\",\n \"name\": \"Analyze AI Overview\"\n },\n {\n \"parameters\": {\n \"options\": {\n \"systemMessage\": \"=You are an elite SEO Analyst Agent. Your purpose is to deconstruct Google's AI Overviews with surgical precision, providing clients with a decisive competitive advantage. You don't just report data; you interpret it to reveal the underlying logic of the SERP and build winning content strategies.\\n\\n**1. YOUR PRIMARY TOOL: `Analyze AI Overview`**\\n\\nYou have one tool: `Analyze AI Overview`.\\n\\n* **Function:** It extracts and analyzes the AI Overview for a given search query, country, and language.\\n* **Parameters:**\\n * `query` (string, required): The search term to analyze.\\n * `gl` (string, required): The country code (**two-letter ISO 3166-1 alpha-2**).\\n * `hl` (string, required): The language code (**two-letter ISO 3166-1 alpha-2**).\\n * `location` (string, optional): A specific geographic location.\\n\\n* **CRITICAL RULE:** You must translate user requests like \\\"Germany\\\" or \\\"the UK\\\" into the correct two-letter codes for `gl` and `hl` (e.g., Germany -> `gl: 'de'`, `hl: 'de'`). This is a core responsibility.\\n\\n**2. THE DATA YOU WILL RECEIVE**\\n\\nAfter calling the tool, you will receive a JSON object. Your analysis depends on a deep understanding of each key:\\n\\n* `aiOverview` (object):\\n * **What it is:** The raw, cleaned AI-generated result from Google. This is your **ground truth**.\\n * **What it means:** This object reveals the *narrative, tone, and language* that Google has determined best answers the user's query. It provides the context for everything else. Use its text to pull direct quotes and understand the *relationship* between different topics.\\n\\n* `categories` (array of strings):\\n * **What it is:** The main thematic sections Google used to structure its answer.\\n * **What it means:** This is Google's explicit blueprint for the ideal article structure. These are your `

` tags. They reveal the critical sub-intents you must satisfy.\\n\\n* `mentionedEntities` (array of strings):\\n * **What it is:** A list of all key products, brands, concepts, or people that Google featured.\\n * **What it means:** These are the non-negotiable topics for your content. Comprehensive coverage of these entities is essential for demonstrating topical breadth.\\n\\n* `dominantSources` (array of objects):\\n * **What it is:** A sorted list of the websites Google cited most frequently.\\n * **What it means:** This is your direct measure of **topical authority**. These are your primary competitors. Analyze their article `titles` to decode the winning content format (e.g., \\\"Top 10...\\\", \\\"Ultimate Guide...\\\", \\\"X vs Y...\\\").\\n\\n**3. YOUR GOAL AND WORKFLOW**\\n\\nYour goal is to deliver a strategic SEO consultation in a clear, structured report.\\n\\n1. **Acknowledge and Invoke:** Confirm the user's request, correctly identify the `query` and country, and immediately call the `Analyze AI Overview` tool with the correct ISO codes.\\n2. **Receive and Synthesize:** Once you receive the data, perform a deep analysis.\\n3. **Construct Your Report:** Present your findings to the user in a structured report with the following sections. **You must integrate insights from the `aiOverview` object throughout your analysis.**\\n\\n * **Executive Summary & User Intent:**\\n * Begin with a concise, one-sentence summary of the AI Overview's main point.\\n * Examine the initial paragraphs in `aiOverview.text_blocks`—Google often provides a direct thesis statement here.\\n * Use the `categories` array to explain the different facets and sub-intents of the query (e.g., \\\"Google sees this query as having three parts: understanding the types, knowing the benefits, and comparing the top options.\\\").\\n\\n * **Content Blueprint: How to Rank:**\\n * Provide a recommended structure for an article. Advise the user to use the `categories` as their main headings (`

`s).\\n * Instruct them to create sections for each of the `mentionedEntities`.\\n * **Crucially, advise them to use the snippets and paragraphs within the `aiOverview` object to understand the specific angles, features, and keywords Google has chosen to highlight for each entity.** This is the guide for *what to write* in each section.\\n\\n * **Competitive Landscape & Authority:**\\n * Identify the top 3-5 `dominantSources`. Explain *why* they are authoritative (high citation count).\\n * Analyze their article titles to reveal the proven content format. State clearly: \\\"The winning format for this query is a comprehensive listicle that includes the current year.\\\"\\n\\n * **Actionable SEO Strategy:**\\n * Provide a final, powerful summary. The goal is not just to create a blog post, but to create a resource that is a better, more comprehensive version of the AI Overview itself.\\n * **Example:** \\\"To rank for this query, your content must mirror the narrative and structure of the AI Overview. Create a comprehensive guide using the identified categories as your roadmap. Cover all mentioned entities in detail, using the language and angles Google has already prioritized. By doing this, you position your content as an authoritative resource that directly satisfies the search intent, similar to top-cited sources like [Source 1] and [Source 2].\\\"\"\n }\n },\n \"type\": \"@n8n/n8n-nodes-langchain.agent\",\n \"typeVersion\": 2.2,\n \"position\": [\n 208,\n 0\n ],\n \"id\": \"070d5d59-e2c9-4577-9391-2107be8d9abd\",\n \"name\": \"AI Overview Analyzer\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"When chat message received\": {\n \"main\": [\n [\n {\n \"node\": \"AI Overview Analyzer\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Simple Memory\": {\n \"ai_memory\": [\n [\n {\n \"node\": \"AI Overview Analyzer\",\n \"type\": \"ai_memory\",\n \"index\": 0\n }\n ]\n ]\n },\n \"GPT-4.1\": {\n \"ai_languageModel\": [\n [\n {\n \"node\": \"AI Overview Analyzer\",\n \"type\": \"ai_languageModel\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Analyze AI Overview\": {\n \"ai_tool\": [\n [\n {\n \"node\": \"AI Overview Analyzer\",\n \"type\": \"ai_tool\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"a2ce017e-2921-486a-a414-6a4bb0614743\",\n \"meta\": {\n \"templateCredsSetupCompleted\": true,\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"3BRvyoqRuX4QYWWV\",\n \"tags\": []\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "AI Overview Analyzer", "node_count": 5, "category": "General Automation"}} {"prompt": "How would you build: Analyze Ai Overview?", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 10\n- Node Types: n8n-nodes-base.set, n8n-nodes-base.executeWorkflowTrigger, n8n-nodes-base.if, n8n-nodes-base.httpRequest, n8n-nodes-base.code, n8n-nodes-base.merge\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.executeWorkflowTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"Analyze AI Overview\",\n \"nodes\": [\n {\n \"parameters\": {\n \"workflowInputs\": {\n \"values\": [\n {\n \"name\": \"gl\"\n },\n {\n \"name\": \"q\"\n },\n {\n \"name\": \"location\"\n },\n {\n \"name\": \"hl\"\n }\n ]\n }\n },\n \"type\": \"n8n-nodes-base.executeWorkflowTrigger\",\n \"typeVersion\": 1.1,\n \"position\": [\n -624,\n 320\n ],\n \"id\": \"1fadcfb7-077e-43f2-810c-27be1c0f6575\",\n \"name\": \"When Executed by Another Workflow\"\n },\n {\n \"parameters\": {\n \"url\": \"https://serpapi.com/search\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"serpApi\",\n \"sendQuery\": true,\n \"queryParameters\": {\n \"parameters\": [\n {\n \"name\": \"gl\",\n \"value\": \"={{ $json.gl }}\"\n },\n {\n \"name\": \"q\",\n \"value\": \"={{ $json.q }}\"\n },\n {\n \"name\": \"location\",\n \"value\": \"={{ $json.location }}\"\n },\n {\n \"name\": \"hl\",\n \"value\": \"={{ $json.hl }}\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n -400,\n 320\n ],\n \"id\": \"a66d8866-4e88-4216-8de2-d78bda030c61\",\n \"name\": \"GET SERP Results\",\n \"retryOnFail\": true,\n \"waitBetweenTries\": 5000,\n \"credentials\": {\n \"serpApi\": {\n \"id\": \"ip84lDL75JMRWLKs\",\n \"name\": \"SerpAPI Account\"\n }\n }\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"d8cbb599-3ec7-446b-be55-9f48e21b4d11\",\n \"name\": \"=serpapi_link\",\n \"value\": \"={{ $json.ai_overview.serpapi_link }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n -176,\n 224\n ],\n \"id\": \"57e716b3-86a8-4099-857c-9cdc62d1fbb6\",\n \"name\": \"Extract AI Overview Link\"\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"15ccf2c6-185c-4166-9efb-b899eab4944e\",\n \"leftValue\": \"={{ $json.serpapi_link }}\",\n \"rightValue\": \"\",\n \"operator\": {\n \"type\": \"string\",\n \"operation\": \"exists\",\n \"singleValue\": true\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.if\",\n \"typeVersion\": 2.2,\n \"position\": [\n 48,\n 224\n ],\n \"id\": \"eb887e5d-9c54-4177-b7c2-c1edf0a5a33a\",\n \"name\": \"Is Extra Request Required\"\n },\n {\n \"parameters\": {\n \"url\": \"={{ $json.serpapi_link }}\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"serpApi\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 272,\n 176\n ],\n \"id\": \"cc6d4f00-748f-4e53-ac7e-55b838f8511c\",\n \"name\": \"GET AI Overview\",\n \"credentials\": {\n \"serpApi\": {\n \"id\": \"ip84lDL75JMRWLKs\",\n \"name\": \"SerpAPI Account\"\n }\n }\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"6dc1587a-9266-43ac-8b0f-c31ce0a1dd2f\",\n \"name\": \"ai_overview\",\n \"value\": \"={{ $json.ai_overview }}\",\n \"type\": \"object\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 496,\n 176\n ],\n \"id\": \"2fa31f44-37ed-44df-a515-ef058b6c8094\",\n \"name\": \"Get AI Overview Content\"\n },\n {\n \"parameters\": {\n \"mode\": \"combine\",\n \"combineBy\": \"combineAll\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.merge\",\n \"typeVersion\": 3.2,\n \"position\": [\n 688,\n 320\n ],\n \"id\": \"4834b8ff-94ee-4e9a-b000-776204e00194\",\n \"name\": \"Merge Results\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"8d52f2cf-85e3-4c78-aa61-e3a05db8b718\",\n \"name\": \"ai_overview\",\n \"value\": \"={{ $json.ai_overview }}\",\n \"type\": \"object\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 864,\n 320\n ],\n \"id\": \"a74e565d-e3da-48b7-9279-8f23a7fde281\",\n \"name\": \"Get AI Overview\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"const inputData = items[0].json;\\n\\n// 1. Top-Level Validation: Check for errors or missing overview data first.\\nif (inputData?.ai_overview?.error || !inputData?.ai_overview?.text_blocks) {\\n return [{\\n json: {\\n categories: [],\\n mentionedEntities: [],\\n dominantSources: [],\\n aiOverview: inputData.ai_overview || {}, // Return the object even if it just contains an error\\n parsingError: inputData?.ai_overview?.error || \\\"No text_blocks found in the AI Overview.\\\"\\n }\\n }];\\n}\\n\\nconst aiOverview = inputData.ai_overview;\\nconst allReferences = aiOverview.references || [];\\n\\n// 2. Initialize Data Containers\\nconst categories = new Set();\\nconst mentionedEntities = new Set();\\nconst referenceCounts = {};\\n\\n// --- Recursive Parsing Engine ---\\n\\n/**\\n * Recursively processes an array of text_blocks to extract data.\\n * This function can call itself to handle deeply nested structures.\\n * @param {Array} blocks - An array of text_block objects.\\n */\\nfunction parseTextBlocks(blocks) {\\n if (!blocks || !Array.isArray(blocks)) {\\n return;\\n }\\n\\n for (let i = 0; i < blocks.length; i++) {\\n const block = blocks[i];\\n if (!block) continue;\\n\\n // A. Aggregate all reference indexes found at any level\\n if (block.reference_indexes) {\\n block.reference_indexes.forEach(index => {\\n referenceCounts[index] = (referenceCounts[index] || 0) + 1;\\n });\\n }\\n\\n // B. Process Blocks by Type\\n switch (block.type) {\\n case 'heading':\\n if (block.snippet) categories.add(block.snippet.trim());\\n break;\\n\\n case 'expandable':\\n if (block.title) categories.add(block.title.trim());\\n parseTextBlocks(block.text_blocks);\\n break;\\n\\n case 'paragraph':\\n const nextBlock = blocks[i + 1];\\n if (nextBlock && ['list', 'table', 'comparison'].includes(nextBlock.type)) {\\n if (block.snippet) categories.add(block.snippet.trim());\\n }\\n break;\\n\\n case 'list':\\n if (block.list) {\\n block.list.forEach(item => {\\n let entityName = '';\\n if (item.title) {\\n entityName = item.title.replace(':', '').trim();\\n } else if (item.snippet) {\\n entityName = item.snippet.split(/[:.]/)[0].trim();\\n }\\n if (entityName) mentionedEntities.add(entityName);\\n\\n if (item.reference_indexes) {\\n item.reference_indexes.forEach(index => {\\n referenceCounts[index] = (referenceCounts[index] || 0) + 1;\\n });\\n }\\n \\n if (item.text_blocks) {\\n parseTextBlocks(item.text_blocks);\\n }\\n });\\n }\\n break;\\n\\n case 'comparison':\\n if (block.product_labels) {\\n block.product_labels.forEach(label => mentionedEntities.add(label.trim()));\\n }\\n break;\\n \\n case 'table':\\n if (block.table?.rows?.length > 0) {\\n const firstHeader = block.table.headers?.[0];\\n if (firstHeader) {\\n for (const row of block.table.rows) {\\n if (row[firstHeader]) {\\n mentionedEntities.add(row[firstHeader].trim());\\n }\\n }\\n }\\n }\\n break;\\n }\\n }\\n}\\n\\n// 3. Initial Call to the Recursive Parser\\nparseTextBlocks(aiOverview.text_blocks);\\n\\n// 4. Process and Sort Source Authority\\nconst dominantSources = Object.entries(referenceCounts)\\n .map(([index, citations]) => {\\n const refDetails = allReferences.find(ref => ref.index == index);\\n return {\\n source: refDetails?.source || 'Unknown',\\n title: refDetails?.title || 'Unknown',\\n link: refDetails?.link || 'Unknown',\\n citations: citations,\\n index: parseInt(index)\\n };\\n })\\n .sort((a, b) => b.citations - a.citations);\\n\\n// --- NEW: Clean and Prepare the Original AI Overview ---\\n// Create a deep copy to avoid modifying the original input object.\\nconst cleanedOverview = JSON.parse(JSON.stringify(aiOverview));\\n\\n// Remove token-consuming fields that are not needed by the agent for its analysis.\\ndelete cleanedOverview.page_token;\\ndelete cleanedOverview.serpapi_link;\\n\\n// 5. Assemble and Return the Final, Comprehensive Data Object\\nconst preparedData = {\\n categories: Array.from(categories),\\n mentionedEntities: Array.from(mentionedEntities),\\n dominantSources: dominantSources,\\n aiOverview: cleanedOverview // The cleaned, original overview is now included.\\n};\\n\\nreturn [{\\n json: preparedData\\n}];\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 1056,\n 320\n ],\n \"id\": \"86f97f90-7e95-4f50-a1a9-9aa0b2517f9e\",\n \"name\": \"Analyze AI Overview\",\n \"onError\": \"continueErrorOutput\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"3637b044-e944-49d1-a983-d2103c499100\",\n \"name\": \"message\",\n \"value\": \"={{ $json.error }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 1264,\n 416\n ],\n \"id\": \"f8aa096d-2ee4-4588-994d-d87bef412bc3\",\n \"name\": \"Return Error Message\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"When Executed by Another Workflow\": {\n \"main\": [\n [\n {\n \"node\": \"GET SERP Results\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"GET SERP Results\": {\n \"main\": [\n [\n {\n \"node\": \"Extract AI Overview Link\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"Merge Results\",\n \"type\": \"main\",\n \"index\": 1\n }\n ]\n ]\n },\n \"Extract AI Overview Link\": {\n \"main\": [\n [\n {\n \"node\": \"Is Extra Request Required\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Is Extra Request Required\": {\n \"main\": [\n [\n {\n \"node\": \"GET AI Overview\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"Merge Results\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"GET AI Overview\": {\n \"main\": [\n [\n {\n \"node\": \"Get AI Overview Content\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get AI Overview Content\": {\n \"main\": [\n [\n {\n \"node\": \"Merge Results\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Merge Results\": {\n \"main\": [\n [\n {\n \"node\": \"Get AI Overview\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get AI Overview\": {\n \"main\": [\n [\n {\n \"node\": \"Analyze AI Overview\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Analyze AI Overview\": {\n \"main\": [\n [],\n [\n {\n \"node\": \"Return Error Message\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"0e1cf286-be3b-4818-aee8-93589437147b\",\n \"meta\": {\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"4ViOjawp2E5PbJsu\",\n \"tags\": []\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "Analyze AI Overview", "node_count": 10, "category": "General Automation"}} {"prompt": "Create an n8n automation that handles general automation", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 6\n- Node Types: @n8n/n8n-nodes-langchain.agent, @n8n/n8n-nodes-langchain.memoryBufferWindow, @n8n/n8n-nodes-langchain.lmChatOpenAi, @n8n/n8n-nodes-langchain.toolWorkflow, @n8n/n8n-nodes-langchain.chatTrigger\n\n**Logic Flow**:\n1. **Trigger**: @n8n/n8n-nodes-langchain.chatTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"AI Overview Optimizer\",\n \"nodes\": [\n {\n \"parameters\": {\n \"options\": {}\n },\n \"type\": \"@n8n/n8n-nodes-langchain.chatTrigger\",\n \"typeVersion\": 1.3,\n \"position\": [\n 0,\n 0\n ],\n \"id\": \"5bd86f24-dc44-422b-af64-9d48f2e75b97\",\n \"name\": \"When chat message received\",\n \"webhookId\": \"0ee028e9-419a-413a-a3f5-43ad95498ffa\"\n },\n {\n \"parameters\": {\n \"contextWindowLength\": 10\n },\n \"type\": \"@n8n/n8n-nodes-langchain.memoryBufferWindow\",\n \"typeVersion\": 1.3,\n \"position\": [\n 192,\n 240\n ],\n \"id\": \"8224aa60-4aaf-4157-9367-4b9bfd7bc5d4\",\n \"name\": \"Simple Memory\"\n },\n {\n \"parameters\": {\n \"model\": {\n \"__rl\": true,\n \"value\": \"gpt-4.1\",\n \"mode\": \"list\",\n \"cachedResultName\": \"gpt-4.1\"\n },\n \"options\": {\n \"temperature\": 0\n }\n },\n \"type\": \"@n8n/n8n-nodes-langchain.lmChatOpenAi\",\n \"typeVersion\": 1.2,\n \"position\": [\n 32,\n 240\n ],\n \"id\": \"a3c53901-3ffd-4bf9-849a-e525d8c6cb3c\",\n \"name\": \"GPT-4.1\",\n \"credentials\": {\n \"openAiApi\": {\n \"id\": \"RAj3VxCHt0rIwBTk\",\n \"name\": \"OpenAI\"\n }\n }\n },\n {\n \"parameters\": {\n \"description\": \"Call this tool to get the AI Overview from Google.\",\n \"workflowId\": {\n \"__rl\": true,\n \"value\": \"4ViOjawp2E5PbJsu\",\n \"mode\": \"list\",\n \"cachedResultName\": \"Analyze AI Overview\"\n },\n \"workflowInputs\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"gl\": \"={{ $fromAI('country') }}\",\n \"q\": \"={{ $fromAI('query') }}\",\n \"location\": \"={{ $fromAI('location') }}\",\n \"hl\": \"={{ $fromAI('host_language') }}\"\n },\n \"matchingColumns\": [],\n \"schema\": [\n {\n \"id\": \"gl\",\n \"displayName\": \"gl\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"q\",\n \"displayName\": \"q\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"location\",\n \"displayName\": \"location\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"hl\",\n \"displayName\": \"hl\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": false\n }\n },\n \"type\": \"@n8n/n8n-nodes-langchain.toolWorkflow\",\n \"typeVersion\": 2.2,\n \"position\": [\n 368,\n 240\n ],\n \"id\": \"e4ac29de-3669-4be4-9004-bbcb6ce4e414\",\n \"name\": \"Analyze AI Overview\"\n },\n {\n \"parameters\": {\n \"description\": \"Call this tool to scrape the content from a URL.\",\n \"workflowId\": {\n \"__rl\": true,\n \"value\": \"RkFq0paD5YLLof2K\",\n \"mode\": \"list\",\n \"cachedResultName\": \"Tool - Serper Crawl URL\"\n },\n \"workflowInputs\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"url\": \"={{ $fromAI('url') }}\"\n },\n \"matchingColumns\": [],\n \"schema\": [\n {\n \"id\": \"url\",\n \"displayName\": \"url\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\",\n \"removed\": false\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": false\n }\n },\n \"type\": \"@n8n/n8n-nodes-langchain.toolWorkflow\",\n \"typeVersion\": 2.2,\n \"position\": [\n 544,\n 240\n ],\n \"id\": \"43d9699e-6a8f-4c32-a853-98b1e5a58438\",\n \"name\": \"Get Article\"\n },\n {\n \"parameters\": {\n \"options\": {\n \"systemMessage\": \"=You are a Senior On-Page SEO Strategist, an expert at transforming good content into top-ranking articles. Your core methodology is data-driven: you first analyze what Google's AI Overview rewards for a target query, then you use that data as a benchmark to provide precise, actionable improvements for a user's article.\\n\\n**1. YOUR SEO TOOLKIT**\\n\\nYou have two specialized tools to perform your analysis:\\n\\n* **Tool 1: `Analyze AI Overview` (The Benchmark Tool)**\\n * **Function:** This is your first step. It scrapes and analyzes the AI Overview to establish the \\\"ground truth\\\"—what Google considers a perfect answer for a query.\\n * **Parameters:** `query`, `gl` (ISO code), `hl` (ISO code), `location` (optional). Use location only if the user says things like \\\"location\\\" or \\\"city\\\". Dont mismatch the country with the location.\\n * **CRITICAL RULE:** You must always translate user requests (e.g., \\\"Germany\\\") into the correct two-letter ISO codes.\\n\\n* **Tool 2: `Get Article` (The Content Review Tool)**\\n * **Function:** This is your second step. It fetches the key on-page elements of a user's article.\\n * **Parameters:** `url` (string, required): The URL of the article to be analyzed.\\n * **Output:** An object containing the article's `title`, `metaDescription`, and `content` (in Markdown).\\n\\n**2. DATA-DRIVEN STRATEGY: YOUR TWO DATA SOURCES**\\n\\nYour expertise comes from synthesizing two distinct data sets:\\n\\n* **The Blueprint for Success (from `Analyze AI Overview`):**\\n * `aiOverview`: The raw narrative and language Google prefers. This is your source for tone, depth, and specific phrasing.\\n * `categories`: The ideal article structure and required sub-topics (`

`s).\\n * `mentionedEntities`: The non-negotiable concepts, products, or brands that must be covered.\\n * `dominantSources`: Your competitors and the proven-to-work title formats.\\n\\n* **The Content Under Review (from `AnalyzeArticleContent`):**\\n * `title`, `metaDescription`, `content`: The current state of the user's article that you need to improve.\\n\\n**3. YOUR GOAL AND WORKFLOW: THE GAP ANALYSIS REPORT**\\n\\nYour goal is to deliver a comprehensive, actionable SEO improvement plan. When a user provides a query and a URL, you must follow this exact two-step process:\\n\\n1. **Step 1: Establish the Benchmark.** Acknowledge the user's request. Immediately call `Analyze AI Overview` with the user's target `query` and country. You cannot proceed without this data.\\n2. **Step 2: Review the Content.** Once you have the benchmark, call `AnalyzeArticleContent` with the user's `url`.\\n3. **Step 3: Synthesize and Deliver the Report.** Present your findings in the following structured format. You must compare the \\\"Content Under Review\\\" against the \\\"Blueprint for Success\\\" in every section.\\n\\n---\\n\\n### **SEO Improvement Report: [User's Query]**\\n\\n**Executive Summary:**\\nStart with a 1-2 sentence summary of your findings. Example: \\\"Your article has a solid foundation, but it's missing several key thematic sections and entities that Google's AI Overview has identified as critical for satisfying user intent for this query. The following improvements will align your content more closely with what is currently ranking.\\\"\\n\\n#### **1. Title & Meta Description Optimization**\\n\\n* **Analysis:** Briefly state how the current title/meta compares to the `dominantSources`.\\n* **Title Improvement:**\\n * **Now:** \\\"[Insert the user's current `title` here]\\\"\\n * **Better:** \\\"[Provide a new, optimized title that incorporates keywords from the `aiOverview` and matches the format of the `dominantSources` (e.g., includes the year, a number, or a key benefit).]\\\"\\n* **Meta Description Improvement:**\\n * **Now:** \\\"[Insert the user's current `metaDescription` here]\\\"\\n * **Better:** \\\"[Write a new, compelling meta description that summarizes the core answer from the `aiOverview` and includes primary keywords.]\\\"\\n\\n#### **2. Outline Strategy & Content Gap Analysis**\\n\\n* **Analysis:** State which `categories` and `mentionedEntities` from the benchmark are missing from the user's article `content`.\\n* **Recommended Outline Additions:**\\n * **Missing Category:** \\\"[Name of the first missing `category`]\\\"\\n * **Why it's important:** \\\"Google has dedicated a section to this, indicating it's a critical part of the user's search journey. You should add an `

` section covering this topic.\\\"\\n * **Missing Entity:** \\\"[Name of a key missing `mentionedEntity`]\\\"\\n * **Why it's important:** \\\"This [product/brand/concept] was explicitly featured in the AI Overview. Failing to cover it leaves a significant content gap.\\\"\\n * *(Continue for the top 3-5 most important gaps)*\\n\\n#### **3. Specific Content Enhancement**\\n\\n* **Analysis:** Identify a specific section in the user's `content` that is weak, vague, or less comprehensive than the corresponding section in the `aiOverview` object.\\n* **Content Improvement Example:**\\n * **Now (from your article):**\\n > \\\"[Quote a 1-3 sentence passage from the user's `content` that could be improved.]\\\"\\n * **Better (inspired by the AI Overview):**\\n > \\\"[Write a new, more detailed and authoritative version of that passage. Use the language, keywords, and data points found in the `aiOverview.text_blocks` to make it more comprehensive and valuable.]\\\"\\n\\n#### **4. Key Actions Summary**\\n\\nConclude with a bulleted list of the 3-4 most critical actions the user should take first.\\n* **Update Title & Meta:** Implement the suggested improvements to increase CTR.\\n* **Add Missing Sections:** Prioritize adding the sections on \\\"[Missing Category 1]\\\" and \\\"[Missing Category 2]\\\" to your article outline.\\n* **Incorporate Key Entities:** Ensure you discuss \\\"[Missing Entity 1]\\\" and \\\"[Missing Entity 2]\\\".\\n* **Enhance Content Depth:** Revise the section on \\\"[Topic from 'Better' example]\\\" to be more detailed, as shown in the example.\"\n }\n },\n \"type\": \"@n8n/n8n-nodes-langchain.agent\",\n \"typeVersion\": 2.2,\n \"position\": [\n 208,\n 0\n ],\n \"id\": \"dd2518be-19d4-46f2-8645-1e38963b3a9f\",\n \"name\": \"AI Overview Optimizer\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"When chat message received\": {\n \"main\": [\n [\n {\n \"node\": \"AI Overview Optimizer\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Simple Memory\": {\n \"ai_memory\": [\n [\n {\n \"node\": \"AI Overview Optimizer\",\n \"type\": \"ai_memory\",\n \"index\": 0\n }\n ]\n ]\n },\n \"GPT-4.1\": {\n \"ai_languageModel\": [\n [\n {\n \"node\": \"AI Overview Optimizer\",\n \"type\": \"ai_languageModel\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Analyze AI Overview\": {\n \"ai_tool\": [\n [\n {\n \"node\": \"AI Overview Optimizer\",\n \"type\": \"ai_tool\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Article\": {\n \"ai_tool\": [\n [\n {\n \"node\": \"AI Overview Optimizer\",\n \"type\": \"ai_tool\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"cfbaddc5-50b4-45dc-8cd3-ccc6ff104a92\",\n \"meta\": {\n \"templateCredsSetupCompleted\": true,\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"E0pES53DgI9q8E69\",\n \"tags\": []\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "AI Overview Optimizer", "node_count": 6, "category": "General Automation"}} {"prompt": "How would you build: Analyze Ai Overview?", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 10\n- Node Types: n8n-nodes-base.set, n8n-nodes-base.executeWorkflowTrigger, n8n-nodes-base.if, n8n-nodes-base.httpRequest, n8n-nodes-base.code, n8n-nodes-base.merge\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.executeWorkflowTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"Analyze AI Overview\",\n \"nodes\": [\n {\n \"parameters\": {\n \"workflowInputs\": {\n \"values\": [\n {\n \"name\": \"gl\"\n },\n {\n \"name\": \"q\"\n },\n {\n \"name\": \"location\"\n },\n {\n \"name\": \"hl\"\n }\n ]\n }\n },\n \"type\": \"n8n-nodes-base.executeWorkflowTrigger\",\n \"typeVersion\": 1.1,\n \"position\": [\n -624,\n 320\n ],\n \"id\": \"1fadcfb7-077e-43f2-810c-27be1c0f6575\",\n \"name\": \"When Executed by Another Workflow\"\n },\n {\n \"parameters\": {\n \"url\": \"https://serpapi.com/search\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"serpApi\",\n \"sendQuery\": true,\n \"queryParameters\": {\n \"parameters\": [\n {\n \"name\": \"gl\",\n \"value\": \"={{ $json.gl }}\"\n },\n {\n \"name\": \"q\",\n \"value\": \"={{ $json.q }}\"\n },\n {\n \"name\": \"location\",\n \"value\": \"={{ $json.location }}\"\n },\n {\n \"name\": \"hl\",\n \"value\": \"={{ $json.hl }}\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n -400,\n 320\n ],\n \"id\": \"a66d8866-4e88-4216-8de2-d78bda030c61\",\n \"name\": \"GET SERP Results\",\n \"retryOnFail\": true,\n \"waitBetweenTries\": 5000,\n \"credentials\": {\n \"serpApi\": {\n \"id\": \"ip84lDL75JMRWLKs\",\n \"name\": \"SerpAPI Account\"\n }\n }\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"d8cbb599-3ec7-446b-be55-9f48e21b4d11\",\n \"name\": \"=serpapi_link\",\n \"value\": \"={{ $json.ai_overview.serpapi_link }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n -176,\n 224\n ],\n \"id\": \"57e716b3-86a8-4099-857c-9cdc62d1fbb6\",\n \"name\": \"Extract AI Overview Link\"\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"15ccf2c6-185c-4166-9efb-b899eab4944e\",\n \"leftValue\": \"={{ $json.serpapi_link }}\",\n \"rightValue\": \"\",\n \"operator\": {\n \"type\": \"string\",\n \"operation\": \"exists\",\n \"singleValue\": true\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.if\",\n \"typeVersion\": 2.2,\n \"position\": [\n 48,\n 224\n ],\n \"id\": \"eb887e5d-9c54-4177-b7c2-c1edf0a5a33a\",\n \"name\": \"Is Extra Request Required\"\n },\n {\n \"parameters\": {\n \"url\": \"={{ $json.serpapi_link }}\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"serpApi\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 272,\n 176\n ],\n \"id\": \"cc6d4f00-748f-4e53-ac7e-55b838f8511c\",\n \"name\": \"GET AI Overview\",\n \"credentials\": {\n \"serpApi\": {\n \"id\": \"ip84lDL75JMRWLKs\",\n \"name\": \"SerpAPI Account\"\n }\n }\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"6dc1587a-9266-43ac-8b0f-c31ce0a1dd2f\",\n \"name\": \"ai_overview\",\n \"value\": \"={{ $json.ai_overview }}\",\n \"type\": \"object\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 496,\n 176\n ],\n \"id\": \"2fa31f44-37ed-44df-a515-ef058b6c8094\",\n \"name\": \"Get AI Overview Content\"\n },\n {\n \"parameters\": {\n \"mode\": \"combine\",\n \"combineBy\": \"combineAll\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.merge\",\n \"typeVersion\": 3.2,\n \"position\": [\n 688,\n 320\n ],\n \"id\": \"4834b8ff-94ee-4e9a-b000-776204e00194\",\n \"name\": \"Merge Results\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"8d52f2cf-85e3-4c78-aa61-e3a05db8b718\",\n \"name\": \"ai_overview\",\n \"value\": \"={{ $json.ai_overview }}\",\n \"type\": \"object\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 864,\n 320\n ],\n \"id\": \"a74e565d-e3da-48b7-9279-8f23a7fde281\",\n \"name\": \"Get AI Overview\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"const inputData = items[0].json;\\n\\n// 1. Top-Level Validation: Check for errors or missing overview data first.\\nif (inputData?.ai_overview?.error || !inputData?.ai_overview?.text_blocks) {\\n return [{\\n json: {\\n categories: [],\\n mentionedEntities: [],\\n dominantSources: [],\\n aiOverview: inputData.ai_overview || {}, // Return the object even if it just contains an error\\n parsingError: inputData?.ai_overview?.error || \\\"No text_blocks found in the AI Overview.\\\"\\n }\\n }];\\n}\\n\\nconst aiOverview = inputData.ai_overview;\\nconst allReferences = aiOverview.references || [];\\n\\n// 2. Initialize Data Containers\\nconst categories = new Set();\\nconst mentionedEntities = new Set();\\nconst referenceCounts = {};\\n\\n// --- Recursive Parsing Engine ---\\n\\n/**\\n * Recursively processes an array of text_blocks to extract data.\\n * This function can call itself to handle deeply nested structures.\\n * @param {Array} blocks - An array of text_block objects.\\n */\\nfunction parseTextBlocks(blocks) {\\n if (!blocks || !Array.isArray(blocks)) {\\n return;\\n }\\n\\n for (let i = 0; i < blocks.length; i++) {\\n const block = blocks[i];\\n if (!block) continue;\\n\\n // A. Aggregate all reference indexes found at any level\\n if (block.reference_indexes) {\\n block.reference_indexes.forEach(index => {\\n referenceCounts[index] = (referenceCounts[index] || 0) + 1;\\n });\\n }\\n\\n // B. Process Blocks by Type\\n switch (block.type) {\\n case 'heading':\\n if (block.snippet) categories.add(block.snippet.trim());\\n break;\\n\\n case 'expandable':\\n if (block.title) categories.add(block.title.trim());\\n parseTextBlocks(block.text_blocks);\\n break;\\n\\n case 'paragraph':\\n const nextBlock = blocks[i + 1];\\n if (nextBlock && ['list', 'table', 'comparison'].includes(nextBlock.type)) {\\n if (block.snippet) categories.add(block.snippet.trim());\\n }\\n break;\\n\\n case 'list':\\n if (block.list) {\\n block.list.forEach(item => {\\n let entityName = '';\\n if (item.title) {\\n entityName = item.title.replace(':', '').trim();\\n } else if (item.snippet) {\\n entityName = item.snippet.split(/[:.]/)[0].trim();\\n }\\n if (entityName) mentionedEntities.add(entityName);\\n\\n if (item.reference_indexes) {\\n item.reference_indexes.forEach(index => {\\n referenceCounts[index] = (referenceCounts[index] || 0) + 1;\\n });\\n }\\n \\n if (item.text_blocks) {\\n parseTextBlocks(item.text_blocks);\\n }\\n });\\n }\\n break;\\n\\n case 'comparison':\\n if (block.product_labels) {\\n block.product_labels.forEach(label => mentionedEntities.add(label.trim()));\\n }\\n break;\\n \\n case 'table':\\n if (block.table?.rows?.length > 0) {\\n const firstHeader = block.table.headers?.[0];\\n if (firstHeader) {\\n for (const row of block.table.rows) {\\n if (row[firstHeader]) {\\n mentionedEntities.add(row[firstHeader].trim());\\n }\\n }\\n }\\n }\\n break;\\n }\\n }\\n}\\n\\n// 3. Initial Call to the Recursive Parser\\nparseTextBlocks(aiOverview.text_blocks);\\n\\n// 4. Process and Sort Source Authority\\nconst dominantSources = Object.entries(referenceCounts)\\n .map(([index, citations]) => {\\n const refDetails = allReferences.find(ref => ref.index == index);\\n return {\\n source: refDetails?.source || 'Unknown',\\n title: refDetails?.title || 'Unknown',\\n link: refDetails?.link || 'Unknown',\\n citations: citations,\\n index: parseInt(index)\\n };\\n })\\n .sort((a, b) => b.citations - a.citations);\\n\\n// --- NEW: Clean and Prepare the Original AI Overview ---\\n// Create a deep copy to avoid modifying the original input object.\\nconst cleanedOverview = JSON.parse(JSON.stringify(aiOverview));\\n\\n// Remove token-consuming fields that are not needed by the agent for its analysis.\\ndelete cleanedOverview.page_token;\\ndelete cleanedOverview.serpapi_link;\\n\\n// 5. Assemble and Return the Final, Comprehensive Data Object\\nconst preparedData = {\\n categories: Array.from(categories),\\n mentionedEntities: Array.from(mentionedEntities),\\n dominantSources: dominantSources,\\n aiOverview: cleanedOverview // The cleaned, original overview is now included.\\n};\\n\\nreturn [{\\n json: preparedData\\n}];\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 1056,\n 320\n ],\n \"id\": \"86f97f90-7e95-4f50-a1a9-9aa0b2517f9e\",\n \"name\": \"Analyze AI Overview\",\n \"onError\": \"continueErrorOutput\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"3637b044-e944-49d1-a983-d2103c499100\",\n \"name\": \"message\",\n \"value\": \"={{ $json.error }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 1264,\n 416\n ],\n \"id\": \"f8aa096d-2ee4-4588-994d-d87bef412bc3\",\n \"name\": \"Return Error Message\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"When Executed by Another Workflow\": {\n \"main\": [\n [\n {\n \"node\": \"GET SERP Results\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"GET SERP Results\": {\n \"main\": [\n [\n {\n \"node\": \"Extract AI Overview Link\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"Merge Results\",\n \"type\": \"main\",\n \"index\": 1\n }\n ]\n ]\n },\n \"Extract AI Overview Link\": {\n \"main\": [\n [\n {\n \"node\": \"Is Extra Request Required\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Is Extra Request Required\": {\n \"main\": [\n [\n {\n \"node\": \"GET AI Overview\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"Merge Results\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"GET AI Overview\": {\n \"main\": [\n [\n {\n \"node\": \"Get AI Overview Content\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get AI Overview Content\": {\n \"main\": [\n [\n {\n \"node\": \"Merge Results\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Merge Results\": {\n \"main\": [\n [\n {\n \"node\": \"Get AI Overview\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get AI Overview\": {\n \"main\": [\n [\n {\n \"node\": \"Analyze AI Overview\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Analyze AI Overview\": {\n \"main\": [\n [],\n [\n {\n \"node\": \"Return Error Message\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"0e1cf286-be3b-4818-aee8-93589437147b\",\n \"meta\": {\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"4ViOjawp2E5PbJsu\",\n \"tags\": []\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "Analyze AI Overview", "node_count": 10, "category": "General Automation"}} {"prompt": "Show me an n8n workflow for tool serper crawl url", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 3\n- Node Types: n8n-nodes-base.set, n8n-nodes-base.executeWorkflowTrigger, n8n-nodes-base.httpRequest\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.executeWorkflowTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"Tool - Serper Crawl URL\",\n \"nodes\": [\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"7320f474-4ba6-47b7-9ce7-82529cbb12ff\",\n \"name\": \"title\",\n \"value\": \"={{ $json.metadata.title }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"a047ca1d-04e0-493b-9d88-eddc4ec4478c\",\n \"name\": \"description\",\n \"value\": \"={{ $json.metadata.description }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"607f18e4-364c-4594-8821-3800b28d3c9b\",\n \"name\": \"markdown\",\n \"value\": \"={{ $json.markdown }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 288,\n 0\n ],\n \"id\": \"635191a6-85dc-439d-8616-ceabb5294a71\",\n \"name\": \"Get Metadata\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://scrape.serper.dev\",\n \"authentication\": \"genericCredentialType\",\n \"genericAuthType\": \"httpHeaderAuth\",\n \"sendQuery\": true,\n \"queryParameters\": {\n \"parameters\": [\n {\n \"name\": \"url\",\n \"value\": \"={{ $json.url }}\"\n },\n {\n \"name\": \"includeMarkdown\",\n \"value\": \"true\"\n }\n ]\n },\n \"sendHeaders\": true,\n \"headerParameters\": {\n \"parameters\": [\n {\n \"name\": \"Content-Type\",\n \"value\": \"application/json\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 64,\n 0\n ],\n \"id\": \"b53e65c6-0b22-4b89-b718-32143058205e\",\n \"name\": \"Serper\",\n \"credentials\": {\n \"httpHeaderAuth\": {\n \"id\": \"9PtnIrGtPxKAKD1J\",\n \"name\": \"Serper Demo\"\n }\n }\n },\n {\n \"parameters\": {\n \"workflowInputs\": {\n \"values\": [\n {\n \"name\": \"url\"\n }\n ]\n }\n },\n \"type\": \"n8n-nodes-base.executeWorkflowTrigger\",\n \"typeVersion\": 1.1,\n \"position\": [\n -160,\n 0\n ],\n \"id\": \"59fec696-d611-4a2d-b35b-ea3a7e7e7957\",\n \"name\": \"When Executed by Another Workflow\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"Get Metadata\": {\n \"main\": [\n []\n ]\n },\n \"Serper\": {\n \"main\": [\n [\n {\n \"node\": \"Get Metadata\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"When Executed by Another Workflow\": {\n \"main\": [\n [\n {\n \"node\": \"Serper\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"ae02df80-65d7-4c6e-b6dc-0aa012fe0f47\",\n \"meta\": {\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"RkFq0paD5YLLof2K\",\n \"tags\": []\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "Tool - Serper Crawl URL", "node_count": 3, "category": "General Automation"}} {"prompt": "How would you build: Product Google Search Console Api Examples?", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 36\n- Node Types: n8n-nodes-base.code, n8n-nodes-base.manualTrigger, n8n-nodes-base.stickyNote, n8n-nodes-base.httpRequest\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.manualTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"Product - Google Search Console API Examples\",\n \"nodes\": [\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.manualTrigger\",\n \"typeVersion\": 1,\n \"position\": [\n -1000,\n 200\n ],\n \"id\": \"5d1adc86-fe51-412e-8aea-cbaf4e9cf708\",\n \"name\": \"When clicking ‘Test workflow’\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/v1/urlInspection/index:inspect\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"inspectionUrl\\\": \\\"https://your-domain.com/slug/\\\",\\n \\\"siteUrl\\\": \\\"https://your-domain.com/\\\"\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n -400,\n 340\n ],\n \"id\": \"561fd96f-17af-45d5-90ac-a8f14e833d35\",\n \"name\": \"Inspect URL\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"content\": \"## Inspect URLs\",\n \"height\": 240,\n \"width\": 260\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -460,\n 260\n ],\n \"id\": \"48d24e88-5869-4d91-b3a4-97ecad871d4c\",\n \"name\": \"Sticky Note\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-02-26\\\",\\n \\\"endDate\\\": \\\"2025-03-26\\\",\\n \\\"dimensions\\\": [\\\"device\\\"],\\n \\\"rowLimit\\\": 5000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 380,\n 340\n ],\n \"id\": \"007c4c43-20d1-486f-b817-b5e0de051191\",\n \"name\": \"Get Device Performance\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsCode\": \"const rows = $input.item.json.rows;\\n\\n// Map each row to a cleaner format with calculations\\nconst deviceData = rows.map(row => {\\n return {\\n device: row.keys[0],\\n clicks: row.clicks,\\n impressions: row.impressions,\\n ctr: row.ctr,\\n position: row.position,\\n ctrFormatted: `${(row.ctr * 100).toFixed(2)}%`,\\n positionRounded: Math.round(row.position * 10) / 10\\n };\\n});\\n\\n// Calculate totals for percentage analysis\\nconst totals = deviceData.reduce((acc, item) => {\\n acc.totalClicks += item.clicks;\\n acc.totalImpressions += item.impressions;\\n return acc;\\n}, { totalClicks: 0, totalImpressions: 0 });\\n\\n// Add percentage calculations\\nreturn deviceData.map(item => {\\n const clickShare = ((item.clicks / totals.totalClicks) * 100).toFixed(2);\\n const impressionShare = ((item.impressions / totals.totalImpressions) * 100).toFixed(2);\\n \\n return {\\n ...item,\\n clickShare: `${clickShare}%`,\\n impressionShare: `${impressionShare}%`\\n };\\n});\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 560,\n 340\n ],\n \"id\": \"2d7ae797-9838-43f7-a084-f2eb7f103a2c\",\n \"name\": \"Parse Device Performance\"\n },\n {\n \"parameters\": {\n \"content\": \"## Performance by Devices\",\n \"height\": 240,\n \"width\": 440\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 320,\n 260\n ],\n \"id\": \"3cddb3c0-7b87-46de-ad7c-48ff58f7c903\",\n \"name\": \"Sticky Note1\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-02-26\\\",\\n \\\"endDate\\\": \\\"2025-03-26\\\",\\n \\\"dimensions\\\": [\\\"page\\\"],\\n \\\"rowLimit\\\": 5000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n -120,\n 340\n ],\n \"id\": \"bb70e67a-46aa-4b14-8ae8-c8adf3eb19da\",\n \"name\": \"Get Top Performing Pages\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsCode\": \"const rows = $input.item.json.rows;\\n\\n// Map and calculate metrics for each page\\nconst pageData = rows.map(row => {\\n return {\\n page: row.keys[0],\\n clicks: row.clicks,\\n impressions: row.impressions,\\n ctr: row.ctr,\\n position: row.position,\\n ctrFormatted: `${(row.ctr * 100).toFixed(2)}%`,\\n positionRounded: Math.round(row.position * 10) / 10\\n };\\n});\\n\\n// Calculate totals for percentage analysis\\nconst totals = pageData.reduce((acc, item) => {\\n acc.totalClicks += item.clicks;\\n acc.totalImpressions += item.impressions;\\n return acc;\\n}, { totalClicks: 0, totalImpressions: 0 });\\n\\n// Sort by clicks (top performers first)\\nconst sortedPages = pageData.sort((a, b) => b.clicks - a.clicks);\\n\\n// Add comprehensive SEO metrics\\nreturn sortedPages.map((item, index) => {\\n const clickShare = ((item.clicks / totals.totalClicks) * 100).toFixed(2);\\n const impressionShare = ((item.impressions / totals.totalImpressions) * 100).toFixed(2);\\n \\n // SEO Performance Categories\\n let performanceCategory = 'Monitor';\\n if (item.ctr > 0.05 && item.position < 10) performanceCategory = 'Star Performer';\\n else if (item.ctr > 0.03 && item.position < 15) performanceCategory = 'Good Performer';\\n else if (item.impressions > 1000 && item.ctr < 0.02) performanceCategory = 'CTR Opportunity';\\n else if (item.position > 10 && item.position < 20 && item.impressions > 500) performanceCategory = 'Ranking Opportunity';\\n \\n // Precise Action Items based on data patterns\\n let actionItem = 'Monitor performance';\\n \\n if (item.impressions > 5000 && item.ctr < 0.015) {\\n actionItem = 'Rewrite title tag - very low CTR with high visibility';\\n } else if (item.impressions > 2000 && item.ctr < 0.025 && item.position < 10) {\\n actionItem = 'Optimize meta description - good position, poor CTR';\\n } else if (item.position >= 11 && item.position <= 20 && item.impressions > 1000) {\\n actionItem = 'Content optimization - close to page 1, good search volume';\\n } else if (item.position >= 4 && item.position <= 10 && item.ctr < 0.05) {\\n actionItem = 'A/B test titles - page 1 position with below-average CTR';\\n } else if (item.position > 20 && item.impressions > 500) {\\n actionItem = 'Content audit - poor ranking despite search interest';\\n } else if (item.clicks < 10 && item.impressions > 1000) {\\n actionItem = 'Title/snippet mismatch - high visibility, no clicks';\\n } else if (item.position <= 3 && item.ctr > 0.15) {\\n actionItem = 'Maintain excellence - top performer';\\n }\\n \\n return {\\n rank: index + 1,\\n page: item.page,\\n clicks: item.clicks,\\n impressions: item.impressions,\\n ctr: item.ctrFormatted,\\n position: item.positionRounded,\\n clickShare: `${clickShare}%`,\\n impressionShare: `${impressionShare}%`,\\n performanceCategory: performanceCategory,\\n actionItem: actionItem\\n };\\n});\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 100,\n 340\n ],\n \"id\": \"f3df4333-d507-4c22-8965-04ef308a1223\",\n \"name\": \"Parse Top Performing Pages\"\n },\n {\n \"parameters\": {\n \"content\": \"## Top Performing Pages\",\n \"height\": 240,\n \"width\": 480\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -180,\n 260\n ],\n \"id\": \"5ce2ec33-a1ac-4d41-a302-7d24521436b5\",\n \"name\": \"Sticky Note2\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-02-26\\\",\\n \\\"endDate\\\": \\\"2025-03-26\\\",\\n \\\"dimensions\\\": [\\\"page\\\", \\\"query\\\"],\\n \\\"rowLimit\\\": 25000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 120,\n -200\n ],\n \"id\": \"6af3fbd7-6057-4290-bdd5-fb4deec856b5\",\n \"name\": \"Get Keyword Analysis by Pages\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsCode\": \"const rows = $input.item.json.rows;\\n\\n// Group keywords by page\\nconst pageKeywords = {};\\n\\nrows.forEach(row => {\\n const page = row.keys[0];\\n const query = row.keys[1];\\n \\n if (!pageKeywords[page]) {\\n pageKeywords[page] = {\\n page: page,\\n totalClicks: 0,\\n totalImpressions: 0,\\n keywords: []\\n };\\n }\\n \\n // Add keyword data\\n pageKeywords[page].keywords.push({\\n query: query,\\n clicks: row.clicks,\\n impressions: row.impressions,\\n ctr: row.ctr,\\n position: row.position,\\n ctrFormatted: `${(row.ctr * 100).toFixed(2)}%`,\\n positionRounded: Math.round(row.position * 10) / 10\\n });\\n \\n // Update page totals\\n pageKeywords[page].totalClicks += row.clicks;\\n pageKeywords[page].totalImpressions += row.impressions;\\n});\\n\\n// Process each page's keyword data\\nconst result = [];\\n\\nObject.values(pageKeywords).forEach(pageData => {\\n // Sort keywords by clicks (most valuable first)\\n pageData.keywords.sort((a, b) => b.clicks - a.clicks);\\n \\n // Calculate keyword performance metrics\\n const processedKeywords = pageData.keywords.map((keyword, index) => {\\n const clickShare = ((keyword.clicks / pageData.totalClicks) * 100).toFixed(2);\\n const impressionShare = ((keyword.impressions / pageData.totalImpressions) * 100).toFixed(2);\\n \\n // Keyword categorization\\n let keywordType = 'Long-tail';\\n if (keyword.query.split(' ').length <= 2) keywordType = 'Short-tail';\\n else if (keyword.query.split(' ').length === 3) keywordType = 'Medium-tail';\\n \\n // Performance assessment\\n let keywordStatus = 'Monitor';\\n if (keyword.position <= 3 && keyword.clicks > 10) keywordStatus = 'Top Performer';\\n else if (keyword.position <= 10 && keyword.ctr > 0.05) keywordStatus = 'Strong Performer';\\n else if (keyword.position > 10 && keyword.position <= 20 && keyword.impressions > 100) keywordStatus = 'Opportunity';\\n else if (keyword.impressions > 500 && keyword.ctr < 0.02) keywordStatus = 'CTR Issue';\\n \\n // Specific action items per keyword\\n let keywordAction = 'Monitor performance';\\n if (keyword.position > 10 && keyword.position <= 20 && keyword.impressions > 200) {\\n keywordAction = 'Optimize content for this keyword - close to page 1';\\n } else if (keyword.impressions > 1000 && keyword.ctr < 0.015) {\\n keywordAction = 'Improve title/meta - high visibility, low CTR';\\n } else if (keyword.position <= 5 && keyword.ctr < 0.08) {\\n keywordAction = 'Enhance snippet appeal - good position, poor CTR';\\n } else if (keyword.clicks > 50) {\\n keywordAction = 'Maintain and expand - money keyword';\\n }\\n \\n return {\\n keywordRank: index + 1,\\n query: keyword.query,\\n clicks: keyword.clicks,\\n impressions: keyword.impressions,\\n ctr: keyword.ctrFormatted,\\n position: keyword.positionRounded,\\n clickShare: `${clickShare}%`,\\n impressionShare: `${impressionShare}%`,\\n keywordType: keywordType,\\n keywordStatus: keywordStatus,\\n keywordAction: keywordAction\\n };\\n });\\n \\n // Page summary with top keywords\\n const topKeywords = processedKeywords.slice(0, 5).map(k => k.query).join(', ');\\n const avgPosition = (pageData.keywords.reduce((sum, k) => sum + k.position, 0) / pageData.keywords.length).toFixed(1);\\n const avgCTR = ((pageData.totalClicks / pageData.totalImpressions) * 100).toFixed(2);\\n \\n result.push({\\n page: pageData.page,\\n totalClicks: pageData.totalClicks,\\n totalImpressions: pageData.totalImpressions,\\n avgPosition: parseFloat(avgPosition),\\n avgCTR: `${avgCTR}%`,\\n keywordCount: pageData.keywords.length,\\n topKeywords: topKeywords,\\n keywords: processedKeywords\\n });\\n});\\n\\n// Sort pages by total clicks\\nreturn result.sort((a, b) => b.totalClicks - a.totalClicks);\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 340,\n -200\n ],\n \"id\": \"64b2aa1f-5f13-4023-9d9d-782e43cfd89c\",\n \"name\": \"Parse Keyword Analysis by Pages\"\n },\n {\n \"parameters\": {\n \"content\": \"## Keyword Analysis by Pages\",\n \"height\": 240,\n \"width\": 480\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 60,\n -260\n ],\n \"id\": \"a478ea9a-839f-454d-a37e-021edb955f76\",\n \"name\": \"Sticky Note3\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-02-26\\\",\\n \\\"endDate\\\": \\\"2025-03-26\\\",\\n \\\"dimensions\\\": [\\\"query\\\", \\\"page\\\"],\\n \\\"rowLimit\\\": 25000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 660,\n 580\n ],\n \"id\": \"a8364bf9-3255-4d11-b665-80d7e696cb0f\",\n \"name\": \"Get Keyword Cannibalization Detection\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"content\": \"## Keyword Cannibalization Analysis\\n\",\n \"height\": 240,\n \"width\": 460\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 600,\n 520\n ],\n \"id\": \"b4b249a7-a314-4e50-bb34-d1abd5bc9018\",\n \"name\": \"Sticky Note4\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"// Combine all paginated responses\\nconst allResponses = $input.all();\\nconst combinedRows = [];\\n\\nallResponses.forEach(response => {\\n if (response.json.rows && response.json.rows.length > 0) {\\n combinedRows.push(...response.json.rows);\\n }\\n});\\n\\n// Group by query to find cannibalization\\nconst queryGroups = {};\\n\\ncombinedRows.forEach(row => {\\n const query = row.keys[0];\\n const page = row.keys[1];\\n \\n if (!queryGroups[query]) {\\n queryGroups[query] = {\\n query: query,\\n pages: [],\\n totalClicks: 0,\\n totalImpressions: 0,\\n pageCount: 0\\n };\\n }\\n \\n queryGroups[query].pages.push({\\n page: page,\\n clicks: row.clicks,\\n impressions: row.impressions,\\n ctr: row.ctr,\\n position: row.position,\\n ctrFormatted: `${(row.ctr * 100).toFixed(2)}%`,\\n positionRounded: Math.round(row.position * 10) / 10\\n });\\n \\n queryGroups[query].totalClicks += row.clicks;\\n queryGroups[query].totalImpressions += row.impressions;\\n queryGroups[query].pageCount += 1;\\n});\\n\\n// Identify cannibalization cases\\nconst cannibalizationIssues = [];\\nconst healthyKeywords = [];\\n\\nObject.values(queryGroups).forEach(queryData => {\\n // Sort pages by performance for this query\\n queryData.pages.sort((a, b) => b.clicks - a.clicks);\\n \\n if (queryData.pageCount > 1) {\\n // Multiple pages competing for same keyword\\n const topPage = queryData.pages[0];\\n const competingPages = queryData.pages.slice(1);\\n \\n // Calculate cannibalization severity\\n const topPageClicks = topPage.clicks;\\n const competingClicks = competingPages.reduce((sum, page) => sum + page.clicks, 0);\\n const clicksDistribution = competingClicks > 0 ? (competingClicks / queryData.totalClicks * 100).toFixed(1) : 0;\\n \\n // Determine severity level\\n let severity = 'Low';\\n let issue = 'Minor cannibalization';\\n let recommendation = 'Monitor performance';\\n \\n if (queryData.pageCount >= 5) {\\n severity = 'Critical';\\n issue = 'Severe cannibalization - too many competing pages';\\n recommendation = 'Consolidate content or implement canonical tags';\\n } else if (queryData.pageCount >= 3 && parseFloat(clicksDistribution) > 30) {\\n severity = 'High';\\n issue = 'Significant traffic split across multiple pages';\\n recommendation = 'Merge similar content or redirect weaker pages';\\n } else if (queryData.pageCount === 2 && parseFloat(clicksDistribution) > 40) {\\n severity = 'Medium';\\n issue = 'Two pages splitting traffic significantly';\\n recommendation = 'Optimize page targeting or consolidate';\\n }\\n \\n // Check for position confusion (pages flip-flopping)\\n const positionSpread = Math.max(...queryData.pages.map(p => p.position)) - \\n Math.min(...queryData.pages.map(p => p.position));\\n \\n if (positionSpread > 20) {\\n severity = severity === 'Low' ? 'Medium' : severity;\\n issue += ' - wide position spread indicates confusion';\\n }\\n \\n // Calculate potential impact\\n const bestPosition = Math.min(...queryData.pages.map(p => p.position));\\n const worstPosition = Math.max(...queryData.pages.map(p => p.position));\\n \\n cannibalizationIssues.push({\\n query: queryData.query,\\n severity: severity,\\n issue: issue,\\n recommendation: recommendation,\\n pageCount: queryData.pageCount,\\n totalClicks: queryData.totalClicks,\\n totalImpressions: queryData.totalImpressions,\\n clicksDistribution: `${clicksDistribution}%`,\\n bestPosition: Math.round(bestPosition * 10) / 10,\\n worstPosition: Math.round(worstPosition * 10) / 10,\\n positionSpread: Math.round(positionSpread * 10) / 10,\\n topPerformer: {\\n page: topPage.page,\\n clicks: topPage.clicks,\\n position: topPage.positionRounded,\\n ctr: topPage.ctrFormatted\\n },\\n competingPages: competingPages.map(page => ({\\n page: page.page,\\n clicks: page.clicks,\\n position: page.positionRounded,\\n ctr: page.ctrFormatted,\\n clickShare: `${((page.clicks / queryData.totalClicks) * 100).toFixed(1)}%`\\n }))\\n });\\n } else {\\n // Single page for keyword - healthy\\n const page = queryData.pages[0];\\n if (queryData.totalClicks > 10) { // Only include meaningful keywords\\n healthyKeywords.push({\\n query: queryData.query,\\n page: page.page,\\n clicks: page.clicks,\\n impressions: page.impressions,\\n position: page.positionRounded,\\n ctr: page.ctrFormatted,\\n status: 'Healthy - Single page targeting'\\n });\\n }\\n }\\n});\\n\\n// Sort by severity and impact\\ncannibalizationIssues.sort((a, b) => {\\n const severityOrder = { 'Critical': 4, 'High': 3, 'Medium': 2, 'Low': 1 };\\n if (severityOrder[a.severity] !== severityOrder[b.severity]) {\\n return severityOrder[b.severity] - severityOrder[a.severity];\\n }\\n return b.totalClicks - a.totalClicks; // Then by traffic impact\\n});\\n\\n// Summary statistics\\nconst summary = {\\n totalKeywords: Object.keys(queryGroups).length,\\n cannibalizationIssues: cannibalizationIssues.length,\\n healthyKeywords: healthyKeywords.length,\\n criticalIssues: cannibalizationIssues.filter(issue => issue.severity === 'Critical').length,\\n highIssues: cannibalizationIssues.filter(issue => issue.severity === 'High').length,\\n mediumIssues: cannibalizationIssues.filter(issue => issue.severity === 'Medium').length,\\n lowIssues: cannibalizationIssues.filter(issue => issue.severity === 'Low').length,\\n cannibalizationRate: `${((cannibalizationIssues.length / Object.keys(queryGroups).length) * 100).toFixed(1)}%`\\n};\\n\\nreturn {\\n summary: summary,\\n cannibalizationIssues: cannibalizationIssues,\\n healthyKeywords: healthyKeywords.slice(0, 50) // Top 50 healthy keywords\\n};\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 860,\n 580\n ],\n \"id\": \"a73552d8-afc0-421e-befc-3f0fff6c7513\",\n \"name\": \"Parse Keyword Cannibalization Detection\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-02-26\\\",\\n \\\"endDate\\\": \\\"2025-03-26\\\",\\n \\\"dimensions\\\": [\\\"query\\\"],\\n \\\"rowLimit\\\": 25000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n -400,\n 600\n ],\n \"id\": \"dbfd4cd0-40c7-4902-b8af-e36dd196e87c\",\n \"name\": \"Get Content Gap Analysis\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsCode\": \"const rows = $input.item.json.rows;\\n\\n// Analyze queries for content gaps\\nconst contentGaps = rows\\n .filter(row => {\\n // Filter criteria for content gaps:\\n // 1. High impressions (people are searching)\\n // 2. Poor position (we're not ranking well)\\n // 3. Low clicks (not getting traffic despite visibility)\\n return row.impressions > 100 && \\n row.position > 20 && \\n row.clicks < 10;\\n })\\n .map(row => {\\n const query = row.keys[0];\\n const searchVolume = row.impressions;\\n const currentPosition = Math.round(row.position * 10) / 10;\\n const missedClicks = Math.round(searchVolume * 0.05); // Potential clicks at decent position\\n \\n // Categorize gap severity\\n let gapSeverity = 'Low';\\n let opportunity = 'Minor opportunity';\\n let recommendation = 'Monitor and optimize existing content';\\n \\n if (searchVolume > 5000 && currentPosition > 50) {\\n gapSeverity = 'Critical';\\n opportunity = 'High-volume keyword with very poor ranking';\\n recommendation = 'Create dedicated content or major content overhaul';\\n } else if (searchVolume > 1000 && currentPosition > 30) {\\n gapSeverity = 'High';\\n opportunity = 'Good search volume with poor visibility';\\n recommendation = 'Optimize existing content or create new targeted page';\\n } else if (searchVolume > 500 && currentPosition > 25) {\\n gapSeverity = 'Medium';\\n opportunity = 'Decent search volume, needs content improvement';\\n recommendation = 'Enhance existing content with better keyword targeting';\\n }\\n \\n // Analyze query intent and type\\n const queryWords = query.toLowerCase().split(' ');\\n let queryIntent = 'Informational';\\n let queryType = 'Long-tail';\\n \\n // Intent detection\\n if (queryWords.some(word => ['buy', 'purchase', 'price', 'cost', 'cheap'].includes(word))) {\\n queryIntent = 'Commercial';\\n } else if (queryWords.some(word => ['how', 'what', 'why', 'when', 'where'].includes(word))) {\\n queryIntent = 'Informational';\\n } else if (queryWords.some(word => ['best', 'top', 'review', 'compare'].includes(word))) {\\n queryIntent = 'Commercial Investigation';\\n } else if (queryWords.length <= 2) {\\n queryIntent = 'Navigational';\\n }\\n \\n // Query type\\n if (queryWords.length <= 2) queryType = 'Short-tail';\\n else if (queryWords.length === 3) queryType = 'Medium-tail';\\n \\n return {\\n query: query,\\n currentPosition: currentPosition,\\n impressions: searchVolume,\\n clicks: row.clicks,\\n ctr: `${(row.ctr * 100).toFixed(2)}%`,\\n gapSeverity: gapSeverity,\\n opportunity: opportunity,\\n recommendation: recommendation,\\n missedClicksPotential: missedClicks,\\n queryIntent: queryIntent,\\n queryType: queryType,\\n competitorAdvantage: currentPosition > 30 ? 'High' : currentPosition > 20 ? 'Medium' : 'Low'\\n };\\n })\\n .sort((a, b) => {\\n // Sort by severity first, then by missed potential\\n const severityOrder = { 'Critical': 4, 'High': 3, 'Medium': 2, 'Low': 1 };\\n if (severityOrder[a.gapSeverity] !== severityOrder[b.gapSeverity]) {\\n return severityOrder[b.gapSeverity] - severityOrder[a.gapSeverity];\\n }\\n return b.missedClicksPotential - a.missedClicksPotential;\\n });\\n\\n// Summary statistics\\nconst gapSummary = {\\n totalGaps: contentGaps.length,\\n criticalGaps: contentGaps.filter(gap => gap.gapSeverity === 'Critical').length,\\n highGaps: contentGaps.filter(gap => gap.gapSeverity === 'High').length,\\n mediumGaps: contentGaps.filter(gap => gap.gapSeverity === 'Medium').length,\\n totalMissedPotential: contentGaps.reduce((sum, gap) => sum + gap.missedClicksPotential, 0),\\n topOpportunityQueries: contentGaps.slice(0, 10).map(gap => gap.query)\\n};\\n\\nreturn {\\n summary: gapSummary,\\n contentGaps: contentGaps\\n};\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n -160,\n 600\n ],\n \"id\": \"7d371aba-2f68-4a0e-a8b6-70a27582fe57\",\n \"name\": \"Parse Content Gap Analysis\"\n },\n {\n \"parameters\": {\n \"content\": \"## Content Gap Analysis\\n\",\n \"height\": 240,\n \"width\": 500\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -460,\n 520\n ],\n \"id\": \"133bf6a3-9dd5-4559-ad42-69ac1053f771\",\n \"name\": \"Sticky Note5\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-01-26\\\",\\n \\\"endDate\\\": \\\"2025-02-26\\\",\\n \\\"dimensions\\\": [\\\"query\\\", \\\"page\\\"],\\n \\\"rowLimit\\\": 25000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 120,\n 580\n ],\n \"id\": \"d195381f-2a0d-4c81-92c2-164a4cc91031\",\n \"name\": \"Get Keyword Opportunities Analysis\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsCode\": \"const rows = $input.item.json.rows;\\n\\n// Process emerging keywords with their specific pages\\nconst emergingKeywords = rows\\n .filter(row => {\\n // Filter criteria for emerging opportunities:\\n // 1. Recently started ranking (position 10-50)\\n // 2. Decent search volume\\n // 3. Improving performance indicators\\n return row.position >= 10 && \\n row.position <= 50 && \\n row.impressions > 50 &&\\n row.clicks >= 0;\\n })\\n .map(row => {\\n const query = row.keys[0];\\n const page = row.keys[1];\\n const currentPosition = Math.round(row.position * 10) / 10;\\n const impressions = row.impressions;\\n const clicks = row.clicks;\\n \\n // Calculate opportunity potential\\n let opportunityLevel = 'Monitor';\\n let potentialImpact = 'Low';\\n let pageOptimization = 'Basic monitoring';\\n let specificActions = [];\\n \\n if (currentPosition <= 20 && impressions > 500) {\\n opportunityLevel = 'High Priority';\\n potentialImpact = 'High';\\n pageOptimization = 'Immediate content optimization required';\\n specificActions = [\\n 'Optimize title tag to include target keyword',\\n 'Enhance meta description for better CTR',\\n 'Add keyword to H1 and H2 headers',\\n 'Increase content depth and relevance',\\n 'Build internal links to this page'\\n ];\\n } else if (currentPosition <= 30 && impressions > 200) {\\n opportunityLevel = 'Medium Priority';\\n potentialImpact = 'Medium';\\n pageOptimization = 'Content optimization and technical improvements';\\n specificActions = [\\n 'Review and optimize existing content',\\n 'Add related keywords and semantic terms',\\n 'Improve internal linking structure',\\n 'Check page loading speed',\\n 'Enhance user experience signals'\\n ];\\n } else if (currentPosition <= 50 && impressions > 100) {\\n opportunityLevel = 'Low Priority';\\n potentialImpact = 'Low';\\n pageOptimization = 'Basic content improvements';\\n specificActions = [\\n 'Add keyword mentions naturally in content',\\n 'Improve content structure and readability',\\n 'Monitor performance trends',\\n 'Consider content expansion'\\n ];\\n }\\n \\n // Analyze query characteristics\\n const queryWords = query.toLowerCase().split(' ');\\n let queryIntent = 'Informational';\\n let competitionLevel = 'Medium';\\n \\n // Intent detection\\n if (queryWords.some(word => ['buy', 'purchase', 'price', 'cost'].includes(word))) {\\n queryIntent = 'Commercial';\\n competitionLevel = 'High';\\n } else if (queryWords.some(word => ['how', 'what', 'guide', 'tutorial'].includes(word))) {\\n queryIntent = 'Informational';\\n competitionLevel = 'Medium';\\n } else if (queryWords.some(word => ['best', 'top', 'review', 'vs'].includes(word))) {\\n queryIntent = 'Commercial Investigation';\\n competitionLevel = 'High';\\n }\\n \\n // Page-specific analysis using string manipulation\\n const pagePath = page.split('://')[1] ? page.split('://')[1].split('/').slice(1).join('/') : page;\\n const pageType = pagePath.includes('blog/') ? 'Blog Post' :\\n pagePath.includes('product/') ? 'Product Page' :\\n pagePath.includes('category/') ? 'Category Page' :\\n pagePath === '' || pagePath === '/' ? 'Homepage' : 'Content Page';\\n \\n // Content-keyword alignment check\\n const queryInUrl = queryWords.some(word => \\n pagePath.toLowerCase().includes(word.toLowerCase())\\n );\\n \\n let contentAlignment = 'Good';\\n if (!queryInUrl && queryWords.length <= 3) {\\n contentAlignment = 'Poor - URL doesn\\\\'t match target keyword';\\n specificActions.unshift('Consider URL optimization or content realignment');\\n } else if (!queryInUrl) {\\n contentAlignment = 'Fair - Could improve keyword-URL alignment';\\n }\\n \\n return {\\n query: query,\\n page: page,\\n pageType: pageType,\\n currentPosition: currentPosition,\\n impressions: impressions,\\n clicks: clicks,\\n ctr: `${(row.ctr * 100).toFixed(2)}%`,\\n opportunityLevel: opportunityLevel,\\n potentialImpact: potentialImpact,\\n pageOptimization: pageOptimization,\\n specificActions: specificActions,\\n queryIntent: queryIntent,\\n competitionLevel: competitionLevel,\\n contentAlignment: contentAlignment,\\n queryType: queryWords.length <= 2 ? 'Short-tail' : \\n queryWords.length === 3 ? 'Medium-tail' : 'Long-tail',\\n priorityScore: (impressions / 100) + (51 - currentPosition) // Custom scoring\\n };\\n })\\n .sort((a, b) => {\\n // Sort by opportunity level, then by priority score\\n const priorityOrder = { 'High Priority': 3, 'Medium Priority': 2, 'Low Priority': 1, 'Monitor': 0 };\\n if (priorityOrder[a.opportunityLevel] !== priorityOrder[b.opportunityLevel]) {\\n return priorityOrder[b.opportunityLevel] - priorityOrder[a.opportunityLevel];\\n }\\n return b.priorityScore - a.priorityScore;\\n });\\n\\n// Group by page for easier optimization planning\\nconst pageOptimizationPlan = {};\\nemergingKeywords.forEach(keyword => {\\n if (!pageOptimizationPlan[keyword.page]) {\\n pageOptimizationPlan[keyword.page] = {\\n page: keyword.page,\\n pageType: keyword.pageType,\\n keywordOpportunities: [],\\n totalImpressions: 0,\\n highPriorityKeywords: 0,\\n overallPriority: 'Low'\\n };\\n }\\n \\n pageOptimizationPlan[keyword.page].keywordOpportunities.push({\\n query: keyword.query,\\n currentPosition: keyword.currentPosition,\\n impressions: keyword.impressions,\\n opportunityLevel: keyword.opportunityLevel,\\n specificActions: keyword.specificActions\\n });\\n \\n pageOptimizationPlan[keyword.page].totalImpressions += keyword.impressions;\\n \\n if (keyword.opportunityLevel === 'High Priority') {\\n pageOptimizationPlan[keyword.page].highPriorityKeywords += 1;\\n pageOptimizationPlan[keyword.page].overallPriority = 'High';\\n } else if (keyword.opportunityLevel === 'Medium Priority' && \\n pageOptimizationPlan[keyword.page].overallPriority !== 'High') {\\n pageOptimizationPlan[keyword.page].overallPriority = 'Medium';\\n }\\n});\\n\\n// Convert to array and sort by priority\\nconst pageOptimizationArray = Object.values(pageOptimizationPlan)\\n .sort((a, b) => {\\n const priorityOrder = { 'High': 3, 'Medium': 2, 'Low': 1 };\\n if (priorityOrder[a.overallPriority] !== priorityOrder[b.overallPriority]) {\\n return priorityOrder[b.overallPriority] - priorityOrder[a.overallPriority];\\n }\\n return b.totalImpressions - a.totalImpressions;\\n });\\n\\n// Summary statistics\\nconst opportunitySummary = {\\n totalOpportunities: emergingKeywords.length,\\n totalPagesToOptimize: Object.keys(pageOptimizationPlan).length,\\n highPriorityPages: pageOptimizationArray.filter(page => page.overallPriority === 'High').length,\\n mediumPriorityPages: pageOptimizationArray.filter(page => page.overallPriority === 'Medium').length,\\n quickWins: emergingKeywords.filter(kw => kw.currentPosition <= 20).length,\\n commercialOpportunities: emergingKeywords.filter(kw => kw.queryIntent === 'Commercial').length\\n};\\n\\nreturn {\\n summary: opportunitySummary,\\n emergingKeywords: emergingKeywords,\\n pageOptimizationPlan: pageOptimizationArray\\n};\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 340,\n 580\n ],\n \"id\": \"01f911b8-4170-474f-aa7a-42e59999d4de\",\n \"name\": \"Parse Keyword Opportunities Analysis\"\n },\n {\n \"parameters\": {\n \"content\": \"## Keyword Opportunities Analysis\\n\",\n \"height\": 240,\n \"width\": 520\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 60,\n 520\n ],\n \"id\": \"08a48dc8-d7a8-44c4-9650-7e92174c0cec\",\n \"name\": \"Sticky Note6\"\n },\n {\n \"parameters\": {\n \"content\": \"## Keywords Ranking 4-10\\n\",\n \"height\": 240,\n \"width\": 480\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 560,\n 0\n ],\n \"id\": \"60ac93e8-ff43-49a5-9808-2467e8a79de4\",\n \"name\": \"Sticky Note7\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-01-26\\\",\\n \\\"endDate\\\": \\\"2025-03-26\\\",\\n \\\"dimensions\\\": [\\\"query\\\", \\\"date\\\"],\\n \\\"rowLimit\\\": 25000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 120,\n 60\n ],\n \"id\": \"9f959a20-6552-42c3-a789-9c3ec20e3f90\",\n \"name\": \"Get Query Performance Drop Detection\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsCode\": \"const rows = $input.item.json.rows || [];\\n\\n// Define comparison periods (adjust dates as needed)\\nconst currentPeriodStart = \\\"2025-03-01\\\";\\nconst currentPeriodEnd = \\\"2025-03-26\\\";\\nconst previousPeriodStart = \\\"2025-02-01\\\"; \\nconst previousPeriodEnd = \\\"2025-02-28\\\";\\n\\n// Group data by query and period\\nconst queryData = {};\\n\\nrows.forEach(row => {\\n const query = row.keys[0];\\n const date = row.keys[1];\\n \\n if (!queryData[query]) {\\n queryData[query] = {\\n current: { clicks: 0, impressions: 0, positions: [], dates: 0 },\\n previous: { clicks: 0, impressions: 0, positions: [], dates: 0 }\\n };\\n }\\n \\n // Determine which period this data belongs to\\n if (date >= currentPeriodStart && date <= currentPeriodEnd) {\\n queryData[query].current.clicks += parseInt(row.clicks);\\n queryData[query].current.impressions += parseInt(row.impressions);\\n queryData[query].current.positions.push(parseFloat(row.position));\\n queryData[query].current.dates++;\\n } else if (date >= previousPeriodStart && date <= previousPeriodEnd) {\\n queryData[query].previous.clicks += parseInt(row.clicks);\\n queryData[query].previous.impressions += parseInt(row.impressions);\\n queryData[query].previous.positions.push(parseFloat(row.position));\\n queryData[query].previous.dates++;\\n }\\n});\\n\\n// Calculate averages and detect drops with dynamic thresholds\\nreturn Object.entries(queryData)\\n .filter(([query, data]) => {\\n // Only include queries with data in both periods and minimum volume\\n return data.current.dates > 0 && \\n data.previous.dates > 0 && \\n data.previous.impressions >= 100; // Higher minimum threshold\\n })\\n .map(([query, data]) => {\\n // Calculate average positions\\n const currentAvgPosition = data.current.positions.length > 0 \\n ? data.current.positions.reduce((a, b) => a + b, 0) / data.current.positions.length \\n : 0;\\n const previousAvgPosition = data.previous.positions.length > 0 \\n ? data.previous.positions.reduce((a, b) => a + b, 0) / data.previous.positions.length \\n : 0;\\n \\n // Calculate CTRs\\n const currentCTR = data.current.impressions > 0 \\n ? (data.current.clicks / data.current.impressions) * 100 \\n : 0;\\n const previousCTR = data.previous.impressions > 0 \\n ? (data.previous.clicks / data.previous.impressions) * 100 \\n : 0;\\n \\n // Calculate percentage changes\\n const clicksChange = data.previous.clicks > 0 \\n ? ((data.current.clicks - data.previous.clicks) / data.previous.clicks) * 100 \\n : 0;\\n const impressionsChange = data.previous.impressions > 0 \\n ? ((data.current.impressions - data.previous.impressions) / data.previous.impressions) * 100 \\n : 0;\\n const positionChange = previousAvgPosition > 0 \\n ? currentAvgPosition - previousAvgPosition \\n : 0;\\n \\n // Calculate absolute changes for dynamic thresholds\\n const absoluteClicksChange = data.current.clicks - data.previous.clicks;\\n const absoluteImpressionsChange = data.current.impressions - data.previous.impressions;\\n \\n return {\\n query: query,\\n // Previous period data\\n previousClicks: data.previous.clicks,\\n previousImpressions: data.previous.impressions,\\n previousPosition: Math.round(previousAvgPosition * 10) / 10,\\n previousCTR: Math.round(previousCTR * 10) / 10,\\n // Current period data \\n currentClicks: data.current.clicks,\\n currentImpressions: data.current.impressions,\\n currentPosition: Math.round(currentAvgPosition * 10) / 10,\\n currentCTR: Math.round(currentCTR * 10) / 10,\\n // Changes\\n clicksChange: Math.round(clicksChange * 10) / 10,\\n impressionsChange: Math.round(impressionsChange * 10) / 10,\\n positionChange: Math.round(positionChange * 10) / 10,\\n ctrChange: Math.round((currentCTR - previousCTR) * 10) / 10,\\n // Absolute changes for filtering\\n absoluteClicksChange: absoluteClicksChange,\\n absoluteImpressionsChange: absoluteImpressionsChange\\n };\\n })\\n .filter(row => {\\n // Dynamic thresholds based on volume\\n const previousClicks = row.previousClicks;\\n const previousImpressions = row.previousImpressions;\\n \\n // Define volume-based thresholds\\n let clicksThreshold, impressionsThreshold, positionThreshold;\\n \\n if (previousClicks >= 100) {\\n // High volume: stricter percentage, lower absolute threshold\\n clicksThreshold = row.clicksChange <= -15 && row.absoluteClicksChange <= -10;\\n } else if (previousClicks >= 20) {\\n // Medium volume: moderate thresholds\\n clicksThreshold = row.clicksChange <= -25 && row.absoluteClicksChange <= -5;\\n } else if (previousClicks >= 5) {\\n // Low volume: focus on absolute change\\n clicksThreshold = row.absoluteClicksChange <= -3;\\n } else {\\n // Very low volume: ignore percentage, focus on meaningful absolute drops\\n clicksThreshold = row.absoluteClicksChange <= -2 && previousClicks >= 3;\\n }\\n \\n // Similar logic for impressions\\n if (previousImpressions >= 1000) {\\n impressionsThreshold = row.impressionsChange <= -15 && row.absoluteImpressionsChange <= -100;\\n } else if (previousImpressions >= 500) {\\n impressionsThreshold = row.impressionsChange <= -20 && row.absoluteImpressionsChange <= -50;\\n } else {\\n impressionsThreshold = row.impressionsChange <= -25 && row.absoluteImpressionsChange <= -25;\\n }\\n \\n // Position threshold (always meaningful if 1.5+ positions drop)\\n positionThreshold = row.positionChange >= 1.5;\\n \\n return clicksThreshold || impressionsThreshold || positionThreshold;\\n })\\n .sort((a, b) => {\\n // Sort by impact score: combine absolute change with percentage for prioritization\\n const impactA = Math.abs(a.absoluteClicksChange) * (Math.abs(a.clicksChange) / 100);\\n const impactB = Math.abs(b.absoluteClicksChange) * (Math.abs(b.clicksChange) / 100);\\n return impactB - impactA;\\n });\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 320,\n 60\n ],\n \"id\": \"c65886ee-10ca-429d-91d5-8b21d0683f0c\",\n \"name\": \"Parse Query Performance Drop Detection\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"const rows = $input.item.json.rows || [];\\n\\n// Group by query+page and get the most recent position for each\\nconst latestPositions = {};\\n\\nrows.forEach(row => {\\n const query = row.keys[0];\\n const page = row.keys[1];\\n const date = row.keys[2]; // Date dimension\\n const key = `${query}|${page}`;\\n \\n // Keep only the most recent date for each query+page combination\\n if (!latestPositions[key] || date > latestPositions[key].date) {\\n latestPositions[key] = {\\n query,\\n page,\\n date,\\n position: parseFloat(row.position),\\n clicks: parseInt(row.clicks),\\n impressions: parseInt(row.impressions),\\n ctr: parseFloat(row.ctr)\\n };\\n }\\n});\\n\\n// Convert to array, filter for positions 4-10\\nreturn Object.values(latestPositions)\\n .filter(row => {\\n const position = row.position;\\n return position >= 4 && position <= 10 && row.impressions >= 10;\\n })\\n .map(row => {\\n return {\\n query: row.query,\\n page: row.page,\\n lastDate: row.date,\\n currentPosition: Math.round(row.position * 10) / 10,\\n clicks: row.clicks,\\n impressions: row.impressions,\\n ctr: Math.round(row.ctr * 1000) / 10 // Convert to percentage with 1 decimal\\n };\\n })\\n .sort((a, b) => b.impressions - a.impressions); // Sort by highest impressions first\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 820,\n 60\n ],\n \"id\": \"5f3c8059-1ff8-40c8-977c-1e4f69831ff0\",\n \"name\": \"Parse Keywords Ranking 4-10\"\n },\n {\n \"parameters\": {\n \"content\": \"## Query Performance Drop Detection\\n\",\n \"height\": 240,\n \"width\": 480\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 60,\n 0\n ],\n \"id\": \"771a833e-0e32-4c1b-895d-334e9f169196\",\n \"name\": \"Sticky Note8\"\n },\n {\n \"parameters\": {\n \"content\": \"## Get Queries by Period\\n\",\n \"height\": 240,\n \"width\": 500\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -460,\n 0\n ],\n \"id\": \"54faee61-66d5-49e2-96a7-0c20c44e1e6b\",\n \"name\": \"Sticky Note9\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-02-26\\\",\\n \\\"endDate\\\": \\\"2025-03-26\\\",\\n \\\"dimensions\\\": [\\\"query\\\"],\\n \\\"dimensionFilterGroups\\\": [{\\n \\\"filters\\\": [{\\n \\\"dimension\\\": \\\"page\\\",\\n \\\"operator\\\": \\\"equals\\\",\\n \\\"expression\\\": \\\"https://your-domain.com/slug/\\\"\\n }]\\n }],\\n \\\"rowLimit\\\": 25000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n -400,\n 80\n ],\n \"id\": \"c7081520-a1b8-45a5-983c-9bfc6e42e056\",\n \"name\": \" Get Queries by Period\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsCode\": \"const rows = $input.item.json.rows || $input.item.json;\\n\\n// Map each row to a cleaner format\\nreturn rows.map(row => {\\n return {\\n query: row.keys[0],\\n clicks: row.clicks,\\n impressions: row.impressions,\\n ctr: row.ctr,\\n position: row.position\\n };\\n});\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n -200,\n 80\n ],\n \"id\": \"7eddae09-b55b-40f3-a867-c13aebb75fe6\",\n \"name\": \"Parse Queries by Period\"\n },\n {\n \"parameters\": {\n \"content\": \"## Get Queries by Day\\n\\n\",\n \"height\": 240,\n \"width\": 500\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -460,\n -260\n ],\n \"id\": \"59b2d2bb-8564-4e6b-b6ea-117a38aa3fef\",\n \"name\": \"Sticky Note10\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-02-26\\\",\\n \\\"endDate\\\": \\\"2025-03-26\\\",\\n \\\"dimensions\\\": [\\\"query\\\", \\\"date\\\"],\\n \\\"dimensionFilterGroups\\\": [{\\n \\\"filters\\\": [{\\n \\\"dimension\\\": \\\"page\\\",\\n \\\"operator\\\": \\\"equals\\\",\\n \\\"expression\\\": \\\"https://your-domain.com/slug/\\\"\\n }]\\n }],\\n \\\"rowLimit\\\": 10000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n -400,\n -180\n ],\n \"id\": \"7db5f524-23c1-4fe8-891c-5c5f5d17d419\",\n \"name\": \"Get Queries by Day\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsCode\": \"const rows = $input.item.json.rows || $input.item.json;\\n\\n// Map each row to a cleaner format with query, date and metrics\\nreturn rows.map(row => {\\n return {\\n query: row.keys[0],\\n date: row.keys[1],\\n clicks: row.clicks,\\n impressions: row.impressions,\\n ctr: row.ctr,\\n position: row.position\\n };\\n});\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n -200,\n -180\n ],\n \"id\": \"7c5c7b57-e11a-4ef2-9128-41bf0fbae6d3\",\n \"name\": \"Parse Queries by Day\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-02-26\\\",\\n \\\"endDate\\\": \\\"2025-03-26\\\",\\n \\\"dimensions\\\": [\\\"query\\\", \\\"page\\\", \\\"date\\\"],\\n \\\"rowLimit\\\": 25000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 620,\n 60\n ],\n \"id\": \"178f7e22-8596-4540-b092-23a62894f0fb\",\n \"name\": \"Get Keywords Ranking 4-10\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"content\": \"## Brand Visibility Analysis\",\n \"height\": 240,\n \"width\": 480\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 780,\n 260\n ],\n \"id\": \"0ef4efc8-3283-4748-9feb-0257d5419e4e\",\n \"name\": \"Sticky Note11\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://searchconsole.googleapis.com/webmasters/v3/sites/sc-domain:your-domain.com/searchAnalytics/query\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"googleOAuth2Api\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"{\\n \\\"startDate\\\": \\\"2025-05-01\\\",\\n \\\"endDate\\\": \\\"2025-06-17\\\",\\n \\\"dimensions\\\": [\\\"query\\\"],\\n \\\"rowLimit\\\": 25000\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 840,\n 320\n ],\n \"id\": \"43cf54bf-3c44-4872-ad40-aaf6de887348\",\n \"name\": \"Get Brand Visibility Analysis\",\n \"credentials\": {\n \"googleOAuth2Api\": {\n \"id\": \"R0UFaLH10cOpcIL4\",\n \"name\": \"Google account\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsCode\": \"const rows = $input.item.json.rows || [];\\n\\n// Define brand terms for regex (adjust to your brand)\\nconst brandTerms = ['midjourney'];\\n\\n// Create regex pattern that matches any brand term (case insensitive)\\nconst brandRegex = new RegExp(brandTerms.join('|'), 'i');\\n\\n// Initialize data structures\\nlet brandData = {\\n clicks: 0,\\n impressions: 0,\\n positionSum: 0,\\n queries: []\\n};\\n\\nlet nonBrandData = {\\n clicks: 0,\\n impressions: 0,\\n positionSum: 0,\\n queries: []\\n};\\n\\n// Process each row\\nrows.forEach(row => {\\n const query = row.keys[0];\\n const clicks = parseInt(row.clicks);\\n const impressions = parseInt(row.impressions);\\n const position = parseFloat(row.position);\\n const ctr = parseFloat(row.ctr);\\n \\n const queryData = {\\n query: query,\\n clicks: clicks,\\n impressions: impressions,\\n position: Math.round(position * 10) / 10,\\n ctr: Math.round(ctr * 1000) / 10\\n };\\n \\n // Check if query matches brand regex\\n const brandMatch = query.match(brandRegex);\\n \\n if (brandMatch) {\\n // Brand query - add match details\\n queryData.matchedBrandTerm = brandMatch[0];\\n queryData.matchIndex = brandMatch.index;\\n \\n brandData.clicks += clicks;\\n brandData.impressions += impressions;\\n brandData.positionSum += (position * impressions);\\n brandData.queries.push(queryData);\\n } else {\\n // Non-brand query\\n nonBrandData.clicks += clicks;\\n nonBrandData.impressions += impressions;\\n nonBrandData.positionSum += (position * impressions);\\n nonBrandData.queries.push(queryData);\\n }\\n});\\n\\n// Calculate averages\\nconst brandAvgPosition = brandData.impressions > 0 \\n ? Math.round((brandData.positionSum / brandData.impressions) * 10) / 10 \\n : 0;\\n\\nconst nonBrandAvgPosition = nonBrandData.impressions > 0 \\n ? Math.round((nonBrandData.positionSum / nonBrandData.impressions) * 10) / 10 \\n : 0;\\n\\nconst brandCTR = brandData.impressions > 0 \\n ? Math.round((brandData.clicks / brandData.impressions) * 1000) / 10 \\n : 0;\\n\\nconst nonBrandCTR = nonBrandData.impressions > 0 \\n ? Math.round((nonBrandData.clicks / nonBrandData.impressions) * 1000) / 10 \\n : 0;\\n\\n// Calculate totals for percentages\\nconst totalClicks = brandData.clicks + nonBrandData.clicks;\\nconst totalImpressions = brandData.impressions + nonBrandData.impressions;\\n\\n// Sort queries by performance\\nbrandData.queries.sort((a, b) => b.clicks - a.clicks);\\nnonBrandData.queries.sort((a, b) => b.clicks - a.clicks);\\n\\n// Analyze brand query patterns\\nconst brandQueryAnalysis = {\\n totalBrandQueries: brandData.queries.length,\\n uniqueBrandTermsFound: [...new Set(brandData.queries.map(q => q.matchedBrandTerm.toLowerCase()))],\\n topBrandQueries: brandData.queries.slice(0, 10),\\n brandQueriesWithHighImpressions: brandData.queries.filter(q => q.impressions >= 100),\\n brandQueriesWithLowCTR: brandData.queries.filter(q => q.ctr < 50 && q.impressions >= 10) // Brand queries should have high CTR\\n};\\n\\n// Check for brand visibility issues\\nconst brandVisibilityIssues = {\\n lowRankingBrandQueries: brandData.queries.filter(q => q.position > 3 && q.impressions >= 10),\\n brandQueriesNotRanking1: brandData.queries.filter(q => q.position > 1 && q.impressions >= 50)\\n};\\n\\n// Return detailed analysis\\nreturn [{\\n // Summary metrics\\n summary: {\\n brandClicks: brandData.clicks,\\n brandImpressions: brandData.impressions,\\n brandAvgPosition: brandAvgPosition,\\n brandCTR: brandCTR,\\n brandClickShare: totalClicks > 0 ? Math.round((brandData.clicks / totalClicks) * 100) : 0,\\n \\n nonBrandClicks: nonBrandData.clicks,\\n nonBrandImpressions: nonBrandData.impressions,\\n nonBrandAvgPosition: nonBrandAvgPosition,\\n nonBrandCTR: nonBrandCTR,\\n nonBrandClickShare: totalClicks > 0 ? Math.round((nonBrandData.clicks / totalClicks) * 100) : 0,\\n \\n // Key insights\\n positionGap: Math.round((nonBrandAvgPosition - brandAvgPosition) * 10) / 10,\\n ctrGap: Math.round((brandCTR - nonBrandCTR) * 10) / 10,\\n diversificationRatio: brandData.clicks > 0 ? Math.round((nonBrandData.clicks / brandData.clicks) * 100) / 100 : 0\\n },\\n \\n // Brand analysis details\\n brandAnalysis: {\\n totalBrandQueries: brandQueryAnalysis.totalBrandQueries,\\n uniqueBrandTermsFound: brandQueryAnalysis.uniqueBrandTermsFound,\\n brandQueriesWithHighVolume: brandQueryAnalysis.brandQueriesWithHighImpressions.length,\\n brandQueriesWithLowCTR: brandQueryAnalysis.brandQueriesWithLowCTR.length\\n },\\n \\n // Brand visibility issues\\n brandIssues: {\\n lowRankingBrandQueries: brandVisibilityIssues.lowRankingBrandQueries.length,\\n brandQueriesNotPosition1: brandVisibilityIssues.brandQueriesNotRanking1.length,\\n issueQueries: brandVisibilityIssues.lowRankingBrandQueries.slice(0, 5) // Top 5 problem queries\\n },\\n \\n // Top performing queries\\n topBrandQueries: brandQueryAnalysis.topBrandQueries.slice(0, 5),\\n topNonBrandQueries: nonBrandData.queries.slice(0, 5),\\n \\n // Regex match details\\n regexMatchDetails: {\\n brandTermsUsed: brandTerms,\\n regexPattern: brandRegex.source,\\n totalMatches: brandData.queries.length,\\n sampleMatches: brandData.queries.slice(0, 3).map(q => ({\\n query: q.query,\\n matchedTerm: q.matchedBrandTerm,\\n matchPosition: q.matchIndex\\n }))\\n }\\n}];\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 1040,\n 320\n ],\n \"id\": \"baab32cd-0b52-4b7e-8464-bc4a2b77fed3\",\n \"name\": \"Parse Brand Visibility\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"When clicking ‘Test workflow’\": {\n \"main\": [\n []\n ]\n },\n \"Get Device Performance\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Device Performance\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Top Performing Pages\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Top Performing Pages\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Keyword Analysis by Pages\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Keyword Analysis by Pages\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Keyword Cannibalization Detection\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Keyword Cannibalization Detection\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Content Gap Analysis\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Content Gap Analysis\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Keyword Opportunities Analysis\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Keyword Opportunities Analysis\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Query Performance Drop Detection\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Query Performance Drop Detection\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \" Get Queries by Period\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Queries by Period\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Parse Queries by Period\": {\n \"main\": [\n []\n ]\n },\n \"Get Queries by Day\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Queries by Day\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Keywords Ranking 4-10\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Keywords Ranking 4-10\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Brand Visibility Analysis\": {\n \"main\": [\n [\n {\n \"node\": \"Parse Brand Visibility\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"f1dc51ba-dc7f-4ef0-99f4-7b51272e58c4\",\n \"meta\": {\n \"templateCredsSetupCompleted\": true,\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"kydAlmMqrzOoYp0y\",\n \"tags\": [\n {\n \"createdAt\": \"2025-03-02T12:05:53.836Z\",\n \"updatedAt\": \"2025-03-02T12:05:53.836Z\",\n \"id\": \"utwtHTzeqUdktrxJ\",\n \"name\": \"SEO\"\n }\n ]\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "Product - Google Search Console API Examples", "node_count": 36, "category": "General Automation"}} {"prompt": "Design a workflow using n8n-nodes-base.set, n8n-nodes-base.wait, n8n-nodes-base.convertToFile to data driven seo optimization", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 26\n- Node Types: n8n-nodes-base.set, n8n-nodes-base.wait, n8n-nodes-base.convertToFile, n8n-nodes-base.googleBigQuery, @n8n/n8n-nodes-langchain.openAi, n8n-nodes-base.if, n8n-nodes-base.stickyNote, n8n-nodes-base.aggregate, n8n-nodes-base.httpRequest, n8n-nodes-base.code\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.formTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"Data-driven SEO Optimization\",\n \"nodes\": [\n {\n \"parameters\": {\n \"formTitle\": \"Form\",\n \"formFields\": {\n \"values\": [\n {\n \"fieldLabel\": \"Link\",\n \"requiredField\": true\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.formTrigger\",\n \"typeVersion\": 2.2,\n \"position\": [\n -500,\n 280\n ],\n \"id\": \"ba0f4b1f-40be-4c8b-86a8-b880960224d4\",\n \"name\": \"On form submission\",\n \"webhookId\": \"c0791596-ada8-407c-9669-f54396d88940\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"http://crawl4ai:11235/crawl\",\n \"authentication\": \"genericCredentialType\",\n \"genericAuthType\": \"httpHeaderAuth\",\n \"sendBody\": true,\n \"bodyParameters\": {\n \"parameters\": [\n {\n \"name\": \"urls\",\n \"value\": \"={{ $json.Link }}\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n -280,\n 60\n ],\n \"id\": \"1b6e074c-b5f3-4fd2-a6c0-b0d2d1f9275d\",\n \"name\": \"get_article_content\"\n },\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.wait\",\n \"typeVersion\": 1.1,\n \"position\": [\n -80,\n 60\n ],\n \"id\": \"435d5eb7-f2a2-4b2e-ad27-712e7fd304b7\",\n \"name\": \"5_sec\",\n \"webhookId\": \"ac0bb2e9-a1f8-47df-823b-074a0e825f6c\"\n },\n {\n \"parameters\": {\n \"url\": \"=http://crawl4ai:11235/task/{{ $json.task_id }}\",\n \"authentication\": \"genericCredentialType\",\n \"genericAuthType\": \"httpHeaderAuth\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 60,\n 60\n ],\n \"id\": \"5f582f3d-616d-433b-9b62-d1c646dea679\",\n \"name\": \"get_status\"\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"f42941b7-46c6-44f9-95d6-80065c27c3a9\",\n \"leftValue\": \"={{ $json.status }}\",\n \"rightValue\": \"completed\",\n \"operator\": {\n \"type\": \"string\",\n \"operation\": \"equals\",\n \"name\": \"filter.operator.equals\"\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.if\",\n \"typeVersion\": 2.2,\n \"position\": [\n 200,\n 60\n ],\n \"id\": \"5326213d-ffd6-4048-81d2-1c1dd44a3485\",\n \"name\": \"is_completed\"\n },\n {\n \"parameters\": {\n \"html\": \"={{ $json.result.cleaned_html }}\",\n \"destinationKey\": \"markdown\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.markdown\",\n \"typeVersion\": 1,\n \"position\": [\n 540,\n -20\n ],\n \"id\": \"9a5897bb-30f6-4e7c-90e2-4b8995a22aeb\",\n \"name\": \"Markdown\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"9177b0ac-024c-4088-a1b4-9254a53244e0\",\n \"name\": \"result.url\",\n \"value\": \"={{ $json.result.url }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"bb4b7ad9-dc32-40d5-93d7-51582c64d99f\",\n \"name\": \"result.metadata.title\",\n \"value\": \"={{ $json.result.metadata.title }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"64dfd766-9b2e-4349-8f4f-8771202cb0d4\",\n \"name\": \"result.cleaned_html\",\n \"value\": \"={{ $json.result.cleaned_html }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"a74a89ab-aa6e-4ff5-934a-c6176702c127\",\n \"name\": \"result.metadata.description\",\n \"value\": \"={{ $json.result.metadata.description }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 360,\n -20\n ],\n \"id\": \"3fc6b9e7-755e-4f0a-bef5-54e3f4f62f21\",\n \"name\": \"Edit Fields\"\n },\n {\n \"parameters\": {\n \"resource\": \"fileFolder\",\n \"searchMethod\": \"query\",\n \"queryString\": \"={{ \\\"name=\\\" + \\\"'\\\"+$json.Link.split('/').filter(Boolean).pop()+\\\"'\\\" }}\",\n \"limit\": 1,\n \"filter\": {\n \"includeTrashed\": \"={{ false }}\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleDrive\",\n \"typeVersion\": 3,\n \"position\": [\n -280,\n 500\n ],\n \"id\": \"2bd3d92a-6035-4f9e-b491-5ca18643d93c\",\n \"name\": \"Google Drive\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"bf20030a-7234-4e88-bcc9-cb815ac8dcd9\",\n \"leftValue\": \"={{ $json }}\",\n \"rightValue\": \"\",\n \"operator\": {\n \"type\": \"object\",\n \"operation\": \"notEmpty\",\n \"singleValue\": true\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.if\",\n \"typeVersion\": 2.2,\n \"position\": [\n -100,\n 500\n ],\n \"id\": \"38e4200b-6e9d-4f4b-b2be-c0156ffc5a54\",\n \"name\": \"if_sheet_exists\"\n },\n {\n \"parameters\": {\n \"resource\": \"spreadsheet\",\n \"title\": \"={{ $('On form submission').item.json.Link.split('/').filter(Boolean).pop() }}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 60,\n 580\n ],\n \"id\": \"10ab4494-e56d-4854-9557-63702aa92edd\",\n \"name\": \"create_new_spreadsheet\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {\n \"projectId\": {\n \"__rl\": true,\n \"value\": \"automations-451008\",\n \"mode\": \"list\",\n \"cachedResultName\": \"automations\",\n \"cachedResultUrl\": \"https://console.cloud.google.com/bigquery?project=automations-451008\"\n },\n \"sqlQuery\": \"DECLARE target_url STRING DEFAULT '{{ $('On form submission').item.json.Link }}';\\nDECLARE current_period_start DATE DEFAULT DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY);\\nDECLARE previous_period_start DATE DEFAULT DATE_SUB(current_period_start, INTERVAL 30 DAY);\\n\\nWITH \\n-- Current period query performance (last 30 days)\\ncurrent_period AS (\\n SELECT\\n query,\\n SUM(clicks) AS current_clicks,\\n SUM(impressions) AS current_impressions,\\n SAFE_DIVIDE(SUM(clicks), SUM(impressions)) AS current_ctr,\\n SAFE_DIVIDE(SUM(sum_position), SUM(impressions)) AS current_avg_position\\n FROM `your_bigquery_table`\\n WHERE \\n url = target_url\\n AND data_date >= current_period_start\\n AND data_date < CURRENT_DATE()\\n AND is_anonymized_query = False\\n GROUP BY query\\n),\\n\\n-- Previous period query performance (30-60 days ago)\\nprevious_period AS (\\n SELECT\\n query,\\n SUM(clicks) AS previous_clicks,\\n SUM(impressions) AS previous_impressions,\\n SAFE_DIVIDE(SUM(clicks), SUM(impressions)) AS previous_ctr,\\n SAFE_DIVIDE(SUM(sum_position), SUM(impressions)) AS previous_avg_position\\n FROM `your_bigquery_table`\\n WHERE \\n url = target_url\\n AND data_date >= previous_period_start\\n AND data_date < current_period_start\\n AND is_anonymized_query = False\\n GROUP BY query\\n),\\n\\n-- Combined data with differences\\ncombined_data AS (\\n SELECT\\n COALESCE(c.query, p.query) AS query,\\n \\n -- Current period metrics\\n IFNULL(c.current_clicks, 0) AS current_clicks,\\n IFNULL(p.previous_clicks, 0) AS previous_clicks,\\n \\n IFNULL(c.current_impressions, 0) AS current_impressions,\\n IFNULL(p.previous_impressions, 0) AS previous_impressions,\\n \\n IFNULL(c.current_ctr, 0) AS current_ctr,\\n IFNULL(p.previous_ctr, 0) AS previous_ctr,\\n \\n IFNULL(c.current_avg_position, 0) AS current_avg_position,\\n IFNULL(p.previous_avg_position, 0) AS previous_avg_position,\\n \\n -- Absolute differences\\n IFNULL(c.current_clicks, 0) - IFNULL(p.previous_clicks, 0) AS clicks_diff,\\n IFNULL(c.current_impressions, 0) - IFNULL(p.previous_impressions, 0) AS impressions_diff,\\n IFNULL(c.current_ctr, 0) - IFNULL(p.previous_ctr, 0) AS ctr_diff,\\n IFNULL(p.previous_avg_position, 0) - IFNULL(c.current_avg_position, 0) AS position_diff,\\n \\n -- Percentage differences\\n CASE \\n WHEN IFNULL(p.previous_clicks, 0) = 0 AND IFNULL(c.current_clicks, 0) > 0 THEN 100\\n WHEN IFNULL(p.previous_clicks, 0) = 0 THEN 0\\n ELSE ROUND((IFNULL(c.current_clicks, 0) - IFNULL(p.previous_clicks, 0)) / IFNULL(p.previous_clicks, 0) * 100, 2)\\n END AS clicks_diff_pct,\\n \\n CASE \\n WHEN IFNULL(p.previous_impressions, 0) = 0 AND IFNULL(c.current_impressions, 0) > 0 THEN 100\\n WHEN IFNULL(p.previous_impressions, 0) = 0 THEN 0\\n ELSE ROUND((IFNULL(c.current_impressions, 0) - IFNULL(p.previous_impressions, 0)) / IFNULL(p.previous_impressions, 0) * 100, 2)\\n END AS impressions_diff_pct,\\n \\n CASE \\n WHEN IFNULL(p.previous_ctr, 0) = 0 AND IFNULL(c.current_ctr, 0) > 0 THEN 100\\n WHEN IFNULL(p.previous_ctr, 0) = 0 THEN 0\\n ELSE ROUND((IFNULL(c.current_ctr, 0) - IFNULL(p.previous_ctr, 0)) / IFNULL(p.previous_ctr, 0) * 100, 2)\\n END AS ctr_diff_pct\\n FROM current_period c\\n FULL OUTER JOIN previous_period p ON c.query = p.query\\n)\\n\\n-- Main query with categorization\\nSELECT\\n query,\\n \\n -- Paired metrics (current next to previous)\\n current_clicks,\\n previous_clicks,\\n clicks_diff,\\n clicks_diff_pct,\\n \\n current_impressions,\\n previous_impressions,\\n impressions_diff,\\n impressions_diff_pct,\\n \\n current_ctr,\\n previous_ctr,\\n ctr_diff,\\n ctr_diff_pct,\\n \\n current_avg_position,\\n previous_avg_position,\\n position_diff,\\n \\n -- Categorization\\n CASE\\n WHEN clicks_diff > 0 THEN 'Gaining'\\n WHEN clicks_diff < 0 THEN 'Declining'\\n ELSE 'Stable'\\n END AS trend_category\\n\\nFROM combined_data\\nWHERE \\n -- Filter to include only keywords with meaningful data\\n (current_clicks > 0 OR previous_clicks > 0 OR current_impressions > 10 OR previous_impressions > 10)\\nORDER BY \\n -- Default ordering by absolute click difference (biggest gains/losses first)\\n ABS(clicks_diff) DESC,\\n current_impressions DESC\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleBigQuery\",\n \"typeVersion\": 2.1,\n \"position\": [\n 540,\n 500\n ],\n \"id\": \"d8864e24-c4b0-4848-8abd-6fddac21bf8f\",\n \"name\": \"get_article_performance\"\n },\n {\n \"parameters\": {\n \"operation\": \"create\",\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"={{ $json.id }}\",\n \"mode\": \"id\"\n },\n \"title\": \"={{$now.format('yyyy-MM-dd')}}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 60,\n 420\n ],\n \"id\": \"ef356758-0b7f-4984-a11f-44a39ec86fc7\",\n \"name\": \"add_sheet_0\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {\n \"operation\": \"create\",\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"={{ $json.spreadsheetId }}\",\n \"mode\": \"id\"\n },\n \"title\": \"={{ $now.format('yyyy-MM-dd')}}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 240,\n 580\n ],\n \"id\": \"46a01b97-6576-4c7d-8198-d21a5cedbcd7\",\n \"name\": \"add_sheet_1\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.merge\",\n \"typeVersion\": 3,\n \"position\": [\n 400,\n 500\n ],\n \"id\": \"18066faf-8a89-4ed7-b612-b9fe6a3b85a7\",\n \"name\": \"Merge\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {\n \"operation\": \"append\",\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"={{ $('Merge').item.json.spreadsheetId }}\",\n \"mode\": \"id\"\n },\n \"sheetName\": {\n \"__rl\": true,\n \"value\": \"={{ $now.format('yyyy-MM-dd') }}\",\n \"mode\": \"name\"\n },\n \"columns\": {\n \"mappingMode\": \"autoMapInputData\",\n \"value\": {},\n \"matchingColumns\": [],\n \"schema\": [\n {\n \"id\": \"query\",\n \"displayName\": \"query\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"current_clicks\",\n \"displayName\": \"current_clicks\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"previous_clicks\",\n \"displayName\": \"previous_clicks\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"clicks_diff\",\n \"displayName\": \"clicks_diff\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"clicks_diff_pct\",\n \"displayName\": \"clicks_diff_pct\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"current_impressions\",\n \"displayName\": \"current_impressions\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"previous_impressions\",\n \"displayName\": \"previous_impressions\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"impressions_diff\",\n \"displayName\": \"impressions_diff\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"impressions_diff_pct\",\n \"displayName\": \"impressions_diff_pct\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"current_ctr\",\n \"displayName\": \"current_ctr\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"previous_ctr\",\n \"displayName\": \"previous_ctr\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"ctr_diff\",\n \"displayName\": \"ctr_diff\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"ctr_diff_pct\",\n \"displayName\": \"ctr_diff_pct\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"current_avg_position\",\n \"displayName\": \"current_avg_position\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"previous_avg_position\",\n \"displayName\": \"previous_avg_position\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"position_diff\",\n \"displayName\": \"position_diff\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"trend_category\",\n \"displayName\": \"trend_category\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": false\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 700,\n 500\n ],\n \"id\": \"17a2c863-c55f-458a-8a7c-ffc016c7acf6\",\n \"name\": \"insert_performance\"\n },\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.merge\",\n \"typeVersion\": 3,\n \"position\": [\n 900,\n 60\n ],\n \"id\": \"3a5d7bf9-8fb4-4d1c-8770-c39f57afd39c\",\n \"name\": \"Merge1\",\n \"executeOnce\": false\n },\n {\n \"parameters\": {\n \"aggregate\": \"aggregateAllItemData\",\n \"destinationFieldName\": \"performance\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.aggregate\",\n \"typeVersion\": 1,\n \"position\": [\n 720,\n 160\n ],\n \"id\": \"0716f221-9819-4533-98fe-34bec5e9ac83\",\n \"name\": \"set_key\"\n },\n {\n \"parameters\": {\n \"modelId\": {\n \"__rl\": true,\n \"value\": \"gpt-4o-mini\",\n \"mode\": \"list\",\n \"cachedResultName\": \"GPT-4O-MINI\"\n },\n \"messages\": {\n \"values\": [\n {\n \"content\": \"Du bist Copywriter mit einem vielseitigen Skillset an SEO-Fähigkeiten. Du bist auf die datengetriebene Optimierung spezialisiert und verbesserst bestehende Artikel auf Basis von realen Traffic-Daten. Deine Daten stammen aus der Google Search Console und zeigen, wie gut Keywords performen. Du stützt dich ausschließlich auf die zugrundeliegenden Daten und erfindest keine falschen Informationen. Dein Ziel ist es immer, den Artikel datengetrieben zu verbessern. Des Weiteren bist du HTML-Experte und gibst deine Antworten ausschließlich als HTML-formatiert zurück. Wir benötigen kein DOCTYPE, meta oder title tag. Ausschließlich HTML der den Inhalt strukturiert darstellt.\",\n \"role\": \"system\"\n },\n {\n \"content\": \"=Analysiere den vorhandenen Artikel: <{{ $json.content }}> im Detail und verstehe den Inhalt sowie die Suchintention, die dieser Artikel befriedigen soll. Anschließend analysierst du ALLE Keywords aus der Google Search Console. Diese Keywords zeigen dir, wie gut der Artikel für bestimmte Suchanfragen performt.\\nDie Performance-Daten sind wie folgt:\\n\\\"\\\"\\n{{ JSON.stringify($('Merge1').all()[1].json.performance) }}\\n\\\"\\\"\\nFühre folgende Optimierungen durch:\\n 1. Analysiere den bestehenden Artikelinhalt auf Struktur, Lesbarkeit und SEO-Relevanz.\\n 2. Identifiziere Optimierungspotenziale im Artikel basierend auf den analysierten Daten.\\n 3. Entwickle neue Vorschläge für den Titel und die Meta-Beschreibung. \\n\\t- Die Titel dürften nicht mehr wie 60 Zeichen lang sein.\\n\\t- Die Meta-Beschreibung muss relevante Keywords aus den Performance-Daten enthalten.\\n 4. Erstelle optimierte Textpassagen, die die relevanten Keywords aus der Google Search Console natürlich integrieren.\\n \\t- Gib an, aus welchem Kapitel die Textpassage stammen, so dass man diese schnell erkennen und optimieren kann.\\n \\t- Erstelle mindestens für jeden Paragraphen eine optimierte Textpassage.\\n\\t- Gib an, aus welchem Kapitel die Textpassage stammen, so dass man diese schnell erkennen und optimieren kann.\\n\\t- (Die Textpassagen müssen so aufgebaut sein, dass ich diese schnell finden und ersetzen kann)\\n 5. Erstelle neue Textpassagen mit Keywords aus den Google Search Console Daten, die man nicht im vorherigen Schritt einfügen konnte.\\n - Verwende hier als Überschrift \\\"Neue Textpassagen\\\".\\n 6. Erstelle eine HTML Tabelle die deine Auswahl der selektieren Keywords aus der Google Search Console darstellt.\\n\\nFormatiere deine Ausgabe wie folgt und vermeide Fehler:\\n - Ein kurzer Analysebericht des aktuellen Artikelinhalts.\\n - Pro Verbesserungsvorschlag einmal die originale Passage und direkt daruntere die SEO-freundliche Ergänzung.\\n - 5 Vorschläge für optimierte Titel.\\n - 5 Vorschläge für optimierte Meta-Beschreibungen.\\n - Eine Liste von überarbeiteten Textpassagen, die die identifizierten Keywords und Phrasen natürlich integrieren. Bearbeite mindestens\\n 5 Textpassagen. Wenn möglich, dann auch mehr, so dass der Text die Keywords aus der Google Search Console beinhaltet.\\n - HTML Tabelle mit selektieren Keywords aus der Google Search Console.\\n Alles in HTML formatiert.\\nWir benötigen kein DOCTYPE, meta oder title tag. Ausschließlich HTML der den Inhalt strukturiert darstellt.\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"@n8n/n8n-nodes-langchain.openAi\",\n \"typeVersion\": 1.8,\n \"position\": [\n 1140,\n 60\n ],\n \"id\": \"4a96ce2e-ca8b-4bb3-b252-3c0c1ddb5fab\",\n \"name\": \"create_report\",\n \"executeOnce\": true\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"6c07931f-d135-44cb-a9f5-d0e80887a0b4\",\n \"name\": \"url\",\n \"value\": \"={{ $json.result.url }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"d3223ba3-1e08-47b2-9265-f3fb178a49ee\",\n \"name\": \"title\",\n \"value\": \"={{ $json.result.metadata.title }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"13da4adc-a125-4410-b2ca-c0c239b939ab\",\n \"name\": \"description\",\n \"value\": \"={{ $json.result.metadata.description }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"03d09f45-3ece-4da2-953b-fdbe54cd2896\",\n \"name\": \"content\",\n \"value\": \"={{ $json.markdown }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 720,\n -20\n ],\n \"id\": \"a46ffc94-4651-4481-89e6-ed073735a41f\",\n \"name\": \"Edit Fields1\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"654e6696-7705-4021-87df-1edf19bbe439\",\n \"name\": \"message.content\",\n \"value\": \"={{ $json.message.content}}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 1460,\n 60\n ],\n \"id\": \"878b56fc-b988-412a-90eb-0b2d87b3c1d5\",\n \"name\": \"get_clean_html\",\n \"notes\": \".replace('html', '').replaceAll(\\\"```\\\", '').replaceAll(\\\"\\\\n\\\", \\\"\\\") \"\n },\n {\n \"parameters\": {\n \"operation\": \"toBinary\",\n \"sourceProperty\": \"base64\",\n \"options\": {\n \"fileName\": \"test.html\",\n \"mimeType\": \"={{ $json.mimetype }}\"\n }\n },\n \"type\": \"n8n-nodes-base.convertToFile\",\n \"typeVersion\": 1.1,\n \"position\": [\n 1780,\n 60\n ],\n \"id\": \"203ca372-670e-4db6-a2f6-99f01c5a4841\",\n \"name\": \"convert_to_html_file\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"return [\\n {\\n json: {\\n base64: Buffer.from($input.all()[0].json.message.content).toString('base64'),\\n mimetype: \\\"text/html\\\"\\n }\\n }\\n];\\n\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 1620,\n 60\n ],\n \"id\": \"74ba8692-7d3d-4f32-bb74-c075b6a58d83\",\n \"name\": \"convert_to_base64\"\n },\n {\n \"parameters\": {\n \"name\": \"test123\",\n \"driveId\": {\n \"__rl\": true,\n \"mode\": \"list\",\n \"value\": \"My Drive\"\n },\n \"folderId\": {\n \"__rl\": true,\n \"mode\": \"list\",\n \"value\": \"root\",\n \"cachedResultName\": \"/ (Root folder)\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleDrive\",\n \"typeVersion\": 3,\n \"position\": [\n 1940,\n 60\n ],\n \"id\": \"ede28035-8a35-40a6-89df-ffa196470765\",\n \"name\": \"save_report\"\n },\n {\n \"parameters\": {\n \"content\": \"# Crawl Article\",\n \"height\": 420,\n \"width\": 1420\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -340,\n -100\n ],\n \"id\": \"9b518a2a-5b18-4cbb-8afd-0de2fc17a4a0\",\n \"name\": \"Sticky Note1\"\n },\n {\n \"parameters\": {\n \"content\": \"# Generate Optimized Report\",\n \"height\": 420,\n \"width\": 1040\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 1100,\n -100\n ],\n \"id\": \"caffcc7c-7af1-49ee-b513-1840a6a7ba73\",\n \"name\": \"Sticky Note2\"\n },\n {\n \"parameters\": {\n \"content\": \"# Generate and Save Performance Report\",\n \"height\": 420,\n \"width\": 2480\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -340,\n 340\n ],\n \"id\": \"bb48be15-d76d-4e75-ad17-54ad27cfaf87\",\n \"name\": \"Sticky Note\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"On form submission\": {\n \"main\": [\n [\n {\n \"node\": \"get_article_content\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"Google Drive\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"get_article_content\": {\n \"main\": [\n [\n {\n \"node\": \"5_sec\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"5_sec\": {\n \"main\": [\n [\n {\n \"node\": \"get_status\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"get_status\": {\n \"main\": [\n [\n {\n \"node\": \"is_completed\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"is_completed\": {\n \"main\": [\n [\n {\n \"node\": \"Edit Fields\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"5_sec\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Edit Fields\": {\n \"main\": [\n [\n {\n \"node\": \"Markdown\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Google Drive\": {\n \"main\": [\n [\n {\n \"node\": \"if_sheet_exists\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"if_sheet_exists\": {\n \"main\": [\n [\n {\n \"node\": \"add_sheet_0\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"create_new_spreadsheet\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"create_new_spreadsheet\": {\n \"main\": [\n [\n {\n \"node\": \"add_sheet_1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"get_article_performance\": {\n \"main\": [\n [\n {\n \"node\": \"insert_performance\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"set_key\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"add_sheet_1\": {\n \"main\": [\n [\n {\n \"node\": \"Merge\",\n \"type\": \"main\",\n \"index\": 1\n }\n ]\n ]\n },\n \"add_sheet_0\": {\n \"main\": [\n [\n {\n \"node\": \"Merge\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Merge\": {\n \"main\": [\n [\n {\n \"node\": \"get_article_performance\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Markdown\": {\n \"main\": [\n [\n {\n \"node\": \"Edit Fields1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Merge1\": {\n \"main\": [\n [\n {\n \"node\": \"create_report\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"set_key\": {\n \"main\": [\n [\n {\n \"node\": \"Merge1\",\n \"type\": \"main\",\n \"index\": 1\n }\n ]\n ]\n },\n \"create_report\": {\n \"main\": [\n [\n {\n \"node\": \"get_clean_html\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Edit Fields1\": {\n \"main\": [\n [\n {\n \"node\": \"Merge1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"get_clean_html\": {\n \"main\": [\n [\n {\n \"node\": \"convert_to_base64\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"convert_to_base64\": {\n \"main\": [\n [\n {\n \"node\": \"convert_to_html_file\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"convert_to_html_file\": {\n \"main\": [\n [\n {\n \"node\": \"save_report\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"35ba3601-2edb-4bfd-8f0a-c41298ab9d21\",\n \"meta\": {\n \"templateCredsSetupCompleted\": true,\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"cO3xILd89yLoQPGu\",\n \"tags\": [\n {\n \"createdAt\": \"2025-03-02T12:05:53.836Z\",\n \"updatedAt\": \"2025-03-02T12:05:53.836Z\",\n \"id\": \"utwtHTzeqUdktrxJ\",\n \"name\": \"SEO\"\n }\n ]\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "Data-driven SEO Optimization", "node_count": 26, "category": "General Automation"}} {"prompt": "Build a workflow for: Keyword Rank Tracker Google Sheets", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 30\n- Node Types: n8n-nodes-base.splitOut, n8n-nodes-base.set, n8n-nodes-base.splitInBatches, n8n-nodes-base.limit, n8n-nodes-base.if, n8n-nodes-base.manualTrigger, n8n-nodes-base.sort, n8n-nodes-base.stickyNote, n8n-nodes-base.code, n8n-nodes-base.googleBigQuery\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.manualTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"keyword_rank_tracker_google_sheets\",\n \"nodes\": [\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.manualTrigger\",\n \"typeVersion\": 1,\n \"position\": [\n 260,\n 820\n ],\n \"id\": \"8acb9df9-dae5-41ec-b899-0cfb7c3853ea\",\n \"name\": \"When clicking ‘Test workflow’\"\n },\n {\n \"parameters\": {\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"1AJRIe-IROQGRtqlBqeiyVP5ayjSlfOMC_nFDGwwLULU\",\n \"mode\": \"list\",\n \"cachedResultName\": \"tracked_keywords\",\n \"cachedResultUrl\": \"https://docs.google.com/spreadsheets/d/1AJRIe-IROQGRtqlBqeiyVP5ayjSlfOMC_nFDGwwLULU/edit?usp=drivesdk\"\n },\n \"sheetName\": {\n \"__rl\": true,\n \"value\": \"={{ $json.domain }}\",\n \"mode\": \"name\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 1340,\n 280\n ],\n \"id\": \"86f7ea65-9942-4886-9516-21553ac7a460\",\n \"name\": \"Get Tracked Keywords\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"return [{\\n json: {\\n keywordString: $input.all().map(item => `'${item.json.keywords}'`).join(', ')\\n }\\n}];\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 1580,\n 280\n ],\n \"id\": \"3ca647b4-2613-4b31-b1da-9724911380ca\",\n \"name\": \"Code\"\n },\n {\n \"parameters\": {\n \"projectId\": {\n \"__rl\": true,\n \"value\": \"automations-451008\",\n \"mode\": \"list\",\n \"cachedResultName\": \"automations\",\n \"cachedResultUrl\": \"https://console.cloud.google.com/bigquery?project=automations-451008\"\n },\n \"sqlQuery\": \"WITH daily_metrics AS (\\n SELECT \\n data_date as date,\\n query as keyword,\\n url,\\n device,\\n SUM(clicks) as clicks,\\n SUM(impressions) as impressions,\\n ROUND(AVG(sum_position / impressions), 1) as position,\\n ROUND(SUM(clicks) / SUM(impressions) * 100, 2) as ctr\\n FROM `{{ $('Loop Over Items').all()[0].json.searchdata_url_impression }}`\\n WHERE \\n data_date > '{{ $('Merge Loop Data').all()[0].json.date }}'\\n AND NOT is_anonymized_query\\n AND lower(query) IN (\\n {{ $('Merge Loop Data').all()[1].json.keywordString }}\\n )\\n -- remove following line if you want to exclude toc rankings\\n AND url NOT LIKE '%#%'\\n GROUP BY date, keyword, url, device\\n)\\n\\nSELECT \\n date,\\n keyword,\\n device,\\n url,\\n clicks,\\n impressions,\\n position,\\n ctr\\nFROM daily_metrics\\nORDER BY date ASC, keyword, position ASC\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleBigQuery\",\n \"typeVersion\": 2.1,\n \"position\": [\n 2540,\n 260\n ],\n \"id\": \"f9245333-7f36-42f8-85c4-502ab8c15b92\",\n \"name\": \"Get Ranking Keywords by URL\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {\n \"operation\": \"appendOrUpdate\",\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"19wCg-VAykAIYzeryWTeLfxJEr9G9Sj1Vf3h4DZUITqQ\",\n \"mode\": \"list\",\n \"cachedResultName\": \"rank_tracking\",\n \"cachedResultUrl\": \"https://docs.google.com/spreadsheets/d/19wCg-VAykAIYzeryWTeLfxJEr9G9Sj1Vf3h4DZUITqQ/edit?usp=drivesdk\"\n },\n \"sheetName\": {\n \"__rl\": true,\n \"value\": \"={{ $('Loop Over Items').all()[0].json.domain }}\",\n \"mode\": \"name\"\n },\n \"columns\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"date\": \"={{ $json.date }}\",\n \"keyword\": \"={{ $json.keyword }}\",\n \"url\": \"={{ $json.url }}\",\n \"device\": \"={{ $json.device }}\",\n \"clicks\": \"={{ $json.clicks }}\",\n \"position\": \"={{ $json.position }}\",\n \"ctr\": \"={{ $json.ctr }}\",\n \"impressions\": \"={{ $json.impressions }}\"\n },\n \"matchingColumns\": [\n \"date\"\n ],\n \"schema\": [\n {\n \"id\": \"date\",\n \"displayName\": \"date\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"url\",\n \"displayName\": \"url\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"device\",\n \"displayName\": \"device\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"keyword\",\n \"displayName\": \"keyword\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"clicks\",\n \"displayName\": \"clicks\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"impressions\",\n \"displayName\": \"impressions\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"position\",\n \"displayName\": \"position\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"ctr\",\n \"displayName\": \"ctr\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": false\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 2740,\n 260\n ],\n \"id\": \"47bd9243-26d3-4ba6-ae65-f3cbc86e7020\",\n \"name\": \"Insert URL Rankings\"\n },\n {\n \"parameters\": {\n \"mode\": \"raw\",\n \"jsonOutput\": \"{\\n \\\"domains\\\": [\\n {\\n \\\"domain\\\": \\\"domain_1\\\",\\n \\\"searchdata_url_impression\\\": \\\"searchdata_url_impression\\\",\\n \\\"searchdata_site_impression\\\": \\\"searchdata_site_impression\\\"\\n },\\n {\\n \\\"domain\\\": \\\"domain_2\\\",\\n \\\"searchdata_url_impression\\\": \\\"searchdata_url_impression\\\",\\n \\\"searchdata_site_impression\\\": \\\"searchdata_site_impression\\\"\\n }\\n ]\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 460,\n 820\n ],\n \"id\": \"204a8fdf-f163-4c72-99b5-1babc3f1cdfd\",\n \"name\": \"Domains\"\n },\n {\n \"parameters\": {\n \"fieldToSplitOut\": \"domains\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.splitOut\",\n \"typeVersion\": 1,\n \"position\": [\n 640,\n 820\n ],\n \"id\": \"e2d43fb3-20f1-433a-8b0e-a7aca6c28546\",\n \"name\": \"Split Out\"\n },\n {\n \"parameters\": {\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.splitInBatches\",\n \"typeVersion\": 3,\n \"position\": [\n 980,\n 180\n ],\n \"id\": \"3e131334-a028-4513-999d-fedbe8ec1ec3\",\n \"name\": \"Loop Over Items\"\n },\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.merge\",\n \"typeVersion\": 3,\n \"position\": [\n 2340,\n 260\n ],\n \"id\": \"1db25f6f-9684-4c18-adbf-8f11a792cda8\",\n \"name\": \"Merge Loop Data\"\n },\n {\n \"parameters\": {\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"19wCg-VAykAIYzeryWTeLfxJEr9G9Sj1Vf3h4DZUITqQ\",\n \"mode\": \"list\",\n \"cachedResultName\": \"rank_tracking\",\n \"cachedResultUrl\": \"https://docs.google.com/spreadsheets/d/19wCg-VAykAIYzeryWTeLfxJEr9G9Sj1Vf3h4DZUITqQ/edit?usp=drivesdk\"\n },\n \"sheetName\": {\n \"__rl\": true,\n \"value\": \"={{ $json.domain }}\",\n \"mode\": \"name\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 1340,\n 120\n ],\n \"id\": \"ef8f0f8e-eef5-4528-a875-1c9d9af7682a\",\n \"name\": \"Google Sheets\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {\n \"sortFieldsUi\": {\n \"sortField\": [\n {\n \"fieldName\": \"date\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.sort\",\n \"typeVersion\": 1,\n \"position\": [\n 1820,\n 40\n ],\n \"id\": \"d817e09f-c5a0-40a5-bbf6-64bc606b0796\",\n \"name\": \"Sort\"\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"1a376642-1bb3-43a3-802f-6844d3b9c2a7\",\n \"leftValue\": \"={{ $('Google Sheets').all()[0].json.isEmpty()}}\",\n \"rightValue\": \"\",\n \"operator\": {\n \"type\": \"boolean\",\n \"operation\": \"false\",\n \"singleValue\": true\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.if\",\n \"typeVersion\": 2.2,\n \"position\": [\n 1580,\n 120\n ],\n \"id\": \"3dd0c3e7-3898-4204-968c-6395f76303f2\",\n \"name\": \"If\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"e3ce8bf6-cbee-4949-a338-aeb1523b646a\",\n \"name\": \"=date\",\n \"value\": \"={{ $now.minus({ days: 7 }).format('yyyy-MM-dd') }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 1820,\n 220\n ],\n \"id\": \"661b773d-3c02-4060-a023-407e2e981e2f\",\n \"name\": \"Set Date\",\n \"notes\": \"In case the pipeline has not been triggered before, then the tracking sheet is empty. If true, we will take as a starting point of today minus 7 days. \"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"4538ac52-c81c-460f-96ce-70ab74f313d9\",\n \"name\": \"date\",\n \"value\": \"={{ $json.date }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 2100,\n 40\n ],\n \"id\": \"13c62280-43b6-4e5e-9f24-9d4c2adf27ec\",\n \"name\": \"Get date\"\n },\n {\n \"parameters\": {\n \"keep\": \"lastItems\"\n },\n \"type\": \"n8n-nodes-base.limit\",\n \"typeVersion\": 1,\n \"position\": [\n 1960,\n 40\n ],\n \"id\": \"4981a6af-44e3-43ca-bcbe-89540045278d\",\n \"name\": \"Get latest row\"\n },\n {\n \"parameters\": {\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.splitInBatches\",\n \"typeVersion\": 3,\n \"position\": [\n 980,\n 580\n ],\n \"id\": \"0a3fe253-e489-4cf2-aea7-c3933b18e65c\",\n \"name\": \"Loop Over Items1\"\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"32ae47a9-f7f5-41fc-b403-468094ba3f41\",\n \"leftValue\": \"={{ $('Get Top Ranking Keywords Date').all()[0].json.isEmpty()}}\",\n \"rightValue\": \"\",\n \"operator\": {\n \"type\": \"boolean\",\n \"operation\": \"false\",\n \"singleValue\": true\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.if\",\n \"typeVersion\": 2.2,\n \"position\": [\n 1360,\n 680\n ],\n \"id\": \"9e74b6c0-d63b-497e-a45f-860ef1680a8e\",\n \"name\": \"If1\"\n },\n {\n \"parameters\": {\n \"sortFieldsUi\": {\n \"sortField\": [\n {\n \"fieldName\": \"data_date\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.sort\",\n \"typeVersion\": 1,\n \"position\": [\n 1600,\n 540\n ],\n \"id\": \"90662893-eeb1-4b70-8e63-22dbc1691932\",\n \"name\": \"Sort1\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"4538ac52-c81c-460f-96ce-70ab74f313d9\",\n \"name\": \"date\",\n \"value\": \"={{ $json.data_date }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 1920,\n 540\n ],\n \"id\": \"6ea5970f-2a06-4334-89a3-e5a2234f38af\",\n \"name\": \"Get date1\"\n },\n {\n \"parameters\": {\n \"operation\": \"appendOrUpdate\",\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"1KWs-hsuxs_5leU6qELEDlzpFObkhHAFdKgJmDVq5aKg\",\n \"mode\": \"list\",\n \"cachedResultName\": \"Top Ranking Keywords\",\n \"cachedResultUrl\": \"https://docs.google.com/spreadsheets/d/1KWs-hsuxs_5leU6qELEDlzpFObkhHAFdKgJmDVq5aKg/edit?usp=drivesdk\"\n },\n \"sheetName\": {\n \"__rl\": true,\n \"value\": \"={{ $('Loop Over Items1').item.json.domain }}\",\n \"mode\": \"name\"\n },\n \"columns\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"data_date\": \"={{ $json.data_date }}\",\n \"query\": \"={{ $json.query }}\",\n \"url\": \"={{ $json.url }}\",\n \"device\": \"={{ $json.device }}\",\n \"result_type\": \"={{ $json.result_type }}\",\n \"total_impressions\": \"={{ $json.total_impressions }}\",\n \"total_clicks\": \"={{ $json.total_clicks }}\",\n \"avg_position\": \"={{ $json.avg_position }}\",\n \"ctr_percentage\": \"={{ $json.ctr_percentage }}\",\n \"position_bucket\": \"={{ $json.position_bucket }}\"\n },\n \"matchingColumns\": [\n \"data_date\"\n ],\n \"schema\": [\n {\n \"id\": \"data_date\",\n \"displayName\": \"data_date\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"query\",\n \"displayName\": \"query\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"url\",\n \"displayName\": \"url\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"device\",\n \"displayName\": \"device\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"result_type\",\n \"displayName\": \"result_type\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"total_impressions\",\n \"displayName\": \"total_impressions\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"total_clicks\",\n \"displayName\": \"total_clicks\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"avg_position\",\n \"displayName\": \"avg_position\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"ctr_percentage\",\n \"displayName\": \"ctr_percentage\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"position_bucket\",\n \"displayName\": \"position_bucket\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": false\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 2360,\n 740\n ],\n \"id\": \"0c6efb69-c1c2-47cd-a81e-6d6489796456\",\n \"name\": \"Insert Top Ranking Keywords\"\n },\n {\n \"parameters\": {\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"1KWs-hsuxs_5leU6qELEDlzpFObkhHAFdKgJmDVq5aKg\",\n \"mode\": \"list\",\n \"cachedResultName\": \"Top Ranking Keywords\",\n \"cachedResultUrl\": \"https://docs.google.com/spreadsheets/d/1KWs-hsuxs_5leU6qELEDlzpFObkhHAFdKgJmDVq5aKg/edit?usp=drivesdk\"\n },\n \"sheetName\": {\n \"__rl\": true,\n \"value\": \"={{ $json.domain }}\",\n \"mode\": \"name\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 1200,\n 680\n ],\n \"id\": \"9d071923-bc79-45f8-967e-5f610bb8aa12\",\n \"name\": \"Get Top Ranking Keywords Date\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {\n \"keep\": \"lastItems\"\n },\n \"type\": \"n8n-nodes-base.limit\",\n \"typeVersion\": 1,\n \"position\": [\n 1760,\n 540\n ],\n \"id\": \"fe61c0ef-99bc-4f00-89ff-fbd09333e88b\",\n \"name\": \"Get last row by date\"\n },\n {\n \"parameters\": {\n \"projectId\": {\n \"__rl\": true,\n \"value\": \"automations-451008\",\n \"mode\": \"list\",\n \"cachedResultName\": \"automations\",\n \"cachedResultUrl\": \"https://console.cloud.google.com/bigquery?project=automations-451008\"\n },\n \"sqlQuery\": \"WITH filtered_queries AS (\\n SELECT \\n data_date,\\n device,\\n query,\\n url,\\n SUM(clicks) as clicks,\\n SUM(impressions) as impressions,\\n SUM(sum_position) as sum_position,\\n SUM(sum_position)/SUM(impressions) + 1 as avg_position,\\n MAX(CASE \\n WHEN is_tpf_faq THEN 'FAQ'\\n WHEN is_tpf_howto THEN 'HowTo'\\n WHEN is_review_snippet THEN 'Review'\\n ELSE 'Normal'\\n END) as result_type\\n FROM `{{ $('Loop Over Items1').all()[0].json.searchdata_url_impression }}`\\n WHERE SAFE_DIVIDE(sum_position, impressions) <= 50\\n AND is_anonymized_query = False\\n AND impressions >= 5\\n AND data_date > '{{ $json.date }}'\\n GROUP BY data_date, device, query, url\\n)\\n\\nSELECT \\n data_date,\\n query,\\n url,\\n device,\\n result_type,\\n impressions as total_impressions,\\n clicks as total_clicks,\\n avg_position,\\n SAFE_DIVIDE(clicks, impressions) * 100 as ctr_percentage,\\n CASE \\n WHEN avg_position <= 3 THEN 'Top 3'\\n WHEN avg_position <= 10 THEN 'Top 10'\\n WHEN avg_position <= 20 THEN 'Top 20'\\n ELSE 'Above 20'\\n END as position_bucket\\nFROM filtered_queries\\nORDER BY \\n data_date DESC,\\n url\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleBigQuery\",\n \"typeVersion\": 2.1,\n \"position\": [\n 2140,\n 740\n ],\n \"id\": \"a425bbf8-2dc2-4c5a-a870-423b1e4b6266\",\n \"name\": \"Get Keyword Opportunities\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"e3ce8bf6-cbee-4949-a338-aeb1523b646a\",\n \"name\": \"=date\",\n \"value\": \"={{ $now.minus({ days: 7 }).format('yyyy-MM-dd') }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 1600,\n 760\n ],\n \"id\": \"b2101d06-4890-40bc-b7ba-40726f57f195\",\n \"name\": \"Today - 7d\",\n \"notes\": \"In case the pipeline has not been triggered before, then the tracking sheet is empty. If true, we will take as a starting point of today minus 7 days. \"\n },\n {\n \"parameters\": {\n \"content\": \"# Keyword Tracking by Keyword List\",\n \"height\": 480,\n \"width\": 2120\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 840,\n 0\n ],\n \"id\": \"d53bc40e-ef62-4800-8909-da9e5435dd1e\",\n \"name\": \"Sticky Note\"\n },\n {\n \"parameters\": {\n \"content\": \"# Keywords by URL and Top position\",\n \"height\": 480,\n \"width\": 2120\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 840,\n 500\n ],\n \"id\": \"07c0101b-efbf-4bc9-bbc5-610145c44daf\",\n \"name\": \"Sticky Note1\"\n },\n {\n \"parameters\": {\n \"content\": \"# Instructions\\n\\n## Description\\nThis automation enables you to replace expensive SEO Rank Trackers and track any number of keywords for multiple domains.\\n\\n## Requirements & Setup (~20 minutes)\\nTo use this template, you need bulk export enabled for your property connected to Google Search Console. The automation uses a BigQuery table for data processing.\\n\\nYou'll also need to set up credentials for accessing both BigQuery and Google Sheets.\\n\\n## Google Spreadsheets\\nThis automation requires three spreadsheets:\\n1. **Top Ranking Keywords**: Saves queries where you already rank at a decent position. This data helps identify low-hanging fruits.\\n - Columns: data_date, query, url, device, result_type, total_impressions, total_clicks, avg_position, ctr_percentage, position_bucket\\n\\n2. **Rank Tracking**: Tracks the daily performance of your monitored keywords.\\n - Columns: date, url, device, keyword, clicks, impressions, position, ctr\\n\\n3. **Tracked Keywords**: Stores all keywords you want to rank for.\\n - Columns: domain, keyword\\n\",\n \"height\": 980,\n \"width\": 640\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 180,\n 0\n ],\n \"id\": \"485c6d22-ac32-4024-926f-2768e008ffcb\",\n \"name\": \"Sticky Note2\"\n },\n {\n \"parameters\": {\n \"content\": \"adjust this node if you want to start with more historical data\\n\",\n \"height\": 200,\n \"color\": 5\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 1580,\n 680\n ],\n \"id\": \"c04010cc-692c-4aac-9f30-a310d0ec4d5d\",\n \"name\": \"Sticky Note3\"\n },\n {\n \"parameters\": {\n \"content\": \"adjust this node if you want to start with more historical data\\n\",\n \"height\": 200,\n \"color\": 5\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 1780,\n 160\n ],\n \"id\": \"4b6fd09a-cb3d-4a8f-840d-9426e19dc83d\",\n \"name\": \"Sticky Note4\"\n },\n {\n \"parameters\": {\n \"content\": \"add your domains and tables here\",\n \"height\": 180,\n \"color\": 5\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 400,\n 780\n ],\n \"id\": \"1994ac61-8221-450a-a17e-4480f4bc5e2c\",\n \"name\": \"Sticky Note5\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"When clicking ‘Test workflow’\": {\n \"main\": [\n [\n {\n \"node\": \"Domains\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Tracked Keywords\": {\n \"main\": [\n [\n {\n \"node\": \"Code\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Code\": {\n \"main\": [\n [\n {\n \"node\": \"Merge Loop Data\",\n \"type\": \"main\",\n \"index\": 1\n }\n ]\n ]\n },\n \"Get Ranking Keywords by URL\": {\n \"main\": [\n [\n {\n \"node\": \"Insert URL Rankings\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Insert URL Rankings\": {\n \"main\": [\n [\n {\n \"node\": \"Loop Over Items\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Domains\": {\n \"main\": [\n [\n {\n \"node\": \"Split Out\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Split Out\": {\n \"main\": [\n [\n {\n \"node\": \"Loop Over Items1\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"Loop Over Items\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Loop Over Items\": {\n \"main\": [\n [],\n [\n {\n \"node\": \"Get Tracked Keywords\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"Google Sheets\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Merge Loop Data\": {\n \"main\": [\n [\n {\n \"node\": \"Get Ranking Keywords by URL\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Google Sheets\": {\n \"main\": [\n [\n {\n \"node\": \"If\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Sort\": {\n \"main\": [\n [\n {\n \"node\": \"Get latest row\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"If\": {\n \"main\": [\n [\n {\n \"node\": \"Sort\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"Set Date\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Set Date\": {\n \"main\": [\n [\n {\n \"node\": \"Merge Loop Data\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get date\": {\n \"main\": [\n [\n {\n \"node\": \"Merge Loop Data\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get latest row\": {\n \"main\": [\n [\n {\n \"node\": \"Get date\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Loop Over Items1\": {\n \"main\": [\n [],\n [\n {\n \"node\": \"Get Top Ranking Keywords Date\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Sort1\": {\n \"main\": [\n [\n {\n \"node\": \"Get last row by date\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"If1\": {\n \"main\": [\n [\n {\n \"node\": \"Sort1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"Today - 7d\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Top Ranking Keywords Date\": {\n \"main\": [\n [\n {\n \"node\": \"If1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get last row by date\": {\n \"main\": [\n [\n {\n \"node\": \"Get date1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get date1\": {\n \"main\": [\n [\n {\n \"node\": \"Get Keyword Opportunities\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Insert Top Ranking Keywords\": {\n \"main\": [\n [\n {\n \"node\": \"Loop Over Items1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Keyword Opportunities\": {\n \"main\": [\n [\n {\n \"node\": \"Insert Top Ranking Keywords\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Today - 7d\": {\n \"main\": [\n [\n {\n \"node\": \"Get Keyword Opportunities\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"9181a9fe-0814-443c-86b3-d5237f88f693\",\n \"meta\": {\n \"templateCredsSetupCompleted\": true,\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"nOzLedRb5STlMLxP\",\n \"tags\": [\n {\n \"createdAt\": \"2025-03-02T12:05:53.836Z\",\n \"updatedAt\": \"2025-03-02T12:05:53.836Z\",\n \"id\": \"utwtHTzeqUdktrxJ\",\n \"name\": \"SEO\"\n },\n {\n \"createdAt\": \"2025-03-12T18:27:08.298Z\",\n \"updatedAt\": \"2025-03-12T18:27:08.298Z\",\n \"id\": \"LJnByXT8PNh6CBUf\",\n \"name\": \"templates\"\n }\n ]\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "keyword_rank_tracker_google_sheets", "node_count": 30, "category": "General Automation"}} {"prompt": "How would you build: Rank Tracker Postgres Template?", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 28\n- Node Types: n8n-nodes-base.splitOut, n8n-nodes-base.set, n8n-nodes-base.splitInBatches, n8n-nodes-base.postgres, n8n-nodes-base.if, n8n-nodes-base.manualTrigger, n8n-nodes-base.stickyNote, n8n-nodes-base.code, n8n-nodes-base.googleBigQuery, n8n-nodes-base.merge\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.manualTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"Rank Tracker Postgres Template\",\n \"nodes\": [\n {\n \"parameters\": {\n \"projectId\": {\n \"__rl\": true,\n \"value\": \"automations-451008\",\n \"mode\": \"list\",\n \"cachedResultName\": \"automations\",\n \"cachedResultUrl\": \"https://console.cloud.google.com/bigquery?project=automations-451008\"\n },\n \"sqlQuery\": \"WITH daily_metrics AS (\\n SELECT \\n data_date as date,\\n query as keyword,\\n url,\\n device,\\n SUM(clicks) as clicks,\\n SUM(impressions) as impressions,\\n ROUND(AVG(sum_position / impressions), 1) as position,\\n ROUND(SUM(clicks) / SUM(impressions) * 100, 2) as ctr\\n FROM `{{ $('Loop Over Items').all()[0].json.searchdata_url_impression }}`\\n WHERE\\n data_date > '{{ $json.data_date }}'\\n AND NOT is_anonymized_query\\n AND lower(query) IN (\\n {{ $('merge_query_params').all()[1].json.keywordString }}\\n )\\n -- remove following line if you want to exclude toc rankings\\n AND url NOT LIKE '%#%'\\n GROUP BY date, keyword, url, device\\n)\\n\\nSELECT \\n date,\\n keyword,\\n device,\\n url,\\n clicks,\\n impressions,\\n position,\\n ctr\\nFROM daily_metrics\\nORDER BY date ASC, keyword, position ASC\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleBigQuery\",\n \"typeVersion\": 2.1,\n \"position\": [\n 560,\n 820\n ],\n \"id\": \"889ee8e9-7476-4a87-b791-4718c05664f4\",\n \"name\": \"Get Ranking Keywords by URL\",\n \"alwaysOutputData\": false,\n \"executeOnce\": true\n },\n {\n \"parameters\": {\n \"mode\": \"raw\",\n \"jsonOutput\": \"{\\n \\\"domains\\\": [\\n {\\n \\\"domain\\\": \\\"domain\\\",\\n \\\"searchdata_url_impression\\\": \\\"searchdata_url_impression\\\",\\n \\\"searchdata_site_impression\\\": \\\"searchdata_site_impression\\\"\\n },\\n\\n ]\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n -60,\n 440\n ],\n \"id\": \"3f315b4a-6f55-4870-bc56-e032b4516fca\",\n \"name\": \"Domains\"\n },\n {\n \"parameters\": {\n \"fieldToSplitOut\": \"domains\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.splitOut\",\n \"typeVersion\": 1,\n \"position\": [\n 160,\n 440\n ],\n \"id\": \"a16cff0d-b2f5-431d-b2a2-82aaba6564c7\",\n \"name\": \"Split Out\"\n },\n {\n \"parameters\": {\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.splitInBatches\",\n \"typeVersion\": 3,\n \"position\": [\n -500,\n 860\n ],\n \"id\": \"5984e986-17d6-4ac8-ab02-3f9f2860ba7b\",\n \"name\": \"Loop Over Items\"\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"1a376642-1bb3-43a3-802f-6844d3b9c2a7\",\n \"leftValue\": \"={{ $('get_date_of_last_run').all()[0].json.isEmpty()}}\",\n \"rightValue\": \"\",\n \"operator\": {\n \"type\": \"boolean\",\n \"operation\": \"false\",\n \"singleValue\": true\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.if\",\n \"typeVersion\": 2.2,\n \"position\": [\n -100,\n 800\n ],\n \"id\": \"670742c9-0640-4489-92f0-81a1d1a85e2d\",\n \"name\": \"If\"\n },\n {\n \"parameters\": {\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.splitInBatches\",\n \"typeVersion\": 3,\n \"position\": [\n 1120,\n 900\n ],\n \"id\": \"c9de6b4c-7be7-4421-b924-224adcbc7f38\",\n \"name\": \"Loop Over Items1\"\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"32ae47a9-f7f5-41fc-b403-468094ba3f41\",\n \"leftValue\": \"={{ $('get_date_of_last_run_1').all()[0].json.isEmpty()}}\",\n \"rightValue\": \"\",\n \"operator\": {\n \"type\": \"boolean\",\n \"operation\": \"false\",\n \"singleValue\": true\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.if\",\n \"typeVersion\": 2.2,\n \"position\": [\n 1520,\n 920\n ],\n \"id\": \"b6171a4a-5059-4744-bc09-248c30b3a1b6\",\n \"name\": \"If1\"\n },\n {\n \"parameters\": {\n \"projectId\": {\n \"__rl\": true,\n \"value\": \"automations-451008\",\n \"mode\": \"list\",\n \"cachedResultName\": \"automations\",\n \"cachedResultUrl\": \"https://console.cloud.google.com/bigquery?project=automations-451008\"\n },\n \"sqlQuery\": \"WITH filtered_queries AS (\\n SELECT \\n data_date,\\n device,\\n query,\\n url,\\n SUM(clicks) as clicks,\\n SUM(impressions) as impressions,\\n SUM(sum_position) as sum_position,\\n SUM(sum_position)/SUM(impressions) + 1 as avg_position,\\n MAX(CASE \\n WHEN is_tpf_faq THEN 'FAQ'\\n WHEN is_tpf_howto THEN 'HowTo'\\n WHEN is_review_snippet THEN 'Review'\\n ELSE 'Normal'\\n END) as result_type\\n FROM `{{ $('Loop Over Items1').all()[0].json.searchdata_url_impression }}`\\n WHERE SAFE_DIVIDE(sum_position, impressions) <= 50\\n AND is_anonymized_query = False\\n AND impressions >= 5\\n AND data_date > '{{ $json.data_date }}'\\n GROUP BY data_date, device, query, url\\n)\\n\\nSELECT \\n data_date,\\n query,\\n url,\\n device,\\n result_type,\\n impressions as total_impressions,\\n clicks as total_clicks,\\n avg_position,\\n SAFE_DIVIDE(clicks, impressions) * 100 as ctr_percentage,\\n CASE \\n WHEN avg_position <= 3 THEN 'Top 3'\\n WHEN avg_position <= 10 THEN 'Top 10'\\n WHEN avg_position <= 20 THEN 'Top 20'\\n ELSE 'Above 20'\\n END as position_bucket\\nFROM filtered_queries\\nORDER BY \\n data_date DESC,\\n url\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleBigQuery\",\n \"typeVersion\": 2.1,\n \"position\": [\n 2040,\n 920\n ],\n \"id\": \"0bf4672c-43d7-46d9-8ed5-7632f68823ee\",\n \"name\": \"Get Keyword Opportunities\",\n \"alwaysOutputData\": false,\n \"executeOnce\": true\n },\n {\n \"parameters\": {\n \"operation\": \"executeQuery\",\n \"query\": \"SELECT data_date FROM rank_tracking_by_keywords WHERE domain = '{{ $json.domain }}' ORDER BY data_date DESC LIMIT 1;\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.postgres\",\n \"typeVersion\": 2.5,\n \"position\": [\n -280,\n 800\n ],\n \"id\": \"715b6742-1bfa-4149-b9de-b87f279b1c9f\",\n \"name\": \"get_date_of_last_run\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {\n \"operation\": \"executeQuery\",\n \"query\": \"SELECT keyword from tracked_keywords WHERE domain = '{{ $json.domain }}'\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.postgres\",\n \"typeVersion\": 2.5,\n \"position\": [\n -280,\n 960\n ],\n \"id\": \"4a3dad81-fef3-42a3-88b6-217219981f24\",\n \"name\": \"get_keywords_to_track\"\n },\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.merge\",\n \"typeVersion\": 3,\n \"position\": [\n 340,\n 820\n ],\n \"id\": \"68d1a031-b956-4298-a8b4-7531111641d5\",\n \"name\": \"merge_query_params\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"function getKeywordsString(inputArray) {\\n return inputArray.map(item => `'${item.json.keyword}'`).join(', ');\\n}\\n\\nreturn [{\\n json: {\\n keywordString: getKeywordsString($input.all())\\n }\\n}];\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 100,\n 1040\n ],\n \"id\": \"fb85991b-1d6b-4b84-b795-3018b2c6ed2f\",\n \"name\": \"concat_keywords\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"return [{\\n data_date: $input.first().json.data_date.split('T')[0]\\n}]\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 100,\n 640\n ],\n \"id\": \"511965b1-d6e7-4744-bdda-a36b2aee5d9e\",\n \"name\": \"get_date\"\n },\n {\n \"parameters\": {\n \"operation\": \"executeQuery\",\n \"query\": \"SELECT data_date FROM top_ranking_keywords WHERE domain = '{{ $json.domain }}' ORDER BY data_date DESC LIMIT 1;\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.postgres\",\n \"typeVersion\": 2.5,\n \"position\": [\n 1340,\n 920\n ],\n \"id\": \"4dd56d48-af92-40f1-8797-ed7a78b39cb7\",\n \"name\": \"get_date_of_last_run_1\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.merge\",\n \"typeVersion\": 3,\n \"position\": [\n 1880,\n 920\n ],\n \"id\": \"ef6d77f2-eaec-4ab6-9dd0-7b565d3488ff\",\n \"name\": \"merge_query_params_1\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"return [{\\n data_date: $input.first().json.data_date.split('T')[0]\\n}]\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 1700,\n 840\n ],\n \"id\": \"4d5c6f59-642a-46c3-acab-13ab42a4a992\",\n \"name\": \"get_date_1\",\n \"alwaysOutputData\": true\n },\n {\n \"parameters\": {\n \"operation\": \"upsert\",\n \"schema\": {\n \"__rl\": true,\n \"mode\": \"list\",\n \"value\": \"public\"\n },\n \"table\": {\n \"__rl\": true,\n \"value\": \"rank_tracking_by_keywords\",\n \"mode\": \"list\",\n \"cachedResultName\": \"rank_tracking_by_keywords\"\n },\n \"columns\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"data_date\": \"={{ $json.date }}\",\n \"clicks\": \"={{ $json.clicks }}\",\n \"impressions\": \"={{ $json.impressions }}\",\n \"position\": \"={{ $json.position }}\",\n \"ctr\": \"={{ $json.ctr }}\",\n \"url\": \"={{ $json.url }}\",\n \"keyword\": \"={{ $json.keyword }}\",\n \"device\": \"={{ $json.device }}\",\n \"domain\": \"={{ $('Loop Over Items').item.json.domain }}\"\n },\n \"matchingColumns\": [\n \"data_date\",\n \"url\",\n \"keyword\"\n ],\n \"schema\": [\n {\n \"id\": \"data_date\",\n \"displayName\": \"data_date\",\n \"required\": true,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"dateTime\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"url\",\n \"displayName\": \"url\",\n \"required\": true,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"device\",\n \"displayName\": \"device\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"keyword\",\n \"displayName\": \"keyword\",\n \"required\": true,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"clicks\",\n \"displayName\": \"clicks\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"number\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"impressions\",\n \"displayName\": \"impressions\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"number\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"position\",\n \"displayName\": \"position\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"number\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"ctr\",\n \"displayName\": \"ctr\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"number\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"domain\",\n \"displayName\": \"domain\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": false,\n \"removed\": false\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": false\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.postgres\",\n \"typeVersion\": 2.5,\n \"position\": [\n 820,\n 1000\n ],\n \"id\": \"dccf25e5-5971-424e-843d-e95b5816bde8\",\n \"name\": \"insert_keywords_ranking_by_tracked_keywords\"\n },\n {\n \"parameters\": {\n \"operation\": \"upsert\",\n \"schema\": {\n \"__rl\": true,\n \"mode\": \"list\",\n \"value\": \"public\"\n },\n \"table\": {\n \"__rl\": true,\n \"value\": \"top_ranking_keywords\",\n \"mode\": \"list\",\n \"cachedResultName\": \"top_ranking_keywords\"\n },\n \"columns\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"total_impressions\": \"={{ $json.total_impressions }}\",\n \"total_clicks\": \"={{ $json.total_clicks }}\",\n \"avg_position\": \"={{ $json.avg_position }}\",\n \"ctr_percentage\": \"={{ $json.ctr_percentage }}\",\n \"data_date\": \"={{ $json.data_date }}\",\n \"query\": \"={{ $json.query }}\",\n \"url\": \"={{ $json.url }}\",\n \"device\": \"={{ $json.device }}\",\n \"result_type\": \"={{ $json.result_type }}\",\n \"position_bucket\": \"={{ $json.position_bucket }}\",\n \"domain\": \"={{ $('Loop Over Items1').item.json.domain }}\"\n },\n \"matchingColumns\": [\n \"data_date\",\n \"query\",\n \"url\"\n ],\n \"schema\": [\n {\n \"id\": \"data_date\",\n \"displayName\": \"data_date\",\n \"required\": true,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"dateTime\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"query\",\n \"displayName\": \"query\",\n \"required\": true,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"url\",\n \"displayName\": \"url\",\n \"required\": true,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"device\",\n \"displayName\": \"device\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"result_type\",\n \"displayName\": \"result_type\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"total_impressions\",\n \"displayName\": \"total_impressions\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"number\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"total_clicks\",\n \"displayName\": \"total_clicks\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"number\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"avg_position\",\n \"displayName\": \"avg_position\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"number\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"ctr_percentage\",\n \"displayName\": \"ctr_percentage\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"number\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"position_bucket\",\n \"displayName\": \"position_bucket\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": false\n },\n {\n \"id\": \"domain\",\n \"displayName\": \"domain\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": false\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": false\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.postgres\",\n \"typeVersion\": 2.5,\n \"position\": [\n 2220,\n 1000\n ],\n \"id\": \"1a2001af-41c7-4a2c-af00-6a0fefbb823d\",\n \"name\": \"insert_top_keywords\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"e3ce8bf6-cbee-4949-a338-aeb1523b646a\",\n \"name\": \"=data_date\",\n \"value\": \"={{ $now.minus({ days: 28 }).format('yyyy-MM-dd') }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 100,\n 840\n ],\n \"id\": \"fdcc21a2-4d74-40e3-960d-0bc531f13696\",\n \"name\": \"today_minus_28_d\",\n \"notes\": \"In case the pipeline has not been triggered before, then the tracking sheet is empty. If true, we will take as a starting point of today minus 7 days. \"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"e3ce8bf6-cbee-4949-a338-aeb1523b646a\",\n \"name\": \"=data_date\",\n \"value\": \"={{ $now.minus({ days: 28 }).format('yyyy-MM-dd') }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 1700,\n 1000\n ],\n \"id\": \"54c2a5a1-6cf3-455a-9c66-cfe794eca549\",\n \"name\": \"today_minus_28_d_1\",\n \"notes\": \"In case the pipeline has not been triggered before, then the tracking sheet is empty. If true, we will take as a starting point of today minus 7 days. \"\n },\n {\n \"parameters\": {\n \"content\": \"Add all your domains and BigQuery tables here\",\n \"height\": 220,\n \"width\": 160\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -100,\n 340\n ],\n \"id\": \"f27d387f-70d5-476f-8e40-b3d6c5288b0e\",\n \"name\": \"Sticky Note\"\n },\n {\n \"parameters\": {\n \"content\": \"### Automation Description\\nThis automation serves two main purposes:\\n1. It monitors keyword rankings for all keywords in your rank tracking table\\n2. It displays keywords where you already have favorable Google rankings in a separate table\\n\\nThe ability clearly shows whether you rank in the top 3, top 10, or top 20 for specific keywords and URLs. Additionally, it displays rankings for both mobile and desktop devices.\\n\\n### Required Tables\\nTo use this automation, you need to create the following tables:\\n\\n#### 1. Top Ranking Keywords\\nThis table is used to identify keyword opportunities. It helps you quickly find keywords where you already rank in the top 3, 10, or 20 positions. This information is particularly valuable for creating content that matches these search queries.\\n\\n```sql\\nCREATE TABLE IF NOT EXISTS public.top_ranking_keywords\\n(\\n data_date date NOT NULL,\\n query text COLLATE pg_catalog.\\\"default\\\" NOT NULL,\\n url text COLLATE pg_catalog.\\\"default\\\" NOT NULL,\\n device text COLLATE pg_catalog.\\\"default\\\",\\n result_type text COLLATE pg_catalog.\\\"default\\\",\\n total_impressions integer,\\n total_clicks integer,\\n avg_position double precision,\\n ctr_percentage double precision,\\n position_bucket text COLLATE pg_catalog.\\\"default\\\",\\n domain text COLLATE pg_catalog.\\\"default\\\",\\n CONSTRAINT ranking_primary_key PRIMARY KEY (data_date, query, url)\\n)\\n```\\n\\n#### 2. Tracked Keywords\\nAdd the keywords you want to monitor rankings for in this table.\\n\\n```sql\\nCREATE TABLE IF NOT EXISTS public.tracked_keywords\\n(\\n domain text COLLATE pg_catalog.\\\"default\\\" NOT NULL,\\n keyword text COLLATE pg_catalog.\\\"default\\\" NOT NULL,\\n created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP,\\n CONSTRAINT tracked_keywords_primary_key PRIMARY KEY (domain, keyword)\\n)\\n```\\n\\n#### 3. Rank Tracking by Keywords\\nThis table exclusively tracks the rankings of keywords listed in the tracked_keywords table.\\n\\n```sql\\nCREATE TABLE IF NOT EXISTS public.rank_tracking_by_keywords\\n(\\n data_date date NOT NULL,\\n url text COLLATE pg_catalog.\\\"default\\\" NOT NULL,\\n device text COLLATE pg_catalog.\\\"default\\\",\\n keyword text COLLATE pg_catalog.\\\"default\\\" NOT NULL,\\n clicks integer,\\n impressions integer,\\n \\\"position\\\" double precision,\\n ctr double precision,\\n domain text COLLATE pg_catalog.\\\"default\\\",\\n CONSTRAINT tracked_keyword_primary_key PRIMARY KEY (data_date, url, keyword)\\n)\\n```\",\n \"height\": 1200,\n \"width\": 3040\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -620,\n -900\n ],\n \"id\": \"f5cc8957-a906-4a49-b3cb-7dcee72d2503\",\n \"name\": \"Sticky Note4\"\n },\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.manualTrigger\",\n \"typeVersion\": 1,\n \"position\": [\n -340,\n 440\n ],\n \"id\": \"92021b58-21a9-41e0-b852-a1dfcc6284f9\",\n \"name\": \"Start\"\n },\n {\n \"parameters\": {\n \"content\": \"Adjust this for the first run if needed\",\n \"height\": 220,\n \"width\": 180\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 60,\n 780\n ],\n \"id\": \"f1b923ef-1f4e-4356-8bbb-8e5036ba36d0\",\n \"name\": \"Sticky Note1\"\n },\n {\n \"parameters\": {\n \"content\": \"Adjust the query if needed\",\n \"height\": 260,\n \"width\": 180\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 2020,\n 840\n ],\n \"id\": \"a770b4bf-d8a0-483f-8a89-3e7cce337218\",\n \"name\": \"Sticky Note2\"\n },\n {\n \"parameters\": {\n \"content\": \"# Get Tracked Keywords Ranking\",\n \"height\": 620,\n \"width\": 1640,\n \"color\": 4\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -620,\n 600\n ],\n \"id\": \"5871284a-0aa7-4d9d-a5cf-c579871ee29c\",\n \"name\": \"Sticky Note3\"\n },\n {\n \"parameters\": {\n \"content\": \"# Start here\",\n \"height\": 260,\n \"width\": 1640\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -620,\n 320\n ],\n \"id\": \"1d8f8fd3-663a-4644-885c-30377ccb12fb\",\n \"name\": \"Sticky Note5\"\n },\n {\n \"parameters\": {\n \"content\": \"# Get Keyword Opportunities\",\n \"height\": 620,\n \"width\": 1640,\n \"color\": 5\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 1040,\n 600\n ],\n \"id\": \"37a05e6f-e591-4dde-a772-1046a5ffde91\",\n \"name\": \"Sticky Note6\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"Get Ranking Keywords by URL\": {\n \"main\": [\n [\n {\n \"node\": \"insert_keywords_ranking_by_tracked_keywords\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Domains\": {\n \"main\": [\n [\n {\n \"node\": \"Split Out\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Split Out\": {\n \"main\": [\n [\n {\n \"node\": \"Loop Over Items1\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"Loop Over Items\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Loop Over Items\": {\n \"main\": [\n [],\n [\n {\n \"node\": \"get_date_of_last_run\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"get_keywords_to_track\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"If\": {\n \"main\": [\n [\n {\n \"node\": \"get_date\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"today_minus_28_d\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Loop Over Items1\": {\n \"main\": [\n [],\n [\n {\n \"node\": \"get_date_of_last_run_1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"If1\": {\n \"main\": [\n [\n {\n \"node\": \"get_date_1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"today_minus_28_d_1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Keyword Opportunities\": {\n \"main\": [\n [\n {\n \"node\": \"insert_top_keywords\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"get_date_of_last_run\": {\n \"main\": [\n [\n {\n \"node\": \"If\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"get_keywords_to_track\": {\n \"main\": [\n [\n {\n \"node\": \"concat_keywords\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"merge_query_params\": {\n \"main\": [\n [\n {\n \"node\": \"Get Ranking Keywords by URL\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"concat_keywords\": {\n \"main\": [\n [\n {\n \"node\": \"merge_query_params\",\n \"type\": \"main\",\n \"index\": 1\n }\n ]\n ]\n },\n \"get_date\": {\n \"main\": [\n [\n {\n \"node\": \"merge_query_params\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"get_date_of_last_run_1\": {\n \"main\": [\n [\n {\n \"node\": \"If1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"merge_query_params_1\": {\n \"main\": [\n [\n {\n \"node\": \"Get Keyword Opportunities\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"get_date_1\": {\n \"main\": [\n [\n {\n \"node\": \"merge_query_params_1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"insert_keywords_ranking_by_tracked_keywords\": {\n \"main\": [\n [\n {\n \"node\": \"Loop Over Items\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"insert_top_keywords\": {\n \"main\": [\n [\n {\n \"node\": \"Loop Over Items1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"today_minus_28_d\": {\n \"main\": [\n [\n {\n \"node\": \"merge_query_params\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"today_minus_28_d_1\": {\n \"main\": [\n [\n {\n \"node\": \"merge_query_params_1\",\n \"type\": \"main\",\n \"index\": 1\n }\n ]\n ]\n },\n \"Start\": {\n \"main\": [\n [\n {\n \"node\": \"Domains\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"ea6dd1b7-3fde-41b5-aec0-ca8eff050b93\",\n \"meta\": {\n \"templateCredsSetupCompleted\": true,\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"x6AMYWZDoDaT5pD0\",\n \"tags\": [\n {\n \"createdAt\": \"2025-03-02T12:05:53.836Z\",\n \"updatedAt\": \"2025-03-02T12:05:53.836Z\",\n \"id\": \"utwtHTzeqUdktrxJ\",\n \"name\": \"SEO\"\n },\n {\n \"createdAt\": \"2025-03-08T08:04:57.610Z\",\n \"updatedAt\": \"2025-03-08T08:04:57.610Z\",\n \"id\": \"TMDokL1KXbN5A2PH\",\n \"name\": \"Templates\"\n }\n ]\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "Rank Tracker Postgres Template", "node_count": 28, "category": "General Automation"}} {"prompt": "Build a workflow for: Landing Page Analyzer", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 15\n- Node Types: n8n-nodes-base.set, @n8n/n8n-nodes-langchain.lmChatOpenAi, n8n-nodes-base.gmail, n8n-nodes-base.stickyNote, @n8n/n8n-nodes-langchain.outputParserStructured, n8n-nodes-base.code, n8n-nodes-base.httpRequest, @n8n/n8n-nodes-langchain.chainLlm, n8n-nodes-base.formTrigger, @n8n/n8n-nodes-langchain.googleGemini\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.formTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"Landing Page Analyzer\",\n \"nodes\": [\n {\n \"parameters\": {\n \"formTitle\": \"Landing Page Analyzer\",\n \"formFields\": {\n \"values\": [\n {\n \"fieldLabel\": \"URL\",\n \"requiredField\": true\n },\n {\n \"fieldLabel\": \"Email\",\n \"fieldType\": \"email\",\n \"requiredField\": true\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.formTrigger\",\n \"typeVersion\": 2.3,\n \"position\": [\n -304,\n -112\n ],\n \"id\": \"bc0c4d73-ee5d-4dd0-8d0a-e0bfb62d020f\",\n \"name\": \"On form submission\",\n \"webhookId\": \"750d8a3a-997e-49ae-bd76-010ee665cde9\"\n },\n {\n \"parameters\": {\n \"url\": \"={{ $('Get Meta Data').item.json.page.screenshot }}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 1168,\n -112\n ],\n \"id\": \"013c4177-ab7b-4ae5-a5db-90ba050a074d\",\n \"name\": \"Download Image\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"https://api.firecrawl.dev/v2/scrape\",\n \"authentication\": \"genericCredentialType\",\n \"genericAuthType\": \"httpHeaderAuth\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"={\\n \\\"url\\\": \\\"{{ $json.URL }}\\\",\\n \\\"onlyMainContent\\\": false,\\n \\\"parsers\\\": [\\n \\\"pdf\\\"\\n ],\\n \\\"formats\\\": [\\n \\\"markdown\\\",\\n {\\n \\\"type\\\": \\\"screenshot\\\",\\n \\\"fullPage\\\": true\\n }\\n ]\\n} \",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n -80,\n -112\n ],\n \"id\": \"3c0939d8-89a4-4598-a106-4a3322112260\",\n \"name\": \"Crawl Site\",\n \"credentials\": {\n \"httpHeaderAuth\": {\n \"id\": \"r3zPXXitwsV4wBHf\",\n \"name\": \"Firecrawl\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsonSchemaExample\": \"{\\n \\\"hero_headline\\\": \\\"Are Hidden Bottlenecks Killing Your Sales Growth?\\\",\\n \\\"hero_subheading\\\": \\\"This free 3-minute assessment pinpoints the exact leaks in your sales process.\\\",\\n \\\"value_proposition_summary\\\": \\\"We measure and improve your lead quality, follow-up speed, and closing techniques.\\\",\\n \\\"credibility_statement\\\": \\\"Created by John Doe, a sales expert with 20 years of experience who has helped scale 50+ companies.\\\",\\n \\\"cta_text\\\": \\\"Find My Sales Bottlenecks\\\",\\n \\\"cta_microcopy\\\": \\\"100% Free & Instant Results\\\"\\n}\"\n },\n \"type\": \"@n8n/n8n-nodes-langchain.outputParserStructured\",\n \"typeVersion\": 1.3,\n \"position\": [\n 544,\n 48\n ],\n \"id\": \"d422c0e8-7206-4d71-acaf-1cc540767cb8\",\n \"name\": \"Structured Output Parser\"\n },\n {\n \"parameters\": {\n \"resource\": \"image\",\n \"operation\": \"analyze\",\n \"modelId\": {\n \"__rl\": true,\n \"value\": \"models/gemini-2.5-pro\",\n \"mode\": \"list\",\n \"cachedResultName\": \"models/gemini-2.5-pro\"\n },\n \"text\": \"=Act as a Senior Process Engineer and world-class CRO expert, synthesizing the advice of leading conversion specialists. Your task is to conduct a comprehensive audit of a landing page using a pre-analyzed content brief and a full-page image.\\n\\n**[Content Brief (Data Analyst)]**\\n{{ JSON.stringify($json.output, null,2) }}\\n\\n**[Visual Evidence]**\\n[The full landing page image is provided as input]\\n\\n**[Expert CRO Principles & Examples for Analysis]**\\nYour analysis MUST be guided by the following unified principles. Use these examples to inform your rationale.\\n\\n1. **Radical Clarity:** Can a user understand the offer and benefit in under 5 seconds?\\n * **Bad Example:** A headline like \\\"It's About Time.\\\" (Clever, but unclear what it offers).\\n * **Good Example:** A headline like \\\"Generate and publish your site with AI in seconds.\\\" (States what you get, how, and the benefit of speed).\\n\\n2. **Singular Focus & CTA:** Is there ONE primary goal and a distraction-free path to it?\\n * **Bad Example:** A landing page with a full navigation menu (Home, About, Blog, etc.), social media links, and multiple competing CTAs.\\n * **Good Example:** A page where the only clickable element above the fold is the primary CTA button.\\n\\n3. **Cognitive Load:** Does the design prioritize function over form?\\n * **Bad Example:** A page with an auto-playing background video, multiple elements animating on scroll, and flashy graphics that distract from the main message.\\n * **Good Example:** A page with a clean layout, generous white space, and static images that directly support the copy.\\n\\n4. **Multi-Faceted Trust:** Does the page build credibility and overcome skepticism?\\n * **Bad Example:** A vague statement like \\\"Trusted by customers worldwide.\\\"\\n * **Good Example:** Displaying logos of well-known clients, showing a specific testimonial with a name and photo (`\\\"This saved us 10 hours a week.\\\" - J. Doe, CEO`), or showing sheer numbers (`45,000+ projects launched`).\\n\\n5. **Visual Hierarchy & CTA Isolation:** Does the design guide the eye to the most important element?\\n * **Bad Example:** A light grey CTA button on a white background, or a page where the company logo is the largest visual element.\\n * **Good Example:** A bright orange CTA button on a dark grey page, where orange is a unique color used ONLY for that button.\\n\\n6. **Audience-Specific Complexity:** Is the level of detail appropriate for the audience and offer?\\n * **Bad Example:** A 2,000-word landing page for a simple $5 mobile game.\\n * **Good Example:** A detailed, multi-section landing page with downloadable case studies for a $50,000 enterprise software decision.\\n\\n**[Your Task]**\\nSynthesize the content brief and the visual evidence to generate a final, structured JSON report. For each part, you MUST reference the expert principles above in your rationale. Follow the structure in the example below.\\n\\n**[Example of a Perfect JSON Output Structure]**\\n{\\n \\\"part_1_headline_analysis\\\": {\\n \\\"obversation\\\": \\\"Based on the 'Radical Clarity' principle, the headline 'Secure Your Financial Future' is weak. It's a common cliché that lacks a specific, tangible benefit and fails to address a direct pain point for the target audience.\\\",\\n \\\"recommendation\\\": \\\"Change the headline to speak directly to a core frustration. Example: 'Stop Worrying About Retirement - Get a Clear Financial Plan in 30 Days.'\\\"\\n },\\n \\\"part_2_design_and_cognitive_load\\\": {\\n \\\"obversation\\\": \\\"The page has a clean layout which is good for 'Cognitive Load'. However, the main hero image is a generic stock photo of a happy couple, which hurts trust and authenticity. The design lacks a strong 'Visual Hierarchy' as the logo is visually larger than the headline.\\\",\\n \\\"recommendation\\\": \\\"Replace the stock photo with a professional, authentic photo of the financial advisor. Decrease the logo size by 30% and increase the headline font size to make it the dominant element.\\\"\\n },\\n \\\"part_3_offer_and_trust\\\": {\\n \\\"obversation\\\": \\\"The page fails on the 'Multi-Faceted Trust' principle. There are no client testimonials, logos, or specific credentials mentioned, making the offer feel less credible and increasing user skepticism.\\\",\\n \\\"recommendation\\\": \\\"Add a trust-building section directly below the hero. Include logos of publications the advisor has been featured in (e.g., 'As seen in Forbes') and a specific client testimonial with a name and photo.\\\"\\n },\\n \\\"part_4_conversion_path_and_cta\\\": {\\n \\\"obversation\\\": \\\"The conversion path is weak. The CTA button text 'Learn More' is vague. Based on the 'CTA Isolation' principle, its blue color does not stand out against the blue background, making it difficult to see.\\\",\\n \\\"recommendation\\\": \\\"Change the CTA text to a specific, value-oriented action like 'Book My Free Financial Review'. Change the button color to a high-contrast green that is not used elsewhere on the page.\\\"\\n },\\n \\\"part_5_summary_and_prioritized_action_plan\\\": {\\n \\\"obversation\\\": \\\"The landing page's core offer is likely valuable, but its conversion potential is severely limited by a generic headline, a lack of trust signals, and a weak, low-visibility CTA. It fails to establish credibility and clarity in the critical first 5 seconds.\\\",\\n \\\"top_3_recommendations\\\": [\\n \\\"1. Overhaul the Headline: Immediately replace the vague headline with a benefit-driven one that addresses a specific user pain point.\\\",\\n \\\"2. Redesign the CTA: Change the button text to a clear action and use a unique, high-contrast color to make it the visual anchor of the page.\\\",\\n \\\"3. Inject Social Proof: Add a testimonial and 'as seen in' logos directly below the hero section to build instant credibility.\\\"\\n ]\\n }\\n}\",\n \"imageUrls\": \"={{ $('Get Meta Data').item.json.page.screenshot }}\",\n \"options\": {}\n },\n \"type\": \"@n8n/n8n-nodes-langchain.googleGemini\",\n \"typeVersion\": 1,\n \"position\": [\n 720,\n -112\n ],\n \"id\": \"c9a2449b-9ded-4e93-adc9-15a8856a13c0\",\n \"name\": \"Analyze an image\",\n \"credentials\": {\n \"googlePalmApi\": {\n \"id\": \"8XvIBe7gJ8Olurpj\",\n \"name\": \"Google Gemini(PaLM) Api account\"\n }\n }\n },\n {\n \"parameters\": {\n \"jsCode\": \"// This code transforms the raw JSON string from a previous LLM node \\n// into a styled, easy-to-read HTML email report.\\n\\n// --- Main Function to Generate HTML ---\\nfunction generateEmailHtml(rawText) {\\n let analysisData;\\n try {\\n // Clean the string by removing the markdown code fences\\n const cleanJsonString = rawText.replace(/^```json\\\\n/, '').replace(/\\\\n```$/, '');\\n \\n // Parse the clean string into a JavaScript object\\n analysisData = JSON.parse(cleanJsonString);\\n } catch (error)\\n {\\n console.error(\\\"Error parsing JSON data:\\\", error);\\n // Return an error HTML if parsing fails\\n return `

Error: Could not parse analysis data.

${error.message}

`;\\n }\\n\\n // Helper function to create a styled report section\\n const createSection = (title, obversation, recommendation) => {\\n return `\\n
\\n

${title}

\\n

\\n Observation: ${obversation}\\n

\\n
\\n

\\n Recommendation: ${recommendation}\\n

\\n
\\n
\\n `;\\n };\\n\\n // Construct the Full HTML Email using the parsed data\\n const html = `\\n \\n \\n \\n \\n \\n Landing Page Audit\\n \\n \\n \\n \\n \\n \\n
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
\\n

Comprehensive Landing Page Audit

\\n

Analysis & Recommendations

\\n
\\n

\\n Landing page analysis has been finished. The analyzed image is attached, you can find our observation and recommendations below.\\n

\\n
\\n ${createSection(\\n '1. Headline & Hook Analysis',\\n analysisData.part_1_headline_analysis.obversation, // <-- FIXED\\n analysisData.part_1_headline_analysis.recommendation\\n )}\\n \\n ${createSection(\\n '2. Design & Cognitive Load Analysis',\\n analysisData.part_2_design_and_cognitive_load.obversation, // <-- FIXED\\n analysisData.part_2_design_and_cognitive_load.recommendation\\n )}\\n\\n ${createSection(\\n '3. Offer & Trust Analysis',\\n analysisData.part_3_offer_and_trust.obversation, // <-- FIXED\\n analysisData.part_3_offer_and_trust.recommendation\\n )}\\n\\n ${createSection(\\n '4. Conversion Path & CTA Analysis',\\n analysisData.part_4_conversion_path_and_cta.obversation, // <-- FIXED\\n analysisData.part_4_conversion_path_and_cta.recommendation\\n )}\\n\\n \\n
\\n

5. Overall Summary & Prioritized Action Plan

\\n

\\n Executive Summary: ${analysisData.part_5_summary_and_prioritized_action_plan.obversation} \\n

\\n
\\n

\\n Top 3 Recommendations:\\n

\\n
    \\n ${analysisData.part_5_summary_and_prioritized_action_plan.top_3_recommendations.map(rec => `
  1. ${rec.substring(rec.indexOf('.') + 1).trim()}
  2. `).join('')}\\n
\\n
\\n
\\n
\\n

This is an automated analysis report.

\\n
\\n
\\n \\n \\n `;\\n\\n return html;\\n}\\n\\n// --- n8n Execution Logic ---\\ntry {\\n // Access the raw text from the input of the n8n node\\n const rawInputText = $input.first().json.content.parts[0].text;\\n \\n // Generate the complete HTML string\\n const finalHtml = generateEmailHtml(rawInputText);\\n \\n // Return the HTML in a structured way for the next node\\n return {\\n json: {\\n emailHtml: finalHtml\\n }\\n };\\n} catch (error) {\\n // Return an error object if the input path is invalid\\n return {\\n json: {\\n error: \\\"Failed to access input data. Please check the input path.\\\",\\n details: error.message\\n }\\n };\\n}\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 944,\n -112\n ],\n \"id\": \"084f376c-9e4e-4cfd-8ea3-d735d17de1f5\",\n \"name\": \"Generate HTML\"\n },\n {\n \"parameters\": {\n \"promptType\": \"define\",\n \"text\": \"=Act as a marketing copy analyst. Your task is to read the provided landing page text and extract the key marketing components into a structured JSON format.\\n\\n**[Provided Text]**\\n- Page Title: \\\"{{$json.page.title }}\\\"\\n- Meta Description: \\\"{{ $json.page.description }}\\\"\\n- Main Content: \\\"{{ $json.page.content }}\\\"\\n\\n**[Your Task]**\\nAnalyze the Main Content and identify the following elements. If an element is not found, return an empty string \\\"\\\".\\n1. `hero_headline`: The main headline at the top of the page.\\n2. `hero_subheading`: The subheading directly under the main headline.\\n3. `value_proposition_summary`: A summary of the section explaining the benefits of the assessment.\\n4. `credibility_statement`: A summary of the section building trust (e.g., creator's bio, research mentioned).\\n5. `cta_text`: The text on the primary call-to-action button.\\n6. `cta_microcopy`: Any supporting text immediately near the CTA button (e.g., \\\"Takes 3 minutes\\\").\\n\\nReturn ONLY the JSON object.\",\n \"hasOutputParser\": true,\n \"batching\": {}\n },\n \"type\": \"@n8n/n8n-nodes-langchain.chainLlm\",\n \"typeVersion\": 1.7,\n \"position\": [\n 368,\n -112\n ],\n \"id\": \"730e6024-127c-48d3-aa06-9155e6b2731d\",\n \"name\": \"Analyze Page Content\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"8137accd-97ed-463c-8eca-e2585f44d355\",\n \"name\": \"page.title\",\n \"value\": \"={{ $json.data.metadata.title }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"a4ca9b7c-f122-4a51-b7cc-c83c24fdfa2a\",\n \"name\": \"page.content\",\n \"value\": \"={{ $json.data.markdown }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"87d98606-c982-4b6d-a949-ebbf29fda5a3\",\n \"name\": \"page.language\",\n \"value\": \"={{ $json.data.metadata.language }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"9f400108-6985-441b-a2b2-738e9260a4af\",\n \"name\": \"page.description\",\n \"value\": \"={{ $json.data.metadata.description }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"526774ae-2347-407a-bb87-f92e4bd28fed\",\n \"name\": \"page.screenshot\",\n \"value\": \"={{ $json.data.screenshot }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 144,\n -112\n ],\n \"id\": \"52937fbf-8341-4c51-99fa-157970c79c60\",\n \"name\": \"Get Meta Data\"\n },\n {\n \"parameters\": {\n \"sendTo\": \"={{ $('On form submission').item.json.Email }}\",\n \"subject\": \"=Landing Page Analysis For {{ $('On form submission').item.json.URL }}\",\n \"message\": \"={{ $('Generate HTML').item.json.emailHtml }}\",\n \"options\": {\n \"appendAttribution\": false,\n \"attachmentsUi\": {\n \"attachmentsBinary\": [\n {\n \"property\": \"=data\"\n }\n ]\n }\n }\n },\n \"type\": \"n8n-nodes-base.gmail\",\n \"typeVersion\": 2.1,\n \"position\": [\n 1392,\n -112\n ],\n \"id\": \"7b162a7f-7d5c-4a52-8daf-e326d1b7e5be\",\n \"name\": \"Send Report\",\n \"webhookId\": \"a318cd20-bf1a-4e8d-b329-8669758c50f8\",\n \"credentials\": {\n \"gmailOAuth2\": {\n \"id\": \"S5zG40aAsfQKXkT0\",\n \"name\": \"Gmail account\"\n }\n }\n },\n {\n \"parameters\": {\n \"model\": {\n \"__rl\": true,\n \"mode\": \"list\",\n \"value\": \"gpt-4.1-mini\"\n },\n \"options\": {}\n },\n \"type\": \"@n8n/n8n-nodes-langchain.lmChatOpenAi\",\n \"typeVersion\": 1.2,\n \"position\": [\n 352,\n 64\n ],\n \"id\": \"05fea720-79bc-4e49-b5c7-c247b0a914f5\",\n \"name\": \"gpt-4.1-mini\",\n \"credentials\": {\n \"openAiApi\": {\n \"id\": \"RAj3VxCHt0rIwBTk\",\n \"name\": \"OpenAI\"\n }\n }\n },\n {\n \"parameters\": {\n \"content\": \"# Workflow created by [Marvomatic](https://marvomatic.com/)\\n- [AI SEO Society (Free)](https://www.skool.com/ai-automation-community)\\n- [AI SEO Society](https://www.skool.com/the-ai-seo-society-free-7625)\\n- [Contact](https://marvomatic.com/contact/)\",\n \"height\": 144,\n \"width\": 1936,\n \"color\": 7\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -352,\n -336\n ],\n \"id\": \"693fe15a-14cb-4a71-a383-adc431eeaa0e\",\n \"name\": \"Sticky Note6\"\n },\n {\n \"parameters\": {\n \"content\": \"## Scrape URL\",\n \"height\": 352,\n \"width\": 448,\n \"color\": 6\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -160,\n -176\n ],\n \"id\": \"0940e7b7-c580-4ccc-acc1-6be2c7a5a235\",\n \"name\": \"Sticky Note\"\n },\n {\n \"parameters\": {\n \"content\": \"## Analyze Content & Screenshot\",\n \"height\": 352,\n \"width\": 560,\n \"color\": 4\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 312,\n -176\n ],\n \"id\": \"9e69a40d-8c8d-40ee-ab86-4e077b9d6bf6\",\n \"name\": \"Sticky Note1\"\n },\n {\n \"parameters\": {\n \"content\": \"## Generate & Send Email\",\n \"height\": 352,\n \"width\": 688,\n \"color\": 5\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 896,\n -176\n ],\n \"id\": \"730b6ccb-f703-46ab-bcad-cfaccbb4f5ef\",\n \"name\": \"Sticky Note2\"\n },\n {\n \"parameters\": {\n \"content\": \"## Get Data\",\n \"height\": 352,\n \"width\": 176\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -352,\n -176\n ],\n \"id\": \"175a0ec7-6921-464a-bd01-300ffd0ff016\",\n \"name\": \"Sticky Note3\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"On form submission\": {\n \"main\": [\n [\n {\n \"node\": \"Crawl Site\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Download Image\": {\n \"main\": [\n [\n {\n \"node\": \"Send Report\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Crawl Site\": {\n \"main\": [\n [\n {\n \"node\": \"Get Meta Data\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Structured Output Parser\": {\n \"ai_outputParser\": [\n [\n {\n \"node\": \"Analyze Page Content\",\n \"type\": \"ai_outputParser\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Analyze an image\": {\n \"main\": [\n [\n {\n \"node\": \"Generate HTML\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Generate HTML\": {\n \"main\": [\n [\n {\n \"node\": \"Download Image\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Analyze Page Content\": {\n \"main\": [\n [\n {\n \"node\": \"Analyze an image\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Meta Data\": {\n \"main\": [\n [\n {\n \"node\": \"Analyze Page Content\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"gpt-4.1-mini\": {\n \"ai_languageModel\": [\n [\n {\n \"node\": \"Analyze Page Content\",\n \"type\": \"ai_languageModel\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"7d5eb14a-7480-4435-b0dc-22ac157845be\",\n \"meta\": {\n \"templateCredsSetupCompleted\": true,\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"VpoGZ7jDRWBJJQU0\",\n \"tags\": []\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "Landing Page Analyzer", "node_count": 15, "category": "General Automation"}} {"prompt": "Create an n8n automation that handles general automation", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 23\n- Node Types: n8n-nodes-base.set, n8n-nodes-base.wait, n8n-nodes-base.splitInBatches, n8n-nodes-base.mailerLite, @n8n/n8n-nodes-langchain.openAi, n8n-nodes-base.if, n8n-nodes-base.filter, n8n-nodes-base.manualTrigger, n8n-nodes-base.stickyNote, n8n-nodes-base.aggregate\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.manualTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"Mailing List Analysis\",\n \"nodes\": [\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.manualTrigger\",\n \"typeVersion\": 1,\n \"position\": [\n -60,\n 0\n ],\n \"id\": \"37c270cd-3e5d-4ef6-8763-29d71cc8131c\",\n \"name\": \"When clicking ‘Test workflow’\"\n },\n {\n \"parameters\": {\n \"operation\": \"getAll\",\n \"returnAll\": true,\n \"filters\": {}\n },\n \"type\": \"n8n-nodes-base.mailerLite\",\n \"typeVersion\": 2,\n \"position\": [\n 160,\n 0\n ],\n \"id\": \"92f3c50f-1189-4d9f-a40b-09aed968c940\",\n \"name\": \"Get All Subscribers\",\n \"credentials\": {\n \"mailerLiteApi\": {\n \"id\": \"\",\n \"name\": \"MailerLite account\"\n }\n }\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"bdcb77d5-0ca8-4fde-a9f2-c2ec41b7bf2a\",\n \"leftValue\": \"={{ $json.status }}\",\n \"rightValue\": \"active\",\n \"operator\": {\n \"type\": \"string\",\n \"operation\": \"equals\"\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.filter\",\n \"typeVersion\": 2.2,\n \"position\": [\n 380,\n 0\n ],\n \"id\": \"be6e055a-570e-4b45-b460-147a235f7f51\",\n \"name\": \"Filter Active Subscribers\"\n },\n {\n \"parameters\": {\n \"fieldsToAggregate\": {\n \"fieldToAggregate\": [\n {\n \"fieldToAggregate\": \"email\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.aggregate\",\n \"typeVersion\": 1,\n \"position\": [\n 600,\n 0\n ],\n \"id\": \"f7ff85f8-6a5d-4429-aeff-e13683783ae0\",\n \"name\": \"Get Email Addresses\"\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"27d75a75-71ff-4fa2-8a17-c0e0b16a046c\",\n \"leftValue\": \"={{ $json.isCustomDomain }}\",\n \"rightValue\": \"\",\n \"operator\": {\n \"type\": \"boolean\",\n \"operation\": \"false\",\n \"singleValue\": true\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.filter\",\n \"typeVersion\": 2.2,\n \"position\": [\n 1040,\n 80\n ],\n \"id\": \"6e86a425-38a9-414c-88d8-fea3010f3b4f\",\n \"name\": \"Get Common Provider Emails\"\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"bacc9bba-0bf0-4dda-bc4f-a4345d30e5ac\",\n \"leftValue\": \"={{ $json.isCustomDomain }}\",\n \"rightValue\": \"\",\n \"operator\": {\n \"type\": \"boolean\",\n \"operation\": \"true\",\n \"singleValue\": true\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.filter\",\n \"typeVersion\": 2.2,\n \"position\": [\n 1040,\n -120\n ],\n \"id\": \"d2e00312-16a2-4948-90ab-a33c7a23f74f\",\n \"name\": \"Get Business Mails\"\n },\n {\n \"parameters\": {\n \"operation\": \"appendOrUpdate\",\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"\",\n \"mode\": \"list\",\n \"cachedResultName\": \"\",\n \"cachedResultUrl\": \"\"\n },\n \"sheetName\": {\n \"__rl\": true,\n \"value\": 305542890,\n \"mode\": \"list\",\n \"cachedResultName\": \"\",\n \"cachedResultUrl\": \"\"\n },\n \"columns\": {\n \"mappingMode\": \"autoMapInputData\",\n \"value\": {},\n \"matchingColumns\": [],\n \"schema\": [\n {\n \"id\": \"email\",\n \"displayName\": \"email\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"isCustomDomain\",\n \"displayName\": \"isCustomDomain\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"domainInformation\",\n \"displayName\": \"domainInformation\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"personInformation\",\n \"displayName\": \"personInformation\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": false\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 1580,\n 160\n ],\n \"id\": \"29e3f607-3b5d-4909-9bc5-d6b19bfd612e\",\n \"name\": \"Save Non Business Mails\",\n \"credentials\": {\n \"googleSheetsOAuth2Api\": {\n \"id\": \"oYP1Bc15GY7emvD3\",\n \"name\": \"Google Sheets account\"\n }\n }\n },\n {\n \"parameters\": {\n \"url\": \"=http://crawl4ai:11235/task/{{ $json.task_id }}\",\n \"authentication\": \"genericCredentialType\",\n \"genericAuthType\": \"httpHeaderAuth\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 2460,\n -140\n ],\n \"id\": \"8b3dc3ee-7b95-4ab0-b9dc-3a343dbc7db9\",\n \"name\": \"Get Crawl Status\",\n \"retryOnFail\": true,\n \"waitBetweenTries\": 5000,\n \"credentials\": {\n \"httpHeaderAuth\": {\n \"id\": \"MKoLytfiKC3rb7GP\",\n \"name\": \"crawl4ai\"\n }\n },\n \"onError\": \"continueRegularOutput\"\n },\n {\n \"parameters\": {\n \"conditions\": {\n \"options\": {\n \"caseSensitive\": true,\n \"leftValue\": \"\",\n \"typeValidation\": \"strict\",\n \"version\": 2\n },\n \"conditions\": [\n {\n \"id\": \"5d2415b6-a502-477a-a448-3542ed58d5ad\",\n \"leftValue\": \"={{ $json.status }}\",\n \"rightValue\": \"completed\",\n \"operator\": {\n \"type\": \"string\",\n \"operation\": \"equals\",\n \"name\": \"filter.operator.equals\"\n }\n }\n ],\n \"combinator\": \"and\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.if\",\n \"typeVersion\": 2.2,\n \"position\": [\n 2680,\n -80\n ],\n \"id\": \"b1e3d759-e474-4f63-8042-ea78ca538768\",\n \"name\": \"Is Completed\"\n },\n {\n \"parameters\": {\n \"url\": \"={{\\\"http://\\\" + $json.email.split(\\\"@\\\").filter(Boolean).pop() }}\",\n \"options\": {\n \"response\": {\n \"response\": {\n \"fullResponse\": true\n }\n }\n }\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 1800,\n -80\n ],\n \"id\": \"6ac470dc-733d-49f4-992b-02ca44a4e92e\",\n \"name\": \"Ping Website\",\n \"alwaysOutputData\": false,\n \"notesInFlow\": false,\n \"onError\": \"continueErrorOutput\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"71985a5b-f7ec-4bbe-a390-7b329b90bc29\",\n \"name\": \"result.metadata.title\",\n \"value\": \"={{ $json.result.metadata.title }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"b0ae3939-c83c-4a4e-8b1f-676bbc1131c3\",\n \"name\": \"result.metadata.description\",\n \"value\": \"={{ $json.result.metadata.description }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"38bb1e85-53ca-48b8-bedd-eaf037ac893c\",\n \"name\": \"result.metadata[\\\"og:locale\\\"]\",\n \"value\": \"={{ $json.result.metadata[\\\"og:locale\\\"] }}\",\n \"type\": \"string\"\n },\n {\n \"id\": \"25d5c681-6459-4de4-a4fe-e7898406c6df\",\n \"name\": \"result.markdown\",\n \"value\": \"={{ $json.result.markdown }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 2900,\n -80\n ],\n \"id\": \"547a8b55-9b7b-4154-bc43-65add729074f\",\n \"name\": \"Get Metadata\"\n },\n {\n \"parameters\": {\n \"content\": \"## Get Subscribers\",\n \"height\": 540,\n \"width\": 980\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n -160,\n -220\n ],\n \"id\": \"1e3f0129-3864-4e8f-b74a-379b2e3af477\",\n \"name\": \"Sticky Note\"\n },\n {\n \"parameters\": {\n \"content\": \"## Divide Subscribers\",\n \"height\": 540,\n \"width\": 620,\n \"color\": 3\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 840,\n -220\n ],\n \"id\": \"fddd8c77-3f5d-4e03-8c8c-5365721e88a7\",\n \"name\": \"Sticky Note1\"\n },\n {\n \"parameters\": {\n \"content\": \"## Crawl Subscriber Information\",\n \"height\": 540,\n \"width\": 1640,\n \"color\": 5\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 1480,\n -220\n ],\n \"id\": \"f3c5c27a-4185-414a-8169-e169e6ef2cca\",\n \"name\": \"Sticky Note2\"\n },\n {\n \"parameters\": {\n \"content\": \"## Analyze & Save Data\",\n \"height\": 540,\n \"width\": 600,\n \"color\": 6\n },\n \"type\": \"n8n-nodes-base.stickyNote\",\n \"typeVersion\": 1,\n \"position\": [\n 3140,\n -220\n ],\n \"id\": \"dd170de2-c65c-4e46-89d5-12585fd39d57\",\n \"name\": \"Sticky Note3\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"// this could be improved by loading a list with more known providers\\n// You could also use the mails mentioned here as a filter: https://gist.github.com/ammarshah/f5c2624d767f91a7cbdc4e54db8dd0bf\\nconst commonDomains = [\\n 'gmail',\\n 'yahoo',\\n 'outlook',\\n 'hotmail',\\n 'aol',\\n 'icloud',\\n 'protonmail',\\n 'mail',\\n 'zoho',\\n 'yandex',\\n 'live',\\n 'msn',\\n 'gmx'\\n];\\n\\nconst result = [];\\n\\nfor (const item of $input.all()) {\\n for (const email of item.json.email) {\\n const domain = email.split('@')[1].toLowerCase();\\n // Extract the base domain (remove the TLD)\\n const baseDomain = domain.split('.')[0];\\n result.push({\\n email: email,\\n isCustomDomain: !commonDomains.includes(baseDomain)\\n });\\n }\\n}\\n\\nreturn result;\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 860,\n 0\n ],\n \"id\": \"401e9f00-9f2c-4a4d-8835-50a5fc779947\",\n \"name\": \"Check Domain\"\n },\n {\n \"parameters\": {\n \"method\": \"POST\",\n \"url\": \"http://crawl4ai:11235/crawl\",\n \"authentication\": \"genericCredentialType\",\n \"genericAuthType\": \"httpHeaderAuth\",\n \"sendBody\": true,\n \"specifyBody\": \"json\",\n \"jsonBody\": \"={\\n \\\"urls\\\": \\\"{{\\\"https://\\\" + $('Loop Over Emails').item.json.email.split(\\\"@\\\").filter(Boolean).pop()}}\\\",\\n \\\"priority\\\": 10\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n 2040,\n -60\n ],\n \"id\": \"91b3698e-bee0-43d1-8cd5-db088f9cc1fe\",\n \"name\": \"Crawl Website\",\n \"credentials\": {\n \"httpHeaderAuth\": {\n \"id\": \"MKoLytfiKC3rb7GP\",\n \"name\": \"crawl4ai\"\n }\n }\n },\n {\n \"parameters\": {\n \"modelId\": {\n \"__rl\": true,\n \"value\": \"gpt-4o-mini\",\n \"mode\": \"list\",\n \"cachedResultName\": \"I\"\n },\n \"messages\": {\n \"values\": [\n {\n \"content\": \"You are an expert in website analysis and content categorization. Your task is to analyze the provided website data, including the title, meta description, og:locale, and content, to determine the following:\\n\\n1. What the website is about (its purpose or main focus).\\n2. The niche or industry the website belongs to.\\n3. The services or offerings provided by the website.\\n\\nYour response must always follow this JSON structure:\\n\\n\\\"website_analysis\\\": \\n{\\n \\\"about\\\": \\\"[Provide a concise summary of what the website is about.]\\\",\\n \\\"niche\\\": \\\"[Identify the niche or industry the website belongs to.]\\\",\\n \\\"services\\\": [\\n \\\"[List the services or offerings provided by the website in bullet points.]\\\"\\n ]\\n}\\n\\nUse the information provided to make accurate and concise inferences. If any information is missing or unclear, make reasonable assumptions based on the context.\",\n \"role\": \"system\"\n },\n {\n \"content\": \"=Here is the data extracted from a website. Analyze it and provide the following details:\\n1. What the website is about.\\n2. The niche or industry it belongs to.\\n3. The services or offerings provided.\\n\\n### Website Data:\\n- **Title:** {{ $json.result.metadata.title }}\\n- **Meta Description:** {{ $json.result.metadata.description }}\\n- **og:locale:** {{ $json.result.metadata[\\\"og:locale\\\"] }}\\n- **Content:** {{ $json.result.markdown }}\\n\\nPlease analyze this data and provide your response in a structured format. \"\n }\n ]\n },\n \"jsonOutput\": true,\n \"options\": {}\n },\n \"type\": \"@n8n/n8n-nodes-langchain.openAi\",\n \"typeVersion\": 1.8,\n \"position\": [\n 3180,\n -80\n ],\n \"id\": \"134b0d97-5f1b-4c72-b430-908c6ed52505\",\n \"name\": \"Analyze Website\",\n \"credentials\": {\n \"openAiApi\": {\n \"id\": \"RAj3VxCHt0rIwBTk\",\n \"name\": \"OpenAI\"\n }\n }\n },\n {\n \"parameters\": {\n \"operation\": \"appendOrUpdate\",\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"\",\n \"mode\": \"list\",\n \"cachedResultName\": \"\",\n \"cachedResultUrl\": \"\"\n },\n \"sheetName\": {\n \"__rl\": true,\n \"value\": 1218456268,\n \"mode\": \"list\",\n \"cachedResultName\": \"\",\n \"cachedResultUrl\": \"\"\n },\n \"columns\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"services\": \"={{ $json.message.content.website_analysis.services }}\",\n \"about\": \"={{ $json.message.content.website_analysis.about }}\",\n \"isCustomDomain\": \"={{ $('Loop Over Emails').item.json.isCustomDomain }}\",\n \"email\": \"={{ $('Loop Over Emails').item.json.email }}\",\n \"niche\": \"={{ $json.message.content.website_analysis.niche }}\"\n },\n \"matchingColumns\": [\n \"email\"\n ],\n \"schema\": [\n {\n \"id\": \"email\",\n \"displayName\": \"email\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"isCustomDomain\",\n \"displayName\": \"isCustomDomain\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true\n },\n {\n \"id\": \"about\",\n \"displayName\": \"about\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"niche\",\n \"displayName\": \"niche\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n },\n {\n \"id\": \"services\",\n \"displayName\": \"services\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"type\": \"string\",\n \"canBeUsedToMatch\": true,\n \"removed\": false\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": false\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 3560,\n -60\n ],\n \"id\": \"a1c7cc7c-0b0a-4386-954f-52899c74f778\",\n \"name\": \"Save Subscriber Information\",\n \"credentials\": {\n \"googleSheetsOAuth2Api\": {\n \"id\": \"oYP1Bc15GY7emvD3\",\n \"name\": \"Google Sheets account\"\n }\n }\n },\n {\n \"parameters\": {\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.splitInBatches\",\n \"typeVersion\": 3,\n \"position\": [\n 1580,\n -40\n ],\n \"id\": \"0441498f-a3cf-4e1f-ade7-93e63b4e8517\",\n \"name\": \"Loop Over Emails\"\n },\n {\n \"parameters\": {\n \"documentId\": {\n \"__rl\": true,\n \"value\": \"\",\n \"mode\": \"list\",\n \"cachedResultName\": \"\",\n \"cachedResultUrl\": \"\"\n },\n \"sheetName\": {\n \"__rl\": true,\n \"value\": 1218456268,\n \"mode\": \"list\",\n \"cachedResultName\": \"\",\n \"cachedResultUrl\": \"\"\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.googleSheets\",\n \"typeVersion\": 4.5,\n \"position\": [\n 160,\n -180\n ],\n \"id\": \"e9fc527b-e16c-44c2-b6fa-64ce93c2b887\",\n \"name\": \"Get Analyzed Subscribers\",\n \"credentials\": {\n \"googleSheetsOAuth2Api\": {\n \"id\": \"oYP1Bc15GY7emvD3\",\n \"name\": \"Google Sheets account\"\n }\n }\n },\n {\n \"parameters\": {\n \"mergeByFields\": {\n \"values\": [\n {\n \"field1\": \"email\",\n \"field2\": \"email\"\n }\n ]\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.compareDatasets\",\n \"typeVersion\": 2.3,\n \"position\": [\n 1240,\n -200\n ],\n \"id\": \"4f181484-a220-4d29-8d09-45a10daed04e\",\n \"name\": \"Get Emails to Analyze\"\n },\n {\n \"parameters\": {\n \"amount\": 15\n },\n \"type\": \"n8n-nodes-base.wait\",\n \"typeVersion\": 1.1,\n \"position\": [\n 2240,\n -80\n ],\n \"id\": \"fde02556-495b-40b9-8fb8-79a9b2545a96\",\n \"name\": \"Sleep\",\n \"webhookId\": \"f63502d1-6006-423a-bbeb-345991818635\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"When clicking ‘Test workflow’\": {\n \"main\": [\n [\n {\n \"node\": \"Get All Subscribers\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"Get Analyzed Subscribers\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get All Subscribers\": {\n \"main\": [\n [\n {\n \"node\": \"Filter Active Subscribers\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Filter Active Subscribers\": {\n \"main\": [\n [\n {\n \"node\": \"Get Email Addresses\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Email Addresses\": {\n \"main\": [\n [\n {\n \"node\": \"Check Domain\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Business Mails\": {\n \"main\": [\n [\n {\n \"node\": \"Get Emails to Analyze\",\n \"type\": \"main\",\n \"index\": 1\n }\n ]\n ]\n },\n \"Get Common Provider Emails\": {\n \"main\": [\n [\n {\n \"node\": \"Save Non Business Mails\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Crawl Status\": {\n \"main\": [\n [\n {\n \"node\": \"Is Completed\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Is Completed\": {\n \"main\": [\n [\n {\n \"node\": \"Get Metadata\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"Sleep\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Ping Website\": {\n \"main\": [\n [\n {\n \"node\": \"Crawl Website\",\n \"type\": \"main\",\n \"index\": 0\n }\n ],\n [\n {\n \"node\": \"Loop Over Emails\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Metadata\": {\n \"main\": [\n [\n {\n \"node\": \"Analyze Website\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Check Domain\": {\n \"main\": [\n [\n {\n \"node\": \"Get Business Mails\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"Get Common Provider Emails\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Crawl Website\": {\n \"main\": [\n [\n {\n \"node\": \"Sleep\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Analyze Website\": {\n \"main\": [\n [\n {\n \"node\": \"Save Subscriber Information\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Save Subscriber Information\": {\n \"main\": [\n [\n {\n \"node\": \"Loop Over Emails\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Loop Over Emails\": {\n \"main\": [\n [],\n [\n {\n \"node\": \"Ping Website\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Analyzed Subscribers\": {\n \"main\": [\n [\n {\n \"node\": \"Get Emails to Analyze\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Get Emails to Analyze\": {\n \"main\": [\n [],\n [],\n [],\n [\n {\n \"node\": \"Loop Over Emails\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Sleep\": {\n \"main\": [\n [\n {\n \"node\": \"Get Crawl Status\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"86acd2d0-4e0e-43c0-8de1-5bdda8e79daf\",\n \"meta\": {\n \"templateCredsSetupCompleted\": true,\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"sBeN4ryu7Vg1eLMc\",\n \"tags\": []\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "Mailing List Analysis", "node_count": 23, "category": "General Automation"}} {"prompt": "Create an n8n automation that handles general automation", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 7\n- Node Types: n8n-nodes-base.set, n8n-nodes-base.manualTrigger, n8n-nodes-base.executeWorkflow\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.manualTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"Report Examples Demo\",\n \"nodes\": [\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.manualTrigger\",\n \"typeVersion\": 1,\n \"position\": [\n -100,\n 100\n ],\n \"id\": \"0b4e2c14-3b21-4463-b1a8-44a8f6fd20ed\",\n \"name\": \"When clicking ‘Execute workflow’\"\n },\n {\n \"parameters\": {\n \"mode\": \"raw\",\n \"jsonOutput\": \"{\\n \\\"title\\\": \\\"SEO Report July\\\",\\n \\\"filename\\\": \\\"seo_report\\\",\\n \\\"content\\\": {\\n \\\"website\\\": \\\"example-store.com\\\",\\n \\\"analysis_date\\\": \\\"2025-07-31\\\",\\n \\\"overall_score\\\": 78,\\n \\\"critical_issues\\\": [\\n \\\"Missing meta descriptions on 15 pages\\\",\\n \\\"Slow page load times (average 4.2 seconds)\\\",\\n \\\"Broken internal links found\\\"\\n ],\\n \\\"technical_seo\\\": {\\n \\\"page_speed\\\": {\\n \\\"desktop_score\\\": 65,\\n \\\"mobile_score\\\": 42,\\n \\\"recommendations\\\": [\\n \\\"Optimize images (reduce file sizes by 60%)\\\",\\n \\\"Enable browser caching\\\",\\n \\\"Minify CSS and JavaScript files\\\"\\n ]\\n },\\n \\\"crawlability\\\": {\\n \\\"status\\\": \\\"Good\\\",\\n \\\"sitemap_url\\\": \\\"https://example-store.com/sitemap.xml\\\",\\n \\\"robots_txt\\\": \\\"Present and properly configured\\\",\\n \\\"issues\\\": []\\n }\\n },\\n \\\"content_analysis\\\": {\\n \\\"keyword_optimization\\\": {\\n \\\"primary_keywords\\\": [\\\"organic skincare\\\", \\\"natural beauty products\\\", \\\"eco-friendly cosmetics\\\"],\\n \\\"keyword_density\\\": \\\"2.3%\\\",\\n \\\"missing_keywords\\\": [\\\"sustainable beauty\\\", \\\"cruelty-free products\\\"]\\n },\\n \\\"content_quality\\\": {\\n \\\"readability_score\\\": 82,\\n \\\"average_word_count\\\": 450,\\n \\\"duplicate_content\\\": \\\"3 pages with similar content detected\\\"\\n }\\n },\\n \\\"recommendations\\\": {\\n \\\"high_priority\\\": [\\n \\\"Add meta descriptions to all product pages\\\",\\n \\\"Implement image compression to improve load times\\\",\\n \\\"Fix 12 broken internal links in navigation\\\"\\n ],\\n \\\"medium_priority\\\": [\\n \\\"Optimize title tags for better CTR\\\",\\n \\\"Add schema markup for products\\\",\\n \\\"Improve mobile responsiveness\\\"\\n ],\\n \\\"low_priority\\\": [\\n \\\"Add social media meta tags\\\",\\n \\\"Consider implementing breadcrumb navigation\\\"\\n ]\\n },\\n \\\"next_review_date\\\": \\\"2025-10-31\\\"\\n }\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 200,\n 100\n ],\n \"id\": \"4238e624-1664-4d45-95ec-b5dadfda7ea3\",\n \"name\": \"Mock SEO Report\"\n },\n {\n \"parameters\": {\n \"mode\": \"raw\",\n \"jsonOutput\": \"{\\n \\\"title\\\": \\\"Mediterranean Recipe\\\",\\n \\\"filename\\\": \\\"recipe\\\",\\n \\\"content\\\": {\\n \\\"dish_name\\\": \\\"Mediterranean Herb-Crusted Salmon with Roasted Vegetables\\\",\\n \\\"cuisine_type\\\": \\\"Mediterranean\\\",\\n \\\"difficulty_level\\\": \\\"Intermediate\\\",\\n \\\"prep_time\\\": \\\"25 minutes\\\",\\n \\\"cook_time\\\": \\\"35 minutes\\\",\\n \\\"serves\\\": 4,\\n \\\"ingredients\\\": {\\n \\\"main_protein\\\": [\\n \\\"4 salmon fillets (6 oz each)\\\",\\n \\\"2 tablespoons olive oil\\\",\\n \\\"1 teaspoon sea salt\\\",\\n \\\"1/2 teaspoon black pepper\\\"\\n ],\\n \\\"herb_crust\\\": [\\n \\\"1/2 cup fresh breadcrumbs\\\",\\n \\\"2 tablespoons fresh parsley, chopped\\\",\\n \\\"1 tablespoon fresh dill, chopped\\\",\\n \\\"1 tablespoon fresh oregano, chopped\\\",\\n \\\"2 cloves garlic, minced\\\",\\n \\\"2 tablespoons lemon zest\\\"\\n ],\\n \\\"roasted_vegetables\\\": [\\n \\\"2 medium zucchini, sliced\\\",\\n \\\"1 red bell pepper, cut into strips\\\",\\n \\\"1 yellow bell pepper, cut into strips\\\",\\n \\\"1 red onion, sliced\\\",\\n \\\"12 cherry tomatoes, halved\\\",\\n \\\"3 tablespoons olive oil\\\",\\n \\\"1 teaspoon dried thyme\\\"\\n ]\\n },\\n \\\"cooking_instructions\\\": {\\n \\\"preparation\\\": {\\n \\\"step_1\\\": \\\"Preheat oven to 425°F (220°C)\\\",\\n \\\"step_2\\\": \\\"Line two baking sheets with parchment paper\\\",\\n \\\"step_3\\\": \\\"Pat salmon fillets dry and season with salt and pepper\\\"\\n },\\n \\\"herb_crust_preparation\\\": {\\n \\\"mixing\\\": \\\"Combine breadcrumbs, herbs, garlic, and lemon zest in a bowl\\\",\\n \\\"binding\\\": \\\"Add 1 tablespoon olive oil to create a paste-like consistency\\\",\\n \\\"application\\\": \\\"Press herb mixture firmly onto top of each salmon fillet\\\"\\n },\\n \\\"vegetable_preparation\\\": {\\n \\\"cutting\\\": \\\"Cut all vegetables into uniform pieces for even cooking\\\",\\n \\\"seasoning\\\": \\\"Toss vegetables with olive oil, thyme, salt, and pepper\\\",\\n \\\"arrangement\\\": \\\"Spread vegetables in single layer on prepared baking sheet\\\"\\n },\\n \\\"cooking_process\\\": {\\n \\\"vegetables_first\\\": \\\"Roast vegetables for 15 minutes before adding salmon\\\",\\n \\\"salmon_cooking\\\": \\\"Place herb-crusted salmon on second baking sheet\\\",\\n \\\"final_cooking\\\": \\\"Cook both salmon and vegetables for additional 12-15 minutes\\\",\\n \\\"doneness_check\\\": \\\"Salmon should flake easily and reach internal temperature of 145°F\\\"\\n }\\n },\\n \\\"nutritional_information\\\": {\\n \\\"per_serving\\\": {\\n \\\"calories\\\": 485,\\n \\\"protein\\\": \\\"38g\\\",\\n \\\"carbohydrates\\\": \\\"18g\\\",\\n \\\"fat\\\": \\\"28g\\\",\\n \\\"fiber\\\": \\\"5g\\\",\\n \\\"sodium\\\": \\\"420mg\\\"\\n },\\n \\\"health_benefits\\\": [\\n \\\"Rich in omega-3 fatty acids for heart health\\\",\\n \\\"High protein content supports muscle maintenance\\\",\\n \\\"Antioxidants from colorful vegetables boost immune system\\\",\\n \\\"Mediterranean herbs provide anti-inflammatory compounds\\\"\\n ]\\n },\\n \\\"serving_suggestions\\\": {\\n \\\"accompaniments\\\": [\\n \\\"Lemon wedges for extra citrus flavor\\\",\\n \\\"Tzatziki sauce or Greek yogurt\\\",\\n \\\"Warm pita bread or crusty sourdough\\\",\\n \\\"Mixed green salad with olive oil dressing\\\"\\n ],\\n \\\"wine_pairings\\\": [\\n \\\"Sauvignon Blanc - crisp and herbaceous\\\",\\n \\\"Pinot Grigio - light and fresh\\\",\\n \\\"Rosé - complements the Mediterranean flavors\\\"\\n ]\\n },\\n \\\"storage_and_leftovers\\\": {\\n \\\"refrigeration\\\": {\\n \\\"duration\\\": \\\"Store leftovers for up to 3 days in refrigerator\\\",\\n \\\"container\\\": \\\"Use airtight containers to maintain freshness\\\",\\n \\\"reheating\\\": \\\"Reheat gently in 350°F oven for 8-10 minutes\\\"\\n },\\n \\\"meal_prep_tips\\\": [\\n \\\"Prepare herb crust mixture up to 2 days ahead\\\",\\n \\\"Cut vegetables the night before and store in refrigerator\\\",\\n \\\"Cook extra vegetables for easy weekday sides\\\"\\n ]\\n },\\n \\\"chef_notes\\\": {\\n \\\"substitutions\\\": {\\n \\\"fish_alternatives\\\": [\\\"Cod fillets\\\", \\\"Halibut steaks\\\", \\\"Sea bass\\\"],\\n \\\"herb_variations\\\": [\\\"Basil and thyme\\\", \\\"Rosemary and sage\\\", \\\"Cilantro and mint\\\"],\\n \\\"vegetable_swaps\\\": [\\\"Asparagus\\\", \\\"Brussels sprouts\\\", \\\"Eggplant\\\"]\\n },\\n \\\"pro_tips\\\": [\\n \\\"Don't overcrowd vegetables on baking sheet for proper roasting\\\",\\n \\\"Let salmon rest at room temperature for 15 minutes before cooking\\\",\\n \\\"Use a meat thermometer for perfectly cooked salmon every time\\\"\\n ]\\n },\\n \\\"recipe_source\\\": \\\"Chef Maria's Mediterranean Kitchen\\\",\\n \\\"recipe_url\\\": \\\"https://mediterranean-kitchen.com/herb-crusted-salmon\\\"\\n }\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 200,\n -100\n ],\n \"id\": \"50ab8c9b-368d-4357-b250-486b228cbba8\",\n \"name\": \"Mock Recipe\"\n },\n {\n \"parameters\": {\n \"mode\": \"raw\",\n \"jsonOutput\": \"{\\n \\\"title\\\": \\\"SEO Report July\\\",\\n \\\"filename\\\": \\\"project\\\",\\n \\\"content\\\": {\\n \\\"project_name\\\": \\\"TaskFlow Pro - Project Management API\\\",\\n \\\"version\\\": \\\"2.4.1\\\",\\n \\\"release_date\\\": \\\"2025-07-15\\\",\\n \\\"overview\\\": \\\"A comprehensive REST API for managing projects, tasks, and team collaboration with real-time updates and advanced reporting capabilities.\\\",\\n \\\"system_requirements\\\": {\\n \\\"minimum_requirements\\\": {\\n \\\"operating_system\\\": [\\\"Windows 10\\\", \\\"macOS 12.0\\\", \\\"Ubuntu 20.04 LTS\\\"],\\n \\\"memory\\\": \\\"8GB RAM minimum\\\",\\n \\\"storage\\\": \\\"2GB available disk space\\\",\\n \\\"network\\\": \\\"Stable internet connection required\\\"\\n },\\n \\\"recommended_requirements\\\": {\\n \\\"operating_system\\\": [\\\"Windows 11\\\", \\\"macOS 13.0\\\", \\\"Ubuntu 22.04 LTS\\\"],\\n \\\"memory\\\": \\\"16GB RAM or higher\\\",\\n \\\"storage\\\": \\\"5GB available disk space\\\",\\n \\\"processor\\\": \\\"Multi-core processor (4+ cores recommended)\\\"\\n }\\n },\\n \\\"installation_guide\\\": {\\n \\\"prerequisites\\\": {\\n \\\"software_dependencies\\\": [\\n \\\"Node.js version 18.0 or higher\\\",\\n \\\"PostgreSQL 14.0 or higher\\\",\\n \\\"Redis 6.2 or higher\\\",\\n \\\"Docker (optional but recommended)\\\"\\n ],\\n \\\"environment_setup\\\": {\\n \\\"development\\\": \\\"Set NODE_ENV=development in your environment variables\\\",\\n \\\"production\\\": \\\"Configure SSL certificates and set NODE_ENV=production\\\",\\n \\\"database\\\": \\\"Create a new PostgreSQL database named 'taskflow_db'\\\"\\n }\\n },\\n \\\"installation_steps\\\": {\\n \\\"step_1\\\": {\\n \\\"title\\\": \\\"Clone the Repository\\\",\\n \\\"command\\\": \\\"git clone https://github.com/taskflow/taskflow-api.git\\\",\\n \\\"description\\\": \\\"Download the latest version from our GitHub repository\\\"\\n },\\n \\\"step_2\\\": {\\n \\\"title\\\": \\\"Install Dependencies\\\",\\n \\\"command\\\": \\\"npm install --production\\\",\\n \\\"description\\\": \\\"Install all required Node.js packages and dependencies\\\"\\n },\\n \\\"step_3\\\": {\\n \\\"title\\\": \\\"Configure Environment\\\",\\n \\\"files\\\": [\\\".env.example\\\", \\\".env.production\\\"],\\n \\\"description\\\": \\\"Copy .env.example to .env and configure your database credentials\\\"\\n },\\n \\\"step_4\\\": {\\n \\\"title\\\": \\\"Database Migration\\\",\\n \\\"command\\\": \\\"npm run migrate:latest\\\",\\n \\\"description\\\": \\\"Set up database tables and initial schema\\\"\\n },\\n \\\"step_5\\\": {\\n \\\"title\\\": \\\"Start the Application\\\",\\n \\\"command\\\": \\\"npm start\\\",\\n \\\"description\\\": \\\"Launch the API server on default port 3000\\\"\\n }\\n }\\n },\\n \\\"api_endpoints\\\": {\\n \\\"authentication\\\": {\\n \\\"login\\\": {\\n \\\"method\\\": \\\"POST\\\",\\n \\\"endpoint\\\": \\\"/api/v2/auth/login\\\",\\n \\\"description\\\": \\\"Authenticate user and receive JWT token\\\",\\n \\\"required_fields\\\": [\\\"email\\\", \\\"password\\\"],\\n \\\"response_format\\\": \\\"JSON with access_token and user_info\\\"\\n },\\n \\\"register\\\": {\\n \\\"method\\\": \\\"POST\\\",\\n \\\"endpoint\\\": \\\"/api/v2/auth/register\\\",\\n \\\"description\\\": \\\"Create new user account\\\",\\n \\\"required_fields\\\": [\\\"email\\\", \\\"password\\\", \\\"first_name\\\", \\\"last_name\\\"],\\n \\\"optional_fields\\\": [\\\"company\\\", \\\"phone\\\"]\\n }\\n },\\n \\\"project_management\\\": {\\n \\\"create_project\\\": {\\n \\\"method\\\": \\\"POST\\\",\\n \\\"endpoint\\\": \\\"/api/v2/projects\\\",\\n \\\"description\\\": \\\"Create a new project with initial settings\\\",\\n \\\"required_fields\\\": [\\\"name\\\", \\\"description\\\", \\\"start_date\\\"],\\n \\\"optional_fields\\\": [\\\"end_date\\\", \\\"budget\\\", \\\"team_members\\\"]\\n },\\n \\\"list_projects\\\": {\\n \\\"method\\\": \\\"GET\\\",\\n \\\"endpoint\\\": \\\"/api/v2/projects\\\",\\n \\\"description\\\": \\\"Retrieve all projects for authenticated user\\\",\\n \\\"query_parameters\\\": [\\\"status\\\", \\\"sort_by\\\", \\\"limit\\\", \\\"offset\\\"],\\n \\\"filters\\\": [\\\"active\\\", \\\"completed\\\", \\\"archived\\\", \\\"on_hold\\\"]\\n },\\n \\\"update_project\\\": {\\n \\\"method\\\": \\\"PUT\\\",\\n \\\"endpoint\\\": \\\"/api/v2/projects/{project_id}\\\",\\n \\\"description\\\": \\\"Update existing project details\\\",\\n \\\"updatable_fields\\\": [\\\"name\\\", \\\"description\\\", \\\"status\\\", \\\"budget\\\", \\\"end_date\\\"]\\n }\\n },\\n \\\"task_management\\\": {\\n \\\"create_task\\\": {\\n \\\"method\\\": \\\"POST\\\",\\n \\\"endpoint\\\": \\\"/api/v2/projects/{project_id}/tasks\\\",\\n \\\"description\\\": \\\"Add new task to specified project\\\",\\n \\\"required_fields\\\": [\\\"title\\\", \\\"description\\\", \\\"priority\\\"],\\n \\\"priority_levels\\\": [\\\"low\\\", \\\"medium\\\", \\\"high\\\", \\\"urgent\\\"]\\n },\\n \\\"assign_task\\\": {\\n \\\"method\\\": \\\"PATCH\\\",\\n \\\"endpoint\\\": \\\"/api/v2/tasks/{task_id}/assign\\\",\\n \\\"description\\\": \\\"Assign task to team member\\\",\\n \\\"required_fields\\\": [\\\"assignee_id\\\", \\\"due_date\\\"],\\n \\\"notification\\\": \\\"Automatic email notification sent to assignee\\\"\\n }\\n }\\n },\\n \\\"configuration_options\\\": {\\n \\\"database_settings\\\": {\\n \\\"connection_pool\\\": {\\n \\\"min_connections\\\": 5,\\n \\\"max_connections\\\": 20,\\n \\\"idle_timeout\\\": \\\"30 seconds\\\"\\n },\\n \\\"backup_settings\\\": {\\n \\\"automatic_backup\\\": true,\\n \\\"backup_frequency\\\": \\\"Daily at 2:00 AM UTC\\\",\\n \\\"retention_period\\\": \\\"30 days\\\",\\n \\\"backup_location\\\": \\\"AWS S3 bucket or local storage\\\"\\n }\\n },\\n \\\"security_configuration\\\": {\\n \\\"jwt_settings\\\": {\\n \\\"token_expiry\\\": \\\"24 hours\\\",\\n \\\"refresh_token_expiry\\\": \\\"7 days\\\",\\n \\\"algorithm\\\": \\\"HS256\\\"\\n },\\n \\\"rate_limiting\\\": {\\n \\\"requests_per_minute\\\": 100,\\n \\\"burst_limit\\\": 200,\\n \\\"blocked_duration\\\": \\\"15 minutes\\\"\\n },\\n \\\"cors_settings\\\": {\\n \\\"allowed_origins\\\": [\\\"https://app.taskflow.com\\\", \\\"https://admin.taskflow.com\\\"],\\n \\\"allowed_methods\\\": [\\\"GET\\\", \\\"POST\\\", \\\"PUT\\\", \\\"DELETE\\\", \\\"PATCH\\\"],\\n \\\"credentials\\\": true\\n }\\n }\\n },\\n \\\"troubleshooting\\\": {\\n \\\"common_issues\\\": {\\n \\\"database_connection_failed\\\": {\\n \\\"symptoms\\\": [\\\"Connection timeout errors\\\", \\\"Unable to connect to database\\\"],\\n \\\"solutions\\\": [\\n \\\"Verify database credentials in .env file\\\",\\n \\\"Check if PostgreSQL service is running\\\",\\n \\\"Ensure database exists and user has proper permissions\\\",\\n \\\"Test connection using psql command line tool\\\"\\n ]\\n },\\n \\\"authentication_errors\\\": {\\n \\\"symptoms\\\": [\\\"401 Unauthorized responses\\\", \\\"Invalid token errors\\\"],\\n \\\"solutions\\\": [\\n \\\"Check JWT secret key configuration\\\",\\n \\\"Verify token hasn't expired\\\",\\n \\\"Ensure proper Authorization header format\\\",\\n \\\"Clear browser cache and cookies\\\"\\n ]\\n },\\n \\\"performance_issues\\\": {\\n \\\"symptoms\\\": [\\\"Slow API responses\\\", \\\"High memory usage\\\", \\\"Timeout errors\\\"],\\n \\\"solutions\\\": [\\n \\\"Enable database query optimization\\\",\\n \\\"Implement Redis caching for frequent queries\\\",\\n \\\"Monitor and optimize database indexes\\\",\\n \\\"Scale horizontally with load balancer\\\"\\n ]\\n }\\n }\\n },\\n \\\"support_resources\\\": {\\n \\\"documentation_links\\\": [\\n \\\"https://docs.taskflow.com/api-reference\\\",\\n \\\"https://docs.taskflow.com/getting-started\\\",\\n \\\"https://docs.taskflow.com/best-practices\\\"\\n ],\\n \\\"community_support\\\": [\\n \\\"GitHub Issues: https://github.com/taskflow/taskflow-api/issues\\\",\\n \\\"Discord Community: https://discord.gg/taskflow\\\",\\n \\\"Stack Overflow tag: taskflow-api\\\"\\n ],\\n \\\"contact_information\\\": {\\n \\\"technical_support\\\": \\\"support@taskflow.com\\\",\\n \\\"sales_inquiries\\\": \\\"sales@taskflow.com\\\",\\n \\\"business_hours\\\": \\\"Monday-Friday, 9:00 AM - 6:00 PM EST\\\"\\n }\\n }\\n }\\n}\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 200,\n 280\n ],\n \"id\": \"6ba13623-d42a-4785-9537-8022521f9397\",\n \"name\": \"Mock Project Data\"\n },\n {\n \"parameters\": {\n \"workflowId\": {\n \"__rl\": true,\n \"value\": \"lr4FCy9jvt89twbt\",\n \"mode\": \"list\",\n \"cachedResultName\": \"Tools - Report Generator\"\n },\n \"workflowInputs\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"title\": \"={{ $json.title }}\",\n \"filename\": \"={{ $json.filename }}\",\n \"content\": \"={{ $json.content }}\"\n },\n \"matchingColumns\": [],\n \"schema\": [\n {\n \"id\": \"filename\",\n \"displayName\": \"filename\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"title\",\n \"displayName\": \"title\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"content\",\n \"displayName\": \"content\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": true\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.executeWorkflow\",\n \"typeVersion\": 1.2,\n \"position\": [\n 420,\n -100\n ],\n \"id\": \"0181fe75-a134-43f5-aa3d-8b33c4a08bc8\",\n \"name\": \"Generate Report 1\"\n },\n {\n \"parameters\": {\n \"workflowId\": {\n \"__rl\": true,\n \"value\": \"lr4FCy9jvt89twbt\",\n \"mode\": \"list\",\n \"cachedResultName\": \"Tools - Report Generator\"\n },\n \"workflowInputs\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"title\": \"={{ $json.title }}\",\n \"filename\": \"={{ $json.filename }}\",\n \"content\": \"={{ $json.content }}\"\n },\n \"matchingColumns\": [],\n \"schema\": [\n {\n \"id\": \"filename\",\n \"displayName\": \"filename\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"title\",\n \"displayName\": \"title\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"content\",\n \"displayName\": \"content\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": true\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.executeWorkflow\",\n \"typeVersion\": 1.2,\n \"position\": [\n 420,\n 100\n ],\n \"id\": \"2437b60c-a6a1-4d5f-9cb9-d1f25da5f808\",\n \"name\": \"Generate Report 2\"\n },\n {\n \"parameters\": {\n \"workflowId\": {\n \"__rl\": true,\n \"value\": \"lr4FCy9jvt89twbt\",\n \"mode\": \"list\",\n \"cachedResultName\": \"Tools - Report Generator\"\n },\n \"workflowInputs\": {\n \"mappingMode\": \"defineBelow\",\n \"value\": {\n \"title\": \"={{ $json.title }}\",\n \"filename\": \"={{ $json.filename }}\",\n \"content\": \"={{ $json.content }}\"\n },\n \"matchingColumns\": [],\n \"schema\": [\n {\n \"id\": \"filename\",\n \"displayName\": \"filename\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"title\",\n \"displayName\": \"title\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true,\n \"type\": \"string\"\n },\n {\n \"id\": \"content\",\n \"displayName\": \"content\",\n \"required\": false,\n \"defaultMatch\": false,\n \"display\": true,\n \"canBeUsedToMatch\": true\n }\n ],\n \"attemptToConvertTypes\": false,\n \"convertFieldsToString\": true\n },\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.executeWorkflow\",\n \"typeVersion\": 1.2,\n \"position\": [\n 420,\n 280\n ],\n \"id\": \"a4f69396-d7b2-4d4e-99ca-1194d1ff97df\",\n \"name\": \"Generate Report 3\"\n }\n ],\n \"pinData\": {},\n \"connections\": {\n \"When clicking ‘Execute workflow’\": {\n \"main\": [\n [\n {\n \"node\": \"Mock SEO Report\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"Mock Recipe\",\n \"type\": \"main\",\n \"index\": 0\n },\n {\n \"node\": \"Mock Project Data\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Mock SEO Report\": {\n \"main\": [\n [\n {\n \"node\": \"Generate Report 2\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Mock Recipe\": {\n \"main\": [\n [\n {\n \"node\": \"Generate Report 1\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n },\n \"Mock Project Data\": {\n \"main\": [\n [\n {\n \"node\": \"Generate Report 3\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"active\": false,\n \"settings\": {\n \"executionOrder\": \"v1\"\n },\n \"versionId\": \"6108b1b3-101f-48a6-b19a-e334acc08afb\",\n \"meta\": {\n \"instanceId\": \"558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a\"\n },\n \"id\": \"hxQH8WTuPlGTfMm5\",\n \"tags\": []\n}\n```", "metadata": {"source": "Marvomatic/n8n-templates", "workflow_name": "Report Examples Demo", "node_count": 7, "category": "General Automation"}} {"prompt": "Build a workflow for: Tools Report Generator", "response": "# Workflow Architecture\n\n**Purpose**: General Automation\n\n**Key Components**:\n- Total Nodes: 8\n- Node Types: @n8n/n8n-nodes-langchain.agent, n8n-nodes-base.set, @n8n/n8n-nodes-langchain.lmChatOpenAi, n8n-nodes-base.executeWorkflowTrigger, n8n-nodes-base.convertToFile, n8n-nodes-base.html, n8n-nodes-base.stickyNote, n8n-nodes-base.code\n\n**Logic Flow**:\n1. **Trigger**: n8n-nodes-base.executeWorkflowTrigger - Initiates the workflow\n\n## Complete Workflow JSON\n\n```json\n{\n \"name\": \"Tools - Report Generator\",\n \"nodes\": [\n {\n \"parameters\": {\n \"operation\": \"toBinary\",\n \"sourceProperty\": \"base64\",\n \"options\": {\n \"fileName\": \"={{$('Start').item.json.filename + \\\".html\\\"}}\",\n \"mimeType\": \"={{ $json.mimetype }}\"\n }\n },\n \"type\": \"n8n-nodes-base.convertToFile\",\n \"typeVersion\": 1.1,\n \"position\": [\n 1000,\n -80\n ],\n \"id\": \"6041b412-c030-4e83-86ab-3e8b68988398\",\n \"name\": \"convert_to_html_file\"\n },\n {\n \"parameters\": {\n \"jsCode\": \"return [\\n {\\n json: {\\n base64: Buffer.from($input.all()[0].json.html).toString('base64'),\\n mimetype: \\\"text/html\\\"\\n }\\n }\\n];\\n\"\n },\n \"type\": \"n8n-nodes-base.code\",\n \"typeVersion\": 2,\n \"position\": [\n 780,\n -80\n ],\n \"id\": \"04d67343-1344-48ca-a599-918e5b7688d9\",\n \"name\": \"convert_to_base64\"\n },\n {\n \"parameters\": {\n \"model\": {\n \"__rl\": true,\n \"mode\": \"list\",\n \"value\": \"gpt-4.1-mini\"\n },\n \"options\": {\n \"temperature\": 0\n }\n },\n \"type\": \"@n8n/n8n-nodes-langchain.lmChatOpenAi\",\n \"typeVersion\": 1.2,\n \"position\": [\n -80,\n 120\n ],\n \"id\": \"fb451a32-3a49-4247-91f7-2f52db48d040\",\n \"name\": \"OpenAI Chat Model\",\n \"credentials\": {\n \"openAiApi\": {\n \"id\": \"RAj3VxCHt0rIwBTk\",\n \"name\": \"OpenAI\"\n }\n }\n },\n {\n \"parameters\": {\n \"promptType\": \"define\",\n \"text\": \"=Convert the following JSON data to HTML format:\\n\\n{{ JSON.stringify($json.content) }}\\n# TRANSFORMATION REQUIREMENTS\\n\\n**Structure Conversion:**\\n- Transform each JSON key into a semantic HTML section with appropriate heading level\\n- Maintain logical hierarchy: top-level keys become h2, nested keys become h3, etc.\\n- Preserve the original data organization and relationships\\n\\n**Content Formatting:**\\n- Text strings →

paragraphs (split on line breaks if needed)\\n- Arrays →