{
  "name": "YST Twitter Raid Tracker",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 30
            }
          ]
        }
      },
      "id": "d4e5f6a7-0004-0004-0004-000000000001",
      "name": "Schedule Trigger (30min)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.1,
      "position": [
        240,
        380
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://api.twitter.com/2/tweets/search/recent",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "query",
              "value": "$YST OR #YakkStudios OR @YAKKStudios -is:retweet"
            },
            {
              "name": "max_results",
              "value": "20"
            },
            {
              "name": "tweet.fields",
              "value": "public_metrics,created_at,author_id,text"
            },
            {
              "name": "expansions",
              "value": "author_id"
            },
            {
              "name": "user.fields",
              "value": "username,name"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "={{ $credentials.httpHeaderAuth.value }}"
            }
          ]
        },
        "options": {
          "timeout": 15000,
          "continueOnFail": false
        }
      },
      "id": "d4e5f6a7-0004-0004-0004-000000000002",
      "name": "Twitter API Search",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        490,
        380
      ],
      "notes": "Create a Header Auth credential named 'Twitter Bearer Token'.\nSet Name: Authorization\nSet Value: Bearer YOUR_TWITTER_BEARER_TOKEN\n(Include the word 'Bearer ' with a space before your token.)",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Extract per-tweet metrics from Twitter API v2 response\nconst response = $input.first().json;\nconst tweets = response.data || [];\nconst users = (response.includes?.users || []).reduce((map, u) => {\n  map[u.id] = u;\n  return map;\n}, {});\n\nif (tweets.length === 0) {\n  return [{ json: { tweets: [], tweetCount: 0, hasResults: false } }];\n}\n\nconst enriched = tweets.map(tweet => {\n  const metrics = tweet.public_metrics || {};\n  const author = users[tweet.author_id] || {};\n  return {\n    id: tweet.id,\n    text: tweet.text,\n    authorId: tweet.author_id,\n    authorUsername: author.username || 'unknown',\n    authorName: author.name || '',\n    createdAt: tweet.created_at,\n    retweets: metrics.retweet_count || 0,\n    likes: metrics.like_count || 0,\n    replies: metrics.reply_count || 0,\n    impressions: metrics.impression_count || 0,\n    quoteCount: metrics.quote_count || 0,\n    tweetUrl: `https://twitter.com/i/web/status/${tweet.id}`\n  };\n});\n\nreturn [{ json: { tweets: enriched, tweetCount: enriched.length, hasResults: true } }];"
      },
      "id": "d4e5f6a7-0004-0004-0004-000000000003",
      "name": "Extract Tweet Metrics",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        740,
        380
      ]
    },
    {
      "parameters": {
        "jsCode": "// Calculate raid performance scores and rank tweets\n// Score = (retweets * 3) + (likes * 1) + (replies * 2)\n\nconst d = $input.first().json;\n\nif (!d.hasResults || d.tweets.length === 0) {\n  return [{ json: { ...d, scoredTweets: [], topTweet: null, totalImpressions: 0, hasHighPerformer: false } }];\n}\n\nconst scored = d.tweets.map(tweet => ({\n  ...tweet,\n  score: (tweet.retweets * 3) + (tweet.likes * 1) + (tweet.replies * 2)\n}));\n\n// Sort by score descending\nscored.sort((a, b) => b.score - a.score);\n\nconst topTweet = scored[0];\nconst totalImpressions = scored.reduce((sum, t) => sum + t.impressions, 0);\nconst totalRetweets = scored.reduce((sum, t) => sum + t.retweets, 0);\nconst totalLikes = scored.reduce((sum, t) => sum + t.likes, 0);\nconst totalReplies = scored.reduce((sum, t) => sum + t.replies, 0);\nconst hasHighPerformer = topTweet && topTweet.score > 50;\n\nreturn [{\n  json: {\n    scoredTweets: scored,\n    tweetCount: d.tweetCount,\n    topTweet,\n    totalImpressions,\n    totalRetweets,\n    totalLikes,\n    totalReplies,\n    hasHighPerformer,\n    checkTimestamp: new Date().toISOString()\n  }\n}];"
      },
      "id": "d4e5f6a7-0004-0004-0004-000000000004",
      "name": "Calculate Raid Scores",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        990,
        380
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "high-performer-check",
              "leftValue": "={{ $json.hasHighPerformer }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "d4e5f6a7-0004-0004-0004-000000000005",
      "name": "Score > 50?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1240,
        380
      ]
    },
    {
      "parameters": {
        "jsCode": "// Build Telegram raid report message\nconst d = $input.first().json;\nconst top = d.topTweet;\n\nconst impressionsFmt = new Intl.NumberFormat('en-US').format(d.totalImpressions);\nconst tweetPreview = top.text.length > 60 ? top.text.slice(0, 60) + '...' : top.text;\n\nconst message = `\u2694\ufe0f RAID REPORT\\n\\n` +\n  `\ud83d\udcca Tweets tracked: ${d.tweetCount}\\n` +\n  `\ud83d\udd25 Top performer:\\n` +\n  `   @${top.authorUsername}\\n` +\n  `   \"${tweetPreview}\"\\n` +\n  `   Score: ${top.score} (RT:${top.retweets} \u2764\ufe0f:${top.likes} \ud83d\udcac:${top.replies})\\n` +\n  `   \ud83d\udd17 [View Tweet](${top.tweetUrl})\\n\\n` +\n  `\ud83d\udcc8 Total reach: ${impressionsFmt} impressions\\n` +\n  `\ud83d\udd01 Total retweets: ${d.totalRetweets}\\n` +\n  `\u2764\ufe0f Total likes: ${d.totalLikes}\\n` +\n  `\ud83d\udcac Total replies: ${d.totalReplies}\\n\\n` +\n  `Keep raiding! \ud83d\ude80 #YST #YakkStudios`;\n\nreturn [{ json: { ...d, telegramMessage: message } }];"
      },
      "id": "d4e5f6a7-0004-0004-0004-000000000006",
      "name": "Format Raid Report",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1490,
        280
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{ $credentials.httpHeaderAuth.value }}/sendMessage",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"chat_id\":\"@yakkstudios\",\"text\":\"{{ $json.telegramMessage }}\",\"parse_mode\":\"Markdown\",\"disable_web_page_preview\":false}",
        "options": {
          "timeout": 10000,
          "continueOnFail": true
        }
      },
      "id": "d4e5f6a7-0004-0004-0004-000000000007",
      "name": "Telegram Raid Report",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1740,
        280
      ],
      "notes": "Create a Header Auth credential named 'Telegram Bot Token'.\nSet Name: Authorization\nSet Value: <your_bot_token> (just the token, no Bearer prefix).",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Schedule Trigger (30min)": {
      "main": [
        [
          {
            "node": "Twitter API Search",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Twitter API Search": {
      "main": [
        [
          {
            "node": "Extract Tweet Metrics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Tweet Metrics": {
      "main": [
        [
          {
            "node": "Calculate Raid Scores",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Raid Scores": {
      "main": [
        [
          {
            "node": "Score > 50?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Score > 50?": {
      "main": [
        [
          {
            "node": "Format Raid Report",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Format Raid Report": {
      "main": [
        [
          {
            "node": "Telegram Raid Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": true,
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": ""
  },
  "staticData": null,
  "tags": [
    {
      "createdAt": "2026-03-29T02:00:00.000Z",
      "updatedAt": "2026-03-29T02:00:00.000Z",
      "id": "yst-tag-1",
      "name": "YakkStudios"
    }
  ],
  "triggerCount": 1,
  "updatedAt": "2026-03-29T02:00:00.000Z",
  "versionId": "twitter-raid-tracker-v2",
  "active": false
}