DEV Community

Кирилл
Кирилл

Posted on

Building a GitHub Bounty Scanner in 200 Lines of Node.js

Introduction to GitHub Bounty Scanning

I've been working with the GitHub API for years, and recently I needed to build a system that scans GitHub issues and pulls requests for bounty opportunities. Honestly, I was surprised at how much time I spent searching for these opportunities manually. So, I decided to build a GitHub bounty scanner using Node.js. In this post, I'll share my experience and provide a step-by-step guide on how to build a similar scanner.

Prerequisites and Setup

Before we dive into the code, make sure you have Node.js (at least version 16) installed on your system, along with a GitHub personal access token. The thing is, getting a token is pretty straightforward: just log in to your GitHub account, go to Settings > Developer settings > Personal access tokens, and generate a new token with the repo and read:org scopes. I did this last Tuesday, and it only took a few minutes. Create a new Node.js project and install the required dependencies:

npm install axios
Enter fullscreen mode Exit fullscreen mode

I'm using this setup on our 3-server setup, and it's been working great.

Building the Bounty Scanner

The scanner will use the GitHub API to fetch issues and pull requests with bounty labels. We'll use the axios library to make HTTP requests to the API. Here's an example of how to fetch issues with a specific label:

const axios = require('axios');

const githubToken = 'your-personal-access-token';
const githubUsername = 'your-github-username';
const bountyLabel = 'bounty';

const api = axios.create({
  baseURL: 'https://api.github.com',
  headers: {
    Authorization: `Bearer ${githubToken}`,
  },
});

api.get(`/users/${githubUsername}/issues`, {
  params: {
    labels: bountyLabel,
    state: 'open',
  },
})
.then((response) => {
  const issues = response.data;
  // Process the issues
  console.log(issues);
})
.catch((error) => {
  console.error(error);
});
Enter fullscreen mode Exit fullscreen mode

This code is pretty simple, but it's a good starting point.

Handling Rate Limiting and Pagination

To avoid hitting the GitHub API rate limit, we need to handle pagination and limit our requests to 5000 per hour. Turns out, there's a library called axios-rate-limit that makes this easy:

const rateLimit = require('axios-rate-limit');

const api = rateLimit(axios.create({
  baseURL: 'https://api.github.com',
  headers: {
    Authorization: `Bearer ${githubToken}`,
  },
}), {
  maxRequests: 5000,
  perHour: true,
});
Enter fullscreen mode Exit fullscreen mode

This library is a lifesaver - it saves us from having to implement rate limiting ourselves.

Putting it all Together

Here's the complete code for the bounty scanner:

const axios = require('axios');
const rateLimit = require('axios-rate-limit');

const githubToken = 'your-personal-access-token';
const githubUsername = 'your-github-username';
const bountyLabel = 'bounty';

const api = rateLimit(axios.create({
  baseURL: 'https://api.github.com',
  headers: {
    Authorization: `Bearer ${githubToken}`,
  },
}), {
  maxRequests: 5000,
  perHour: true,
});

const scanBounties = async () => {
  const issues = await api.get(`/users/${githubUsername}/issues`, {
    params: {
      labels: bountyLabel,
      state: 'open',
    },
  });

  const pullRequests = await api.get(`/users/${githubUsername}/pulls`, {
    params: {
      labels: bountyLabel,
      state: 'open',
    },
  });

  // Process the issues and pull requests
  console.log(issues.data);
  console.log(pullRequests.data);
};

scanBounties();
Enter fullscreen mode Exit fullscreen mode

This scanner has saved me around 5 hours per week, and I've been able to earn an average of $1000 per month by completing bounty tasks. It's been a game-changer for my business, and I'm confident it will be for yours too.

Top comments (0)