├── old ├── .gitignore ├── scraper_usernames │ ├── .gitignore │ ├── scraper.py │ └── scrape_it_from_github_user.py └── main.py ├── requirements.txt ├── state.json ├── __pycache__ ├── state_manager.cpython-311.pyc └── fetching_new_users.cpython-311.pyc ├── .gitignore ├── state_manager.py ├── LICENSE ├── fetching_new_users.py ├── .github └── workflows │ └── master_manual-gh-follower.yml ├── main.py ├── README.md └── usernames.txt /old/.gitignore: -------------------------------------------------------------------------------- 1 | venv -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | python-dotenv 3 | ratelimit -------------------------------------------------------------------------------- /old/scraper_usernames/.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | following_users.txt -------------------------------------------------------------------------------- /state.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_followed_user": "defunkt", 3 | "how_many_bot_followed_so_far_counter": 0, 4 | "last_fetched_user": 136 5 | } -------------------------------------------------------------------------------- /__pycache__/state_manager.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficialCodeVoyage/Github_Automation_Follower_Bot/HEAD/__pycache__/state_manager.cpython-311.pyc -------------------------------------------------------------------------------- /__pycache__/fetching_new_users.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficialCodeVoyage/Github_Automation_Follower_Bot/HEAD/__pycache__/fetching_new_users.cpython-311.pyc -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | follow_users.log 3 | /old/scraper_usernames/.env 4 | old/fething_new_users.ipynb 5 | __pycache__/ 6 | .idea/ 7 | venv/ 8 | .gitattributes 9 | github_follow.log 10 | check_api_call.ipynb -------------------------------------------------------------------------------- /state_manager.py: -------------------------------------------------------------------------------- 1 | # state_manager.py - json operations with main and fetching_new_users 2 | 3 | import json 4 | 5 | STATE_FILE = 'state.json' 6 | 7 | def load_state(): 8 | with open(STATE_FILE, 'r') as file: 9 | state = json.load(file) 10 | return state 11 | 12 | def save_state(state): 13 | with open(STATE_FILE, 'w') as file: 14 | try: 15 | json.dump(state, file, indent=4) 16 | except Exception as e: 17 | print(f"Error occurred while saving state: {e}") 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Pavlo Bondarenko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /old/scraper_usernames/scraper.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from bs4 import BeautifulSoup 3 | 4 | # The URL of the Gist page 5 | url = "https://gist.github.com/paulmillr/2657075/a31455729440672467ada20ac10452d74a871e54" 6 | 7 | # Send a GET request to the page 8 | response = requests.get(url) 9 | 10 | # Check if the request was successful 11 | if response.status_code == 200: 12 | # Parse the HTML content using BeautifulSoup 13 | soup = BeautifulSoup(response.text, 'html.parser') 14 | 15 | # Find the table that contains the usernames 16 | table = soup.find('table') 17 | 18 | if table: 19 | # Extract usernames from the table rows 20 | usernames = [] 21 | for row in table.find_all('tr')[1:]: # Skip the header row 22 | username_cell = row.find('td') 23 | if username_cell: 24 | # Extract the text and strip unnecessary characters 25 | username_with_name = username_cell.text.strip() 26 | 27 | # Split the username at the first occurrence of '(' and take the first part 28 | username = username_with_name.split('(')[0].strip() 29 | 30 | # Append the cleaned username to the list 31 | usernames.append(username) 32 | 33 | # Print the usernames 34 | for username in usernames: 35 | print(username) 36 | else: 37 | print("Table not found on the page.") 38 | else: 39 | print(f"Failed to retrieve the page. Status code: {response.status_code}") 40 | -------------------------------------------------------------------------------- /fetching_new_users.py: -------------------------------------------------------------------------------- 1 | # fetching_new_users.py = only getting 100 new users for each iteration 2 | 3 | import os 4 | import requests 5 | import dotenv 6 | from typing import List 7 | from state_manager import load_state, save_state 8 | 9 | dotenv.load_dotenv() 10 | github_token = os.getenv("GITHUB_TOKEN") # your github token 11 | 12 | 13 | def fetching_users_from_github(users_to_fetch=100, token=None) -> List[str]: 14 | 15 | state = load_state() 16 | last_fetched_user = state.get('last_fetched_user', None) 17 | 18 | querry = 'language:python repos:>2 followers:>10' 19 | url = "https://api.github.com/users" 20 | params = { 21 | 'per_page': users_to_fetch, 22 | 'since': last_fetched_user 23 | 24 | } 25 | headers = { 26 | 'Authorization': f'token {github_token}', 27 | 'Accept': 'application/vnd.github.v3+json', 28 | 'User-Agent': 'Github Follow Script' 29 | } 30 | 31 | try: 32 | response = requests.get(url, params=params, headers=headers) 33 | response.raise_for_status() 34 | data = response.json() 35 | fetched_users_api = response.json() 36 | fetched_users = [user['login'] for user in fetched_users_api] 37 | 38 | 39 | last_fetched_user = fetched_users_api[-1]['id'] 40 | state['last_fetched_user'] = last_fetched_user 41 | save_state(state) 42 | 43 | 44 | except requests.exceptions.HTTPError as e: 45 | print(f"Error: {e}") 46 | except requests.exceptions.RequestException as e: 47 | print(f"Error: {e}") 48 | 49 | return fetched_users 50 | 51 | -------------------------------------------------------------------------------- /.github/workflows/master_manual-gh-follower.yml: -------------------------------------------------------------------------------- 1 | # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy 2 | # More GitHub Actions for Azure: https://github.com/Azure/actions 3 | # More info on Python, GitHub Actions, and Azure App Service: https://aka.ms/python-webapps-actions 4 | 5 | name: Build and deploy Python app to Azure Web App - Manual-gh-follower 6 | 7 | on: 8 | push: 9 | branches: 10 | - master 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: Set up Python version 21 | uses: actions/setup-python@v5 22 | with: 23 | python-version: '3.11' 24 | 25 | - name: Create and start virtual environment 26 | run: | 27 | python -m venv venv 28 | source venv/bin/activate 29 | 30 | - name: Install dependencies 31 | run: pip install -r requirements.txt 32 | 33 | # Optional: Add step to run tests here (PyTest, Django test suites, etc.) 34 | 35 | - name: Zip artifact for deployment 36 | run: zip release.zip ./* -r 37 | 38 | - name: Upload artifact for deployment jobs 39 | uses: actions/upload-artifact@v4 40 | with: 41 | name: python-app 42 | path: | 43 | release.zip 44 | !venv/ 45 | 46 | deploy: 47 | runs-on: ubuntu-latest 48 | needs: build 49 | environment: 50 | name: 'Production' 51 | url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} 52 | permissions: 53 | id-token: write #This is required for requesting the JWT 54 | 55 | steps: 56 | - name: Download artifact from build job 57 | uses: actions/download-artifact@v4 58 | with: 59 | name: python-app 60 | 61 | - name: Unzip artifact for deployment 62 | run: unzip release.zip 63 | 64 | 65 | - name: Login to Azure 66 | uses: azure/login@v2 67 | with: 68 | client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_1DCE186E223F46CDB17A8B74AE70AD4B }} 69 | tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_1B631C54A6FA40E282A5557452B8F98E }} 70 | subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_CB2781C43A1945DBAE727EE1CEAA3BFF }} 71 | 72 | - name: 'Deploy to Azure Web App' 73 | uses: azure/webapps-deploy@v3 74 | id: deploy-to-webapp 75 | with: 76 | app-name: 'Manual-gh-follower' 77 | slot-name: 'Production' 78 | -------------------------------------------------------------------------------- /old/scraper_usernames/scrape_it_from_github_user.py: -------------------------------------------------------------------------------- 1 | import dotenv 2 | import requests 3 | from time import sleep 4 | import time 5 | import os 6 | from dotenv import load_dotenv 7 | 8 | load_dotenv() 9 | # Replace with your GitHub username and token 10 | username = os.getenv("USERNAME") # 11 | token = os.getenv("GITHUB_TOKEN") # 12 | 13 | # GitHub API endpoint and headers 14 | api_url = f"https://api.github.com/users/{username}/following" 15 | headers = {"Authorization": f"token {token}"} 16 | 17 | # Initialize variables 18 | following_users = [] 19 | start_user_number = 107001 # Change this to the user number to start from 20 | per_page = 100 # Max is 100 21 | start_page = start_user_number // per_page + 1 # Calculate the starting page 22 | start_index = start_user_number % per_page # Calculate the index on that page 23 | collected_count = 0 24 | save_interval = 1000 25 | rate_limit_remaining = 5000 26 | 27 | # File name to store usernames 28 | file_name = "following_users.txt" 29 | 30 | # Check if file exists and count the number of existing lines 31 | if os.path.exists(file_name): 32 | with open(file_name, "r") as file: 33 | existing_lines = len(file.readlines()) 34 | else: 35 | existing_lines = 0 36 | 37 | # Set starting line for saving 38 | start_line = existing_lines + 1 39 | 40 | # Start scraping from the calculated page and index 41 | page = start_page 42 | 43 | while True: 44 | # API request to fetch following users 45 | response = requests.get(api_url, headers=headers, params={"per_page": per_page, "page": page}) 46 | data = response.json() 47 | 48 | if response.status_code != 200: 49 | print(f"Error: {response.status_code} - {response.json()}") 50 | break 51 | 52 | if not data: 53 | # No more data, break the loop 54 | break 55 | 56 | # Process data starting from the desired index 57 | if page == start_page: 58 | data = data[start_index:] 59 | 60 | # Extract usernames and add to the list 61 | following_users.extend([user["login"] for user in data]) 62 | collected_count += len(data) 63 | 64 | # Save usernames every 1000 users 65 | if collected_count >= save_interval: 66 | with open(file_name, "a") as file: 67 | for user in following_users: 68 | file.write(user + "\n") 69 | print(f"{len(following_users)} usernames saved to {file_name} starting from line {start_line}") 70 | start_line += len(following_users) 71 | following_users.clear() 72 | collected_count = 0 73 | 74 | # Handle rate limit 75 | rate_limit_remaining = int(response.headers.get("X-RateLimit-Remaining", 0)) 76 | if rate_limit_remaining <= 1: 77 | reset_time = int(response.headers.get("X-RateLimit-Reset", 0)) 78 | sleep_time = max(reset_time - int(time.time()), 0) 79 | print(f"Rate limit hit. Sleeping for {sleep_time} seconds.") 80 | sleep(sleep_time + 1) # Wait until the rate limit resets 81 | continue 82 | 83 | # Print progress 84 | print(f"Page {page} fetched. Total users collected: {collected_count}") 85 | 86 | # Increment page for next API request 87 | page += 1 88 | 89 | # Respectful delay between requests to avoid hitting rate limits too quickly 90 | sleep(10) 91 | 92 | # Save any remaining usernames after the loop ends 93 | if following_users: 94 | with open(file_name, "a") as file: 95 | for user in following_users: 96 | file.write(user + "\n") 97 | print(f"Remaining {len(following_users)} usernames saved to {file_name} starting from line {start_line}") 98 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import os 2 | from datetime import time 3 | from time import sleep 4 | import requests 5 | from fetching_new_users import fetching_users_from_github 6 | import logging 7 | import dotenv 8 | import json 9 | from state_manager import load_state, save_state 10 | from ratelimit import sleep_and_retry, limits 11 | import random 12 | import logging 13 | 14 | #configure logging 15 | logging.basicConfig( 16 | level=logging.INFO, 17 | format="%(asctime)s [%(levelname)s] %(message)s", 18 | handlers=[ 19 | logging.FileHandler("github_follow.log"), 20 | logging.StreamHandler() 21 | ] 22 | ) 23 | 24 | dotenv.load_dotenv() 25 | USERNAMES_FILE = 'usernames.txt' 26 | github_token = os.getenv("GITHUB_TOKEN")# your github token 27 | 28 | 29 | ### read the users from the file 30 | def read_users_from_file(): 31 | with open(USERNAMES_FILE, 'r') as file: 32 | try: 33 | users = file.readlines() 34 | return [user.strip() for user in users] 35 | except FileNotFoundError as e: 36 | print(f"Error occurred while reading users from file: {e}") 37 | return [] 38 | 39 | 40 | ### write the users to a file 41 | def write_users_to_file(users): 42 | with open(USERNAMES_FILE, 'a') as file: 43 | try: 44 | existing_users = read_users_from_file() 45 | for user in users: 46 | if user not in existing_users: 47 | file.write(f"{user}\n") 48 | except IOError as e: 49 | print(f"Error occurred while writing users to file: {e}") 50 | except Exception as e: 51 | print(f"Error occurred while writing users to file: {e}") 52 | 53 | 54 | ### keep track of last followed user 55 | def read_last_followed_user(): 56 | state = load_state() 57 | return state.get('last_followed_user', None) 58 | 59 | 60 | ### write the last followed user to a file 61 | def write_last_followed_user(user): 62 | state = load_state() 63 | state['last_followed_user'] = user 64 | save_state(state) 65 | 66 | 67 | def simple_counter(): 68 | state = load_state() 69 | state['how_many_bot_followed_so_far_counter'] = state.get('how_many_bot_followed_so_far_counter', 0) + 1 70 | save_state(state) 71 | 72 | 73 | ### follow the users 74 | ONE_HOUR = 3600 75 | MAX_CALLS_PER_HOUR = 5000 76 | @sleep_and_retry 77 | @limits(calls=MAX_CALLS_PER_HOUR, period=ONE_HOUR) 78 | def follow_users(users): 79 | 80 | headers = { 81 | 'Authorization': f'token {github_token}', 82 | 'Accept': 'application/vnd.github.v3+json', 83 | 'User-Agent': 'Github Follow Script' 84 | } 85 | 86 | for user in users: 87 | url = f'https://api.github.com/user/following/{user}' 88 | try: 89 | response = requests.put(url, headers=headers) 90 | print(f"Response status code for {user}: {response.status_code}") 91 | write_last_followed_user(user) 92 | simple_counter() 93 | print("sleeping for 3 second") 94 | sleep(random.uniform(3, 6)) 95 | if response.status_code == 204: 96 | logging.info(f"Successfully followed {user}") 97 | elif response.status_code == 404: 98 | logging.info(f"User {user} not found") 99 | elif response.status_code == 429: 100 | logging.info(f"Rate limit exceeded - Sleeping for 100 seconds") 101 | sleep(100) 102 | except requests.exceptions.RequestException as e: 103 | print(f"Error occurred while following {user}: {e}") 104 | 105 | 106 | def main(): 107 | ### fetch 100 users from GitHub 108 | try: 109 | fetched_users = fetching_users_from_github(100, github_token) 110 | print(fetched_users) 111 | write_users_to_file(fetched_users) 112 | logging.info(f"Users written to file: {fetched_users}") 113 | users = read_users_from_file() 114 | # logging.info(f"Users read from file: {users}") 115 | last_user = read_last_followed_user() 116 | logging.info(f"Last followed user: {last_user}") 117 | last_user_index = users.index(last_user) 118 | print(f"Last user index: {last_user_index}") 119 | users_to_follow = users[last_user_index + 1:] 120 | print(f"Users to follow: {users_to_follow}") 121 | follow_users(users_to_follow) 122 | logging.info(f"Users followed: {users_to_follow}") 123 | except Exception as e: 124 | logging.error(f"Error occurred: {e}") 125 | 126 | 127 | if __name__ == '__main__': 128 | # I wll be running on VM 24/7, so I will have a while loop 129 | while True: 130 | try: 131 | main() 132 | print("Sleeping for 90 seconds") 133 | sleep(90) 134 | except Exception as e: 135 | logging.error(f"Error occurred: {e}") 136 | sleep(90) 137 | 138 | -------------------------------------------------------------------------------- /old/main.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import aiohttp 3 | import time 4 | import os 5 | import logging 6 | from typing import List 7 | from dotenv import load_dotenv 8 | 9 | # Load environment variables from .env file 10 | load_dotenv() 11 | 12 | # Configure logging 13 | logging.basicConfig( 14 | level=logging.INFO, # Set to INFO for general logs; use DEBUG for more verbosity 15 | format='%(asctime)s [%(levelname)s] %(message)s', 16 | handlers=[ 17 | logging.FileHandler("../follow_users.log"), 18 | logging.StreamHandler() 19 | ] 20 | ) 21 | 22 | # Constants 23 | USERNAMES_FILE = os.getenv('USERNAMES_FILE', 'usernames.txt') 24 | LAST_LINE_FILE = os.getenv('LAST_LINE_FILE', '../last_line.txt') 25 | GITHUB_TOKEN = os.getenv('GITHUB_TOKEN') 26 | 27 | if not GITHUB_TOKEN: 28 | logging.error("GitHub token not found. Please set GITHUB_TOKEN in the environment variables.") 29 | exit(1) 30 | 31 | # Semaphore to limit concurrent requests (set to 1 for sequential processing) 32 | SEM = asyncio.Semaphore(1) 33 | 34 | # Function to read usernames from a file 35 | def read_usernames(file_path: str) -> List[str]: 36 | try: 37 | with open(file_path, 'r') as file: 38 | usernames = [line.strip() for line in file if line.strip()] 39 | logging.info(f"Loaded {len(usernames)} usernames from '{file_path}'.") 40 | return usernames 41 | except FileNotFoundError: 42 | logging.error(f"Usernames file '{file_path}' not found.") 43 | exit(1) 44 | except Exception as e: 45 | logging.exception(f"An error occurred while reading '{file_path}': {e}") 46 | exit(1) 47 | 48 | # Function to read the last processed line number 49 | def read_last_line(file_path: str) -> int: 50 | if os.path.exists(file_path): 51 | try: 52 | with open(file_path, 'r') as file: 53 | last_line = int(file.read().strip()) 54 | logging.info(f"Resuming from line {last_line + 1}.") 55 | return last_line 56 | except ValueError: 57 | logging.warning(f"Invalid content in '{file_path}'. Starting from the beginning.") 58 | return 0 59 | except Exception as e: 60 | logging.exception(f"An error occurred while reading '{file_path}': {e}") 61 | return 0 62 | logging.info(f"No last line file found. Starting from the beginning.") 63 | return 0 64 | 65 | # Function to write the last processed line number 66 | def write_last_line(file_path: str, line_number: int) -> None: 67 | try: 68 | with open(file_path, 'w') as file: 69 | file.write(str(line_number)) 70 | logging.debug(f"Updated last line to {line_number} in '{file_path}'.") 71 | except Exception as e: 72 | logging.exception(f"An error occurred while writing to '{file_path}': {e}") 73 | 74 | # Asynchronous function to follow a user on GitHub 75 | async def follow_user(session: aiohttp.ClientSession, username: str, line_number: int) -> None: 76 | url = f'https://api.github.com/user/following/{username}' 77 | async with SEM: # Ensure sequential processing 78 | try: 79 | async with session.put(url) as response: 80 | status = response.status 81 | text = await response.text() 82 | 83 | if status == 204: 84 | logging.info(f"Line {line_number + 1}: Successfully followed '{username}'.") 85 | elif status == 404: 86 | logging.warning(f"Line {line_number + 1}: User '{username}' not found.") 87 | elif status == 403 or status == 429: 88 | logging.error(f"Line {line_number + 1}: Rate limit exceeded or forbidden access.") 89 | else: 90 | logging.error(f"Line {line_number + 1}: Failed to follow '{username}': {status}, {text}") 91 | 92 | except Exception as e: 93 | logging.exception(f"Line {line_number + 1}: Error following user '{username}': {e}") 94 | 95 | # Main asynchronous function 96 | async def main(): 97 | usernames = read_usernames(USERNAMES_FILE) 98 | last_line = read_last_line(LAST_LINE_FILE) 99 | total_usernames = len(usernames) 100 | logging.info(f"Starting to follow users from line {last_line + 1} to {total_usernames}.") 101 | 102 | headers = { 103 | 'Authorization': f'token {GITHUB_TOKEN}', 104 | 'Accept': 'application/vnd.github.v3+json', 105 | 'User-Agent': 'GitHub-Follow-Script' # Replace with your application's name 106 | } 107 | 108 | async with aiohttp.ClientSession(headers=headers) as session: 109 | for i, username in enumerate(usernames[last_line:], start=last_line): 110 | await follow_user(session, username, i) 111 | 112 | # Wait for 10 seconds before processing the next user 113 | if i < total_usernames - 1: 114 | #logging.info("Waiting for 10 seconds before following the next user...") 115 | await asyncio.sleep(10) 116 | 117 | # Update the last processed line 118 | write_last_line(LAST_LINE_FILE, i + 1) 119 | 120 | logging.info("Finished processing all usernames.") 121 | 122 | if __name__ == "__main__": 123 | try: 124 | asyncio.run(main()) 125 | except KeyboardInterrupt: 126 | logging.info("Script interrupted by user.") 127 | except Exception as e: 128 | logging.exception(f"An unexpected error occurred: {e}") 129 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 GitHub Automation Follower Bot 2 | 3 | ## 🎉 Introduction 4 | 5 | The GitHub Automation Follower Bot is a fully automated tool designed to streamline the process of discovering and following GitHub users based on specific criteria. The goal of this bot to follow **1 000 000** users on Github based on your criteria! 6 | 7 | You have two options to run the script: 8 | 9 | 1. **Run on your local machine:** Ideal for testing and short-term usage. 10 | 11 | [Jump to Installation on local machine](#-installation-on-local-machine) 12 | 13 | 3. **Set up a Virtual Machine (VM) to run 24/7:** Recommended to maximize the effect by continuously running the bot without interruption. 14 | 15 | [Jump to Installation on VM](#-installation-on-virtual-machine) 16 | 17 | 18 | ## ⭐ New Features 19 | 20 | - **🤖 Automated User Scraping:** Transitioned from manual user lists to automated scraping using the GitHub API, eliminating the need for manual updates. 21 | - **💾 Automated State Management:** Introduced state management with `state.json` to persist progress and ensure smooth resumption after interruptions. 22 | - **🖥️ 24/7 VM Deployment:** Optimized for continuous operation on a virtual machine, allowing the bot to run around the clock without manual restarts. 23 | 24 | ## 📁 File Descriptions 25 | 26 | - **`main.py`:** The entry point of the bot. It orchestrates the main flow, handles logging, and ensures continuous operation with a `while True` loop. 27 | - **`fetching_new_users.py`:** Fetches a specified number of new GitHub users based on criteria using the GitHub API. 28 | - **`state_manager.py`:** Manages the loading and saving of the bot's state, ensuring progress is saved and can be resumed. 29 | - **`state.json`:** A JSON file that stores information such as the last followed user and tracking counters for state persistence. 30 | 31 | ## 🛠️ How It Works 32 | 33 | 1. **Automated User Scraping:** 34 | - The bot uses `fetching_new_users.py` to automatically fetch new GitHub users based on specified criteria. 35 | - It leverages the GitHub API to retrieve users, removing the need for manual username lists. 36 | 37 | 2. **State Management:** 38 | - `state_manager.py` handles loading and saving the bot's state to `state.json`. 39 | - This ensures that the bot can resume from where it left off in case of interruptions. 40 | 41 | 3. **Continuous Operation:** 42 | - `main.py` runs an infinite loop (`while True`) to keep the bot running continuously. 43 | - Designed for deployment on a VM for 24/7 operation. 44 | 45 | 46 | ## 📦 Installation on local machine 47 | 48 | ### 🛠️ Prerequisites 49 | 50 | - **🐍 Python 3.6 or higher** 51 | - **🔑 GitHub Personal Access Token (PAT)** 52 | - **Scopes Required:** `read:user`, `user:follow` 53 | - [Creating a PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) 54 | 55 | ### 📜 Steps 56 | 57 | 1. **Clone the Repository:** 58 | 59 | ```sh 60 | git https://github.com/OfficialCodeVoyage/Github_Automation_Follower_Bot.git 61 | cd Github_Automation_Follower_Bot 62 | ``` 63 | 64 | 2. **Set Up a Virtual Environment (Optional but Recommended):** 65 | 66 | ```sh 67 | python -m venv venv 68 | # Activate the virtual environment: 69 | # On Windows: 70 | venv\Scripts\activate 71 | # On macOS/Linux: 72 | source venv/bin/activate 73 | ``` 74 | 75 | 3. **Install the Required Python Packages:** 76 | 77 | It's recommended to use a `requirements.txt` file for managing dependencies. Ensure you have a `requirements.txt` file with the following content: 78 | 79 | ```plaintext 80 | requests 81 | python-dotenv 82 | ratelimit 83 | ``` 84 | 85 | Then, install the dependencies: 86 | 87 | ```sh 88 | pip install -r requirements.txt 89 | ``` 90 | 91 | **⚠️ Note:** Avoid installing standard library modules like `time` via `pip` as they are already included with Python. 92 | 93 | 94 | ## 📦 Installation on Virtual Machine 95 | TBD - TBD 96 | 97 | 98 | 99 | ## 🛠️ Usage 100 | 101 | ### 1. **🔧 Configure Environment Variables** 102 | 103 | Create a `.env` file in the root directory of the project to securely store your GitHub PAT and other configurations. 104 | 105 | ```dotenv 106 | GITHUB_TOKEN="your_github_personal_access_token_here" 107 | ``` 108 | 109 | ### 2. 📄 Prepare the Usernames File 110 | 111 | Create a file named usernames.txt in the same directory as the script and add the GitHub usernames you want to follow, 112 | one per line. You are welcome to use my file as an example. 113 | 114 | ### 3. 🚀 Run the Script 115 | 116 | ```sh 117 | python follow_users.py 118 | ``` 119 | 120 | 🔍 Optional Parameters: 121 | 122 | If you want to specify a starting line number (useful for resuming), you can modify the .env file: 123 | 124 | ```dotenv 125 | START_LINE=0# Change to the desired line number (0-indexed) 126 | ``` 127 | 📝 Note: The script automatically resumes from the last processed line by reading the last_line.txt file. Adjusting START_LINE can override this behavior if needed. 128 | 129 | 130 | ## 🤝 Contributing 131 | 132 | We welcome contributions from the community! Here’s how you can help: 133 | 134 | 1. **Fork the Repository.** 135 | 136 | 2. **Create a New Branch:** 137 | 138 | ```sh 139 | git checkout -b feature-branch 140 | ``` 141 | 142 | 3. **Make Your Changes and Commit Them:** 143 | 144 | ```sh 145 | git commit -m "Add new feature" 146 | ``` 147 | 148 | 4. **Push to the Branch:** 149 | 150 | ```sh 151 | git push origin feature-branch 152 | ``` 153 | 154 | 5. **Open a Pull Request.** 155 | 156 | ## 🛡️ Security Best Practices 157 | 158 | - **🚫 Never Commit `.env` Files:** 159 | Ensure that `.env` is listed in `.gitignore` to prevent accidental commits of sensitive information. 160 | 161 | - **🔒 Use Git Hooks to Prevent Secret Exposure:** 162 | Implement tools like `git-secrets` to scan for sensitive data before allowing commits. 163 | 164 | - **🔄 Regularly Rotate Personal Access Tokens (PATs):** 165 | Periodically revoke and regenerate PATs to minimize the risk of unauthorized access. 166 | 167 | - **👥 Educate Collaborators:** 168 | Ensure that all team members are aware of best practices for handling secrets and sensitive information. 169 | 170 | ## 📜 License 171 | 172 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. 173 | 174 | ## 📚 Additional Resources 175 | 176 | - **📖 GitHub REST API Documentation:** 177 | [https://docs.github.com/en/rest](https://docs.github.com/en/rest) 178 | 179 | - **🛠️ BFG Repo-Cleaner:** 180 | [https://rtyley.github.io/bfg-repo-cleaner/](https://rtyley.github.io/bfg-repo-cleaner/) 181 | 182 | - **🔐 GitHub Secret Scanning:** 183 | [https://docs.github.com/en/code-security/secret-scanning](https://docs.github.com/en/code-security/secret-scanning) 184 | 185 | - **📝 GitHub CLI Documentation:** 186 | [https://cli.github.com/manual/](https://cli.github.com/manual/) 187 | -------------------------------------------------------------------------------- /usernames.txt: -------------------------------------------------------------------------------- 1 | karpathy 2 | openai 3 | rafaballerini 4 | google 5 | geohot 6 | huggingface 7 | michaelliao 8 | llSourcell 9 | taylorotwell 10 | 3b1b 11 | ry 12 | krishnaik06 13 | kennethreitz 14 | buckyroberts 15 | tiangolo 16 | facebookresearch 17 | rasbt 18 | jwasham 19 | gvanrossum 20 | python 21 | techwithtim 22 | mitsuhiko 23 | MorvanZhou 24 | donnemartin 25 | elyxdev 26 | Visualize-ML 27 | BEPb 28 | jakevdp 29 | liyupi 30 | fchollet 31 | tensorflow 32 | iam-veeramalla 33 | chiphuyen 34 | wesm 35 | ageron 36 | lllyasviel 37 | goodfeli 38 | fengdu78 39 | breakwa11 40 | angusshire 41 | miguelgrinberg 42 | leerob 43 | aws-samples 44 | Stability-AI 45 | JohnHammond 46 | GoogleCloudPlatform 47 | jrohitofficial 48 | amueller 49 | htr-tech 50 | eust-w 51 | mnielsen 52 | t3dotgg 53 | flipperdevices 54 | bojone 55 | jhaddix 56 | google-research 57 | home-assistant 58 | jvns 59 | alex 60 | Sentdex 61 | AllenDowney 62 | replicate 63 | pjreddie 64 | noob-hackers 65 | pytorch 66 | george0st 67 | Jack-Cherish 68 | colah 69 | abhishekkrthakur 70 | jcjohnson 71 | THUDM 72 | ChristianLempa 73 | 521xueweihan 74 | CleverProgrammer 75 | s0md3v 76 | carpedm20 77 | NeuralNine 78 | lepture 79 | evilsocket 80 | swisskyrepo 81 | lilianweng 82 | EbookFoundation 83 | vinta 84 | django 85 | Germey 86 | drkostas 87 | UberGuidoZ 88 | davidbombal 89 | awslabs 90 | ip681 91 | rougier 92 | phith0n 93 | simonw 94 | byt3bl33d3r 95 | divanov11 96 | ethanflower1903 97 | rwightman 98 | Rafaelmdcarneiro 99 | labuladong 100 | rhiever 101 | giswqs 102 | Lightning-AI 103 | Fernanda-Kipper 104 | LingDong- 105 | qiwsir 106 | ultralytics 107 | PySimpleGUI 108 | cmlsharp 109 | yihong0618 110 | ashishps1 111 | daveshap 112 | Neo23x0 113 | eliben 114 | avelino 115 | fogleman 116 | sebastianruder 117 | sobolevn 118 | asottile 119 | lmstudio-ai 120 | hak5darren 121 | lidangzzz 122 | vakila 123 | KevinHock 124 | aymericdamien 125 | murtazahassan 126 | dabeaz 127 | huangzworks 128 | SkalskiP 129 | alanhamlett 130 | jindongwang 131 | Uniswap 132 | rfyiamcool 133 | samuelcolvin 134 | NationalSecurityAgency 135 | wepe 136 | hardmaru 137 | asweigart 138 | ogrisel 139 | meta-llama 140 | joelgrus 141 | mistralai 142 | CamDavidsonPilon 143 | gakonst 144 | acantril 145 | marcan 146 | Ignitetechnologies 147 | oobabooga 148 | arpitbbhayani 149 | pandas-dev 150 | odoo 151 | inconvergent 152 | lazyprogrammer 153 | hmason 154 | rochacbruno 155 | iamtrask 156 | cclauss 157 | yeasy 158 | kovidgoyal 159 | orangetw 160 | pydanny 161 | AtsushiSakai 162 | scikit-learn 163 | OpenBMB 164 | ageitgey 165 | karan 166 | jlevy 167 | lodhik9 168 | ring04h 169 | ramalho 170 | anyproto 171 | josephmisiti 172 | HackerPoet 173 | blackmatrix7 174 | hunkim 175 | bregman-arie 176 | developerrahulofficial 177 | willmcgugan 178 | dunossauro 179 | zedshaw 180 | LAION-AI 181 | cypherm0nk 182 | 0dayCTF 183 | rhettinger 184 | progrium 185 | tomchristie 186 | Borda 187 | adamchainz 188 | wangshub 189 | Significant-Gravitas 190 | lijiejie 191 | crowsonkb 192 | jalammar 193 | ymcui 194 | Akkariiin 195 | x0rz 196 | formidablae 197 | xinntao 198 | brightmart 199 | omarsar 200 | yunjey 201 | dbader 202 | jofpin 203 | ChristianChiarulli 204 | dongweiming 205 | TideSec 206 | codingo 207 | shenweichen 208 | iNeuronai 209 | erikbern 210 | EdOverflow 211 | sgugger 212 | chubin 213 | wsvincent 214 | g0tmi1k 215 | vitorfs 216 | nvie 217 | LauraBeatris 218 | guilhermeonrails 219 | mubix 220 | mongodb 221 | jrosebr1 222 | merveenoyan 223 | shykes 224 | bannedbook 225 | GaelVaroquaux 226 | floodsung 227 | twiecki 228 | yang-song 229 | extreme-assistant 230 | Mr-Un1k0d3r 231 | fxsjy 232 | FreeCAD 233 | aantonop 234 | FeeiCN 235 | zhoubolei 236 | mwaskom 237 | geekan 238 | felixonmars 239 | srush 240 | dragen1860 241 | VikParuchuri 242 | CHYbeta 243 | leah 244 | hiddify 245 | adi1090x 246 | merrymercy 247 | boy-hack 248 | jacobian 249 | tkipf 250 | noahgift 251 | CyberSecurityUP 252 | ChoiceCoin 253 | dipanjanS 254 | j2kun 255 | rajkumardusad 256 | Daynlight 257 | ehmatthes 258 | dcramer 259 | mikeckennedy 260 | Akegarasu 261 | keon 262 | LukeMathWalker 263 | m4ll0k 264 | JonathanSalwan 265 | emilybache 266 | DanMcInerney 267 | SudalaiRajkumar 268 | binux 269 | orhun 270 | livid 271 | lilydjwg 272 | soimort 273 | commaai 274 | Kyubyong 275 | kiransagar1 276 | QwenLM 277 | MuiseDestiny 278 | r0ysue 279 | BruceEckel 280 | linuxmint 281 | RimoChan 282 | riverscuomo 283 | logankilpatrick 284 | colinhacks 285 | AI0228 286 | NielsRogge 287 | Ridter 288 | comfyanonymous 289 | cisagov 290 | waylybaye 291 | aldrshan 292 | gaogaotiantian 293 | ashishkumar30 294 | chenjiandongx 295 | llvm 296 | hemantapkh 297 | jezdez 298 | nlohmann 299 | ProgrammerZamanNow 300 | riusksk 301 | AntonOsika 302 | stamparm 303 | CarlosAlexandre197 304 | dlloyd09 305 | alexforencich 306 | hyperb1iss 307 | sayakpaul 308 | ansible 309 | rdegges 310 | balloob 311 | kamyu104 312 | ContinuumIO 313 | OCA 314 | greyli 315 | modelscope 316 | mblondel 317 | andrewgodwin 318 | scutan90 319 | ranaroussi 320 | ujjwalkarn 321 | anathonic 322 | mgeeky 323 | justcallmekoko 324 | ayyucekizrak 325 | bamos 326 | shmilylty 327 | banteg 328 | ktbyers 329 | realpython 330 | uvipen 331 | l3m0n 332 | jupyter 333 | wkentaro 334 | geektutu 335 | TheKingOfDuck 336 | RicterZ 337 | jacobsomer 338 | OpenGVLab 339 | wzhe06 340 | wardviaene 341 | williamFalcon 342 | nschloe 343 | mdisec 344 | fs0c131y 345 | frappe 346 | mahmoud 347 | phuslu 348 | Newmu 349 | aaronsw 350 | CharlesPikachu 351 | sb2nov 352 | bhattbhavesh91 353 | KasRoudra 354 | misterch0c 355 | yichengchen 356 | temirovazat 357 | lucasjinreal 358 | nedbat 359 | twtrubiks 360 | cvrebert 361 | laike9m 362 | StanGirard 363 | bobuk 364 | Cracked5pider 365 | brandon-rhodes 366 | kodekloudhub 367 | ChenglongChen 368 | turicas 369 | yenchenlin 370 | songhan 371 | mingrammer 372 | gazijarin 373 | WalletConnect 374 | wbond 375 | kgretzky 376 | bfirsh 377 | madawei2699 378 | 1st1 379 | toxtli 380 | axi0mX 381 | shervinea 382 | 0atman 383 | Perkles 384 | yk 385 | judygab 386 | ambv 387 | Sam666O 388 | sdispater 389 | charlax 390 | rspivak 391 | amitness 392 | haris989 393 | elebumm 394 | theacodes 395 | ptrblck 396 | WongKinYiu 397 | philipperemy 398 | patrick-kidger 399 | shidenggui 400 | LandGrey 401 | brettcannon 402 | KillianLucas 403 | isislovecruft 404 | servetgulnaroglu 405 | chenyuntc 406 | adrianholovaty 407 | Rvn0xsy 408 | coleifer 409 | TencentARC 410 | ZHO-ZHO-ZHO 411 | AlexisAhmed 412 | MoienTajik 413 | zhzyker 414 | cbfinn 415 | Kulbear 416 | neargle 417 | astonzhang 418 | timgraham 419 | t3l3machus 420 | awsdocs 421 | henriquebastos 422 | mtlynch 423 | foosel 424 | pythontoday 425 | tomast1337 426 | hemansnation 427 | PrettyPrinted 428 | davidism 429 | Yixiaohan 430 | keras-team 431 | hpdang 432 | Premalatha-success 433 | meliksahyorulmazlar 434 | Ehco1996 435 | IDEA-Research 436 | ibab 437 | hamelsmu 438 | mandatoryprogrammer 439 | perborgen 440 | labmlai 441 | dynamicwebpaige 442 | ask 443 | megadose 444 | teknium1 445 | Rapptz 446 | Eugeny 447 | bit4woo 448 | vysecurity 449 | bryanyzhu 450 | musikalkemist 451 | zardus 452 | stefan-jansen 453 | leggedrobotics 454 | nvbn 455 | cheetz 456 | audreyfeldroy 457 | messense 458 | hzwer 459 | remzi-arpacidusseau 460 | tapaswenipathak 461 | DataDog 462 | taki0112 463 | opengeos 464 | xpn 465 | bentrevett 466 | littlecodersh 467 | AISoltani 468 | fmasanori 469 | petertodd 470 | sdushantha 471 | pycodebr 472 | honnibal 473 | binance 474 | quantopian 475 | getsentry 476 | mattjj 477 | clear-code-projects 478 | D4Vinci 479 | Y4er 480 | tobegit3hub 481 | tonybaloney 482 | zigoo0 483 | Rust-Sol-Dev 484 | NoahZinsmeister 485 | TeoCalvo 486 | alexey-goloburdin 487 | robbiebarrat 488 | Project-MONAI 489 | RedHatOfficial 490 | WangYihang 491 | Xyntax 492 | torproject 493 | Hannan-404 494 | fanquake 495 | Anankke 496 | danijar 497 | robmarkcole 498 | jgamblin 499 | mrocklin 500 | ZeroMemoryEx 501 | hackerxphantom 502 | ethanhe42 503 | ashish1294 504 | uknowsec 505 | PegasusWang 506 | mattharrison 507 | victorbjorklund 508 | freakboy3742 509 | nnja 510 | noraj 511 | ericmjl 512 | davideuler 513 | curiousily 514 | sloria 515 | run-llama 516 | timwhitez 517 | rlabbe 518 | jazzband 519 | yaahc 520 | stong 521 | dataiteam 522 | achael 523 | RubensZimbres 524 | saghul 525 | amazon-science 526 | zer0yu 527 | tridao 528 | p0dalirius 529 | Hvass-Labs 530 | huseinzol05 531 | vcwild 532 | jkbrzt 533 | ajinabraham 534 | httpie 535 | yaringal 536 | zachgoll 537 | STARK-404 538 | vas3k 539 | carltongibson 540 | secretsquirrel 541 | mistercrunch 542 | hpreston 543 | kvfrans 544 | ashawkey 545 | mre 546 | CiscoDevNet 547 | ohld 548 | lxRbckl 549 | Lucifer1993 550 | sunnysavita10 551 | hpcaitech 552 | blueedgetechno 553 | Arachnid 554 | veekaybee 555 | pirate 556 | imhuay 557 | random-robbie 558 | SummerSec 559 | zanfranceschi 560 | xiaolonw 561 | Sven-Bo 562 | NullArray 563 | ncbi 564 | 00mjk 565 | jesstess 566 | awjuliani 567 | yidao620c 568 | pypa 569 | Textualize 570 | WhitePoodleMoth 571 | Wanderson-Magalhaes 572 | blackhatethicalhacking 573 | entbappy 574 | aparrish 575 | BBuf 576 | ternaus 577 | wzpan 578 | Bitwise-01 579 | richzhang 580 | bee-san 581 | xiaolincoder 582 | bitprophet 583 | n1nj4sec 584 | guicarvalho 585 | alexjc 586 | cuducos 587 | xairy 588 | Spartanlasergun 589 | DarkCoderSc 590 | Zheaoli 591 | AngelSecurityTeam 592 | sigmavirus24 593 | Zulko 594 | googlecolab 595 | piglei 596 | guofei9987 597 | web3batman 598 | lcdevelop 599 | stanfordnlp 600 | BrodieRobertson 601 | REMitchell 602 | yutiansut 603 | laixintao 604 | trietptm 605 | encode 606 | infosec-au 607 | qiyeboy 608 | JessicaSachs 609 | 404notf0und 610 | ahangchen 611 | arendst 612 | LoRexxar 613 | bdarnell 614 | Alex-bytedroid 615 | rg3 616 | hynek 617 | awni 618 | tr4m0ryp 619 | hpc203 620 | fantasy1114 621 | mlc-ai 622 | DGKSK8LIFE 623 | Yenthe666 624 | dayoonasanya 625 | mxrch 626 | mandiant 627 | yt-dlp 628 | benhamner 629 | tintinweb 630 | shreyashankar 631 | conanhujinming 632 | trustedsec 633 | ErikBjare 634 | YJango 635 | bigcode-project 636 | pallets 637 | yuandong-tian 638 | nexxeln 639 | AlexxIT 640 | krishnadey30 641 | Obijuan 642 | tualatrix 643 | databricks-academy 644 | Tib3rius 645 | robcarver17 646 | jackyzha0 647 | Cyfrin 648 | careermonk 649 | Diolinux 650 | micahflee 651 | dfm 652 | mattmakai 653 | fperez 654 | Q1mi 655 | ruotianluo 656 | wagoodman 657 | samuelclay 658 | psf 659 | ShuoYangRobotics 660 | mr-karan 661 | Peng-YM 662 | CyberPunkMetalHead 663 | robertmartin8 664 | TeoMeWhy 665 | zsdonghao 666 | rvrsh3ll 667 | lipiji 668 | microverseinc 669 | taizilongxu 670 | Chan9390 671 | hongqn 672 | ikostrikov 673 | dpgaspar 674 | facebookincubator 675 | foone 676 | plotly 677 | fafhrd91 678 | singleton11 679 | Hironsan 680 | sahildua2305 681 | localstack 682 | TennyZhuang 683 | mikedewar 684 | pdeitel 685 | chenzomi12 686 | asvetlov 687 | BishopFox 688 | eevee 689 | TarrySingh 690 | tennc 691 | AlessandroZ 692 | MilesCranmer 693 | guoday 694 | ajdavis 695 | atashfeshan 696 | ChrisTruncer 697 | carlini 698 | vmware 699 | Python3WebSpider 700 | wklken 701 | ritchieng 702 | cloudcommunity 703 | binhnguyennus 704 | paperswithcode 705 | ihciah 706 | zzzeek 707 | Dr-TSNG 708 | achow101 709 | ritchie46 710 | zhiwehu 711 | platformio 712 | lmcinnes 713 | morrolinux 714 | vulnersCom 715 | abuhabban 716 | irvaniamirali 717 | brohrer 718 | frostming 719 | WebBreacher 720 | starkware-libs 721 | Z-Siqi 722 | imartinez 723 | skickar 724 | 0x90 725 | pry0cc 726 | hellock 727 | ProbiusOfficial 728 | Medicean 729 | AprendeIngenia 730 | Gameye98 731 | thiagofa 732 | botherder 733 | leportella 734 | moskytw 735 | ericholscher 736 | eastmountyxz 737 | XTeam-Wing 738 | inducer 739 | datitran 740 | Miserlou 741 | oppia 742 | ShizukuIchi 743 | stephenmcd 744 | aviaryan 745 | hoochanlon 746 | thtrieu 747 | jorisvandenbossche 748 | rishavchanda 749 | PromtEngineer 750 | shelhamer 751 | tkhirianov 752 | kaiwalyakoparkar 753 | strazzere 754 | terraform-google-modules 755 | chronark 756 | ossf 757 | phalt 758 | dbt-labs 759 | alireza0 760 | brentp 761 | molly 762 | swapagarwal 763 | j3ssie 764 | teamdandelion 765 | hjwp 766 | kubeflow 767 | vmihailenco 768 | PaulSec 769 | craffel 770 | vstinner 771 | apparentlymart 772 | Lukasa 773 | smartcontracts 774 | aleenzz 775 | agramfort 776 | Furkan-Gulsen 777 | k4m4 778 | 0xInfection 779 | davidsandberg 780 | willingc 781 | shadow5688 782 | Carreau 783 | TomAugspurger 784 | wiseodd 785 | howl-anderson 786 | PwnFunction 787 | devttys0 788 | bashtage 789 | aaugustin 790 | gunthercox 791 | KathanP19 792 | wh1t3p1g 793 | 0xfff0800 794 | Y4tacker 795 | RoseSecurity 796 | soxoj 797 | peterbe 798 | zema1 799 | KingOfBugbounty 800 | openex-network 801 | OJ 802 | hexiangnan 803 | NirantK 804 | dgtlmoon 805 | jtemporal 806 | cystanford 807 | andrewsyc 808 | astrojuanlu 809 | mpdehaan 810 | svpino 811 | santosomar 812 | adarob 813 | minrk 814 | ayaka14732 815 | maxg203 816 | Orange-Cyberdefense 817 | 3150601355 818 | seanpm2001 819 | ZoomQuiet 820 | enjoy-digital 821 | luyishisi 822 | BotolMehedi 823 | mhausenblas 824 | Hawstein 825 | internetarchive 826 | saelo 827 | seisman 828 | pinecone-io 829 | HeshamAsem 830 | iswbm 831 | wdxtub 832 | ultrafunkamsterdam 833 | asciimoo 834 | Jelleas 835 | ytisf 836 | mdsecactivebreach 837 | LimerBoy 838 | ecnerwala 839 | hktalent 840 | teoliphant 841 | nneonneo 842 | jtauber 843 | HadzhieV777 844 | mpgn 845 | crownpku 846 | harshadvali11 847 | Farama-Foundation 848 | 0x727 849 | zygmuntz 850 | eatonphil 851 | dennyzhang 852 | ChristosChristofidis 853 | FunnyWolf 854 | cazzwastaken 855 | yasoob 856 | jakewright 857 | corazzon 858 | adulau 859 | plantsgo 860 | maxcohen31 861 | TimDettmers 862 | Flangvik 863 | blackorbird 864 | termuxhackers-id 865 | rushter 866 | RodolfoFerro 867 | juanpflores 868 | mstrYoda 869 | GDQuest 870 | jd 871 | PatrykIA 872 | mnot 873 | hugsy 874 | kimiyoung 875 | a312863063 876 | milad-azami 877 | shamhi 878 | econchick 879 | equinor 880 | dstufft 881 | chendaniely 882 | Sophia-11 883 | coffeehb 884 | Bo0oM 885 | OpenBB-finance 886 | satwikkansal 887 | h9-tect 888 | xenova 889 | leticiadasilva 890 | linuxscout 891 | wnzhang 892 | ArduPilot 893 | Kourva 894 | sml2h3 895 | StanislavPetrovV 896 | Panther-12 897 | ellisonleao 898 | apenwarr 899 | jmpews 900 | PicPay 901 | jsvine 902 | kevinzakka 903 | benanne 904 | GFW-knocker 905 | zerodha 906 | mytechnotalent 907 | astorfi 908 | EZFNDEV 909 | skelsec 910 | thautwarm 911 | huxiaoman7 912 | ruppysuppy 913 | xianhu 914 | ajtulloch 915 | FranxYao 916 | cocomelonc 917 | stephencwelch 918 | uranusjr 919 | ZephrFish 920 | PrasoonPratham 921 | MUMIT-404-CYBER 922 | EdjeElectronics 923 | pipermerriam 924 | lcatro 925 | vsitzmann 926 | xnl-h4ck3r 927 | DingXiaoH 928 | Ranginang67 929 | kdeldycke 930 | kmike 931 | gpu-mode 932 | Azim-Vau 933 | perone 934 | ildoonet 935 | TomSchimansky 936 | bmaltais 937 | guillaume-chevalier 938 | JuanBindez 939 | truell20 940 | evildevill 941 | tuna 942 | bansalkanav 943 | holiman 944 | defaultnamehere 945 | grugq 946 | lengstrom 947 | xiaoxian521 948 | todsac 949 | Qengineering 950 | Dliv3 951 | tinygrad 952 | usnistgov 953 | explosion 954 | dhellmann 955 | araffin 956 | wwj718 957 | syrusakbary 958 | jestemAria 959 | swharden 960 | Urinx 961 | mxbi 962 | wilsonfreitas 963 | albinowax 964 | yohanesnuwara 965 | fishaudio 966 | jimmysong 967 | major 968 | useragents 969 | mantvydasb 970 | princewen 971 | The-Compiler 972 | LmeSzinc 973 | r0oth3x49 974 | lining0806 975 | tgalal 976 | mhmzdev 977 | malwaredllc 978 | grayddq 979 | LantaoYu 980 | fxia22 981 | rg3915 982 | W01fh4cker 983 | junhoyeo 984 | DefTruth 985 | farizrahman4u 986 | ourren 987 | tao12345666333 988 | anitagraser 989 | zackchase 990 | matplotlib 991 | pyn3rd 992 | Y1ran 993 | mjpieters 994 | sigridjineth 995 | veo 996 | dutc 997 | faif 998 | me115 999 | yangxue0827 1000 | Cadene 1001 | programthink 1002 | CoreyMSchafer 1003 | cursoemvideo 1004 | defunkt 1005 | pjhyett 1006 | wycats 1007 | ezmobius 1008 | ivey 1009 | evanphx 1010 | vanpelt 1011 | wayneeseguin 1012 | brynary 1013 | kevinclark 1014 | technoweenie 1015 | macournoyer 1016 | takeo 1017 | caged 1018 | topfunky 1019 | anotherjesse 1020 | roland 1021 | lukas 1022 | fanvsfan 1023 | tomtt 1024 | railsjitsu 1025 | nitay 1026 | kevwil 1027 | KirinDave 1028 | jamesgolick 1029 | atmos 1030 | errfree 1031 | mojodna 1032 | bmizerany 1033 | jnewland 1034 | joshknowles 1035 | hornbeck 1036 | jwhitmire 1037 | elbowdonkey 1038 | reinh 1039 | knzai 1040 | bs 1041 | rsanheim 1042 | schacon 1043 | uggedal 1044 | bruce 1045 | sam 1046 | mmower 1047 | abhay 1048 | rabble 1049 | benburkert 1050 | indirect 1051 | fearoffish 1052 | engineyard 1053 | jsierles 1054 | tweibley 1055 | peimei 1056 | brixen 1057 | tmornini 1058 | outerim 1059 | daksis 1060 | sr 1061 | lifo 1062 | rsl 1063 | imownbey 1064 | dylanegan 1065 | jm 1066 | kmarsh 1067 | jvantuyl 1068 | BrianTheCoder 1069 | freeformz 1070 | hassox 1071 | automatthew 1072 | queso 1073 | lancecarlson 1074 | drnic 1075 | lukesutton 1076 | danwrong 1077 | HamptonMakes 1078 | jfrost 1079 | mattetti 1080 | ctennis 1081 | lawrencepit 1082 | marcjeanson 1083 | grempe 1084 | peterc 1085 | ministrycentered 1086 | afarnham 1087 | up_the_irons 1088 | cristibalan 1089 | heavysixer 1090 | brosner 1091 | danielmorrison 1092 | danielharan 1093 | kvnsmth 1094 | collectiveidea 1095 | canadaduane 1096 | corasaurus-hex 1097 | dstrelau 1098 | sunny 1099 | dkubb 1100 | jnicklas 1101 | richcollins 1102 | simonjefford 1103 | --------------------------------------------------------------------------------