{
  "id": "NgPUu4IA2QDZRRVT",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Smart Viral Content Opportunity Spotter",
  "tags": [],
  "nodes": [
    {
      "id": "3a3acceb-dd95-47a3-a71a-b6560d364690",
      "name": "Every 2 Hours - Trend Scanner",
      "type": "n8n-nodes-base.scheduleTrigger",
      "notes": "Runs every 2 hours to capture fresh trending topics",
      "position": [
        800,
        512
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 2
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 1.2
    },
    {
      "id": "3a1f497e-7af6-4876-812a-11ca06a4f56e",
      "name": "Fetch Twitter/X Trends",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Gets trending topics and hashtags from Twitter API",
      "position": [
        1024,
        320
      ],
      "parameters": {
        "url": "https://api.twitter.com/2/trends/place",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "id",
              "value": "1"
            }
          ]
        },
        "nodeCredentialType": "twitterOAuth2Api"
      },
      "credentials": {
        "twitterOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "typeVersion": 4.2
    },
    {
      "id": "03636a38-7087-4f03-a381-603343601e9c",
      "name": "Fetch Reddit Hot Topics",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Retrieves trending posts from relevant subreddits",
      "position": [
        1024,
        512
      ],
      "parameters": {
        "url": "https://oauth.reddit.com/r/{{$node[\"Load Niche Config\"].json.subreddits}}/hot",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "limit",
              "value": "25"
            },
            {
              "name": "t",
              "value": "day"
            }
          ]
        },
        "nodeCredentialType": "redditOAuth2Api"
      },
      "credentials": {
        "redditOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "typeVersion": 4.2
    },
    {
      "id": "65318f86-fefb-4d1f-92e2-1cfda5e1947d",
      "name": "Fetch Google Trends",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Gets trending searches from Google Trends API",
      "position": [
        1024,
        704
      ],
      "parameters": {
        "url": "https://trends.google.com/trends/api/dailytrends",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "geo",
              "value": "US"
            },
            {
              "name": "hl",
              "value": "en-US"
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 4.2
    },
    {
      "id": "79d27f62-ed94-4a9d-a2eb-f441f328a7f1",
      "name": "Load Niche Config",
      "type": "n8n-nodes-base.code",
      "notes": "Defines your niche keywords, subreddits, and tracking parameters",
      "position": [
        4832,
        416
      ],
      "parameters": {
        "jsCode": "// Configure your niche settings here\nconst nicheConfig = {\n  // Your niche/industry\n  niche: 'AI & Technology',\n  \n  // Primary keywords to track\n  keywords: [\n    'artificial intelligence',\n    'machine learning',\n    'AI tools',\n    'chatgpt',\n    'claude',\n    'automation',\n    'generative ai',\n    'deep learning',\n    'neural networks',\n    'ai ethics'\n  ],\n  \n  // Related subreddits (comma-separated for multi-reddit)\n  subreddits: 'artificial+machinelearning+technology+Futurology',\n  \n  // Twitter accounts to monitor (optional)\n  twitterAccounts: [\n    'OpenAI',\n    'AnthropicAI',\n    'GoogleAI',\n    'DeepMind'\n  ],\n  \n  // Minimum engagement thresholds\n  thresholds: {\n    minTwitterLikes: 1000,\n    minRedditUpvotes: 500,\n    minComments: 50\n  },\n  \n  // Content formats to suggest\n  contentFormats: [\n    'Thread',\n    'Carousel Post',\n    'Video Script',\n    'Long-form Article',\n    'Infographic Outline',\n    'Short-form Video'\n  ],\n  \n  // Target platforms\n  platforms: ['Twitter', 'LinkedIn', 'Instagram', 'TikTok', 'YouTube'],\n  \n  // Time window (hours)\n  timeWindow: 48\n};\n\nreturn [{ json: nicheConfig }];"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "8528d5bc-b800-466a-980b-70d59c518c49",
      "name": "Parse Twitter Data",
      "type": "n8n-nodes-base.code",
      "notes": "Normalizes Twitter trend data into standard format",
      "position": [
        1248,
        320
      ],
      "parameters": {
        "jsCode": "// Parse Twitter API response\nconst response = $input.first().json;\nconst trends = response.data || [];\n\nconst parsed = trends.map(trend => ({\n  source: 'Twitter',\n  topic: trend.name || trend.query || '',\n  description: trend.tweet_volume ? `${trend.tweet_volume} tweets` : 'Trending',\n  url: trend.url || `https://twitter.com/search?q=${encodeURIComponent(trend.name)}`,\n  engagement: trend.tweet_volume || 0,\n  timestamp: new Date().toISOString(),\n  raw: trend\n}));\n\nreturn parsed.map(item => ({ json: item }));"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "30cce528-0118-4a0b-8f78-806562d4b88e",
      "name": "Parse Reddit Data",
      "type": "n8n-nodes-base.code",
      "notes": "Normalizes Reddit post data into standard format",
      "position": [
        1248,
        512
      ],
      "parameters": {
        "jsCode": "// Parse Reddit API response\nconst response = $input.first().json;\nconst posts = response.data?.children || [];\n\nconst parsed = posts.map(post => {\n  const data = post.data;\n  return {\n    source: 'Reddit',\n    topic: data.title,\n    description: data.selftext?.substring(0, 200) || '',\n    url: `https://reddit.com${data.permalink}`,\n    engagement: data.ups + data.num_comments,\n    upvotes: data.ups,\n    comments: data.num_comments,\n    subreddit: data.subreddit,\n    timestamp: new Date(data.created_utc * 1000).toISOString(),\n    raw: data\n  };\n});\n\nreturn parsed.map(item => ({ json: item }));"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "f8fe24fa-9e91-4bd4-9d4d-a048f43d7fb7",
      "name": "Parse Google Trends",
      "type": "n8n-nodes-base.code",
      "notes": "Normalizes Google Trends data into standard format",
      "position": [
        1248,
        704
      ],
      "parameters": {
        "jsCode": "// Parse Google Trends response (remove leading characters)\nlet response = $input.first().json.toString();\nif (response.startsWith(')]}\\',\\n')) {\n  response = response.substring(6);\n}\n\ntry {\n  const data = JSON.parse(response);\n  const trends = data.default?.trendingSearchesDays?.[0]?.trendingSearches || [];\n  \n  const parsed = trends.map(trend => {\n    const articles = trend.articles || [];\n    const totalTraffic = parseInt(trend.formattedTraffic?.replace(/[^0-9]/g, '') || '0');\n    \n    return {\n      source: 'Google Trends',\n      topic: trend.title?.query || '',\n      description: articles[0]?.title || '',\n      url: articles[0]?.url || `https://trends.google.com/trends/trendingsearches/daily?geo=US`,\n      engagement: totalTraffic,\n      traffic: trend.formattedTraffic || 'N/A',\n      timestamp: new Date().toISOString(),\n      raw: trend\n    };\n  });\n  \n  return parsed.map(item => ({ json: item }));\n  \n} catch (error) {\n  console.error('Failed to parse Google Trends:', error);\n  return [];\n}"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "f0f79024-acfe-47d5-89d1-73355a2db52f",
      "name": "Merge All Trend Sources",
      "type": "n8n-nodes-base.merge",
      "notes": "Combines data from Twitter, Reddit, and Google Trends",
      "position": [
        1472,
        416
      ],
      "parameters": {},
      "notesInFlow": true,
      "typeVersion": 3
    },
    {
      "id": "2a9d4fa8-704b-4176-a44f-d98a3d20a135",
      "name": "Filter by Niche Keywords",
      "type": "n8n-nodes-base.code",
      "notes": "Matches trends against your niche keywords for relevance",
      "position": [
        1696,
        416
      ],
      "parameters": {
        "jsCode": "// Filter trends by niche relevance\nconst items = $input.all();\nconst config = $node['Load Niche Config'].json;\nconst keywords = config.keywords.map(k => k.toLowerCase());\n\nconst relevantTrends = items.filter(item => {\n  const text = `${item.json.topic} ${item.json.description}`.toLowerCase();\n  \n  // Check if any keyword matches\n  return keywords.some(keyword => text.includes(keyword));\n}).map(item => ({\n  json: {\n    ...item.json,\n    relevanceScore: 0 // Will be calculated in next node\n  }\n}));\n\nreturn relevantTrends;"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "aefdb520-4fe3-44f2-9272-d65b6703dcd6",
      "name": "Remove Duplicate Topics",
      "type": "n8n-nodes-base.code",
      "notes": "Deduplicates similar trends from different sources",
      "position": [
        1920,
        416
      ],
      "parameters": {
        "jsCode": "// Remove duplicate or very similar topics\nconst items = $input.all();\nconst seen = new Map();\n\nfunction similarity(str1, str2) {\n  const s1 = str1.toLowerCase().split(' ');\n  const s2 = str2.toLowerCase().split(' ');\n  const intersection = s1.filter(word => s2.includes(word));\n  return intersection.length / Math.max(s1.length, s2.length);\n}\n\nconst unique = [];\n\nfor (const item of items) {\n  const topic = item.json.topic;\n  let isDuplicate = false;\n  \n  for (const [seenTopic, seenItem] of seen.entries()) {\n    if (similarity(topic, seenTopic) > 0.7) {\n      // Keep the one with higher engagement\n      if (item.json.engagement > seenItem.json.engagement) {\n        seen.delete(seenTopic);\n        seen.set(topic, item);\n      }\n      isDuplicate = true;\n      break;\n    }\n  }\n  \n  if (!isDuplicate) {\n    seen.set(topic, item);\n  }\n}\n\nreturn Array.from(seen.values()).map(item => ({ json: item.json }));"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "3f532e9e-b713-4f5c-a97c-4f92d6e7a92e",
      "name": "Calculate Viral Potential Score",
      "type": "n8n-nodes-base.code",
      "notes": "Scores each trend based on engagement, recency, and growth",
      "position": [
        2144,
        416
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Calculate viral potential score (0-100)\nconst trend = $input.item.json;\nconst config = $node['Load Niche Config'].json;\n\nlet score = 0;\n\n// Engagement score (0-40 points)\nlet engagementScore = 0;\nif (trend.source === 'Twitter') {\n  engagementScore = Math.min(40, (trend.engagement / 10000) * 40);\n} else if (trend.source === 'Reddit') {\n  engagementScore = Math.min(40, (trend.engagement / 1000) * 40);\n} else if (trend.source === 'Google Trends') {\n  engagementScore = Math.min(40, (trend.engagement / 100000) * 40);\n}\nscore += engagementScore;\n\n// Recency score (0-30 points)\nconst hoursSincePost = (Date.now() - new Date(trend.timestamp).getTime()) / (1000 * 60 * 60);\nconst recencyScore = Math.max(0, 30 - (hoursSincePost / config.timeWindow) * 30);\nscore += recencyScore;\n\n// Source credibility (0-15 points)\nconst sourceScore = {\n  'Google Trends': 15,\n  'Twitter': 12,\n  'Reddit': 10\n}[trend.source] || 5;\nscore += sourceScore;\n\n// Keyword relevance (0-15 points)\nconst text = `${trend.topic} ${trend.description}`.toLowerCase();\nconst matchCount = config.keywords.filter(k => text.includes(k.toLowerCase())).length;\nconst relevanceScore = Math.min(15, matchCount * 5);\nscore += relevanceScore;\n\n// Determine opportunity level\nlet opportunityLevel = 'LOW';\nif (score >= 75) opportunityLevel = 'HIGH';\nelse if (score >= 50) opportunityLevel = 'MEDIUM';\n\nreturn {\n  json: {\n    ...trend,\n    viralScore: Math.round(score),\n    opportunityLevel,\n    scoreBreakdown: {\n      engagement: Math.round(engagementScore),\n      recency: Math.round(recencyScore),\n      source: sourceScore,\n      relevance: Math.round(relevanceScore)\n    }\n  }\n};"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "5fc00882-9c04-42f9-b3d9-6fd1e1a2fd01",
      "name": "Filter High Potential Only",
      "type": "n8n-nodes-base.filter",
      "notes": "Only keeps trends with viral score above 40",
      "position": [
        2368,
        416
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "score-threshold",
              "operator": {
                "type": "number",
                "operation": "largerEqual"
              },
              "leftValue": "={{ $json.viralScore }}",
              "rightValue": 40
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "7e266831-96a7-48d0-b556-068b479f278b",
      "name": "Sort by Viral Score",
      "type": "n8n-nodes-base.code",
      "notes": "Ranks opportunities by score (highest first)",
      "position": [
        2592,
        416
      ],
      "parameters": {
        "jsCode": "// Sort trends by viral score descending\nconst items = $input.all();\nconst sorted = items.sort((a, b) => b.json.viralScore - a.json.viralScore);\n\n// Take top 10\nreturn sorted.slice(0, 10);"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "2a029ebb-ba06-45c9-8c55-4b14e9257217",
      "name": "Check Already Covered",
      "type": "n8n-nodes-base.code",
      "notes": "Prevents suggesting topics you've already created content about",
      "position": [
        2816,
        416
      ],
      "parameters": {
        "jsCode": "// Check against previously covered topics\nconst items = $input.all();\nconst staticData = $getWorkflowStaticData('global');\n\n// Initialize covered topics tracker\nif (!staticData.coveredTopics) {\n  staticData.coveredTopics = {};\n}\n\n// Clean up old entries (older than 30 days)\nconst thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000);\nfor (const key in staticData.coveredTopics) {\n  if (staticData.coveredTopics[key].timestamp < thirtyDaysAgo) {\n    delete staticData.coveredTopics[key];\n  }\n}\n\n// Filter out already covered topics\nconst newOpportunities = items.filter(item => {\n  const topicKey = item.json.topic.toLowerCase().replace(/[^a-z0-9]/g, '');\n  return !staticData.coveredTopics[topicKey];\n}).map(item => ({\n  json: {\n    ...item.json,\n    isNew: true\n  }\n}));\n\nreturn newOpportunities;"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "935c1484-dd12-4015-bad5-5896deeee4ad",
      "name": "AI - Generate Content Ideas",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Uses Claude AI to generate creative content ideas for each trend",
      "position": [
        3040,
        416
      ],
      "parameters": {
        "url": "https://api.anthropic.com/v1/messages",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "model",
              "value": "claude-sonnet-4-20250514"
            },
            {
              "name": "max_tokens",
              "value": "2000"
            },
            {
              "name": "messages",
              "value": "={{ [{role: 'user', content: `You are a viral content strategist. Analyze this trending topic and generate 5 unique, high-engagement content ideas.\n\nTrending Topic: ${$json.topic}\nSource: ${$json.source}\nEngagement: ${$json.engagement}\nContext: ${$json.description}\nNiche: ${$node['Load Niche Config'].json.niche}\n\nFor each idea, provide:\n1. Content Format (Thread, Carousel, Video, Article, etc.)\n2. Hook/Title (attention-grabbing)\n3. Key Points (3-5 bullet points)\n4. Platform Recommendation\n5. Viral Potential Reason\n\nMake ideas actionable, specific, and optimized for virality. Return as JSON array with keys: format, hook, keyPoints (array), platform, viralReason.`}] }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "={{ $credentials.apiKey }}"
            },
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            }
          ]
        },
        "nodeCredentialType": "anthropicApi"
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "typeVersion": 4.2
    },
    {
      "id": "347f0ef9-3842-4cac-b493-42145afdc67b",
      "name": "Parse AI Content Ideas",
      "type": "n8n-nodes-base.code",
      "notes": "Extracts and structures AI-generated content ideas",
      "position": [
        3264,
        416
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Parse Claude AI response\nconst response = $input.item.json;\nconst trend = $node['Check Already Covered'].all().find(i => i.json.topic === $json.topic).json;\n\ntry {\n  const aiContent = response.content?.[0]?.text || '';\n  \n  // Try to extract JSON from response\n  let ideas = [];\n  const jsonMatch = aiContent.match(/\\[\\s*\\{[\\s\\S]*\\}\\s*\\]/);\n  \n  if (jsonMatch) {\n    ideas = JSON.parse(jsonMatch[0]);\n  } else {\n    // Fallback: create structured response from text\n    ideas = [{\n      format: 'Mixed Content',\n      hook: `${trend.topic} - Viral Opportunity`,\n      keyPoints: [aiContent.substring(0, 200)],\n      platform: 'Multi-platform',\n      viralReason: 'High engagement trend'\n    }];\n  }\n  \n  return {\n    json: {\n      ...trend,\n      contentIdeas: ideas,\n      aiGenerated: true,\n      generatedAt: new Date().toISOString()\n    }\n  };\n  \n} catch (error) {\n  console.error('Failed to parse AI response:', error);\n  return {\n    json: {\n      ...trend,\n      contentIdeas: [],\n      aiGenerated: false,\n      error: error.message\n    }\n  };\n}"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "842024ea-fd0b-4298-b565-6f412a861771",
      "name": "Add Research Links",
      "type": "n8n-nodes-base.code",
      "notes": "Adds relevant research and reference links for each opportunity",
      "position": [
        3488,
        416
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Add research resources\nconst opportunity = $input.item.json;\n\nconst researchLinks = [\n  {\n    type: 'Google Search',\n    url: `https://www.google.com/search?q=${encodeURIComponent(opportunity.topic)}`,\n    purpose: 'General research and fact-checking'\n  },\n  {\n    type: 'Twitter Search',\n    url: `https://twitter.com/search?q=${encodeURIComponent(opportunity.topic)}&f=live`,\n    purpose: 'Real-time conversations and reactions'\n  },\n  {\n    type: 'YouTube',\n    url: `https://www.youtube.com/results?search_query=${encodeURIComponent(opportunity.topic)}`,\n    purpose: 'Video content inspiration'\n  },\n  {\n    type: 'Reddit',\n    url: `https://www.reddit.com/search/?q=${encodeURIComponent(opportunity.topic)}&sort=hot`,\n    purpose: 'Community discussions and insights'\n  }\n];\n\nreturn {\n  json: {\n    ...opportunity,\n    researchLinks,\n    originalSourceUrl: opportunity.url\n  }\n};"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "091c53de-1c97-46f7-97db-4be61d9ebddd",
      "name": "Create Opportunity Report",
      "type": "n8n-nodes-base.code",
      "notes": "Generates comprehensive report for each content opportunity",
      "position": [
        3712,
        416
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Generate detailed opportunity report\nconst opp = $input.item.json;\nconst config = $node['Load Niche Config'].json;\n\nconst report = {\n  // Summary\n  opportunityId: `OPP-${Date.now()}-${Math.random().toString(36).substr(2, 6).toUpperCase()}`,\n  detectedAt: new Date().toISOString(),\n  \n  // Trend Details\n  trend: {\n    topic: opp.topic,\n    source: opp.source,\n    description: opp.description,\n    sourceUrl: opp.url,\n    engagement: opp.engagement,\n    timestamp: opp.timestamp\n  },\n  \n  // Scoring\n  analysis: {\n    viralScore: opp.viralScore,\n    opportunityLevel: opp.opportunityLevel,\n    scoreBreakdown: opp.scoreBreakdown,\n    niche: config.niche\n  },\n  \n  // Content Ideas\n  contentSuggestions: opp.contentIdeas.map((idea, idx) => ({\n    ideaNumber: idx + 1,\n    format: idea.format,\n    hook: idea.hook,\n    keyPoints: idea.keyPoints,\n    platform: idea.platform,\n    viralReason: idea.viralReason,\n    estimatedCreationTime: '2-4 hours'\n  })),\n  \n  // Research Resources\n  resources: opp.researchLinks,\n  \n  // Action Items\n  nextSteps: [\n    '1. Review all content ideas and select the best fit',\n    '2. Conduct additional research using provided links',\n    '3. Create content outline based on selected idea',\n    '4. Develop and publish content within 24-48 hours',\n    '5. Track performance and engagement metrics'\n  ],\n  \n  // Timing\n  urgency: opp.viralScore >= 75 ? 'HIGH - Create within 24 hours' : \n           opp.viralScore >= 50 ? 'MEDIUM - Create within 48 hours' : \n           'LOW - Create when ready',\n  \n  // Metadata\n  metadata: {\n    aiGenerated: opp.aiGenerated,\n    generatedAt: opp.generatedAt,\n    workflowVersion: 'v1.0'\n  }\n};\n\nreturn { json: report };"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "7d064533-3081-4cd9-90a9-b82719cc17e2",
      "name": "Aggregate All Opportunities",
      "type": "n8n-nodes-base.code",
      "notes": "Combines all opportunities into a single digest",
      "position": [
        3936,
        416
      ],
      "parameters": {
        "jsCode": "// Create aggregated report\nconst opportunities = $input.all().map(i => i.json);\n\nconst digest = {\n  scanDate: new Date().toISOString(),\n  totalOpportunities: opportunities.length,\n  \n  summary: {\n    high: opportunities.filter(o => o.analysis.opportunityLevel === 'HIGH').length,\n    medium: opportunities.filter(o => o.analysis.opportunityLevel === 'MEDIUM').length,\n    low: opportunities.filter(o => o.analysis.opportunityLevel === 'LOW').length\n  },\n  \n  topOpportunities: opportunities.slice(0, 5).map(o => ({\n    topic: o.trend.topic,\n    score: o.analysis.viralScore,\n    level: o.analysis.opportunityLevel,\n    source: o.trend.source,\n    bestIdea: o.contentSuggestions[0]?.hook || 'See full report'\n  })),\n  \n  opportunities: opportunities,\n  \n  stats: {\n    averageScore: Math.round(opportunities.reduce((sum, o) => sum + o.analysis.viralScore, 0) / opportunities.length),\n    sources: {\n      twitter: opportunities.filter(o => o.trend.source === 'Twitter').length,\n      reddit: opportunities.filter(o => o.trend.source === 'Reddit').length,\n      googleTrends: opportunities.filter(o => o.trend.source === 'Google Trends').length\n    },\n    totalContentIdeas: opportunities.reduce((sum, o) => sum + o.contentSuggestions.length, 0)\n  }\n};\n\nreturn [{ json: digest }];"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "10104634-bdac-43c9-85ee-de8f3f999171",
      "name": "Send Email Digest",
      "type": "n8n-nodes-base.emailSend",
      "notes": "Sends comprehensive email with all content opportunities",
      "position": [
        4160,
        320
      ],
      "parameters": {
        "options": {},
        "subject": "=\ud83d\ude80 {{ $json.totalOpportunities }} New Viral Content Opportunities Detected",
        "toEmail": "user@example.com",
        "fromEmail": "user@example.com"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "typeVersion": 2.1
    },
    {
      "id": "aff49db2-c405-4cb3-8bb5-940daabb2ab8",
      "name": "Send Slack Summary",
      "type": "n8n-nodes-base.slack",
      "notes": "Posts quick summary to Slack channel",
      "position": [
        4160,
        512
      ],
      "parameters": {
        "resource": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "typeVersion": 2.1
    },
    {
      "id": "2d9c82ad-9fea-4ef9-82c3-90a06b2f51c6",
      "name": "Log to Content Database",
      "type": "n8n-nodes-base.postgres",
      "notes": "Stores opportunities in database for tracking and analytics",
      "position": [
        4384,
        416
      ],
      "parameters": {
        "table": "viral_opportunities",
        "schema": "content",
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "typeVersion": 2.4
    },
    {
      "id": "6ef0386d-b622-4e27-ab11-0a7bb86185cd",
      "name": "Mark Topic as Suggested",
      "type": "n8n-nodes-base.code",
      "notes": "Updates workflow memory to track suggested topics",
      "position": [
        4608,
        416
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Mark topic as suggested to prevent future duplicates\nconst opportunity = $input.item.json;\nconst staticData = $getWorkflowStaticData('global');\n\nif (!staticData.coveredTopics) {\n  staticData.coveredTopics = {};\n}\n\nconst topicKey = opportunity.trend.topic.toLowerCase().replace(/[^a-z0-9]/g, '');\nstaticData.coveredTopics[topicKey] = {\n  opportunityId: opportunity.opportunityId,\n  topic: opportunity.trend.topic,\n  suggestedAt: opportunity.detectedAt,\n  timestamp: Date.now()\n};\n\nconsole.log(`\u2705 Marked as suggested: ${opportunity.trend.topic}`);\n\nreturn { json: opportunity };"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "f451f6db-e55f-4e6d-a198-28b1677f1784",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -240
      ],
      "parameters": {
        "width": 720,
        "height": 1264,
        "content": "Automatically discovers trending topics in your niche and generates ready-to-use content ideas with AI.\n\n## \ud83c\udfaf How It Works\n\n### 1. **Multi-Source Trend Monitoring**\n   - Twitter/X trending topics and hashtags\n   - Reddit hot posts from niche subreddits\n   - Google Trends daily search trends\n   - Runs every 2 hours for fresh opportunities\n\n### 2. **Smart Filtering & Scoring**\n   - Filters by your niche keywords\n   - Removes duplicates across sources\n   - Calculates viral potential score (0-100)\n   - Ranks by engagement, recency, and relevance\n   - Prevents suggesting already-covered topics\n\n### 3. **AI Content Generation**\n   - Uses Claude AI to analyze each trend\n   - Generates 5 unique content ideas per trend\n   - Provides hooks, key points, and platform recommendations\n   - Explains why each idea has viral potential\n\n### 4. **Comprehensive Delivery**\n   - Beautiful HTML email digest with all opportunities\n   - Slack summary for quick review\n   - Database logging for tracking\n   - Research links for deeper investigation\n\n\n## \ud83c\udfa8 Customization Options\n\n### Adjust Scan Frequency\nEdit \"Every 2 Hours\" trigger:\n- More frequent: Every 1 hour\n- Less frequent: Every 4-6 hours\n- Consider API rate limits\n\n### Tune Viral Score Algorithm\nEdit \"Calculate Viral Potential Score\" node:\n- Adjust engagement weight (currently 40%)\n- Change recency importance (currently 30%)\n- Modify threshold in \"Filter High Potential Only\" (currently 40)\n\n### Customize Content Ideas\nModify the AI prompt in \"AI - Generate Content Ideas\":\n- Change number of ideas (currently 5)\n- Add specific format requirements\n- Include brand voice guidelines\n- Target specific platforms\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4a320c45-d7f3-46e1-a647-5bb4ea1627cd",
      "name": "Sticky Note - Collection",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        176
      ],
      "parameters": {
        "color": 6,
        "width": 640,
        "height": 688,
        "content": "## \ud83d\udce1 TREND COLLECTION\nFetch from multiple sources, parse, and normalize data"
      },
      "typeVersion": 1
    },
    {
      "id": "f809d301-6b66-4e15-b8c9-15c104eb5263",
      "name": "Sticky Note - Analysis",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1440,
        256
      ],
      "parameters": {
        "color": 4,
        "width": 1056,
        "height": 336,
        "content": "## \ud83d\udd0d FILTERING & SCORING\nKeyword filtering, deduplication, viral potential scoring, ranking"
      },
      "typeVersion": 1
    },
    {
      "id": "842ffdfa-ea0a-4d66-bb90-6804892fb698",
      "name": "Sticky Note - AI",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2552,
        240
      ],
      "parameters": {
        "color": 5,
        "width": 1088,
        "height": 368,
        "content": "## \ud83e\udd16 AI CONTENT GENERATION\nCheck history, generate ideas with AI, enrich with research"
      },
      "typeVersion": 1
    },
    {
      "id": "8053a523-abbc-4101-9812-17253970237f",
      "name": "Sticky Note - Delivery",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3680,
        224
      ],
      "parameters": {
        "width": 1328,
        "height": 448,
        "content": "## \ud83d\udce8 REPORTING & DELIVERY\nCreate reports, send digest, notify team, log to database"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b0ea2038-51da-44a7-8151-adf6dd960eaa",
  "connections": {
    "Parse Reddit Data": {
      "main": [
        [
          {
            "node": "Merge All Trend Sources",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Send Email Digest": {
      "main": [
        [
          {
            "node": "Log to Content Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Research Links": {
      "main": [
        [
          {
            "node": "Create Opportunity Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Twitter Data": {
      "main": [
        [
          {
            "node": "Merge All Trend Sources",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Slack Summary": {
      "main": [
        [
          {
            "node": "Log to Content Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Google Trends": {
      "main": [
        [
          {
            "node": "Parse Google Trends",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Google Trends": {
      "main": [
        [
          {
            "node": "Merge All Trend Sources",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort by Viral Score": {
      "main": [
        [
          {
            "node": "Check Already Covered",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Already Covered": {
      "main": [
        [
          {
            "node": "AI - Generate Content Ideas",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Twitter/X Trends": {
      "main": [
        [
          {
            "node": "Parse Twitter Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Content Ideas": {
      "main": [
        [
          {
            "node": "Add Research Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Reddit Hot Topics": {
      "main": [
        [
          {
            "node": "Parse Reddit Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Content Database": {
      "main": [
        [
          {
            "node": "Mark Topic as Suggested",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Topic as Suggested": {
      "main": [
        [
          {
            "node": "Load Niche Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge All Trend Sources": {
      "main": [
        [
          {
            "node": "Filter by Niche Keywords",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicate Topics": {
      "main": [
        [
          {
            "node": "Calculate Viral Potential Score",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter by Niche Keywords": {
      "main": [
        [
          {
            "node": "Remove Duplicate Topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Opportunity Report": {
      "main": [
        [
          {
            "node": "Aggregate All Opportunities",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter High Potential Only": {
      "main": [
        [
          {
            "node": "Sort by Viral Score",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI - Generate Content Ideas": {
      "main": [
        [
          {
            "node": "Parse AI Content Ideas",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate All Opportunities": {
      "main": [
        [
          {
            "node": "Send Email Digest",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send Slack Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every 2 Hours - Trend Scanner": {
      "main": [
        [
          {
            "node": "Fetch Twitter/X Trends",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Reddit Hot Topics",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Google Trends",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Viral Potential Score": {
      "main": [
        [
          {
            "node": "Filter High Potential Only",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}