Vulnerability-Bounty-Informationen-Sammler

Fortgeschritten

Dies ist ein Market Research, Multimodal AI-Bereich Automatisierungsworkflow mit 8 Nodes. Hauptsächlich werden Code, HttpRequest, GoogleSheets, ScheduleTrigger und andere Nodes verwendet. Automatische Sammlung von Twitter-Sicherheitslohn- Hinweisen in Google Tabellen

Voraussetzungen
  • Möglicherweise sind Ziel-API-Anmeldedaten erforderlich
  • Google Sheets API-Anmeldedaten
Workflow-Vorschau
Visualisierung der Node-Verbindungen, mit Zoom und Pan
Workflow exportieren
Kopieren Sie die folgende JSON-Konfiguration und importieren Sie sie in n8n
{
  "id": "Hl5YR8MHd1AyDYXk",
  "meta": {
    "instanceId": "c5257b5cf4d48704d636909c07c4408a69d6799d0a855eab46287eeb702c84b0",
    "templateCredsSetupCompleted": true
  },
  "name": "BB Tip Harvestor",
  "tags": [],
  "nodes": [
    {
      "id": "95247308-430c-4f13-bc7d-98beecb5b945",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        320,
        80
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 4
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6b347ec0-fb37-4ce8-889f-2b29bc1b2e1b",
      "name": "📒 Workflow-Übersicht",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -272,
        16
      ],
      "parameters": {
        "color": 4,
        "width": 480,
        "height": 232,
        "content": "## 🎯 Bug Bounty Tip Harvester\n\nAutomatically collects bug bounty tips from Twitter every 4 hours and saves to Google Sheets.\n\n**Setup required:**\n1. Get API key from https://twitterapi.io/\n2. Configure Google Sheets credentials\n3. Update Google Sheet ID"
      },
      "typeVersion": 1
    },
    {
      "id": "fa97a28d-cb1c-4e37-8272-3b6efc7f1a44",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        544,
        80
      ],
      "parameters": {
        "url": "https://api.twitterapi.io/twitter/tweet/advanced_search",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "query",
              "value": "(#bugbountytips OR #bugbounty OR #bugbountytip) -Writeups -discount -phishing -fuck"
            },
            {
              "name": "queryType",
              "value": "Latest"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "OlMRj5cL1g7C7eNH",
          "name": "Twitterapi.io Xcal"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d7ef4868-ef6b-4a57-95f4-b987dbcea50c",
      "name": "📒 Twitter API",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        496,
        -256
      ],
      "parameters": {
        "color": 2,
        "width": 348,
        "height": 198,
        "content": "## 🔐 Twitter API Setup\n\n1. Sign up at https://twitterapi.io/\n2. Get your API key\n3. Add HTTP Header Auth:\n   - **Header**: `x-api-key`\n   - **Value**: `YOUR_API_KEY`"
      },
      "typeVersion": 1
    },
    {
      "id": "e76166b2-e6e4-4543-aad2-68bc8885d231",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        752,
        80
      ],
      "parameters": {
        "jsCode": "// This approach handles both single tweets and collections\n// It focuses on properly formatting the output for n8n\n\nconsole.log(\"Input item structure:\", JSON.stringify($input.item, null, 2));\n\n// Function to format the date in a more human-readable way\nfunction formatDate(dateString) {\n  if (!dateString) return '';\n\n  try {\n    const date = new Date(dateString);\n    // Format: \"March 13, 2025 at 19:25\"\n    return date.toLocaleString('en-US', {\n      year: 'numeric',\n      month: 'long',\n      day: 'numeric',\n      hour: '2-digit',\n      minute: '2-digit',\n    });\n  } catch (error) {\n    console.log(\"Error formatting date:\", error);\n    return dateString; // Return original if parsing fails\n  }\n}\n\n// Check if this is a Twitter Search result with multiple tweets\nif ($input.item.json.tweets && Array.isArray($input.item.json.tweets)) {\n  const items = $input.item.json.tweets.map(tweet => {\n    return {\n      json: {\n        tweetId: tweet.id || '',\n        url: tweet.url || '',\n        content: tweet.text || '',\n        likeCount: tweet.likeCount || 0,\n        retweetCount: tweet.retweetCount || 0,\n        replyCount: tweet.replyCount || 0,\n        quoteCount: tweet.quoteCount || 0,\n        viewCount: tweet.viewCount || 0,\n        createdAt: formatDate(tweet.createdAt),\n      }\n    };\n  });\n\n  console.log(`Processing ${items.length} tweets`);\n  // Return all items\n  return items;\n} else {\n  // This is a single tweet. Just extract and return its data\n  const tweetData = {\n    tweetId: $input.item.json.id || '',\n    url: $input.item.json.url || '',\n    content: $input.item.json.text || '',\n    likeCount: $input.item.json.likeCount || 0,\n    retweetCount: $input.item.json.retweetCount || 0,\n    replyCount: $input.item.json.replyCount || 0,\n    quoteCount: $input.item.json.quoteCount || 0,\n    viewCount: $input.item.json.viewCount || 0,\n    createdAt: formatDate($input.item.json.createdAt)\n  };\n\n  console.log(\"Processing single tweet\");\n\n  // Return as a single item\n  return {\n    json: tweetData\n  };\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "ca01565b-ded3-42af-832c-0662f0ea2c4d",
      "name": "📒 Verarbeitung",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        368
      ],
      "parameters": {
        "color": 3,
        "width": 376,
        "height": 168,
        "content": "## ⚙️ Data Processing\n\nExtracts tweet data and formats for Google Sheets:\n- Tweet content, URLs, engagement metrics\n- Date formatting for proper sorting\n- Handles both single tweets and collections"
      },
      "typeVersion": 1
    },
    {
      "id": "ed06b8aa-c7ac-4e69-8e19-c2ce422f2bdb",
      "name": "Zeile in Tabelle anhängen oder aktualisieren",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        992,
        80
      ],
      "parameters": {
        "columns": {
          "value": {
            "Url": "={{ $json.url }}",
            "Date": "={{ \n  (() => {\n    const raw = $json.createdAt; // e.g. \"July 7, 2025 at 04:43 AM\"\n    const [monthStr, day, yearTime, , time, meridian] = raw.split(/[\\s,]+/);\n    const months = {\n      January: \"01\", February: \"02\", March: \"03\", April: \"04\", May: \"05\", June: \"06\",\n      July: \"07\", August: \"08\", September: \"09\", October: \"10\", November: \"11\", December: \"12\"\n    };\n\n    const [hour, minute] = time.split(\":\").map(Number);\n    let hh = meridian === \"PM\" && hour !== 12 ? hour + 12 : (meridian === \"AM\" && hour === 12 ? 0 : hour);\n    const formattedHour = String(hh).padStart(2, '0');\n\n    return `${yearTime}-${months[monthStr]}-${String(day).padStart(2, '0')} ${formattedHour}:${minute}:00`;\n  })() \n}}",
            "Content": "={{ $json.content }}",
            "TweetID": "={{ $json.tweetId }}",
            "Created At": "={{ $json.createdAt }}"
          },
          "schema": [
            {
              "id": "Content",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "TweetID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "TweetID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Created At",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Created At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "TweetID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "",
          "cachedResultName": "Your Google Sheet"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "GniS74XmPh4KjdoT",
          "name": "Google Sheets beethical"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "462cb2c0-136f-454e-9e32-f7fe734c51a9",
      "name": "📊 Google Sheets",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1248,
        -64
      ],
      "parameters": {
        "color": 5,
        "width": 448,
        "height": 198,
        "content": "## 📊 Google Sheets Setup\n\n1. Create Google Sheet with columns: Date, Created At, TweetID, Content, Url\n2. Set up Google Sheets OAuth2 credentials\n3. Replace empty documentId with your Sheet ID\n\n**Prevents duplicates using TweetID matching**"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "65c1d539-9a53-41ed-af0a-330c314826b9",
  "connections": {
    "e76166b2-e6e4-4543-aad2-68bc8885d231": {
      "main": [
        [
          {
            "node": "ed06b8aa-c7ac-4e69-8e19-c2ce422f2bdb",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fa97a28d-cb1c-4e37-8272-3b6efc7f1a44": {
      "main": [
        [
          {
            "node": "e76166b2-e6e4-4543-aad2-68bc8885d231",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "95247308-430c-4f13-bc7d-98beecb5b945": {
      "main": [
        [
          {
            "node": "fa97a28d-cb1c-4e37-8272-3b6efc7f1a44",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Häufig gestellte Fragen

Wie verwende ich diesen Workflow?

Kopieren Sie den obigen JSON-Code, erstellen Sie einen neuen Workflow in Ihrer n8n-Instanz und wählen Sie "Aus JSON importieren". Fügen Sie die Konfiguration ein und passen Sie die Anmeldedaten nach Bedarf an.

Für welche Szenarien ist dieser Workflow geeignet?

Fortgeschritten - Marktforschung, Multimodales KI

Ist es kostenpflichtig?

Dieser Workflow ist völlig kostenlos. Beachten Sie jedoch, dass Drittanbieterdienste (wie OpenAI API), die im Workflow verwendet werden, möglicherweise kostenpflichtig sind.

Workflow-Informationen
Schwierigkeitsgrad
Fortgeschritten
Anzahl der Nodes8
Kategorie2
Node-Typen5
Schwierigkeitsbeschreibung

Für erfahrene Benutzer, mittelkomplexe Workflows mit 6-15 Nodes

Autor

Hi, I'm an ethical hacker. I hack websites for fun and profit

Externe Links
Auf n8n.io ansehen

Diesen Workflow teilen

Kategorien

Kategorien: 34