From 33bcda782a24d228a85861e76e26410f3e545e26 Mon Sep 17 00:00:00 2001 From: nusquama Date: Sun, 15 Mar 2026 12:01:51 +0800 Subject: [PATCH] creation --- ...s_and_generate_market_insights_with_claude_ai_and_notion.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 workflows/Monitor competitors and generate market insights with Claude AI and Notion-13983/monitor_competitors_and_generate_market_insights_with_claude_ai_and_notion.json diff --git a/workflows/Monitor competitors and generate market insights with Claude AI and Notion-13983/monitor_competitors_and_generate_market_insights_with_claude_ai_and_notion.json b/workflows/Monitor competitors and generate market insights with Claude AI and Notion-13983/monitor_competitors_and_generate_market_insights_with_claude_ai_and_notion.json new file mode 100644 index 000000000..d4897a719 --- /dev/null +++ b/workflows/Monitor competitors and generate market insights with Claude AI and Notion-13983/monitor_competitors_and_generate_market_insights_with_claude_ai_and_notion.json @@ -0,0 +1 @@ +{"meta":{"instanceId":"0fd24758e45cbed1f63c03b9ca7326acab4b855985945af441ee95f8874d3e22","templateCredsSetupCompleted":true},"nodes":[{"id":"2aebbaa2-d3fd-4131-8fd5-7448f3d76394","name":"Weekly competitor scan","type":"n8n-nodes-base.scheduleTrigger","position":[176,112],"webhookId":"","parameters":{"rule":{"interval":[{"field":"weeks","triggerAtDay":1,"triggerAtHour":9}]}},"typeVersion":1},{"id":"4cc44160-626a-4202-be39-bd55238e40eb","name":"Set competitor URLs","type":"n8n-nodes-base.set","position":[432,112],"parameters":{"options":{}},"typeVersion":3},{"id":"de0074a5-b0f2-40e9-a3c6-32a0bc7d1208","name":"Initialize loop counter","type":"n8n-nodes-base.set","position":[672,112],"parameters":{"options":{}},"typeVersion":3},{"id":"6dec60a9-b0c9-40af-982a-9d45c495077f","name":"Fetch competitor content","type":"n8n-nodes-base.httpRequest","position":[912,112],"parameters":{"url":"={{ $json.competitor_urls[$json.current_index] }}","options":{"timeout":10000}},"typeVersion":4},{"id":"a854f812-83ca-4545-9836-1299b2601ca5","name":"Extract and hash content","type":"n8n-nodes-base.code","position":[1152,112],"parameters":{"jsCode":"// Parse HTML and extract key content\nconst cheerio = require('cheerio');\nconst crypto = require('crypto');\n\nconst html = $input.first()?.body || '';\nconst $ = cheerio.load(html);\n\n// Extract main content areas\nconst title = $('title').text().trim();\nconst h1 = $('h1').map((i, el) => $(el).text().trim()).get().join(' | ');\nconst pricing = $('*:contains(\"$\"), *:contains(\"price\"), *:contains(\"plan\")').map((i, el) => $(el).text().trim()).get().slice(0, 5);\nconst features = $('*:contains(\"feature\"), *:contains(\"benefit\")').map((i, el) => $(el).text().trim()).get().slice(0, 10);\n\n// Create content hash for change detection\nconst contentString = [title, h1, ...pricing, ...features].join('');\nconst contentHash = crypto.createHash('md5').update(contentString).digest('hex');\n\n// Get URL and competitor name\nconst url = $('$node[\"Fetch competitor content\"].json.url');\nconst competitorName = $('$node[\"Set competitor URLs\"].json.competitor_names[$node[\"Set competitor URLs\"].json.current_index]');\n\nreturn {\n url: url,\n competitor_name: competitorName,\n title: title,\n headings: h1,\n pricing_mentions: pricing,\n feature_mentions: features,\n content_hash: contentHash,\n extracted_at: new Date().toISOString(),\n raw_html: html.substring(0, 5000) // Truncate for storage\n};"},"typeVersion":2},{"id":"425aa47a-76fe-4b88-8f6b-3c1f59a3b404","name":"Detect content changes","type":"n8n-nodes-base.code","position":[1392,112],"parameters":{"jsCode":"// Compare with previous content hash from Notion\n// This is a simplified version - in practice, you'd query Notion first\n\nconst currentData = $input.first();\nconst currentHash = currentData.content_hash;\n\n// Simulate previous hash lookup (replace with actual Notion query)\nconst simulatedPreviousHash = 'abc123def456'; // This would come from Notion\n\nconst hasChanges = currentHash !== simulatedPreviousHash;\n\nreturn {\n ...currentData,\n has_changes: hasChanges,\n previous_hash: simulatedPreviousHash,\n change_detected_at: hasChanges ? new Date().toISOString() : null\n};"},"typeVersion":2},{"id":"97f22337-cd93-43c5-8e57-43c4f6339ca4","name":"Changes detected?","type":"n8n-nodes-base.if","position":[1632,112],"parameters":{"options":{},"conditions":{"boolean":[{"value1":"={{ $json.has_changes }}","operation":"true"}]}},"typeVersion":2},{"id":"cb9feedc-c845-4d40-85cd-94a259e745b3","name":"Analyze competitor changes","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[1872,112],"parameters":{"text":"You are a competitive intelligence analyst. Analyze the following competitor website changes and provide strategic insights.\n\nCompetitor: {{ $json.competitor_name }}\nURL: {{ $json.url }}\nPage Title: {{ $json.title }}\nMain Headings: {{ $json.headings }}\nPricing Information: {{ $json.pricing_mentions }}\nFeature Mentions: {{ $json.feature_mentions }}\n\nPrevious content hash: {{ $json.previous_hash }}\nCurrent content hash: {{ $json.content_hash }}\n\nAnalyze and provide:\n1. What likely changed (pricing, features, messaging)\n2. Strategic implications for our business\n3. Recommended actions\n4. Market trend insights\n5. Competitive threats or opportunities\n\nProvide your analysis in structured JSON format with clear, actionable insights.","promptType":"define"},"typeVersion":1.4},{"id":"f710d391-8cf8-4652-99fe-05959a7f05f0","name":"Claude AI model","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[1872,304],"parameters":{"model":"claude-3-5-sonnet-20241022","options":{}},"typeVersion":1},{"id":"3059bbe9-f43a-4107-b4b4-b3cabe489013","name":"Save to Notion database","type":"n8n-nodes-base.notion","position":[2256,112],"parameters":{"title":"{{ $json.competitor_name }} - {{ $now.format('YYYY-MM-DD') }}","options":{},"resource":"databasePage","databaseId":"{{ $vars.NOTION_COMPETITOR_DB_ID }}","propertiesUi":{"propertyValues":[{"key":"Competitor"},{"key":"URL","urlValue":"={{ $json.url }}"},{"key":"Content Hash"},{"key":"AI Analysis"},{"key":"Scan Date"}]}},"typeVersion":2},{"id":"5bd0a9ff-7a4b-4066-aa92-1ea25207a5fb","name":"Evaluate notification priority","type":"n8n-nodes-base.code","position":[2448,112],"parameters":{"jsCode":"// Determine if this change warrants immediate Slack notification\nconst analysis = $node['Analyze competitor changes'].json.response;\nconst competitor = $json.competitor_name;\nconst url = $json.url;\n\n// Define trigger keywords for urgent notifications\nconst urgentKeywords = ['price', 'pricing', 'launch', 'feature', 'acquisition', 'funding', 'partnership'];\nconst analysisText = analysis.toLowerCase();\n\nconst isUrgent = urgentKeywords.some(keyword => analysisText.includes(keyword));\n\nif (isUrgent) {\n return {\n should_notify: true,\n slack_message: `🚨 *Important competitor update detected*\\n\\n**Competitor:** ${competitor}\\n**URL:** ${url}\\n**Summary:** ${analysis}\\n\\n_Automated scan at ${new Date().toLocaleString()}_`,\n analysis: analysis,\n competitor: competitor\n };\n} else {\n return {\n should_notify: false,\n reason: 'Minor changes detected, not urgent'\n };\n}"},"typeVersion":2},{"id":"c2068370-b6ce-46aa-ab45-c4213f2b7c22","name":"Send urgent notification?","type":"n8n-nodes-base.if","position":[2640,112],"parameters":{"options":{},"conditions":{"boolean":[{"value1":"={{ $json.should_notify }}","operation":"true"}]}},"typeVersion":2},{"id":"33c5ac89-8747-44ca-b6e5-deb1ccadf7ed","name":"Send Slack alert","type":"n8n-nodes-base.slack","position":[2832,112],"webhookId":"cec55b31-8a58-453b-bc40-88056c21140c","parameters":{"text":"={{ $json.slack_message }}","otherOptions":{}},"typeVersion":2},{"id":"1bf9cdcb-0996-4df2-a52d-ec8ef987b5e8","name":"Generate weekly report","type":"n8n-nodes-base.code","position":[1648,576],"parameters":{"jsCode":"// Generate weekly summary report from all competitor data\n// This simplified version creates a basic report structure\n\nconst allData = $input.all();\nconst competitors = [...new Set(allData.map(item => item.competitor_name))].filter(Boolean);\nconst totalChanges = allData.filter(item => item.has_changes).length;\nconst scanDate = new Date().toLocaleDateString();\n\nconst summaryReport = {\n report_title: `Weekly Competitive Intelligence Report - ${scanDate}`,\n summary: {\n competitors_monitored: competitors.length,\n changes_detected: totalChanges,\n scan_date: scanDate\n },\n competitor_details: competitors.map(comp => {\n const compData = allData.filter(item => item.competitor_name === comp);\n const hasChanges = compData.some(item => item.has_changes);\n return {\n name: comp,\n urls_scanned: compData.length,\n changes_detected: hasChanges,\n last_analysis: compData[0]?.extracted_at || 'N/A'\n };\n }),\n recommendations: [\n 'Continue monitoring pricing page changes',\n 'Focus on feature announcement tracking',\n 'Consider expanding monitoring to include blog posts'\n ]\n};\n\n// Convert to email-friendly format\nconst emailBody = `\n# ${summaryReport.report_title}\n\n## Summary\n- Competitors monitored: ${summaryReport.summary.competitors_monitored}\n- Changes detected this week: ${summaryReport.summary.changes_detected}\n- Scan date: ${summaryReport.summary.scan_date}\n\n## Competitor Activity\n${summaryReport.competitor_details.map(comp => \n `**${comp.name}**: ${comp.changes_detected ? '⚠️ Changes detected' : '✅ No significant changes'} (${comp.urls_scanned} pages scanned)`\n).join('\\n')}\n\n## Recommendations\n${summaryReport.recommendations.map(rec => `- ${rec}`).join('\\n')}\n\n---\n*This report was generated automatically by your competitive intelligence workflow.*\n`;\n\nreturn {\n email_subject: `Weekly Competitive Intelligence Report - ${scanDate}`,\n email_body: emailBody,\n report_data: summaryReport\n};"},"typeVersion":2},{"id":"26d9a3a2-c0f3-480f-b164-7f0b7a91d643","name":"Email weekly report","type":"n8n-nodes-base.gmail","position":[1920,576],"webhookId":"c647c167-53bc-4835-900f-10bf25c9df8b","parameters":{"sendTo":"{{ $vars.TEAM_EMAIL_LIST }}","message":"={{ $json.email_body }}","options":{},"subject":"={{ $json.email_subject }}","emailType":"text"},"typeVersion":2},{"id":"be6be3ce-f037-46cc-96ae-a96ab8f97261","name":"Main workflow overview","type":"n8n-nodes-base.stickyNote","position":[-352,32],"parameters":{"width":468,"height":692,"content":"# Research competitors and generate market insights\n\n### How it works\nThis workflow automatically monitors competitor websites weekly, detects content changes using hash comparison, analyzes updates with Claude AI, and stores insights in Notion. Important changes trigger immediate Slack notifications, while comprehensive weekly reports are emailed to your team.\n\n### Setup steps\n1. **Configure competitor URLs** in the Set node - add websites, pricing pages, and feature pages to monitor\n2. **Set up credentials**: Anthropic Claude API, Notion API, Slack API, Gmail OAuth2\n3. **Create Notion database** with properties: Competitor (text), URL (url), Content Hash (text), AI Analysis (text), Scan Date (date)\n4. **Set environment variables**: `NOTION_COMPETITOR_DB_ID`, `SLACK_ALERTS_CHANNEL`, `TEAM_EMAIL_LIST`\n5. **Test the workflow** with manual execution before activating the weekly schedule\n\n### Customization\n- Adjust the schedule trigger for different monitoring frequencies\n- Modify urgent keywords in the priority evaluation node\n- Customize the Claude AI prompt for specific analysis focus areas\n- Add more competitor URLs or change notification thresholds"},"typeVersion":1},{"id":"f2ca6b60-4aa8-4911-b327-35b94aa723c3","name":"Collection section","type":"n8n-nodes-base.stickyNote","position":[128,32],"parameters":{"color":7,"width":1396,"height":264,"content":"## Data collection\nScheduled scraping of competitor websites with change detection"},"typeVersion":1},{"id":"ca702376-932f-40b8-9a9a-4341b536a81b","name":"Analysis section","type":"n8n-nodes-base.stickyNote","position":[1536,32],"parameters":{"color":7,"width":600,"height":404,"content":"## Analysis & storage\nClaude AI analyzes changes and results are saved to Notion database"},"typeVersion":1},{"id":"2804c7de-e990-4ea1-b50f-6a1363dfd51c","name":"Notifications section","type":"n8n-nodes-base.stickyNote","position":[2160,32],"parameters":{"color":7,"width":868,"height":360,"content":"## Notifications\nImportant changes trigger immediate Slack alerts with AI insights"},"typeVersion":1},{"id":"d08a34de-871a-469d-9e13-2f305d355b7e","name":"Reporting section","type":"n8n-nodes-base.stickyNote","position":[1536,448],"parameters":{"color":7,"width":592,"height":280,"content":"## Reporting\nWeekly summary emails with competitive intelligence insights"},"typeVersion":1}],"pinData":{},"connections":{"Claude AI model":{"ai_languageModel":[[{"node":"Analyze competitor changes","type":"ai_languageModel","index":0}]]},"Changes detected?":{"main":[[{"node":"Analyze competitor changes","type":"main","index":0}]]},"Set competitor URLs":{"main":[[{"node":"Initialize loop counter","type":"main","index":0}]]},"Detect content changes":{"main":[[{"node":"Changes detected?","type":"main","index":0},{"node":"Generate weekly report","type":"main","index":0}]]},"Generate weekly report":{"main":[[{"node":"Email weekly report","type":"main","index":0}]]},"Weekly competitor scan":{"main":[[{"node":"Set competitor URLs","type":"main","index":0}]]},"Initialize loop counter":{"main":[[{"node":"Fetch competitor content","type":"main","index":0}]]},"Save to Notion database":{"main":[[{"node":"Evaluate notification priority","type":"main","index":0}]]},"Extract and hash content":{"main":[[{"node":"Detect content changes","type":"main","index":0}]]},"Fetch competitor content":{"main":[[{"node":"Extract and hash content","type":"main","index":0}]]},"Send urgent notification?":{"main":[[{"node":"Send Slack alert","type":"main","index":0}]]},"Analyze competitor changes":{"main":[[{"node":"Save to Notion database","type":"main","index":0}]]},"Evaluate notification priority":{"main":[[{"node":"Send urgent notification?","type":"main","index":0}]]}}} \ No newline at end of file