Google Apps Scripts to track weekly KPIs for open-source projects, stored in a Google Spreadsheet.
Each script appends a dated row on every run, building a time series you can chart and query over time.
Stay up to date: This code runs inside your own Apps Script project β updates are not applied automatically. Subscribe to release notifications on GitHub (Watch β Custom β Releases) to be notified when a new version is available, then copy the updated files into your project manually.
| Category | Metrics | Cadence |
|---|---|---|
| GitHub repo | Stars, forks, watchers, open issues, page views & clones (all-time + last 7 days, count + uniques) | Weekly |
| GitHub profile | Followers, following, public repos, public gists | Weekly |
| GitHub stargazers | Full directory: login, name, email, company, location, bio, Twitter, blog, followers, public repos, starred_at | Weekly (incremental) |
| GitHub search | Mentions across code, repos, issues, PRs (open/closed), discussions, users, commits, topics | Weekly |
| GitHub dependents | Repositories that depend on your projects (name, stars, forks) | Weekly |
| Google Analytics | Active users (7-day, 28-day), new users, sessions, bounce rate, avg session duration, page views | Weekly |
| Pixel tracking | Cumulative view count per README badge tracker | Daily |
| File | Entry point | Target sheet | Notes |
|---|---|---|---|
github-repositories.gs |
mainGithubRepositories |
Github repositories |
|
github-followers.gs |
mainGithubFollowers |
Github Followers |
|
github-stargazers.gs |
mainGithubStargazers |
Github stargazers |
Incremental; also run mainPeriodicGithubStargazersSyncOldestRows to refresh stale profiles |
github-search.gs |
mainGithubSearch |
Github search stats |
|
github-dependents.gs |
mainGithubDependents |
Github dependents |
Scrapes HTML; 20-min guard (free accounts limited to 6 min) |
google-analytics.gs |
mainGA |
GA stats |
|
pixel-tracking.gs |
mainGithubPixelTracking |
Pixel tracking |
Reads visitor-badge.laobi.icu |
Note: The
codecounter ingithub-search.gsis unreliable β GitHub is migrating its search engine and the API returns inconsistent values. See github/rest-api-description#2956.
Create a Google Spreadsheet using this template and list your OSS projects in the following sheets:
| Sheet name | Purpose |
|---|---|
List GitHub repositories |
Repository list (columns A = owner, B = repo) |
List GA |
GA4 property list (columns A = website, B = property ID) |
List pixel trackers |
Pixel tracker list (columns A = name, B = tracker ID) |
Then copy the code into Apps Script and create weekly triggers. The following "Bronze" sheets will fill up:
| Sheet name | Purpose |
|---|---|
Github repositories |
Output β repository stats |
Github Followers |
Output β profile follower stats |
Github stargazers |
Output β stargazer directory |
Github search stats |
Output β search result counts |
Github dependents |
Output β dependent repositories |
GA stats |
Output β GA4 metrics |
Pixel tracking |
Output β pixel view counts |
- Open Extensions β Apps Script in your spreadsheet.
- Copy all
.gsfiles into the project (one file per script, or paste into a single file). - In
github-utils.gs, replace the placeholder token(s) inGITHUB_TOKENSwith your GitHub personal access tokens. - Set
GITHUB_PROFILEingithub-utils.gsto your GitHub username.
Traffic endpoints (/traffic/views, /traffic/clones) require push access on each repository. For a classic PAT: enable the repo scope. For a fine-grained PAT: grant Administration: Read on each target repository, plus Read-only access to account metadata for the profile endpoint.
Enable the Google Analytics Data API in the Apps Script project (Services β Google Analytics Data API). Then enable the manifest via Project Settings β Show "appsscript.json" manifest file and add the required OAuth scopes:
{
"timeZone": "America/New_York",
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets.currentonly",
"https://www.googleapis.com/auth/analytics.readonly",
"https://www.googleapis.com/auth/script.external_request"
],
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}Set up time-based triggers in Triggers (clock icon) for each entry point. Most scripts run weekly; pixel tracking runs daily.
| Function | Suggested frequency |
|---|---|
mainGithubRepositories |
Weekly |
mainGithubFollowers |
Weekly |
mainGithubStargazers |
Weekly |
mainPeriodicGithubStargazersSyncOldestRows |
Weekly x3 |
mainGithubSearch |
Weekly |
mainGithubDependents |
Weekly |
mainGA |
Weekly |
mainGithubPixelTracking |
Daily |
- Ping me on twitter @samuelberthe (DMs, mentions, whatever :))
- Fork the project
- Fix open issues or request new features
Don't hesitate ;)
Give a βοΈ if this project helped you!
Copyright Β© 2026 Samuel Berthe.
This project is under MIT license.