{
  "id": "vjfcsEnVAOpoXe_p7mUL8",
  "name": "Track crypto narrative trends and send AI sector analysis to Discord",
  "tags": [],
  "nodes": [
    {
      "id": "1ce5846c-3319-48b6-888a-c1c0df56e7fd",
      "name": "Sticky Note - Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        -352
      ],
      "parameters": {
        "width": 420,
        "height": 928,
        "content": "## \ud83d\udd25 Crypto narrative trend tracker\n\n**Who is this for?**\nCrypto traders who want to identify trending sectors and narratives before they become mainstream.\n\n**What it does:**\nFetches top gaining cryptocurrencies, groups them by sector (AI, DeFi, Meme, Gaming, etc.), uses Gemini AI to analyze why each sector is pumping, and sends a formatted digest to Discord.\n\n**\u2705 Identifies Emerging Narratives!**\nAutomatically detects which crypto sectors are gaining momentum based on real-time market data.\n\n**How it works:**\n1. Triggers on schedule (configurable)\n2. Fetches top 200 gainers from CoinMarketCap API\n3. Filters tokens: >40% gain, >$10M market cap, >$1M volume\n4. Groups tokens by sector using tag analysis\n5. Gemini AI researches catalysts for each pumping sector\n6. Creates formatted digest report\n7. Splits message and sends to Discord\n\n**Setup steps:**\n- Get CoinMarketCap API key (free tier: 10K credits/month)\n- Get Google Gemini API key from Google AI Studio\n- Create Discord webhook in your server\n- Connect CMC credentials to Fetch Top Gainers node\n- Connect Gemini credentials to Gemini Sector Research node\n- Connect Discord webhook to Send to Discord node\n\n**Configuration:**\n- Adjust filters in Filter Top Gainers node (MIN_PERCENT_CHANGE, MIN_MARKET_CAP, MIN_VOLUME)\n- Modify sector mappings in Group Tokens by Sector node"
      },
      "typeVersion": 1
    },
    {
      "id": "9677cd27-98b9-4e07-9ad6-6224e18b00b4",
      "name": "Sticky Note - Data Collection",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 604,
        "height": 184,
        "content": "### \ud83d\udce5 Data Collection & Processing\nFetch gainers from CMC, filter by criteria, and group by sector"
      },
      "typeVersion": 1
    },
    {
      "id": "a8a012f5-2a45-42b2-ac61-7b5f6acd513e",
      "name": "Sticky Note - AI Analysis",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        16
      ],
      "parameters": {
        "color": 7,
        "width": 1492,
        "height": 200,
        "content": "### \ud83e\udd16 AI Analysis & Output\nGenerate sector research prompts, analyze with Gemini, and send digest to Discord"
      },
      "typeVersion": 1
    },
    {
      "id": "d72c6852-47b5-4f0d-aed3-38880a9d8675",
      "name": "Schedule Trigger (Hourly)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -32,
        208
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "ef3d5990-ae36-4671-980b-072f4e7a3f90",
      "name": "Fetch Top 200 Gainers from CMC",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        192,
        208
      ],
      "parameters": {
        "url": "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "limit",
              "value": "200"
            },
            {
              "name": "sort",
              "value": "percent_change_24h"
            },
            {
              "name": "sort_dir",
              "value": "desc"
            },
            {
              "name": "convert",
              "value": "USD"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "d1cac68e-d48a-4322-82de-8a3b50b9c33c",
      "name": "Filter Top Gainers (40% gain, $10M MC, $1M vol)",
      "type": "n8n-nodes-base.code",
      "position": [
        416,
        208
      ],
      "parameters": {
        "jsCode": "var items = $input.all();\nvar cryptoData = items[0].json.data;\n\nvar MIN_PERCENT_CHANGE = 40;\nvar MIN_MARKET_CAP = 10000000;\nvar MIN_VOLUME = 1000000;\n\nvar filteredTokens = [];\n\nfor (var i = 0; i < cryptoData.length; i++) {\n  var token = cryptoData[i];\n  var percentChange = token.quote.USD.percent_change_24h;\n  var marketCap = token.quote.USD.market_cap;\n  var volume = token.quote.USD.volume_24h;\n  \n  if (percentChange >= MIN_PERCENT_CHANGE && \n      marketCap >= MIN_MARKET_CAP && \n      volume >= MIN_VOLUME) {\n    filteredTokens.push({\n      json: {\n        name: token.name,\n        symbol: token.symbol,\n        price: token.quote.USD.price,\n        percent_change_24h: token.quote.USD.percent_change_24h,\n        market_cap: token.quote.USD.market_cap,\n        volume_24h: token.quote.USD.volume_24h,\n        tags: token.tags || []\n      }\n    });\n  }\n}\n\nreturn filteredTokens;"
      },
      "typeVersion": 2
    },
    {
      "id": "59fa7b69-0219-4180-b44c-0cb6933ed19a",
      "name": "Group Tokens by Sector",
      "type": "n8n-nodes-base.code",
      "position": [
        640,
        208
      ],
      "parameters": {
        "jsCode": "var items = $input.all();\n\nvar sectorMapping = {\n  'ai': ['ai', 'artificial-intelligence', 'ai-big-data', 'gpt'],\n  'depin': ['depin', 'infrastructure', 'storage', 'oracle'],\n  'defi': ['defi', 'dex', 'lending', 'yield-farming', 'derivatives', 'stablecoin'],\n  'gaming': ['gaming', 'metaverse', 'nft', 'play-to-earn', 'collectibles'],\n  'rwa': ['rwa', 'real-world-assets', 'tokenized-assets'],\n  'layer1': ['layer-1', 'platform', 'smart-contracts'],\n  'layer2': ['layer-2', 'scaling', 'rollup'],\n  'meme': ['meme', 'memes', 'dog-themed'],\n  'infrastructure': ['oracle', 'data', 'storage', 'privacy', 'interoperability']\n};\n\nfunction determineSector(tags) {\n  if (!tags || tags.length === 0) return 'other';\n  \n  var sectorKeys = Object.keys(sectorMapping);\n  for (var s = 0; s < sectorKeys.length; s++) {\n    var sector = sectorKeys[s];\n    var keywords = sectorMapping[sector];\n    for (var t = 0; t < tags.length; t++) {\n      var tag = tags[t].toLowerCase();\n      for (var k = 0; k < keywords.length; k++) {\n        if (tag.indexOf(keywords[k]) !== -1) {\n          return sector;\n        }\n      }\n    }\n  }\n  return 'other';\n}\n\nvar tokensWithSectors = [];\nfor (var i = 0; i < items.length; i++) {\n  var token = items[i].json;\n  var sector = determineSector(token.tags);\n  var tokenCopy = {};\n  for (var key in token) {\n    tokenCopy[key] = token[key];\n  }\n  tokenCopy.sector = sector;\n  tokensWithSectors.push(tokenCopy);\n}\n\nvar sectorGroups = {};\nfor (var j = 0; j < tokensWithSectors.length; j++) {\n  var tkn = tokensWithSectors[j];\n  var sec = tkn.sector;\n  if (!sectorGroups[sec]) {\n    sectorGroups[sec] = [];\n  }\n  sectorGroups[sec].push(tkn);\n}\n\nvar sectorStats = [];\nvar sectorNames = Object.keys(sectorGroups);\nfor (var m = 0; m < sectorNames.length; m++) {\n  var sectorName = sectorNames[m];\n  var tokens = sectorGroups[sectorName];\n  var totalGain = 0;\n  for (var n = 0; n < tokens.length; n++) {\n    totalGain += tokens[n].percent_change_24h;\n  }\n  var avgGain = totalGain / tokens.length;\n  sectorStats.push({\n    sector: sectorName,\n    count: tokens.length,\n    avgGain: avgGain.toFixed(2),\n    tokens: tokens\n  });\n}\n\nsectorStats.sort(function(a, b) { return b.count - a.count; });\n\nreturn [{\n  json: {\n    totalGainers: tokensWithSectors.length,\n    sectorStats: sectorStats,\n    allTokens: tokensWithSectors\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "9237ccd9-37ec-4ffa-af65-1322eae81200",
      "name": "Prepare Gemini Research Prompts",
      "type": "n8n-nodes-base.code",
      "position": [
        864,
        128
      ],
      "parameters": {
        "jsCode": "var data = $input.first().json;\nvar sectorStats = data.sectorStats;\n\nvar sectorsToResearch = [];\nfor (var i = 0; i < sectorStats.length; i++) {\n  if (sectorStats[i].count >= 2) {\n    sectorsToResearch.push(sectorStats[i]);\n  }\n}\n\nvar prompts = [];\nfor (var j = 0; j < sectorsToResearch.length; j++) {\n  var sectorData = sectorsToResearch[j];\n  \n  var tokenList = '';\n  for (var k = 0; k < sectorData.tokens.length; k++) {\n    var t = sectorData.tokens[k];\n    tokenList += '- ' + t.name + ' (' + t.symbol + '): +' + t.percent_change_24h.toFixed(2) + '% | MC: $' + (t.market_cap / 1000000).toFixed(2) + 'M\\n';\n  }\n  \n  var prompt = 'You are a crypto market analyst. Analyze this sector pump:\\n\\n';\n  prompt += 'SECTOR: ' + sectorData.sector.toUpperCase() + '\\n';\n  prompt += 'Number of tokens pumping: ' + sectorData.count + '\\n';\n  prompt += 'Average gain: ' + sectorData.avgGain + '%\\n\\n';\n  prompt += 'TOKENS:\\n' + tokenList + '\\n';\n  prompt += 'Please research and provide:\\n';\n  prompt += '1. What is driving the ' + sectorData.sector + ' sector today? Search for recent news, announcements, or market catalysts.\\n';\n  prompt += '2. Is this a sector-wide narrative or coincidental?\\n';\n  prompt += '3. Key catalyst or event (be specific with dates/sources)\\n';\n  prompt += '4. Risk assessment: Is this sustainable or likely a short-term pump?\\n';\n  prompt += '5. Confidence level: High/Medium/Low\\n\\n';\n  prompt += 'Keep response concise (3-4 paragraphs max).';\n\n  prompts.push({\n    json: {\n      sector: sectorData.sector,\n      prompt: prompt,\n      tokenCount: sectorData.count,\n      avgGain: sectorData.avgGain\n    }\n  });\n}\n\nreturn prompts;"
      },
      "typeVersion": 2
    },
    {
      "id": "c06477be-d939-470d-afce-5b3e9c63d96e",
      "name": "Gemini Sector Research",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        1088,
        128
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-2.5-flash"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "={\n  \"contents\": [{\n    \"parts\": [{\n      \"text\": \"={{ $json.prompt }}\"\n    }]\n  }],\n  \"generationConfig\": {\n    \"temperature\": 0.7,\n    \"maxOutputTokens\": 1024\n  }\n}"
            }
          ]
        }
      },
      "executeOnce": false,
      "typeVersion": 1
    },
    {
      "id": "2bfc1ab1-5520-4644-9bde-88d1b995b612",
      "name": "Format Sector Analysis Results",
      "type": "n8n-nodes-base.code",
      "position": [
        1440,
        128
      ],
      "parameters": {
        "jsCode": "var items = $input.all();\n\nvar sectors = ['meme', 'ai'];\n\nvar sectorAnalyses = [];\nfor (var i = 0; i < items.length; i++) {\n  var geminiResponse = items[i].json.content.parts[0].text;\n  sectorAnalyses.push({\n    json: {\n      sector: sectors[i],\n      analysis: geminiResponse\n    }\n  });\n}\n\nreturn sectorAnalyses;"
      },
      "typeVersion": 2
    },
    {
      "id": "46954855-e9a0-4d83-ad31-450d635588f0",
      "name": "Merge Sector Data with Analysis",
      "type": "n8n-nodes-base.merge",
      "position": [
        1680,
        224
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "f0a6d9e7-47e1-46a2-9157-437029b31c7b",
      "name": "Create Narrative Digest Report",
      "type": "n8n-nodes-base.code",
      "position": [
        1840,
        128
      ],
      "parameters": {
        "jsCode": "var mergedItem = $input.first().json;\n\nvar sectorData = mergedItem.sectorStats;\nvar analysis = mergedItem.analysis;\n\nvar now = new Date();\nvar dateStr = now.toLocaleString('en-US', { \n  weekday: 'long', \n  year: 'numeric', \n  month: 'long', \n  day: 'numeric',\n  hour: '2-digit',\n  minute: '2-digit',\n  timeZone: 'UTC'\n});\n\nvar separator = '\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501';\n\nvar report = '\ud83d\udd25 CRYPTO NARRATIVE DIGEST\\n';\nreport += '\ud83d\udcc5 ' + dateStr + ' UTC\\n\\n';\nreport += separator + '\\n';\nreport += '\ud83d\udcca MARKET SNAPSHOT\\n';\nreport += 'Total Gainers: ' + mergedItem.totalGainers + ' tokens | ' + sectorData.length + ' sector(s) detected\\n';\nreport += separator + '\\n\\n';\n\nfor (var i = 0; i < sectorData.length; i++) {\n  var sector = sectorData[i];\n  var sectorEmoji = '\ud83d\udcc8';\n  if (sector.sector === 'meme') sectorEmoji = '\ud83c\udfad';\n  else if (sector.sector === 'ai') sectorEmoji = '\ud83e\udd16';\n  else if (sector.sector === 'defi') sectorEmoji = '\ud83d\udcb0';\n  else if (sector.sector === 'gaming') sectorEmoji = '\ud83c\udfae';\n  \n  report += separator + '\\n';\n  report += sectorEmoji + ' SECTOR #' + (i + 1) + ': ' + sector.sector.toUpperCase() + '\\n\\n';\n  \n  report += '\ud83d\udcc8 PERFORMANCE:\\n';\n  for (var j = 0; j < sector.tokens.length; j++) {\n    var token = sector.tokens[j];\n    report += (j + 1) + '. ' + token.name + ' (' + token.symbol + ')\\n';\n    report += '   \u2022 Gain: +' + token.percent_change_24h.toFixed(2) + '%\\n';\n    report += '   \u2022 Market Cap: $' + (token.market_cap / 1000000).toFixed(1) + 'M\\n';\n    report += '   \u2022 Volume: $' + (token.volume_24h / 1000000).toFixed(1) + 'M\\n\\n';\n  }\n  \n  if (analysis) {\n    report += '\ud83d\udd0d KEY INSIGHTS:\\n';\n    var paragraphs = analysis.split('\\n\\n');\n    var paraNum = 1;\n    for (var p = 0; p < paragraphs.length; p++) {\n      var para = paragraphs[p].trim();\n      if (para && para.indexOf('It appears there might be') === -1) {\n        report += paraNum + '. ' + para + '\\n\\n';\n        paraNum++;\n      }\n    }\n  }\n}\n\nreport += separator + '\\n';\nreport += '\ud83d\udca1 Filters: >40% gain \u2022 >$10M market cap \u2022 >$1M volume\\n';\nreport += '\u26a0\ufe0f  For research only - Not financial advice | DYOR\\n';\n\nreturn [{ \n  json: { \n    report: report, \n    timestamp: now.toISOString()\n  } \n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "557d704f-b691-46ee-9931-da6449e82343",
      "name": "Split Report for Discord (2000 char limit)",
      "type": "n8n-nodes-base.code",
      "position": [
        2048,
        128
      ],
      "parameters": {
        "jsCode": "var report = $input.first().json.report;\n\nvar DISCORD_LIMIT = 1900;\n\nvar separator = '\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501';\nvar sections = report.split(separator);\n\nvar messages = [];\nvar currentMessage = '';\n\nfor (var i = 0; i < sections.length; i++) {\n  var sectionText = sections[i].trim();\n  \n  if (!sectionText) continue;\n  \n  if ((currentMessage + sectionText).length > DISCORD_LIMIT) {\n    if (currentMessage) {\n      messages.push(currentMessage);\n    }\n    currentMessage = sectionText + '\\n' + separator + '\\n';\n  } else {\n    currentMessage += sectionText + '\\n' + separator + '\\n';\n  }\n}\n\nif (currentMessage) {\n  messages.push(currentMessage);\n}\n\nvar output = [];\nfor (var j = 0; j < messages.length; j++) {\n  output.push({\n    json: {\n      content: messages[j],\n      partNumber: j + 1,\n      totalParts: messages.length\n    }\n  });\n}\n\nreturn output;"
      },
      "typeVersion": 2
    },
    {
      "id": "5e6384e9-d277-4674-aa71-8e7a31f6c824",
      "name": "Send to Discord",
      "type": "n8n-nodes-base.discord",
      "position": [
        2256,
        128
      ],
      "parameters": {
        "content": "=={{ $json.content }}",
        "options": {},
        "authentication": "webhook"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "db673829-2576-4433-a114-c37e6f4708af",
  "connections": {
    "Gemini Sector Research": {
      "main": [
        [
          {
            "node": "Format Sector Analysis Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Group Tokens by Sector": {
      "main": [
        [
          {
            "node": "Prepare Gemini Research Prompts",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Sector Data with Analysis",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Schedule Trigger (Hourly)": {
      "main": [
        [
          {
            "node": "Fetch Top 200 Gainers from CMC",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Narrative Digest Report": {
      "main": [
        [
          {
            "node": "Split Report for Discord (2000 char limit)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Top 200 Gainers from CMC": {
      "main": [
        [
          {
            "node": "Filter Top Gainers (40% gain, $10M MC, $1M vol)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Sector Analysis Results": {
      "main": [
        [
          {
            "node": "Merge Sector Data with Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Sector Data with Analysis": {
      "main": [
        [
          {
            "node": "Create Narrative Digest Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Gemini Research Prompts": {
      "main": [
        [
          {
            "node": "Gemini Sector Research",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Report for Discord (2000 char limit)": {
      "main": [
        [
          {
            "node": "Send to Discord",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Top Gainers (40% gain, $10M MC, $1M vol)": {
      "main": [
        [
          {
            "node": "Group Tokens by Sector",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}