AutomationFlowsAI & RAG › Spot Social Media Trends and Generate Post Ideas with Claude and Google Sheets

Spot Social Media Trends and Generate Post Ideas with Claude and Google Sheets

ByOneclick AI Squad @oneclick-ai on n8n.io

This AI-powered workflow monitors trending topics across multiple social platforms, generates creative post ideas with captions and visual suggestions, and recommends optimal posting times based on engagement data. Trigger - Runs on schedule or webhook to start trend monitoring…

Webhook trigger★★★★☆ complexityAI-powered21 nodesHTTP RequestAgentAnthropic ChatGoogle Sheets
AI & RAG Trigger: Webhook Nodes: 21 Complexity: ★★★★☆ AI nodes: yes Added:
Spot Social Media Trends and Generate Post Ideas with Claude and Google Sheets — n8n workflow card showing HTTP Request, Agent, Anthropic Chat integration

This workflow corresponds to n8n.io template #15017 — we link there as the canonical source.

This workflow follows the Agent → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "ZanLxRR8F108sLWM",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Social Media Trend Spotter & Idea Generator",
  "tags": [],
  "nodes": [
    {
      "id": "5ac9c135-a80b-42cb-bdc6-67ae9bc3d7da",
      "name": "Sticky Note - Documentation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        -256
      ],
      "parameters": {
        "width": 820,
        "height": 1360,
        "content": "## Social Media Trend Spotter & Idea Generator\n\nThis AI-powered workflow monitors trending topics across multiple social platforms, generates creative post ideas with captions and visual suggestions, and recommends optimal posting times based on engagement data.\n\n### How it works\n\n1. **Trigger** - Runs on schedule or webhook to start trend monitoring\n2. **Fetch Trends** - Pulls trending topics from Twitter, Reddit, Google Trends\n3. **Wait & Aggregate** - Allows trend data to settle for better analysis\n4. **Filter & Parse** - JavaScript code filters relevant trends for your niche\n5. **AI Content Generation** - Claude creates post ideas, captions, hashtags\n6. **Visual Suggestions** - Recommends image/video concepts\n7. **Wait for Analysis** - Pauses before engagement time calculation\n8. **Optimal Timing** - JavaScript calculates best posting times\n9. **Log & Track** - Records all ideas in Google Sheets\n10. **Response** - Returns ready-to-use content ideas\n\n### Setup Steps\n\n1. Import this workflow into your n8n instance\n2. Configure credentials:\n   - **Twitter API v2** - For trending hashtags and topics\n   - **Reddit API** - For subreddit trending posts\n   - **Google Trends (no auth)** - For search trends\n   - **Anthropic API** - For Claude AI content generation\n   - **Google Sheets** - To track generated ideas\n3. Update your brand profile and niche in the config node\n4. Set your target social platforms and audience\n5. Activate the workflow\n\n### Sample Trigger Payload\n```json\n{\n  \"platforms\": [\"twitter\", \"instagram\", \"linkedin\"],\n  \"niche\": \"AI & Technology\",\n  \"trendSources\": [\"twitter\", \"reddit\", \"google\"],\n  \"contentTypes\": [\"educational\", \"entertaining\", \"news\"],\n  \"targetAudience\": \"tech professionals, 25-45\",\n  \"brandVoice\": \"professional yet approachable\",\n  \"minTrendScore\": 60,\n  \"maxIdeasPerTrend\": 3,\n  \"includeVisuals\": true\n}\n```\n\n### Features\n\n- **Multi-platform trend monitoring** (Twitter, Reddit, Google Trends)\n- **AI-powered content generation** with brand voice matching\n- **Visual concept suggestions** for each post idea\n- **Optimal timing recommendations** based on engagement patterns\n- **Hashtag strategy** with trending and niche tags\n- **Content calendar integration** via Google Sheets\n- **Duplicate prevention** - tracks used trends\n- **Performance tracking** - logs which ideas perform best"
      },
      "typeVersion": 1
    },
    {
      "id": "64e9c1ba-59fb-4188-8528-5ce9db7826c8",
      "name": "Sticky Note - Section 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        288
      ],
      "parameters": {
        "color": 5,
        "width": 500,
        "height": 380,
        "content": "## 1. Trigger & Configuration"
      },
      "typeVersion": 1
    },
    {
      "id": "b82fdc2d-33e5-4cda-9c73-6b69fbd9f668",
      "name": "Sticky Note - Section 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        832,
        -80
      ],
      "parameters": {
        "color": 5,
        "width": 928,
        "height": 900,
        "content": "## 2. Fetch Trends & Wait for Aggregation"
      },
      "typeVersion": 1
    },
    {
      "id": "d4caf36f-ecb5-4178-8877-3785ddda6b0e",
      "name": "Sticky Note - Section 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1792,
        128
      ],
      "parameters": {
        "color": 5,
        "width": 760,
        "height": 668,
        "content": "## 3. Parse, Filter & AI Generation"
      },
      "typeVersion": 1
    },
    {
      "id": "89994ea3-2dea-4e40-8c9a-919b78398b94",
      "name": "Sticky Note - Section 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2592,
        192
      ],
      "parameters": {
        "color": 5,
        "width": 960,
        "height": 580,
        "content": "## 4. Timing Analysis & Output"
      },
      "typeVersion": 1
    },
    {
      "id": "2ec84eca-f1be-4d0c-bf2c-8cacbfa444c7",
      "name": "Receive Trend Request",
      "type": "n8n-nodes-base.webhook",
      "position": [
        416,
        448
      ],
      "parameters": {
        "path": "social-trends",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "21cccaf5-4715-44ad-9287-6e8dc7090fa8",
      "name": "Validate Config & Build Parameters",
      "type": "n8n-nodes-base.code",
      "position": [
        656,
        448
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Extract configuration from request\nconst body = $input.item.json.body || $input.item.json;\n\n// Default configuration\nconst config = {\n  platforms: body.platforms || ['twitter', 'instagram', 'linkedin'],\n  niche: body.niche || 'Technology & Innovation',\n  trendSources: body.trendSources || ['twitter', 'reddit', 'google'],\n  contentTypes: body.contentTypes || ['educational', 'entertaining', 'news'],\n  targetAudience: body.targetAudience || 'tech-savvy professionals, 25-45',\n  brandVoice: body.brandVoice || 'professional yet approachable',\n  minTrendScore: parseInt(body.minTrendScore) || 60,\n  maxIdeasPerTrend: parseInt(body.maxIdeasPerTrend) || 3,\n  includeVisuals: Boolean(body.includeVisuals !== false),\n  includeHashtags: Boolean(body.includeHashtags !== false),\n  waitTimeSeconds: parseInt(body.waitTimeSeconds) || 120,\n  analysisWaitSeconds: parseInt(body.analysisWaitSeconds) || 60\n};\n\n// Brand profile (customize per user)\nconst brandProfile = {\n  name: body.brandName || 'YOUR_BRAND',\n  industry: body.industry || config.niche,\n  values: body.brandValues || ['innovation', 'authenticity', 'expertise'],\n  prohibitedTopics: body.prohibitedTopics || ['politics', 'controversial'],\n  preferredFormats: body.preferredFormats || ['carousel', 'infographic', 'video'],\n  colorScheme: body.colorScheme || ['#0066CC', '#FF6B35', '#F7F7F7']\n};\n\n// Engagement patterns (historical data or defaults)\nconst engagementPatterns = {\n  twitter: {\n    peakHours: [9, 12, 17, 20],\n    peakDays: ['Tuesday', 'Wednesday', 'Thursday'],\n    avgEngagementRate: 0.03\n  },\n  instagram: {\n    peakHours: [11, 13, 19, 21],\n    peakDays: ['Wednesday', 'Friday', 'Sunday'],\n    avgEngagementRate: 0.045\n  },\n  linkedin: {\n    peakHours: [8, 12, 17],\n    peakDays: ['Tuesday', 'Wednesday', 'Thursday'],\n    avgEngagementRate: 0.02\n  }\n};\n\nreturn {\n  json: {\n    config,\n    brandProfile,\n    engagementPatterns,\n    metadata: {\n      requestId: `SMTS-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n      startedAt: new Date().toISOString(),\n      timezone: body.timezone || 'Asia/Kolkata'\n    }\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "2b50f0db-04ea-40e2-93aa-c3e4211a7bfe",
      "name": "Fetch Twitter Trending Topics",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        896,
        208
      ],
      "parameters": {
        "url": "https://api.twitter.com/2/trends/place",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "id",
              "value": "1"
            }
          ]
        },
        "nodeCredentialType": "twitterOAuth2Api"
      },
      "credentials": {
        "twitterOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "31b23fc2-792b-45de-957f-baff90f4c27b",
      "name": "Fetch Reddit Hot Topics",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        896,
        400
      ],
      "parameters": {
        "url": "https://oauth.reddit.com/r/all/hot",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "limit",
              "value": "25"
            },
            {
              "name": "t",
              "value": "day"
            }
          ]
        },
        "nodeCredentialType": "redditOAuth2Api"
      },
      "credentials": {
        "redditOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "b8b0d45e-6d27-41ef-afe0-bdd25976920c",
      "name": "Fetch Google Trends",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        896,
        608
      ],
      "parameters": {
        "url": "https://trends.google.com/trends/api/dailytrends",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "hl",
              "value": "en-US"
            },
            {
              "name": "tz",
              "value": "-330"
            },
            {
              "name": "geo",
              "value": "IN"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "5078752f-c964-4f4c-a35e-0d95eb61e416",
      "name": "Merge All Trend Sources",
      "type": "n8n-nodes-base.merge",
      "position": [
        1152,
        400
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "mergeByFields": {
          "values": [
            {},
            {}
          ]
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "20f2810f-754d-41a7-8121-6ebce58a71b5",
      "name": "Wait for Trend Aggregation",
      "type": "n8n-nodes-base.wait",
      "position": [
        1392,
        400
      ],
      "parameters": {
        "resume": "after-execution"
      },
      "typeVersion": 1.1
    },
    {
      "id": "6db7ec5b-a25c-4bba-8c4b-437cd77eaeb6",
      "name": "Parse & Filter Trending Topics",
      "type": "n8n-nodes-base.code",
      "position": [
        1632,
        400
      ],
      "parameters": {
        "jsCode": "// Get configuration and trend data\nconst config = $('Validate Config & Build Parameters').first().json.config;\nconst brandProfile = $('Validate Config & Build Parameters').first().json.brandProfile;\n\nconst allTrends = [];\n\n// Parse Twitter trends\nconst twitterData = $input.all().find(item => item.json.data?.trends);\nif (twitterData) {\n  const trends = twitterData.json.data.trends || [];\n  trends.forEach(trend => {\n    allTrends.push({\n      source: 'twitter',\n      topic: trend.name || trend.query,\n      volume: trend.tweet_volume || 0,\n      url: trend.url,\n      rawScore: Math.min(100, (trend.tweet_volume || 0) / 1000)\n    });\n  });\n}\n\n// Parse Reddit trends\nconst redditData = $input.all().find(item => item.json.data?.children);\nif (redditData) {\n  const posts = redditData.json.data.children || [];\n  posts.forEach(post => {\n    const data = post.data;\n    allTrends.push({\n      source: 'reddit',\n      topic: data.title,\n      volume: data.ups + data.num_comments,\n      url: `https://reddit.com${data.permalink}`,\n      subreddit: data.subreddit,\n      rawScore: Math.min(100, ((data.ups + data.num_comments) / 100))\n    });\n  });\n}\n\n// Parse Google Trends\nconst googleData = $input.all().find(item => item.json.default?.trendingSearchesDays);\nif (googleData) {\n  const trendDays = googleData.json.default.trendingSearchesDays || [];\n  trendDays.forEach(day => {\n    (day.trendingSearches || []).forEach(search => {\n      allTrends.push({\n        source: 'google',\n        topic: search.title?.query || search.title,\n        volume: parseInt(search.formattedTraffic?.replace(/[+,]/g, '')) || 0,\n        url: search.articles?.[0]?.url || '',\n        rawScore: Math.min(100, (parseInt(search.formattedTraffic?.replace(/[+,]/g, '')) || 0) / 10000)\n      });\n    });\n  });\n}\n\n// Filter and score trends\nconst processedTrends = allTrends\n  .filter(trend => {\n    // Remove prohibited topics\n    const topicLower = trend.topic.toLowerCase();\n    return !brandProfile.prohibitedTopics.some(prohibited => \n      topicLower.includes(prohibited.toLowerCase())\n    );\n  })\n  .map(trend => {\n    // Calculate relevance score\n    const nicheLower = config.niche.toLowerCase();\n    const topicLower = trend.topic.toLowerCase();\n    \n    // Niche matching bonus\n    const nicheWords = nicheLower.split(/\\s+/);\n    const nicheMatch = nicheWords.some(word => topicLower.includes(word)) ? 30 : 0;\n    \n    // Volume score (normalized)\n    const volumeScore = trend.rawScore || 0;\n    \n    // Final score\n    const finalScore = Math.min(100, volumeScore + nicheMatch);\n    \n    return {\n      ...trend,\n      nicheRelevance: nicheMatch,\n      finalScore,\n      timestamp: new Date().toISOString()\n    };\n  })\n  .filter(trend => trend.finalScore >= config.minTrendScore)\n  .sort((a, b) => b.finalScore - a.finalScore)\n  .slice(0, 10); // Top 10 trends\n\nif (processedTrends.length === 0) {\n  throw new Error('No relevant trends found matching your niche and score threshold');\n}\n\nconsole.log(`Filtered ${processedTrends.length} relevant trends from ${allTrends.length} total`);\n\n// Return each trend as separate item for parallel processing\nreturn processedTrends.map(trend => ({\n  json: {\n    trend,\n    config,\n    brandProfile,\n    metadata: $('Validate Config & Build Parameters').first().json.metadata\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "8d898ed1-b695-408b-9258-5312ea099e20",
      "name": "Generate Content Ideas with Claude AI",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1808,
        400
      ],
      "parameters": {
        "text": "=You are a creative social media strategist and content creator. Generate {{$json.config.maxIdeasPerTrend}} unique post ideas based on this trending topic.\n\n**Trending Topic:**\n- Topic: {{$json.trend.topic}}\n- Source: {{$json.trend.source}}\n- Trend Score: {{$json.trend.finalScore}}/100\n- Volume: {{$json.trend.volume}}\n- URL: {{$json.trend.url}}\n\n**Brand Profile:**\n- Brand: {{$json.brandProfile.name}}\n- Industry: {{$json.brandProfile.industry}}\n- Voice: {{$json.config.brandVoice}}\n- Target Audience: {{$json.config.targetAudience}}\n- Values: {{$json.brandProfile.values.join(', ')}}\n\n**Content Requirements:**\n- Platforms: {{$json.config.platforms.join(', ')}}\n- Content Types: {{$json.config.contentTypes.join(', ')}}\n- Include Visuals: {{$json.config.includeVisuals}}\n- Preferred Formats: {{$json.brandProfile.preferredFormats.join(', ')}}\n\n**Generate {{$json.config.maxIdeasPerTrend}} unique post ideas in this JSON format:**\n{\n  \"ideas\": [\n    {\n      \"platform\": \"twitter\",\n      \"contentType\": \"educational\",\n      \"angle\": \"Brief description of the unique angle/hook\",\n      \"caption\": \"Full caption text (platform-optimized length)\",\n      \"hashtags\": [\"#trending\", \"#relevant\", \"#niche\"],\n      \"visualConcept\": \"Detailed description of recommended image/graphic/video\",\n      \"visualType\": \"infographic\",\n      \"callToAction\": \"What action you want audience to take\",\n      \"estimatedEngagement\": \"high\",\n      \"reasoning\": \"Why this will resonate with the target audience\"\n    }\n  ],\n  \"trendContext\": \"Brief explanation of why this trend matters to your audience\",\n  \"timingSensitivity\": \"low/medium/high - how time-sensitive is this trend\"\n}\n\n**Important Guidelines:**\n- Make each idea distinctly different in angle and format\n- Optimize caption length for each platform (Twitter: 280 chars, Instagram: engaging first line, LinkedIn: professional)\n- Visual concepts should be specific and actionable for designers\n- Match brand voice consistently\n- Avoid generic content - be creative and specific\n- Consider the trend's virality potential",
        "options": {
          "systemMessage": "You are an expert social media strategist who creates viral, engaging content tailored to specific brand voices and platforms. Always respond in valid JSON format without markdown code blocks."
        },
        "promptType": "define"
      },
      "typeVersion": 1.6
    },
    {
      "id": "bcfe708f-c0fd-4833-bcb7-4681256c5ac0",
      "name": "Claude AI Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        1952,
        640
      ],
      "parameters": {
        "model": "=claude-sonnet-4-20250514",
        "options": {
          "temperature": 0.7
        }
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "977954b7-ed50-4441-8f60-ccbaa87bab79",
      "name": "Parse Claude Response",
      "type": "n8n-nodes-base.code",
      "position": [
        2112,
        400
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const aiResponse = $input.item.json;\nlet aiText = aiResponse.response || aiResponse.output || aiResponse.text || '';\n\n// Handle content array format from Anthropic\nif (aiResponse.content && Array.isArray(aiResponse.content)) {\n  aiText = aiResponse.content[0]?.text || '';\n}\n\n// Clean JSON from markdown code blocks\nconst cleanText = aiText\n  .replace(/```json\\s*/g, '')\n  .replace(/```\\s*/g, '')\n  .trim();\n\nlet generatedContent;\ntry {\n  generatedContent = JSON.parse(cleanText);\n} catch (error) {\n  throw new Error(`Failed to parse AI response: ${error.message}. Response was: ${cleanText.substring(0, 200)}...`);\n}\n\n// Get trend and config from upstream\nconst trendData = $('Parse & Filter Trending Topics').item.json;\n\nreturn {\n  json: {\n    trend: trendData.trend,\n    config: trendData.config,\n    brandProfile: trendData.brandProfile,\n    generatedIdeas: generatedContent.ideas || [],\n    trendContext: generatedContent.trendContext,\n    timingSensitivity: generatedContent.timingSensitivity || 'medium',\n    generatedAt: new Date().toISOString(),\n    metadata: trendData.metadata\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "180bc4d7-e2a9-471a-8892-6100363629ac",
      "name": "Wait Before Timing Analysis",
      "type": "n8n-nodes-base.wait",
      "position": [
        2352,
        400
      ],
      "parameters": {
        "resume": "after-execution"
      },
      "typeVersion": 1.1
    },
    {
      "id": "5e51ec00-2a35-4bd6-b561-f8c63c71ab8a",
      "name": "Calculate Optimal Posting Times",
      "type": "n8n-nodes-base.code",
      "position": [
        2624,
        400
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const data = $input.item.json;\nconst config = data.config;\nconst engagementPatterns = $('Validate Config & Build Parameters').first().json.engagementPatterns;\nconst timezone = data.metadata.timezone;\n\n// Calculate optimal posting times for each platform and idea\nconst ideasWithTiming = data.generatedIdeas.map((idea, index) => {\n  const platform = idea.platform;\n  const patterns = engagementPatterns[platform] || engagementPatterns.twitter;\n  \n  // Get current date/time in user's timezone\n  const now = new Date();\n  const currentHour = now.getHours();\n  const currentDay = now.toLocaleDateString('en-US', { weekday: 'long', timeZone: timezone });\n  \n  // Find next optimal posting slot\n  let recommendedTime;\n  let daysUntilPost = 0;\n  let foundSlot = false;\n  \n  // Check next 7 days for optimal slot\n  for (let day = 0; day < 7 && !foundSlot; day++) {\n    const checkDate = new Date(now);\n    checkDate.setDate(checkDate.getDate() + day);\n    const dayName = checkDate.toLocaleDateString('en-US', { weekday: 'long', timeZone: timezone });\n    \n    if (patterns.peakDays.includes(dayName)) {\n      // Find next peak hour on this day\n      for (const peakHour of patterns.peakHours) {\n        if (day === 0 && peakHour <= currentHour) continue; // Skip past hours today\n        \n        checkDate.setHours(peakHour, 0, 0, 0);\n        recommendedTime = checkDate.toISOString();\n        daysUntilPost = day;\n        foundSlot = true;\n        break;\n      }\n    }\n  }\n  \n  // Fallback: next peak hour on any day\n  if (!recommendedTime) {\n    const fallbackDate = new Date(now);\n    fallbackDate.setDate(fallbackDate.getDate() + 1);\n    fallbackDate.setHours(patterns.peakHours[0], 0, 0, 0);\n    recommendedTime = fallbackDate.toISOString();\n    daysUntilPost = 1;\n  }\n  \n  // Calculate expected engagement score\n  const baseEngagement = patterns.avgEngagementRate;\n  const trendBoost = data.trend.finalScore / 100; // Trending topics boost engagement\n  const timingSensitivityMultiplier = \n    data.timingSensitivity === 'high' ? 1.5 :\n    data.timingSensitivity === 'medium' ? 1.2 : 1.0;\n  \n  const expectedEngagement = baseEngagement * (1 + trendBoost) * timingSensitivityMultiplier;\n  \n  // Format human-readable time\n  const timeObj = new Date(recommendedTime);\n  const formattedTime = timeObj.toLocaleString('en-US', {\n    timeZone: timezone,\n    weekday: 'long',\n    year: 'numeric',\n    month: 'long',\n    day: 'numeric',\n    hour: 'numeric',\n    minute: '2-digit',\n    hour12: true\n  });\n  \n  return {\n    ...idea,\n    timing: {\n      recommendedPostTime: recommendedTime,\n      formattedTime,\n      daysUntilPost,\n      timezone,\n      urgency: data.timingSensitivity === 'high' && daysUntilPost > 2 ? 'URGENT - Trend may fade' : 'optimal',\n      expectedEngagementRate: (expectedEngagement * 100).toFixed(2) + '%',\n      peakHours: patterns.peakHours,\n      peakDays: patterns.peakDays\n    },\n    metadata: {\n      ideaId: `${data.metadata.requestId}-idea-${index + 1}`,\n      trendTopic: data.trend.topic,\n      trendSource: data.trend.source,\n      trendScore: data.trend.finalScore\n    }\n  };\n});\n\n// Summary statistics\nconst summary = {\n  totalIdeas: ideasWithTiming.length,\n  platformBreakdown: config.platforms.reduce((acc, platform) => {\n    acc[platform] = ideasWithTiming.filter(i => i.platform === platform).length;\n    return acc;\n  }, {}),\n  urgentIdeas: ideasWithTiming.filter(i => i.timing.urgency === 'URGENT - Trend may fade').length,\n  avgExpectedEngagement: (\n    ideasWithTiming.reduce((sum, i) => sum + parseFloat(i.timing.expectedEngagementRate), 0) / \n    ideasWithTiming.length\n  ).toFixed(2) + '%',\n  nextPostingWindow: ideasWithTiming[0]?.timing.formattedTime\n};\n\nreturn {\n  json: {\n    trendTopic: data.trend.topic,\n    trendScore: data.trend.finalScore,\n    trendSource: data.trend.source,\n    trendContext: data.trendContext,\n    timingSensitivity: data.timingSensitivity,\n    contentIdeas: ideasWithTiming,\n    summary,\n    brandProfile: data.brandProfile,\n    generatedAt: data.generatedAt,\n    processedAt: new Date().toISOString(),\n    requestId: data.metadata.requestId\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "b899050a-fddd-4bc1-9314-baab9da66c45",
      "name": "Log Ideas to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2864,
        400
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "=hhyy64rfyy654"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "=hhyy64rfyy654"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5,
      "continueOnFail": true
    },
    {
      "id": "6c28d6f8-7ee4-4110-9e5f-816def22d99e",
      "name": "Format Final Response",
      "type": "n8n-nodes-base.code",
      "position": [
        3104,
        400
      ],
      "parameters": {
        "jsCode": "// Aggregate all processed ideas from all trends\nconst allResults = $input.all().map(item => item.json);\n\n// Create comprehensive response\nconst response = {\n  success: true,\n  message: `Generated ${allResults.reduce((sum, r) => sum + r.contentIdeas.length, 0)} content ideas from ${allResults.length} trending topics`,\n  trends: allResults.map(result => ({\n    topic: result.trendTopic,\n    score: result.trendScore,\n    source: result.trendSource,\n    context: result.trendContext,\n    timingSensitivity: result.timingSensitivity,\n    ideasCount: result.contentIdeas.length,\n    ideas: result.contentIdeas\n  })),\n  summary: {\n    totalTrends: allResults.length,\n    totalIdeas: allResults.reduce((sum, r) => sum + r.contentIdeas.length, 0),\n    platformsTargeted: [...new Set(allResults.flatMap(r => r.contentIdeas.map(i => i.platform)))],\n    urgentPosts: allResults.reduce((sum, r) => \n      sum + r.contentIdeas.filter(i => i.timing.urgency.includes('URGENT')).length, 0\n    ),\n    nextPostingWindow: allResults[0]?.summary?.nextPostingWindow,\n    generatedAt: allResults[0]?.generatedAt,\n    requestId: allResults[0]?.requestId\n  },\n  recommendations: [\n    \"Review all ideas and select the ones that best match your brand voice\",\n    \"Schedule urgent posts within 24-48 hours to capitalize on trend momentum\",\n    \"Customize captions to add your unique brand personality\",\n    \"Create or commission visuals based on the provided concepts\",\n    \"Track performance and log results back to this system for better future recommendations\"\n  ]\n};\n\nreturn [{ json: response }];"
      },
      "typeVersion": 2
    },
    {
      "id": "5459c306-5b82-4274-8088-fd3dd847b710",
      "name": "Send Response to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        3344,
        400
      ],
      "parameters": {
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "application/json"
              }
            ]
          }
        },
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json, null, 2) }}"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "aad62668-4b3d-4de9-bfb3-49d413199552",
  "connections": {
    "Claude AI Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Content Ideas with Claude AI",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Google Trends": {
      "main": [
        [
          {
            "node": "Merge All Trend Sources",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Format Final Response": {
      "main": [
        [
          {
            "node": "Send Response to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Claude Response": {
      "main": [
        [
          {
            "node": "Wait Before Timing Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive Trend Request": {
      "main": [
        [
          {
            "node": "Validate Config & Build Parameters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Reddit Hot Topics": {
      "main": [
        [
          {
            "node": "Merge All Trend Sources",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge All Trend Sources": {
      "main": [
        [
          {
            "node": "Wait for Trend Aggregation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Ideas to Google Sheets": {
      "main": [
        [
          {
            "node": "Format Final Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Trend Aggregation": {
      "main": [
        [
          {
            "node": "Parse & Filter Trending Topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait Before Timing Analysis": {
      "main": [
        [
          {
            "node": "Calculate Optimal Posting Times",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Twitter Trending Topics": {
      "main": [
        [
          {
            "node": "Merge All Trend Sources",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Filter Trending Topics": {
      "main": [
        [
          {
            "node": "Generate Content Ideas with Claude AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Optimal Posting Times": {
      "main": [
        [
          {
            "node": "Log Ideas to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Config & Build Parameters": {
      "main": [
        [
          {
            "node": "Fetch Twitter Trending Topics",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Reddit Hot Topics",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Google Trends",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Content Ideas with Claude AI": {
      "main": [
        [
          {
            "node": "Parse Claude Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This AI-powered workflow monitors trending topics across multiple social platforms, generates creative post ideas with captions and visual suggestions, and recommends optimal posting times based on engagement data. Trigger - Runs on schedule or webhook to start trend monitoring…

Source: https://n8n.io/workflows/15017/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

⏺ 🚀 How it works

Agent, Anthropic Chat, Output Parser Structured +6
AI & RAG

Fully automates your service order pipeline from incoming booking to supplier confirmation — with built-in SLA enforcement and automatic escalation if a supplier goes silent. 📥 Receives orders via web

HTTP Request, Google Sheets, Agent +4
AI & RAG

Tired of grinding out YouTube content? This n8n workflow turns AI into your personal video factory—creating engaging, faceless shorts on autopilot. Perfect for creators, marketers, or side-hustlers lo

HTTP Request, Google Drive, Google Sheets +6
AI & RAG

Faceless YouTube Generator. Uses httpRequest, limit, googleDrive, googleSheets. Webhook trigger; 49 nodes.

HTTP Request, Google Drive, Google Sheets +7
AI & RAG

This workflow turns your WhatsApp Business number into a 24/7 AI-powered customer assistant — without any third-party chatbot platform. It receives incoming WhatsApp messages via Evolution API, unders

OpenAI, Information Extractor, Anthropic Chat +7