{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "01ba443c-da8b-4f6e-a010-a3ef376f4139",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1392,
        112
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "855969ab-cdb5-4966-8ed2-87377f859318",
      "name": "Define Developer Searches",
      "type": "n8n-nodes-base.code",
      "position": [
        -1200,
        112
      ],
      "parameters": {
        "jsCode": "// Define your target developer searches\nconst searches = [\n  {\n    location: \"New Jersey\",\n    language: \"javascript\",\n    minFollowers: 50\n  },\n  {\n    location: \"Texas\",\n    language: \"python\",\n    minFollowers: 100\n  },\n  {\n    location: \"New York\",\n    language: \"react\",\n    minFollowers: 200\n  }\n];\n\nreturn searches.map(search => ({ json: search }));"
      },
      "typeVersion": 2
    },
    {
      "id": "cf6adb6b-b5b4-4a17-bff6-06b46df66887",
      "name": "Search GitHub Users",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Replace YOUR_GITHUB_TOKEN with your personal access token",
      "position": [
        -1008,
        112
      ],
      "parameters": {
        "url": "https://api.github.com/search/users",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "=location:{{ $json.location }} followers:>{{ $json.minFollowers }} language:{{ $json.language }}"
            },
            {
              "name": "per_page",
              "value": "30"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/vnd.github.v3+json"
            },
            {
              "name": "Authorization",
              "value": "Github_API_Token"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "ae61b477-85c5-4d18-9883-6ff7a1200511",
      "name": "Parse Users",
      "type": "n8n-nodes-base.code",
      "position": [
        -1008,
        -32
      ],
      "parameters": {
        "jsCode": "const allInputs = $input.all();   // get all input items\nconst developers = [];\n\nallInputs.forEach(input => {\n  const users = input.json.items || [];\n\n  users.forEach(user => {\n    developers.push({\n      json: {\n        username: user.login,\n        profileUrl: user.html_url,\n        avatarUrl: user.avatar_url,\n        userApiUrl: user.url\n      }\n    });\n  });\n});\n\nreturn developers;\n"
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "57e872f8-4778-4272-af2d-5dbcc7104b1b",
      "name": "Get User Details",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Replace YOUR_GITHUB_TOKEN",
      "position": [
        -784,
        -32
      ],
      "parameters": {
        "url": "={{ $json.userApiUrl }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/vnd.github.v3+json"
            },
            {
              "name": "Authorization",
              "value": "Github_API_Token"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "e00f0903-9776-48ac-97a2-81ca557dc374",
      "name": "Extract Developer Data",
      "type": "n8n-nodes-base.code",
      "position": [
        -544,
        224
      ],
      "parameters": {
        "jsCode": "const data = $input.item.json;\n\n// Extract website/blog URL and domain\nlet website = data.blog || \"\";\nlet domain = \"\";\n\nif (website) {\n  try {\n    // Clean up the URL\n    if (!website.startsWith('http')) {\n      website = 'https://' + website;\n    }\n    const url = new URL(website);\n    domain = url.hostname.replace('www.', '');\n  } catch (e) {\n    domain = website;\n  }\n}\n\n// Calculate lead score based on GitHub activity\nlet score = 20; // Base score\n\n// Followers (max 30 points)\nconst followers = data.followers || 0;\nif (followers > 500) score += 30;\nelse if (followers > 200) score += 25;\nelse if (followers > 100) score += 20;\nelse if (followers > 50) score += 15;\nelse score += 10;\n\n// Public repos (max 20 points)\nconst repos = data.public_repos || 0;\nif (repos > 50) score += 20;\nelse if (repos > 20) score += 15;\nelse if (repos > 10) score += 10;\nelse score += 5;\n\n// Has contact info (max 30 points)\nif (data.email) score += 15;\nif (website && website !== \"\") score += 10;\nif (data.company) score += 5;\n\n// Determine quality\nlet quality = \"Cold\";\nif (score >= 70) quality = \"Hot\";\nelse if (score >= 50) quality = \"Warm\";\n\nconst today = new Date().toISOString().split('T')[0];\n\nreturn {\n  json: {\n    name: data.name || data.login,\n    username: data.login,\n    email: data.email || \"Check website\",\n    bio: data.bio || \"\",\n    company: data.company || \"\",\n    location: data.location || \"\",\n    website: website,\n    domain: domain,\n    twitter: data.twitter_username ? `https://twitter.com/${data.twitter_username}` : \"\",\n    followers: followers,\n    following: data.following || 0,\n    publicRepos: repos,\n    profileUrl: data.html_url,\n    avatarUrl: data.avatar_url,\n    leadSource: \"GitHub\",\n    leadScore: Math.min(score, 100),\n    leadQuality: quality,\n    scrapedDate: today,\n    notes: `GitHub developer with ${repos} repos and ${followers} followers. ${data.bio || ''}`\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "078acd2a-fc09-4896-a587-f5decf3f123e",
      "name": "Need Email Enrichment?",
      "type": "n8n-nodes-base.if",
      "position": [
        -288,
        224
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-1",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.domain }}",
              "rightValue": ""
            },
            {
              "id": "condition-2",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.email }}",
              "rightValue": "Check website"
            },
            {
              "id": "0c2a31a2-5e74-44bc-b5c4-78ee30e4bbf4",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "75d37ae2-6945-44c5-a3ad-79a1c6df6155",
      "name": "Hunter.io Email Lookup",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Optional - uses Hunter.io credits",
      "position": [
        -304,
        -64
      ],
      "parameters": {
        "url": "https://api.hunter.io/v2/domain-search",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "domain",
              "value": "={{ $json.domain }}"
            },
            {
              "name": "api_key",
              "value": "Hunter_API_Key"
            },
            {
              "name": "limit",
              "value": "3"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "38c503d3-fd25-4159-9129-c81ee51e356c",
      "name": "Update With Email",
      "type": "n8n-nodes-base.code",
      "position": [
        -48,
        -64
      ],
      "parameters": {
        "jsCode": "const hunterData = $input.item.json.data || {};\nconst emails = hunterData.emails || [];\nconst previousData = $('Extract Developer Data').item.json;\n\nlet bestEmail = previousData.email;\n\nif (emails.length > 0) {\n  const sortedEmails = emails.sort((a, b) => b.confidence - a.confidence);\n  bestEmail = sortedEmails[0].value;\n}\n\nreturn {\n  json: {\n    ...previousData,\n    email: bestEmail,\n    emailConfidence: emails[0]?.confidence || 0\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "4ee6842b-59e2-4d4f-ab23-3802fc9f46fd",
      "name": "Check For Duplicates",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        288,
        -128
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/14HMjinBDThPcs7_D4AUCvFJ6Bvx3WjA2ImGTkrvLCUw/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "14HMjinBDThPcs7_D4AUCvFJ6Bvx3WjA2ImGTkrvLCUw",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/14HMjinBDThPcs7_D4AUCvFJ6Bvx3WjA2ImGTkrvLCUw/edit?usp=drivesdk",
          "cachedResultName": "Lead Scraper Database"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "dd7b6634-4e7b-46e1-9c4f-275046257470",
      "name": "Filter Duplicates",
      "type": "n8n-nodes-base.code",
      "position": [
        288,
        256
      ],
      "parameters": {
        "jsCode": "const existingLeads = $('Check For Duplicates').all();\nconst currentLead = $input.item.json;\n\n// Check if username already exists\nconst isDuplicate = existingLeads.some(item => {\n  const row = item.json;\n  return row['Business Name'] === currentLead.name || \n         row.Email === currentLead.email ||\n         (row.Notes && row.Notes.includes(currentLead.username));\n});\n\nif (isDuplicate) {\n  return [];\n}\n\nreturn [{ json: currentLead }];"
      },
      "typeVersion": 2
    },
    {
      "id": "530fc573-1c93-40d6-84f6-ec2ab1d33a9e",
      "name": "Format For Database",
      "type": "n8n-nodes-base.code",
      "position": [
        512,
        256
      ],
      "parameters": {
        "jsCode": "const data = $input.item.json;\nconst timestamp = Date.now();\nconst randomNum = Math.floor(Math.random() * 1000);\nconst leadId = `GITHUB-${timestamp}-${randomNum}`;\n\nreturn {\n  json: {\n    leadId: leadId,\n    businessName: data.name,\n    contactName: data.name,\n    jobTitle: \"Developer\",\n    email: data.email,\n    phone: \"Not available\",\n    website: data.website,\n    address: data.location,\n    industry: \"Software Development\",\n    companySize: data.company || \"Freelancer\",\n    rating: 0,\n    reviews: 0,\n    leadScore: data.leadScore,\n    leadQuality: data.leadQuality,\n    scrapedDate: data.scrapedDate,\n    status: \"New - Scraped\",\n    contacted: \"No\",\n    notes: data.notes,\n    leadSource: data.leadSource\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "be8f6c5d-fbea-404f-bf4b-603069f5a7b4",
      "name": "Add to Lead Database",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        720,
        256
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "Lead ID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Lead ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Business Name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Business Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contact Name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Contact Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Job Title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Job Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Website",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Website",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Address",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Industry",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Industry",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company Size",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Company Size",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lead Source",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Lead Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Rating",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Rating",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Reviews",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Reviews",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lead Score",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Lead Score",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lead Quality",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Lead Quality",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Scraped Date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Scraped Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contacted",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Contacted",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notes",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/14HMjinBDThPcs7_D4AUCvFJ6Bvx3WjA2ImGTkrvLCUw/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "14HMjinBDThPcs7_D4AUCvFJ6Bvx3WjA2ImGTkrvLCUw",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/14HMjinBDThPcs7_D4AUCvFJ6Bvx3WjA2ImGTkrvLCUw/edit?usp=drivesdk",
          "cachedResultName": "Lead Scraper Database"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "071dc01a-1789-4382-be06-590d9f9ccb22",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        288,
        64
      ],
      "parameters": {
        "mode": "chooseBranch",
        "useDataOfInput": 2
      },
      "typeVersion": 3.2
    },
    {
      "id": "98375c2d-ddef-40e6-a671-c0db2d7d58b4",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1440,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 816,
        "height": 480,
        "content": "## 1. Find Developers on GitHub"
      },
      "typeVersion": 1
    },
    {
      "id": "74e2f051-4251-401f-b67e-f5bd1cf36c08",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -592,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 592,
        "content": "## 2. Find Developers emails using Hunter.io"
      },
      "typeVersion": 1
    },
    {
      "id": "6d36c795-e279-41d3-b63e-fade3d04807c",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 672,
        "content": "## 3. Remove Duplicates and Save To CRM Database"
      },
      "typeVersion": 1
    },
    {
      "id": "3f7aa46a-d008-4ccc-bc6c-9a3ff18d4e54",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2288,
        -272
      ],
      "parameters": {
        "width": 736,
        "height": 800,
        "content": "## GitHub Developer Scraper With Email Lookup and Lead Database Sync\n\n## How it works\n1. Schedule Trigger: start trigger at a certain interval\n2. Define developer searches Code nodes: find a developer at a certain location and demographic\n3. Search GitHub users: Run code through GitHub to collect details\n4. Parse users: Analyze users' data\n5. Get users' details: Return users' data\n6. Extract developer data: clean and organize the returned users' data\n7. Need enrichment: check if no email\n8. Hunter.io email lookup: find and verify user email\n9. Update with email: organize data\n10. Check for duplicate data, remove duplicates, organize for the database and store to Google Sheets accordingly. \n\n## Setup\n* Schedule trigger to start\n* Get the GitHub API and insert it in the \"Search GitHub users\" HTTP request node. Also, insert it in the \"Get user details\" HTTP request node\n* Get Hunter.io API and insert it in the Hunter.io Email Lookup HTTP request\n* Use \"Get the template\" Google sheet\n\n## Get the template sheet: https://docs.google.com/spreadsheets/d/1HyoSj2HncMgap96eNxkzLEMxt1DjO6J4uOj8CHrYkFc/edit?usp=sharing"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Filter Duplicates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Users": {
      "main": [
        [
          {
            "node": "Get User Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get User Details": {
      "main": [
        [
          {
            "node": "Extract Developer Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Define Developer Searches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Duplicates": {
      "main": [
        [
          {
            "node": "Format For Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update With Email": {
      "main": [
        [
          {
            "node": "Check For Duplicates",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Format For Database": {
      "main": [
        [
          {
            "node": "Add to Lead Database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search GitHub Users": {
      "main": [
        [
          {
            "node": "Parse Users",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add to Lead Database": {
      "main": [
        []
      ]
    },
    "Check For Duplicates": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Developer Data": {
      "main": [
        [
          {
            "node": "Need Email Enrichment?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Hunter.io Email Lookup": {
      "main": [
        [
          {
            "node": "Update With Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Need Email Enrichment?": {
      "main": [
        [
          {
            "node": "Hunter.io Email Lookup",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Filter Duplicates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Define Developer Searches": {
      "main": [
        [
          {
            "node": "Search GitHub Users",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}