Herramienta de recolección de información para vulnerabilidades
Este es unMarket Research, Multimodal AIflujo de automatización del dominio deautomatización que contiene 8 nodos.Utiliza principalmente nodos como Code, HttpRequest, GoogleSheets, ScheduleTrigger. Recopilación automática de recompensas por vulnerabilidades de Twitter a Google Sheets
- •Pueden requerirse credenciales de autenticación para la API de destino
- •Credenciales de API de Google Sheets
Nodos utilizados (8)
{
"id": "Hl5YR8MHd1AyDYXk",
"meta": {
"instanceId": "c5257b5cf4d48704d636909c07c4408a69d6799d0a855eab46287eeb702c84b0",
"templateCredsSetupCompleted": true
},
"name": "BB Tip Harvestor",
"tags": [],
"nodes": [
{
"id": "95247308-430c-4f13-bc7d-98beecb5b945",
"name": "Disparador Programado",
"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": "📒 Resumen del Flujo de Trabajo",
"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 Solicitud",
"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": "Código",
"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": "📒 Procesamiento",
"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": "Añadir o actualizar fila en hoja",
"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 Hojas",
"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
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Intermedio - Investigación de mercado, IA Multimodal
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Compartir este flujo de trabajo