Skip to content

Instantly share code, notes, and snippets.

@zfogg
Last active October 11, 2021 14:45
Show Gist options
  • Save zfogg/84e8198e7431d49b4f66cdab324b8fa9 to your computer and use it in GitHub Desktop.
Save zfogg/84e8198e7431d49b4f66cdab324b8fa9 to your computer and use it in GitHub Desktop.
Follow everyone in a GitHub Organization

GitHub Org - Follow Members

How to use it

Manually

  1. Navigate to a GitHub organization's member page.
  2. Open your browser devtools and go to the JavaScript console tab.
  3. Copy 1.follow-github-org-members.js to your clipboard.
  4. Paste the script into the JavaScript console and run it, once per page of organization members.
  5. Watch your JavaScript console logs to view the progress.
  6. Wait for the script to finish before navigating to the next page or closing the tab.

Bookmarklet

  1. Make a bookmarklet from 2.bookmarklet.
  2. Add it to your bookmarks toolbar.
  3. Click the bookmarklet to run this script for each page of an organization's members.
  4. If there are <1 pages of members, wait for the code to finish following members on the current page before navigating to the next one or closing the tab.
/*jshint esversion: 6 */
/*
Run this snippet in your browser devtools JavaScript console to follow everyone in a GitHub organization.
It only works for the current page, so wait for it to finish, navigate to the next page, and run it again.
NOTE: Using this too much might trigger a rate-limited from GitHub.
*/
;(function() {
'use strict';
const followPage = () => {
/* NOTE: GitHub could change their markup at any point */
let followButtonSelector = [
'#js-pjax-container',
'.user-following-container >',
'form:not([hidden="hidden"])',
'input.btn.btn-sm',
].join(' ');
/* milliseconds */
let randRange = (min=750, max=1750) => (
Math.floor(Math.random()*(max - min + 1) + min)
);
let delay = (ms=0) => (
/* ms: wait this many milliseconds before resolving */
new Promise(resolve => setTimeout(resolve, ms))
);
let followButtons = document.querySelectorAll(followButtonSelector);
let toFollow = Array.from(followButtons)
/* let's not unfollow people we already follow */
.filter((b) => (b.getAttribute("value") === "Follow"));
console.group(`⏳ Following ${toFollow.length} users... πŸ’€`);
toFollow.reduce((acc, b, i) => {
return acc
.then(() => {
const ms = randRange(500,2500);
return delay(ms)
.then(() => {
b.click();
console.info([
`βœ…πŸ”›${(i+1).toString().padStart(3, ' ')}πŸ”›βœ…`,
`πŸ“‰πŸ”š${Math.abs(i-toFollow.length).toString().padStart(3, ' ')}πŸ”šπŸ“‰`,
`β³πŸ”œ${ms.toString().padStart(7,' ')}msπŸ”œβŒ›οΈ`,
].join(' | '));
})
.catch((e) => console.error(e));
});
}, delay(0))
.then(() => {
console.info(`⏰ Done! ✌🏾`);
console.groupEnd();
})
.catch((e) => console.error(e));
};
followPage();
})();
javascript:(function()%7Bfunction%20callback()%7B%2F*jshint%20esversion%3A%206%20*%2F%2F*Run%20this%20snippet%20in%20your%20browser%20devtools%20JavaScript%20console%20to%20follow%20everyone%20in%20a%20GitHub%20organization.It%20only%20works%20for%20the%20current%20page%2C%20so%20wait%20for%20it%20to%20finish%2C%20navigate%20to%20the%20next%20page%2C%20and%20run%20it%20again.NOTE%3A%20Using%20this%20too%20much%20might%20trigger%20a%20rate-limited%20from%20GitHub.*%2F%3B(function()%20%7B'use%20strict'%3Bconst%20followPage%20%3D%20()%20%3D%3E%20%7B%2F*%20NOTE%3A%20GitHub%20could%20change%20their%20markup%20at%20any%20point%20*%2Flet%20followButtonSelector%20%3D%20%5B'%23js-pjax-container'%2C'.user-following-container%20%3E'%2C'form%3Anot(%5Bhidden%3D%22hidden%22%5D)'%2C'input.btn.btn-sm'%2C%5D.join('%20')%3B%2F*%20milliseconds%20*%2Flet%20randRange%20%3D%20(min%3D750%2C%20max%3D1750)%20%3D%3E%20(Math.floor(Math.random()*(max%20-%20min%20%2B%201)%20%2B%20min))%3Blet%20delay%20%3D%20(ms%3D0)%20%3D%3E%20(%2F*%20ms%3A%20wait%20this%20many%20milliseconds%20before%20resolving%20*%2Fnew%20Promise(resolve%20%3D%3E%20setTimeout(resolve%2C%20ms)))%3Blet%20followButtons%20%3D%20document.querySelectorAll(followButtonSelector)%3Blet%20toFollow%20%3D%20Array.from(followButtons)%2F*%20let's%20not%20unfollow%20people%20we%20already%20follow%20*%2F.filter((b)%20%3D%3E%20(b.getAttribute(%22value%22)%20%3D%3D%3D%20%22Follow%22))%3Bconsole.group(%60%E2%8F%B3%20Following%20%24%7BtoFollow.length%7D%20users...%20%F0%9F%92%A4%60)%3BtoFollow.reduce((acc%2C%20b%2C%20i)%20%3D%3E%20%7Breturn%20acc.then(()%20%3D%3E%20%7Bconst%20ms%20%3D%20randRange(500%2C2500)%3Breturn%20delay(ms).then(()%20%3D%3E%20%7Bb.click()%3Bconsole.info(%5B%60%E2%9C%85%F0%9F%94%9B%24%7B(i%2B1).toString().padStart(3%2C%20'%20')%7D%F0%9F%94%9B%E2%9C%85%60%2C%60%F0%9F%93%89%F0%9F%94%9A%24%7BMath.abs(i-toFollow.length).toString().padStart(3%2C%20'%20')%7D%F0%9F%94%9A%F0%9F%93%89%60%2C%60%E2%8F%B3%F0%9F%94%9C%24%7Bms.toString().padStart(7%2C'%20')%7Dms%F0%9F%94%9C%E2%8C%9B%EF%B8%8F%60%2C%5D.join('%20%20%20%20%7C%20%20%20%20'))%3B%7D).catch((e)%20%3D%3E%20console.error(e))%3B%7D)%3B%7D%2C%20delay(0)).then(()%20%3D%3E%20%7Bconsole.info(%60%E2%8F%B0%20Done!%20%E2%9C%8C%F0%9F%8F%BE%60)%3Bconsole.groupEnd()%3B%7D).catch((e)%20%3D%3E%20console.error(e))%3B%7D%3BfollowPage()%3B%7D)()%7Dvar%20s%3Ddocument.createElement(%22script%22)%3Bs.src%3D%22GitHub%20Org%20-%20Follow%20Members%22%3Bif(s.addEventListener)%7Bs.addEventListener(%22load%22%2Ccallback%2Cfalse)%7Delse%20if(s.readyState)%7Bs.onreadystatechange%3Dcallback%7Ddocument.body.appendChild(s)%3B%7D)()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment