Skip to content

Instantly share code, notes, and snippets.

@samber
Last active November 9, 2025 22:55
Show Gist options
  • Select an option

  • Save samber/833fa3561cd53c24fcf1402757b1d706 to your computer and use it in GitHub Desktop.

Select an option

Save samber/833fa3561cd53c24fcf1402757b1d706 to your computer and use it in GitHub Desktop.
function main() {
extractFollowers();
extractRepos();
}
// Create a token and restrict repos visibility: https://github.com/settings/personal-access-tokens/
const GITHUB_TOKEN = "github_pat_xxx";
const SHEET_LIST = 'List repos for stats';
const SHEET_STATS_REPOS = 'Raw stats';
function getRepoList() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_LIST);
const range = sheet.getRange("A2:B");
const values = range.getValues();
return values.map((row) => `${row[0]}/${row[1]}`)
}
function appendRowsRepos(rows) {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_STATS_REPOS);
// Get the last row with content
const lastRow = sheet.getLastRow();
// Get the range for the new data
const range = sheet.getRange(lastRow + 1, 1, rows.length, rows[0].length);
// Set the values in the range
range.setValues(rows);
}
function fetchRepo(repo, subpath) {
const url = 'https://api.github.com/repos/' + repo + subpath;
const response = UrlFetchApp.fetch(url, {
headers: {
Authorization: 'Bearer ' + GITHUB_TOKEN,
Accept: 'application/vnd.github.v3+json',
},
muteHttpExceptions: true,
});
const result = JSON.parse(response.getContentText());
return result;
}
function extractRepos() {
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const day = String(today.getDate()).padStart(2, '0');
const date = `${year}-${month}-${day}`;
const repos = getRepoList();
const stats = [];
for (let repo of repos) {
const base = fetchRepo(repo, "");
const views = fetchRepo(repo, "/traffic/views");
const clones = fetchRepo(repo, "/traffic/clones");
// const contributors = makeRequest(repo, "/stats/contributors?per_page=100");
const weeklyViews = views.views.slice(-7);
const weeklyClones = clones.clones.slice(-7);
console.log("base", base)
console.log("views", views)
console.log("clones", clones)
console.log("repo", repo)
stats.push([
repo,
date,
base.subscribers_count,
base.forks_count,
base.stargazers_count,
base.open_issues_count,
views.count,
views.uniques,
clones.count,
clones.uniques,
weeklyViews.reduce((acc, cur) => acc + cur.count, 0),
weeklyViews.reduce((acc, cur) => acc + cur.uniques, 0),
weeklyClones.reduce((acc, cur) => acc + cur.count, 0),
weeklyClones.reduce((acc, cur) => acc + cur.uniques, 0),
// contributors.length,
// "",
]);
}
appendRowsRepos(stats);
}
const SHEET_STATS_FOLLOWERS = 'Raw Github Followers';
const GITHUB_USER = 'samber';
function appendRowsFollowers(rows) {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_STATS_FOLLOWERS);
// Get the last row with content
const lastRow = sheet.getLastRow();
// Get the range for the new data
const range = sheet.getRange(lastRow + 1, 1, rows.length, rows[0].length);
// Set the values in the range
range.setValues(rows);
}
function fetchUser() {
const url = 'https://api.github.com/users/'+GITHUB_USER;
const response = UrlFetchApp.fetch(url, {
muteHttpExceptions: true,
});
const result = JSON.parse(response.getContentText());
return result;
}
function extractFollowers() {
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const day = String(today.getDate()).padStart(2, '0');
const date = `${year}-${month}-${day}`;
const repos = getRepoList();
const user = fetchUser();
const stats = [];
stats.push([
date,
user.followers,
user.following,
user.public_repos,
user.public_gists,
]);
appendRowsFollowers(stats);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment