Назад до шаблонів
ШАБЛОН ВОРКФЛОУ
Create Prompt Dataset To Monitor Visibility For GEO/ALLMO | Operasyon için n8n Otomasyon İş Akışı Şablonu (HTTP)
n8n için hazır otomasyon şablonu: Create Prompt Dataset To Monitor Visibility For GEO/ALLMO. 23 düğüm. Entegrasyonlar: HTTP. JSON'u kopyalayıp n8n'e içe aktarın.
23 вузлиCreate_Prompt_Dataset_To_Monitor_Visibility_For_Geo_Allmo-workflow.json
{"id": "","meta": {"instanceId": "","templateCredsSetupCompleted": true},"name": "Create Prompt Dataset to monitor Visibility for GEO/ALLMO","tags": [],"nodes": [{"id": "eee878af-206c-45cc-be8d-eb211bd7047e","name": "Edit Fields","type": "n8n-nodes-base.set","position": [-176,0],"parameters": {"options": {},"assignments": {"assignments": [{"id": "29cf4747-80ac-4a93-93f5-f9a0717040a9","name": "company_name","type": "string","value": "={{ $json['Provide a Company Name'] }}"},{"id": "78cb8a10-3c8c-4ccf-99a5-af86e418b857","name": "company_website","type": "string","value": "={{ $json['Provide a Website URL'] }}"}]}},"typeVersion": 3.4},{"id": "c05115d7-122b-4fac-9174-0a32c293c4f2","name": "Claude_text_writer","type": "@n8n/n8n-nodes-langchain.anthropic","position": [1552,-176],"parameters": {"modelId": {"__rl": true,"mode": "list","value": "claude-sonnet-4-5-20250929","cachedResultName": "claude-sonnet-4-5-20250929"},"options": {},"messages": {"values": [{"role": "assistant","content": "You are a Query Refinement Agent.\n\nYour task is to review and lightly improve a list of 13 phrases simulating search terms or user queries for an AI system such as ChatGPT, Claude, or Perplexity.\n\n🎯 Your Goal\nEnhance each phrase if necessary so it reads as a natural, human-written search query, while preserving the original meaning.\n\n🧠 Required Actions\nFor each of the 13 input phrases:\n\n- Check grammar, spelling, and sentence structure.\n- Correct unnatural phrasing, remnants of template language, or inconsistent word choice.\n- Fix minor logical problems (e.g., contradicting features or broken sentences).\n- Clarify and adjust so the phrase sounds like something a real person would search for.\n- Keep the phrasing's core intent and meaning unchanged—do not alter the search intent.\n- If a phrase is already natural, leave it as is.\n- Return all 13 revised phrases in the original order, even if nothing was changed.\n\n🔒 Constraints\n\n- Do not make phrases shorter, merge, or split them.\n- Do not change the query topic or introduce new ideas.\n- Maintain a neutral, search-query tone.\n- Do not add unnecessary descriptions or embellishments.\n- Preserve all brand mentions exactly as provided.\n\n📝 Input Format\nYou will receive a list of all phrases. \n\n## Output Format\nOutput a strict JSON object with precisely this structure:\n{\n \"phrases\": [\n \"\",\n \" \",\n ...\n \" \"\n ]\n}\n\n- Return only this JSON object—do not include any notes or explanations.\n- The array must contain exactly 13 strings.\n- If the input does not contain exactly 13 strings, output this error format:\n {\n \"error\": \"Expected 13 phrases as input.\"\n }\n- If any input phrase is not a string, output this error format:\n {\n \"error\": \"All phrases must be strings.\"\n }\nAfter completing the refinement, briefly validate that all constraints have been observed and the output matches the required format. If validation fails, self-correct before final output." },{"content": "=INPUT_JSONL\nTerm 1: {{ $json.phrases[0] }}\nTerm 2: {{ $json.phrases[1] }}\nTerm 3: {{ $json.phrases[2] }}\nTerm 4: {{ $json.phrases[3] }}\nTerm 5: {{ $json.phrases[4] }}\nTerm 6: {{ $json.phrases[5] }}\nTerm 7: {{ $json.phrases[6] }}\nTerm 8: {{ $json.phrases[7] }}\nTerm 9: {{ $json.phrases[8] }}\nTerm 10: {{ $json.phrases[9] }}\nTerm 11: {{ $json.phrases[10] }}\nTerm 12: {{ $json.phrases[11] }}\nTerm 13: {{ $json.phrases[12] }}\n\n\nOutput rules:\nCRITICAL RULES:\n1. Your output MUST be in JSONL format (one JSON object per line, no array brackets)\n2. Process every input line and maintain the same count of output lines\n3. Do not add any extra text, explanations, or formatting outside the JSONL output"}]},"simplify": false},"credentials": {"anthropicApi": {"id": "","name": ""}},"typeVersion": 1},{"id": "395bfb37-0ad5-4c3d-b7fe-f3b547a3f95d","name": "GPT_company_research","type": "n8n-nodes-base.httpRequest","position": [80,0],"parameters": {"url": "https://api.openai.com/v1/responses","method": "POST","options": {"timeout": 1500000},"jsonBody": "={\n \"model\": \"gpt-5-mini\",\n \"input\": [\n {\n \"role\": \"system\",\n \"content\": \"You are an AI Research Agent. Your role is to enrich and complete company information based on a company name and website provided by the user.\\nBegin with a concise checklist (4-8 bullets) of what you will do; keep items conceptual, not implementation-level.\\n# Core Responsibilities\\n1. Enrich the company profile with accurate and current information.\\n2. YOU MUST visit the provided website—including all pertinent subpages—to extract factual details.\\n3. Research and fill in the following fields:\\n - Industry\\n - Solution or Product Category & Name (UNBRANDED; e.g., \\\"Google Search\\\" → \\\"web search engine\\\")\\n - Target Buyer Personas (provide exactly 3 personas)\\n - Problems Solved (provide exactly 4 problems clearly derived from the website; one problem must be a short, concise value proposition: max 2 to 5 words)\\n - Key Features (provide exactly 5 features clearly derived from the website)\\n - Value Proposition (provide a short, concise value proposition: max 2 to 5 words)\\n# Requirements\\n- All information MUST be based on the company website and credible online sources only.\\n- DO NOT fabricate data. If certain information cannot be ascertained, set the field value to: \\\"Not enough information available\\\".\\n- Do NOT answer from prior knowledge or memory; you MUST visit and use the provided website for each response. Do not rely on knowledge—website review is critical to ensure the information is applied to the correct company.\\n- Only output valid JSON—do NOT include explanations, text, or Markdown.\\nAfter reviewing the website and sources, validate that each field is filled with either verifiable information or \\\"Not enough information available\\\" in the correct schema. If unable to confirm data for any item, double-check before finalizing the response.\\n# Output Schema\\nYour response MUST be a valid JSON object using the following exact schema and field/order:\\n{\\n \\\"industry\\\": \\\"string\\\",\\n \\\"solution\\\": {\\n \\\"category\\\": \\\"string\\\",\\n \\\"unbranded_name\\\": \\\"string\\\"\\n },\\n \\\"buyer_personas\\\": [\\n {\\n \\\"name\\\": \\\"string\\\",\\n \\\"description\\\": \\\"string\\\"\\n },\\n {\\n \\\"name\\\": \\\"string\\\",\\n \\\"description\\\": \\\"string\\\"\\n },\\n {\\n \\\"name\\\": \\\"string\\\",\\n \\\"description\\\": \\\"string\\\"\\n }\\n ],\\n \\\"problems_solved\\\": [\\n \\\"string\\\",\\n \\\"string\\\",\\n \\\"string\\\",\\n \\\"string\\\" \\n ],\\n \\\"key_features\\\": [\\n \\\"string\\\",\\n \\\"string\\\",\\n \\\"string\\\",\\n \\\"string\\\",\\n \\\"string\\\"\\n ],\\n \\\"value_proposition\\\": \\\"string\\\" \\n}\\n- All listed fields must be present, with values in the required order.\\n- For any field where information cannot be found or verified, use: \\\"Not enough information available\\\" (for strings) or an appropriately sized array containing \\\"Not enough information available\\\" repeated as needed.\\n- Output must NOT include any extra keys or fields.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Company: {{ $json.company_name }}.\\nWebsite: {{ $json.company_website }}\\nTask: Conduct your research on the topic above and deliver results following the system instructions.\"\n }\n ],\n \"tools\": [\n {\n \"type\": \"web_search\",\n \"filters\": {\n \"allowed_domains\": [\"{{ $json.company_website }}\"]\n }\n }\n ],\n \"tool_choice\": \"auto\"\n}","sendBody": true,"specifyBody": "json","authentication": "predefinedCredentialType","nodeCredentialType": "openAiApi"},"credentials": {"openAiApi": {"id": "","name": ""}},"typeVersion": 4.2},{"id": "8fcf08d9-d729-43e6-bc3e-1d48ed28784d","name": "Code in JavaScript","type": "n8n-nodes-base.code","position": [384,0],"parameters": {"jsCode": "// The input is already the response object\nconst response = $input.item.json;\n\n// Extract the final message content\nconst messageOutput = response.output.find(item => item.type === 'message');\nconst textContent = messageOutput.content[0].text;\n\n// Parse the JSON string to get structured data\nconst result = JSON.parse(textContent);\n\nreturn {\n json: result\n};"},"typeVersion": 2},{"id": "f5975c96-7123-4537-ba7c-25631c9b5676","name": "Remove citations","type": "n8n-nodes-base.code","position": [624,0],"parameters": {"jsCode": "// Get the input data (it's an array with one object)\nconst data = $input.item.json;\n\n// Recursive function to clean strings\nfunction cleanString(str) {\n if (typeof str !== 'string') return str;\n // Remove everything from \" ([\" to the end, including the pattern\n return str.replace(/\\s*\\(\\[.*?\\]\\(.*?\\)\\)/g, '').trim();\n}\n\n// Recursive function to process all values in an object/array\nfunction cleanObject(obj) {\n if (Array.isArray(obj)) {\n return obj.map(item => cleanObject(item));\n } else if (obj !== null && typeof obj === 'object') {\n const cleaned = {};\n for (const key in obj) {\n cleaned[key] = cleanObject(obj[key]);\n }\n return cleaned;\n } else if (typeof obj === 'string') {\n return cleanString(obj);\n }\n return obj;\n}\n\n// Clean the entire data structure (handles the array wrapper)\nconst cleanedData = cleanObject(data);\n\nreturn {\n json: cleanedData\n};"},"typeVersion": 2},{"id": "e752c9c7-c140-4486-93a4-cd437113d33a","name": "Edit Fields2","type": "n8n-nodes-base.set","position": [832,0],"parameters": {"options": {},"assignments": {"assignments": [{"id": "66d125fb-b0a8-4d9b-89fe-e557d85b79b8","name": "industry","type": "string","value": "={{ $json.industry }}"},{"id": "cba5ae79-9771-44b9-bc15-83ccf75a3a2e","name": "Unbranded category","type": "string","value": "={{ $json.solution.unbranded_name }}"},{"id": "183cc26d-0fce-4154-9150-5b36f53b0ee8","name": "category","type": "string","value": "={{ $json.solution.category }}"},{"id": "1845a73d-5bb4-4b8c-81b4-52acf227250b","name": "Persona 0 - name","type": "string","value": "={{ $json.buyer_personas[0].name }}"},{"id": "3bfef52c-ca9f-460a-a757-014d0c6e6e6e","name": "Persona 0 - description","type": "string","value": "={{ $json.buyer_personas[0].description }}"},{"id": "944afca1-1c57-4acb-a7bd-399f72c7e811","name": "Persona 1 - name ","type": "string","value": "={{ $json.buyer_personas[1].name }}"},{"id": "70057952-81d2-43e6-9ec1-a3f173429360","name": "Persona 1 - description","type": "string","value": "={{ $json.buyer_personas[1].description }}"},{"id": "44124fce-15f1-4e0c-b0ae-f8f7122fdded","name": "Persona 2 - name","type": "string","value": "={{ $json.buyer_personas[2].name }}"},{"id": "1aabb8d4-a9ab-47cb-a9db-f5ba4ac9ff54","name": "Persona 2 - description","type": "string","value": "={{ $json.buyer_personas[2].description }}"},{"id": "87318b87-9863-4801-81e4-62e81273790e","name": "Problem 1","type": "string","value": "={{ $json.problems_solved[0] }}"},{"id": "ac0def6c-a7a2-4780-ae28-20dda6e69032","name": "Problem 2","type": "string","value": "={{ $json.problems_solved[1] }}"},{"id": "ee7fabe1-d52f-474c-8068-f2887c0df159","name": "Problem 3","type": "string","value": "={{ $json.problems_solved[2] }}"},{"id": "7c3e6337-3ee5-4d40-b3ab-7db274ccde0b","name": "Problem 4","type": "string","value": "={{ $json.problems_solved[3] }}"},{"id": "1ebc7753-dd91-4561-8aad-931b3de4ab44","name": "Key_features 0","type": "string","value": "={{ $json.key_features[0] }}"},{"id": "1fe8b736-d1ae-43e6-9e91-0cbe41ac1244","name": "Key_features 1","type": "string","value": "={{ $json.key_features[1] }}"},{"id": "85b891f7-ed0a-4af3-bb7b-97da165cfe42","name": "Key_features 2","type": "string","value": "={{ $json.key_features[2] }}"},{"id": "011aeeaa-f2f4-4853-92f4-4babbb562e89","name": "Key_features 3","type": "string","value": "={{ $json.key_features[3] }}"},{"id": "2b69346c-e94b-4fb0-b93d-f90c12b3b8ec","name": "Key_features 4","type": "string","value": "={{ $json.key_features[4] }}"},{"id": "720aa0dc-5129-4a61-9da7-cf0c8dbd4e87","name": "value_propostion","type": "string","value": "={{ $json.value_proposition }}"}]}},"typeVersion": 3.4},{"id": "d569413f-7ec9-4ea5-a94a-9e585c77b835","name": "Hard coded phrase - returns 13","type": "n8n-nodes-base.code","position": [1280,-176],"parameters": {"jsCode": "// Get the data - handle both array and object\nconst data = Array.isArray($input.item.json) ? $input.item.json[0] : $input.item.json;\n\n// Extract values\nconst industry = data.industry;\nconst category = data.category;\nconst unbrandedCategory = data[\"Unbranded category\"];\nconst valueProposition = data.value_propostion;\nconst feature0 = data[\"Key_features 0\"];\nconst feature1 = data[\"Key_features 1\"];\nconst feature2 = data[\"Key_features 2\"];\nconst feature3 = data[\"Key_features 3\"];\nconst problem1 = data[\"Problem 1\"];\nconst problem2 = data[\"Problem 2\"];\nconst problem3 = data[\"Problem 3\"];\nconst problem4 = data[\"Problem 4\"];\n\n// Generate the phrases\nconst phrases = [\n `Leading companies in the ${industry}`,\n `Best ${category} providers`,\n `Best alternatives to established players in the ${unbrandedCategory}`,\n `Top solutions for ${valueProposition}`,\n `What are the leading solutions for ${industry} looking to implement ${unbrandedCategory}`,\n `What are new, innovative solutions for ${unbrandedCategory} to solve`,\n `What is the best way to ${valueProposition}`,\n `${category} solution with ${feature0}, ${feature2}`,\n `${category} solution with ${feature1}, ${feature3}`,\n `Create a longlist of companies active in ${industry} with a focus on ${unbrandedCategory} that help with ${valueProposition} `,\n `How do I solve this problem: ${problem1}`,\n `How do I solve this problem: ${problem2}`,\n `How do I solve this problem: ${problem3}`,\n `How do I solve this problem: ${problem4}`\n];\n\nreturn {\n json: {\n phrases: phrases\n }\n};"},"typeVersion": 2},{"id": "b5c3fd1e-4ec0-4fe5-bf3d-28f324d30cee","name": "GPT_keywords_return 5","type": "n8n-nodes-base.httpRequest","position": [1552,64],"parameters": {"url": "https://api.openai.com/v1/responses","method": "POST","options": {"timeout": 1500000},"jsonBody": "={\n \"model\": \"gpt-5-mini\",\n \"input\": [\n {\n \"role\": \"system\",\n \"content\": \"Developer: You are an AI Search Term Analyst tasked with identifying the top 5 non-brand search terms relevant to a company's website. None of the search terms may contain or reference the company's brand name.\\nUse the provided industry and category as your primary context when selecting relevant terms. If actual search-volume data is unavailable, estimate values based on general market knowledge.\\nInputs:\\n- company: The company or brand name.\\n- website: The primary company domain.\\n- industry: For example, \\\"healthcare\\\", \\\"finance\\\".\\n- category: For example, \\\"fitness equipment\\\", \\\"personal banking\\\".\\nTask Requirements:\\n- Identify exactly 5 relevant, non-brand search terms for the website, industry, and category.\\n- Check the company website to ensure you've identified the entity correctly.\\nBefore finalizing your answer, explicitly validate:\\n- That none of the terms include or reference the brand name.\\n- If any input is missing or you cannot infer data, output an informative error message instead of proceeding.\\nOutput Format:\\nIf all required inputs are present and terms are generated:\\n{\\n \\\"top_search_terms\\\": [\\n {\\n \\\"term1\\\": \\\"\\\"\\n }\\n ]\\n}\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Company:{{ $('Edit Fields').item.json.company_name }}.\\n Website: {{ $('Edit Fields').item.json.company_website }} \\n Industry:{{ $('Remove citations').item.json.industry }} Category: {{ $('Remove citations').item.json.solution.unbranded_name }}\\nTask: Conduct your research on the topic above and deliver results following the system instructions.\"\n }\n ],\n \"tools\": [\n {\n \"type\": \"web_search\"\n }\n ],\n \"tool_choice\": \"auto\"\n}", "sendBody": true,"specifyBody": "json","authentication": "predefinedCredentialType","nodeCredentialType": "openAiApi"},"credentials": {"openAiApi": {"id": "","name": ""}},"typeVersion": 4.2},{"id": "38c4c25e-334c-4506-b034-9238ed473518","name": "Claude_text_writer_return7","type": "@n8n/n8n-nodes-langchain.anthropic","position": [1552,336],"parameters": {"modelId": {"__rl": true,"mode": "list","value": "claude-sonnet-4-5-20250929","cachedResultName": "claude-sonnet-4-5-20250929"},"options": {},"messages": {"values": [{"role": "assistant","content": "# AI Writing Agent Instructions\n\nYou are simulating the behavior of a **real person** asking questions to an AI chatbot (e.g., ChatGPT, Claude, or Perplexity).\n\nBegin with a concise checklist (3-7 bullets) of what you will do; keep items conceptual, not implementation-level. Do not output the checklist.\n\n## 🎯 Objective\n\nGiven a JSON object describing a company, your task is to generate **7 natural, human-like AI search prompts/questions** by combining different elements from the input data.\n\n### You Will Receive JSON Including:\n- Industry context\n- User personas (roles and needs)\n- Problems faced\n- Product features\n- Value propositions\n- Product categories\n\nGenerate **one fluent question** that falls naturally into **one** of these two categories:\n\n1. **Practical Guidance** – asking for advice, how-to steps, or creative ideas.\n2. **Seeking Information** – factual or knowledge-based queries, similar to what users type into a search engine.\n\n---\n\n## 📝 Critical Requirement\n- **All searches and generated questions must be strictly unbranded; do not mention or refer to any specific company name, including direct or indirect references.**\n\n---\n\n## 📝 Question Templates\nFor each of the following, select the most relevant data from the JSON and integrate them naturally:\n\n1. **Persona-Problem Match (Persona 0)**\n - Use: Persona 0's role/description + 2 related problems\n\n2. **Persona-Solution Search (Persona 1)**\n - Use: Persona 1's role + unbranded category or relevant solution\n\n3. **Persona-Feature Need (Persona 2)**\n - Use: Persona 2's role + 2 key features relevant to their needs\n\n4. **Category + Feature**\n - Use: Category + 1 important feature\n\n5. **Unbranded Category + Value Proposition + Feature**\n - Use: Unbranded category + value proposition + 1 relevant feature\n\n6. **Value Proposition + Features Discovery**\n - Use: Value proposition + 2 fitting features\n\n7. **Industry Landscape Research**\n - Use: Industry + unbranded category + value proposition context\n\n---\n\n## ✍️ Writing Guidelines\n- **Length:** Each question should be 8–35 words.\n- **Tone:** Natural, conversational, and curious—reflecting how a real person would ask.\n- **Style:** Mix question formats:\n - Direct: \"What are the best...?\"\n - Advice-seeking: \"How can I...?\"\n - Exploratory: \"Which solutions...?\"\n - Research-oriented: \"List companies that...\"\n- **Keyword Use:** Highlight the selected elements naturally and make them central to the question.\n- **Avoid:**\n - Robotic or overly formal language\n - Lists or bullet points within the question\n - Advertorial or promotional tone\n - Direct mention of company name (keep generic)\n - **Any branded or company names—ensure all questions remain strictly unbranded**\n- **Vary Openings:** Begin each question differently for variety.\n\n---\n\n## 📥 Input Format\nThe input will be a JSON object with industry, unbranded category, category, persona, problems, key features and a value proposition. \n---\n\n## ✅ Output Format\nReturn exactly **7 questions** as a JSON array:\n```json\n{\n \"questions\": [\n \"Prompt 1 here\",\n \"Prompt 2 here\",\n \"Prompt 3 here\",\n \"Question 4 here\",\n \"Question 5 here\",\n \"Question 6 here\",\n \"Question 7 here\"\n ]\n}\n```\n\n---\nAfter generating the questions, validate that each matches its assigned template, is within the required length, uses natural, varied language, and **remains strictly unbranded**. If any question does not meet guidelines, self-correct and revise before final output.\n\n---\n\n## 💡 Key Principle\nAlways think and phrase questions just like a real person with a specific problem or role would do in an AI chat—purpose-driven, natural, contextual, and strictly unbranded."},{"content": "=INPUT\n\n\"industry\": {{ $json.industry }},\n\"Unbranded category\":{{ $json['Unbranded category'] }} ,\n\"category\": {{ $json.category }},\n\"Persona 0\": {{ $json['Persona 0 - name'] }}\n\"Persona 0 - description\": {{ $json['Persona 0 - description'] }},\n\"Persona 1\": {{ $json['Persona 1 - name '] }}\n\"Persona 1 - description\": {{ $json['Persona 1 - description'] }},\n\"Persona 2\": {{ $json['Persona 2 - name'] }}\n\"Persona 2 - description\": {{ $json['Persona 2 - description'] }},\n\"Problem 1\": {{ $json['Problem 1'] }},\n\"Problem 2\": {{ $json['Problem 2'] }},\n\"Problem 3\": {{ $json['Problem 3'] }},\n\"Problem 4\": {{ $json['Problem 4'] }}\n\"Key_features 0\": {{ $json['Key_features 0'] }}\n\"Key_features 1\": {{ $json['Key_features 1'] }},\n\"Key_features 2\": {{ $json['Key_features 2'] }},\n\"Key_features 3\": {{ $json['Key_features 3'] }},\n\"Key_features 4\": {{ $json['Key_features 4'] }},\n\"value_propostion\": {{ $json.value_propostion }}\n\nOutput rules:\nCRITICAL RULES:\n1. Your output MUST be in JSONL format (one JSON object per line, no array brackets)\n2. Do not add any extra text, explanations, or formatting outside the JSONL output"}]},"simplify": false},"credentials": {"anthropicApi": {"id": "","name": ""}},"typeVersion": 1},{"id": "31fcf20e-f0ba-40e9-95b8-7bd8c422f66e","name": "Code in JavaScript1","type": "n8n-nodes-base.code","position": [1904,64],"parameters": {"jsCode": "// Get the input data\nconst items = $input.all();\n\n// Process each item\nreturn items.map(item => {\n const data = item.json;\n \n // Navigate to the message output content\n const outputs = data.output || [];\n \n // Find the message type output\n const messageOutput = outputs.find(output => output.type === 'message');\n \n if (!messageOutput || !messageOutput.content) {\n return {\n json: {\n error: 'No message content found',\n searchTerms: []\n }\n };\n }\n \n // Get the text content\n const textContent = messageOutput.content.find(c => c.type === 'output_text');\n \n if (!textContent || !textContent.text) {\n return {\n json: {\n error: 'No text content found',\n searchTerms: []\n }\n };\n }\n \n const fullText = textContent.text;\n \n // Extract JSON from the text (look for { and } that contain \"top_search_terms\")\n let jsonText = '';\n let startIdx = fullText.indexOf('{');\n \n if (startIdx === -1) {\n return {\n json: {\n error: 'No JSON object found in text',\n searchTerms: []\n }\n };\n }\n \n // Find the matching closing brace\n let braceCount = 0;\n let endIdx = -1;\n \n for (let i = startIdx; i < fullText.length; i++) {\n if (fullText[i] === '{') braceCount++;\n if (fullText[i] === '}') braceCount--;\n \n if (braceCount === 0) {\n endIdx = i + 1;\n break;\n }\n }\n \n if (endIdx === -1) {\n return {\n json: {\n error: 'Could not find complete JSON object',\n searchTerms: []\n }\n };\n }\n \n jsonText = fullText.substring(startIdx, endIdx);\n \n // Parse the JSON text\n let parsedData;\n try {\n parsedData = JSON.parse(jsonText);\n } catch (e) {\n return {\n json: {\n error: 'Failed to parse JSON content',\n rawJson: jsonText,\n searchTerms: []\n }\n };\n }\n \n // Extract search terms\n const topSearchTerms = parsedData.top_search_terms || [];\n const searchTerms = topSearchTerms.map(termObj => {\n // Get the first key-value pair from each term object\n const key = Object.keys(termObj)[0];\n return termObj[key];\n });\n \n // Return the extracted search terms\n return {\n json: {\n searchTerms: searchTerms,\n allTerms: topSearchTerms\n }\n };\n});"},"typeVersion": 2},{"id": "97648ead-164d-4c5c-82df-cf41e583093b","name": "Code in JavaScript2","type": "n8n-nodes-base.code","position": [1904,-176],"parameters": {"jsCode": "// Get the input data\nconst items = $input.all();\n\n// Process each item\nreturn items.map(item => {\n const data = item.json;\n \n // Get the content array\n const content = data.content || [];\n \n // Find the text content\n const textContent = content.find(c => c.type === 'text');\n \n if (!textContent || !textContent.text) {\n return {\n json: {\n error: 'No text content found',\n phrases: []\n }\n };\n }\n \n // Extract JSONL content (remove ```jsonl and ``` markers)\n let jsonlText = textContent.text;\n jsonlText = jsonlText.replace(/```jsonl?\\n?/g, '').replace(/```\\n?/g, '').trim();\n \n // Split by newlines and parse each line as a separate JSON object\n const lines = jsonlText.split('\\n').filter(line => line.trim() !== '');\n \n const phrases = [];\n \n for (const line of lines) {\n try {\n const parsedLine = JSON.parse(line);\n // Extract the \"phrase\" field from each JSONL object\n if (parsedLine.phrase) {\n phrases.push(parsedLine.phrase);\n }\n } catch (e) {\n // Skip invalid lines\n console.error('Failed to parse line:', line, e);\n }\n }\n \n // Return the extracted phrases\n return {\n json: {\n phrases: phrases,\n model: data.model || null,\n phraseCount: phrases.length\n }\n };\n});"},"typeVersion": 2},{"id": "27ce4ca7-0b80-48b6-b47b-86536da5eb98","name": "Code in JavaScript3","type": "n8n-nodes-base.code","position": [1904,336],"parameters": {"jsCode": "// Get the input data\nconst items = $input.all();\n\n// Process each item\nreturn items.map(item => {\n const data = item.json;\n \n // Get the content array\n const content = data.content || [];\n \n // Find the text content\n const textContent = content.find(c => c.type === 'text');\n \n if (!textContent || !textContent.text) {\n return {\n json: {\n error: 'No text content found',\n prompts: []\n }\n };\n }\n \n // Extract JSON from code block (remove ```json and ```)\n let jsonText = textContent.text;\n jsonText = jsonText.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n \n // Parse the JSON\n let parsedData;\n try {\n parsedData = JSON.parse(jsonText);\n } catch (e) {\n return {\n json: {\n error: 'Failed to parse JSON content',\n rawText: jsonText,\n prompts: []\n }\n };\n }\n \n // Extract questions from the parsed data\n const questions = parsedData.questions || [];\n \n // Return the extracted questions as \"prompts\"\n return {\n json: {\n prompts: questions,\n model: data.model || null,\n promptCount: questions.length\n }\n };\n});"},"typeVersion": 2},{"id": "4b10ccca-a07d-4161-b726-820665a2fe40","name": "Merge","type": "n8n-nodes-base.merge","position": [2256,-48],"parameters": {},"typeVersion": 3.2},{"id": "f1896dc6-1092-4310-a4cc-927d2a1576e6","name": "Merge1","type": "n8n-nodes-base.merge","position": [2752,64],"parameters": {},"typeVersion": 3.2},{"id": "9a266ce0-e7e2-4e0a-bfaa-89fe5f74ed8a","name": "Clean-up","type": "n8n-nodes-base.code","position": [2464,-48],"parameters": {"jsCode": "// Get all items\nconst items = $input.all();\n\n// Collect all prompts from both phrases and searchTerms\nconst allPrompts = [];\n\nitems.forEach(item => {\n // Add phrases if they exist\n if (item.json.phrases) {\n allPrompts.push(...item.json.phrases);\n }\n \n // Add searchTerms if they exist\n if (item.json.searchTerms) {\n allPrompts.push(...item.json.searchTerms);\n }\n});\n\n// Return single item with all prompts\nreturn [{\n json: {\n prompts: allPrompts,\n language: 'english',\n country: 'global'\n }\n}];"},"typeVersion": 2},{"id": "80aebc55-4a05-4212-8614-189d7ecb06b5","name": "English full dataset","type": "n8n-nodes-base.code","position": [2960,64],"parameters": {"jsCode": "// Get all items\nconst items = $input.all();\n\n// Collect all prompts from both prompts and questions\nconst allPrompts = [];\n\nitems.forEach(item => {\n // Add prompts if they exist\n if (item.json.prompts) {\n allPrompts.push(...item.json.prompts);\n }\n \n // Add questions if they exist\n if (item.json.questions) {\n allPrompts.push(...item.json.questions);\n }\n});\n\n// Return single item with all prompts\nreturn [{\n json: {\n prompts: allPrompts,\n language: 'english',\n country: 'global'\n }\n}];"},"typeVersion": 2},{"id": "39e3ac21-f89b-445d-ab37-8545db0bc111","name": "Code in JavaScript4","type": "n8n-nodes-base.code","position": [3664,352],"parameters": {"jsCode": "// Get all items\nconst items = $input.all();\n\n// Extract translated_phrases from the JSON\nconst allPrompts = [];\n\nitems.forEach(item => {\n // Get the text content\n if (item.json.content && item.json.content[0] && item.json.content[0].text) {\n const textContent = item.json.content[0].text;\n \n // Remove markdown code block markers\n const jsonText = textContent.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n \n try {\n // Parse the JSON\n const parsedData = JSON.parse(jsonText);\n \n // Extract translated_phrases array\n if (parsedData.translated_phrases && Array.isArray(parsedData.translated_phrases)) {\n allPrompts.push(...parsedData.translated_phrases);\n }\n } catch (e) {\n console.error('Failed to parse JSON:', e);\n }\n }\n});\n\n// Return one item per prompt with language and country columns\nreturn allPrompts.map(prompt => ({\n json: {\n prompt: prompt,\n language: 'german',\n country: 'DE'\n }\n}));"},"typeVersion": 2},{"id": "95281c7d-6a5f-4e18-9fd4-5dadd9429b6d","name": "Turn into table","type": "n8n-nodes-base.code","position": [3600,-192],"parameters": {"jsCode": "// Get all items\nconst items = $input.all();\n\n// Create one row per prompt\nconst result = [];\n\nitems.forEach(item => {\n if (item.json.prompts && Array.isArray(item.json.prompts)) {\n item.json.prompts.forEach(prompt => {\n result.push({\n json: {\n prompt: prompt,\n language: item.json.language || 'english',\n country: item.json.country || 'global'\n }\n });\n });\n }\n});\n\nreturn result;"},"typeVersion": 2},{"id": "52270483-cd00-4be3-b865-f2589df01d95","name": "Merge2","type": "n8n-nodes-base.merge","position": [4112,96],"parameters": {},"typeVersion": 3.2},{"id": "2e05100e-f85d-4b4f-89a1-5080207508a3","name": "Claude_text_writer-first12","type": "@n8n/n8n-nodes-langchain.anthropic","position": [3344,352],"parameters": {"modelId": {"__rl": true,"mode": "list","value": "claude-sonnet-4-5-20250929","cachedResultName": "claude-sonnet-4-5-20250929"},"options": {"maxTokens": 5000},"messages": {"values": [{"role": "assistant","content": "System Prompt: German Translation Task for Search Terms, Questions, and Prompts\n\nYou will receive a JSON object containing exactly 25 English phrases. These phrases may include search terms, questions, or prompts related to consumer, business, products, research, or decision-making.\n\n## Task\n- Translate all 25 phrases into natural, fluent German while preserving the tone and intent of each phrase.\n\n## Requirements\n- Maintain the original JSON structure and return all 25 phrases in the exact same order as received.\n- Ensure translations sound authentic and realistic for typical German search queries or prompts.\n- Common business English terms that are widely used in German (e.g., \"AI\", \"Performance Marketing\", \"Growth Strategy\", \"Product Roadmap\", \"Benchmarking\") can be left untranslated.\n- Preserve the meaning of each phrase, but adapt the phrasing so it reads naturally for German speakers and search behavior.\n- Do not add, remove, or merge any items in the JSON array.\n- The output must be valid JSON.\n\nAfter translation, validate that all original phrases are represented in the output, the order is preserved, and the output is valid JSON. If an issue is detected, self-correct and revise as needed.\n\n## Output Format\n```json\n{\n \"translated_phrases\": [\n \"...\",\n \"...\",\n \"...\"\n ]\n}\n```"},{"content": "=Prompts that require translation:\n{{ $json.prompts }}"}]},"simplify": false},"credentials": {"anthropicApi": {"id": "","name": ""}},"typeVersion": 1},{"id": "b01c2e95-22ba-40dc-a93d-a4d0bc1dcc1c","name": "Set required fields for upload","type": "n8n-nodes-base.code","position": [4480,32],"parameters": {"jsCode": "// Get all items from the previous node\nconst items = $input.all();\n\n// Add the new columns to each item\nreturn items.map(item => ({\n json: {\n ...item.json,\n model: [\n \"gpt-5-mini-2025-08-07\",\n \"sonar\",\n \"gemini-2.5-flash-lite-search\"\n ],\n search_question: item.json.prompt,\n tracking_interval: \"Weekly\",\n status: \"active\"\n }\n}));"},"typeVersion": 2},{"id": "872bec4d-1a72-4a54-8506-9345216ec9ce","name": "On form submission","type": "n8n-nodes-base.formTrigger","position": [-416,0],"webhookId": "2d953f6f-3d0a-4e6a-ba49-bdaeec1ea40e","parameters": {"options": {},"formTitle": "Input","formFields": {"values": [{"fieldLabel": "Provide a Company Name","placeholder": "ALLMO.ai"},{"fieldLabel": "Provide a Website URL","placeholder": "www.allmo.ai"}]},"formDescription": "Provide a company name and a website"},"typeVersion": 2.3},{"id": "df63ac93-099f-4012-8069-d5f22cfdfd80","name": "Sticky Note","type": "n8n-nodes-base.stickyNote","position": [-528,-256],"parameters": {"color": 7,"width": 480,"height": 448,"content": "## Trigger \n\n***Provide a Company Name and Website URL.***\n\nYou can also connect this to an API, Google Sheets or any other data source.\n\n"},"typeVersion": 1},{"id": "3a1fae28-48aa-4723-b9b9-325d66cc8b5d","name": "Sticky Note1","type": "n8n-nodes-base.stickyNote","position": [0,-256],"parameters": {"color": 7,"width": 944,"height": 448,"content": "## Company Research\n\nThis node researches and extract key dimensions of the business model, especially the marketing customer profile to create a relevant prompt dataset.\n\nAfterwards the data is cleaned and split up so that it can be used for the prompt dataset."},"typeVersion": 1},{"id": "b073217d-8c1f-4a1d-8c59-d0a9defec850","name": "Sticky Note2","type": "n8n-nodes-base.stickyNote","position": [1216,-592],"parameters": {"color": 7,"width": 1904,"height": 1200,"content": "## Prompt Dataset Creation\n\nHere the prompt dataset is created using 3 different dimensions:\n\n***1. Common Questions***: Combination of hard coded questions with company specific information (\"How to\", \"Best provider for ...\")\n***2. AI generate typical keywords using ChatGPT***: The prompt instructs an AI to analyze a company's website, industry, and category to identify exactly 5 relevant non-branded search terms (excluding any company name references), validating inputs and outputting results in a specified JSON format.\n***3. AI generate typical prompts using Claude***: The prompt instructs an AI agent to generate 7 natural, unbranded search questions that simulate how real people would query AI chatbots, by combining elements (personas, problems, features, value propositions, categories) from a provided company JSON input according to specific templates.\n\nUse Claude and ChatGPT to get a good variation of results. \n\nSimply update the system prompts, if you want more phrases."},"typeVersion": 1},{"id": "9550ce84-93f4-4218-9e2f-ce8e65b82611","name": "Sticky Note3","type": "n8n-nodes-base.stickyNote","position": [3264,128],"parameters": {"color": 7,"width": 672,"height": 480,"content": "## Optional: Translation into any language.\n\nTranslate the dataset into any other language, if you want to review performance by language. \nPreset: German\n\nRemove this path to continue without translation. "},"typeVersion": 1},{"id": "e36d0d88-c87d-4bea-87e1-8e226b68429a","name": "Sticky Note4","type": "n8n-nodes-base.stickyNote","position": [4400,-192],"parameters": {"color": 7,"width": 832,"height": 480,"content": "## Optional: Configure for upload \n\nAdd information like \"model\" or any information to the table so that you can directly upload it into an AI Search Visibility tool (like allmo.ai) of your choice."},"typeVersion": 1},{"id": "fcfd5903-b6b1-4553-84f9-7dee0b2b5b6f","name": "Convert to File","type": "n8n-nodes-base.convertToFile","position": [4736,32],"parameters": {"options": {}},"typeVersion": 1.1},{"id": "e55a19dd-2ef9-47e3-b9c6-018f97b55c78","name": "Sticky Note5","type": "n8n-nodes-base.stickyNote","position": [-1680,-528],"parameters": {"width": 960,"height": 960,"content": "## **Create Prompt Dataset to Monitor Visibility for GEO/ALLMO**\n\n### **General Summary**\nThis n8n workflow automatically generates a comprehensive dataset of 50 AI search prompts (25 English + 25 German) tailored to a specific company. It combines AI-powered company research with structured prompt generation to create prompt monitoring datasets for tracking AI visiblity. \n\n**Who's it for & Use Cases**\nSEO/GEO Marketing teams, Growth Managers, GTM engineers and Founders who want to:\n- Create custom prompt datasets for visibility tracking platforms like ALLMO.ai\n- Generate industry-specific search queries for AI model monitoring\n\n---\n\n### **How It Works**\n\n**Phase 1: Company Research**\n\n1. Start the workflow via the form and input your company name and website URL\n2. GPT-5 Mini with web search collects company information, including buyer personas, key features, and value proposition\n\n**Phase 2: Prompt Generation**\n\n3. Claude Sonnet 4.5 generates and refines natural language prompts based on Phase 1 findings \n4. English prompts are automatically translated into German\n\n**Phase 3: Export & Implementation**\n\n5. Wait for processing (~total of 2-5 minutes depending on website complexity) \n6. English and German prompt sets are merged with metadata and structured into table format \n7. Download the CSV file containing 50 prompts ready for import into AI Search monitoring systems (allmo.ai, etc.)\n\n### **How to Setup**\n- Just enter your API credentials in the Claude and ChatGPT Nodes.\n\n### **Requirements**\n**API Credentials:**\n- Anthropic API \n- OpenAI API\n\n**Data Input:**\n- Valid company website URL (publicly accessible)\n- Your company name"},"typeVersion": 1}],"active": false,"pinData": {},"settings": {"executionOrder": "v1"},"versionId": "","connections": {"Merge": {"main": [[{"node": "Clean-up","type": "main","index": 0}]]},"Merge1": {"main": [[{"node": "English full dataset","type": "main","index": 0}]]},"Merge2": {"main": [[{"node": "Set required fields for upload","type": "main","index": 0}]]},"Clean-up": {"main": [[{"node": "Merge1","type": "main","index": 0}]]},"Edit Fields": {"main": [[{"node": "GPT_company_research","type": "main","index": 0}]]},"Edit Fields2": {"main": [[{"node": "Hard coded phrase - returns 13","type": "main","index": 0},{"node": "GPT_keywords_return 5","type": "main","index": 0},{"node": "Claude_text_writer_return7","type": "main","index": 0}]]},"Turn into table": {"main": [[{"node": "Merge2","type": "main","index": 0}]]},"Remove citations": {"main": [[{"node": "Edit Fields2","type": "main","index": 0}]]},"Claude_text_writer": {"main": [[{"node": "Code in JavaScript2","type": "main","index": 0}]]},"Code in JavaScript": {"main": [[{"node": "Remove citations","type": "main","index": 0}]]},"On form submission": {"main": [[{"node": "Edit Fields","type": "main","index": 0}]]},"Code in JavaScript1": {"main": [[{"node": "Merge","type": "main","index": 1}]]},"Code in JavaScript2": {"main": [[{"node": "Merge","type": "main","index": 0}]]},"Code in JavaScript3": {"main": [[{"node": "Merge1","type": "main","index": 1}]]},"Code in JavaScript4": {"main": [[{"node": "Merge2","type": "main","index": 1}]]},"English full dataset": {"main": [[{"node": "Turn into table","type": "main","index": 0},{"node": "Claude_text_writer-first12","type": "main","index": 0}]]},"GPT_company_research": {"main": [[{"node": "Code in JavaScript","type": "main","index": 0}]]},"GPT_keywords_return 5": {"main": [[{"node": "Code in JavaScript1","type": "main","index": 0}]]},"Claude_text_writer-first12": {"main": [[{"node": "Code in JavaScript4","type": "main","index": 0}]]},"Claude_text_writer_return7": {"main": [[{"node": "Code in JavaScript3","type": "main","index": 0}]]},"Hard coded phrase - returns 13": {"main": [[{"node": "Claude_text_writer","type": "main","index": 0}]]},"Set required fields for upload": {"main": [[{"node": "Convert to File","type": "main","index": 0}]]}}}
В редакторі n8n: вставте через Ctrl+V→Workflow буде створено