Chat about this codebase

AI-powered code exploration

Online

Project Overview

This project provides a serverless Cloudflare Workers application that fetches, visualizes, and analyzes GitHub user data. It exposes multiple API endpoints to retrieve contribution heatmaps, badge status, and AI-generated insights. Frontend applications integrate with these routes for real-time profile analytics.

Problem Statement

Developers and teams lack a unified, extensible service to:

  • Aggregate GitHub profile metrics across repositories
  • Generate visual assets (heatmaps, badges) on the fly
  • Receive contextual AI-driven commentary on activity patterns

Main Capabilities

  • Contribution Heatmaps: Render SVG calendars showing daily commit activity
  • Badge Generation: Produce status badges (e.g., “Top Collaborator”, “Issue Closer”)
  • AI Insights: Summarize trends and suggest improvement areas via OpenAI integration
  • Extensible API Routes:
    • /api/heatmap/:username
    • /api/badge/:username/:badgeType
    • /api/insights/:username

When to Use

  • Embedding dynamic GitHub profile visuals in personal sites or dashboards
  • Automating badge updates in README files or status pages
  • Providing project maintainers with AI-driven summaries of contributor behavior
  • Building internal analytics tools without managing servers

Example: Fetching a Contribution Heatmap

Developers can call the heatmap endpoint directly or within their frontend code.

# Replace YOUR_DOMAIN and USERNAME
curl https://YOUR_DOMAIN/api/heatmap/USERNAME \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
  --output heatmap.svg

# Display inline in HTML
<img src="https://YOUR_DOMAIN/api/heatmap/USERNAME" alt="Contribution Heatmap">

Use this service when you need up-to-date, on-demand GitHub profile analytics without maintaining backend infrastructure.

Getting Started & Deployment

This guide walks you through installing dependencies, configuring environment variables, and deploying the GitHub Profile Analyzer on Cloudflare Workers using Wrangler.

Prerequisites

  • Node.js v14+ and npm or Yarn
  • Cloudflare account with Workers & KV enabled
  • One or more GitHub Personal Access Tokens (no scopes required)
  • Frontend origin URL (e.g. https://localhost:3000)

1. Install Wrangler CLI

Use npm or Yarn to install Wrangler globally:

npm install -g wrangler
# or
yarn global add @cloudflare/wrangler

Authenticate with your Cloudflare account:

wrangler login

2. Clone the Repository

git clone https://github.com/0xarchit/github-profile-analyzer.git
cd github-profile-analyzer

3. Configure wrangler.toml

Create or update wrangler.toml at project root:

name = "github-profile-analyzer"
type = "javascript"
account_id = "<YOUR_ACCOUNT_ID>"
workers_dev = true

# Bind a KV namespace for caching contributions
kv_namespaces = [
  { binding = "CONTRIB_CACHE", id = "<KV_NAMESPACE_ID>" }
]

[vars]
# These can also be set via Wrangler secrets
FRONTEND_ORIGIN = "https://localhost:3000"
  • Replace <YOUR_ACCOUNT_ID> with your Cloudflare account ID.
  • Create a KV namespace in the Cloudflare dashboard and replace <KV_NAMESPACE_ID>.

4. Set Environment Variables & Secrets

Store sensitive values as Wrangler secrets:

# Comma-separated GitHub tokens (rotate to avoid rate limits)
wrangler secret put GITHUB_TOKENS
# Your frontend’s origin for CORS checks
wrangler secret put FRONTEND_ORIGIN

You’ll be prompted to paste each value. Wrangler stores these securely and injects them at runtime.

5. Local Development

Run a local dev server with live reloading:

wrangler dev --local --env dev
  • Visits APIs at http://127.0.0.1:8787
  • Supports testing /api, /contributions, /badge endpoints against live GitHub

6. Deploy to Cloudflare

Publish your Worker to Cloudflare’s edge:

wrangler publish

On success, Wrangler prints your Worker’s URL, e.g.:

https://github-profile-analyzer.YOUR_SUBDOMAIN.workers.dev

7. Verify the Deployment

  1. Fetch AI-powered profile report:
    curl "https://<your-worker>.workers.dev/api?user=octocat"
    
  2. Retrieve SVG heatmap:
    curl "https://<your-worker>.workers.dev/contributions?username=octocat"
    
  3. Check badge statuses:
    curl "https://<your-worker>.workers.dev/api/badges?user=octocat"
    

Tips & Best Practices

  • Rotate multiple GitHub tokens to distribute rate limits.
  • Purge or expire KV entries via the Cloudflare dashboard when debugging caching.
  • Use workers_dev = false and configure route & zone_id in production to bind to a custom domain.
  • Monitor usage and errors in the Cloudflare dashboard’s Logs & Analytics.

API Reference

This section documents all HTTP endpoints exposed by the Cloudflare Workers in this repository. Each endpoint’s path, parameters, responses, and usage examples appear below.


Badge Extraction Endpoint

Script: badge.js
URL: GET https://<your-domain>/badge?username=<github_username>

Parameters

username (required): GitHub login whose achievements you want to probe.

Response (200)

Content-Type: application/json
Cache-Control: max-age=900

{
  "pull-shark": "https://github.githubassets.com/assets/pull-shark-default-498c279a747d.png",
  "yolo": "https://github.githubassets.com/assets/yolo-default-be0bbff04951.png"
}

Error Responses

  • 400 if username is missing.
  • 500 on network or internal errors.

Example

curl "https://<your-domain>/badge?username=octocat"

Contribution Graph Endpoint

Script: contri-graph.js
URL: GET https://<your-domain>/contributions?username=<github_username>

CORS

Only requests with Origin or Referer matching your FRONTEND_ORIGIN are allowed. Others yield 403.

Parameters

username (required): GitHub login to render the contribution heatmap.

Response (200)

Content-Type: image/svg+xml
Cache-Control: public, max-age=3600

The body is an SVG heatmap matching GitHub’s dark‐mode style.

Error Responses

  • 400 if username is missing.
  • 403 if CORS check fails.
  • 500 on GitHub API or rendering errors.

Example (img tag)

<img
  src="https://<your-domain>/contributions?username=octocat"
  alt="Octocat’s contribution heatmap" />

Global Hit Counter

Script: count.js
URL: GET https://<your-domain>/cnt

Description

Atomically increments a single-row counter in D1 and returns the total hits.

Response (200)

Content-Type: application/json

{ "hits": 42 }

Example

const res = await fetch("https://<your-domain>/cnt");
const { hits } = await res.json();
console.log(`Total hits: ${hits}`);

User‐Specific Count Update

Script: count.js
URL: POST https://<your-domain>/add

Request Body

Content-Type: application/json

{
  "username": "octocat",
  "increment": 3   // optional, defaults to 1
}

Response (200)

Content-Type: application/json

{
  "username": "octocat",
  "hits": 7
}

D1 Schema

CREATE TABLE user_counts (
  username TEXT PRIMARY KEY,
  hits     INTEGER DEFAULT 0
);

Example

curl -X POST https://<your-domain>/add \
  -H "Content-Type: application/json" \
  -d '{"username":"octocat","increment":2}'

Profile Analysis Endpoint

Script: worker.js
URL: GET https://<your-domain>/profile?username=<github_username>

Description

Aggregates GitHub profile data, badges, contributions, and repositories, then applies AI-based scoring and recommendations. Returns a detailed JSON report.

Parameters

username (required): GitHub login to analyze.

Response (200)

Content-Type: application/json

{
  "profile": {
    "login": "octocat",
    "name": "The Octocat",
    "bio": "GitHub mascot",
    "followers": 3500,
    "following": 9
  },
  "badges": { /* slug→URL map */ },
  "contributions": { /* heatmap data or SVG string */ },
  "repositories": [
    { "name": "hello-world", "stars": 150, "language": "JavaScript" },
    /* … */
  ],
  "insights": {
    "score": 87,
    "recommendations": [
      "Add a README to your newer repos.",
      "Contribute to open source projects in Go."
    ]
  }
}

Error Responses

  • 400 if username is missing.
  • 502 on upstream GitHub/API failures.

Example

import fetch from "node-fetch";

async function getProfile(username) {
  const res = await fetch(`https://<your-domain>/profile?username=${username}`);
  if (!res.ok) throw new Error(`Error ${res.status}`);
  return await res.json();
}

getProfile("octocat").then(console.log);

Frontend Interface

Script: worker.js
URL: GET https://<your-domain>/

Serves the static HTML/CSS/JS UI. Users enter a GitHub username to trigger the Profile Analysis Endpoint. Simply point your browser at the root URL to use the app.

Development & Contribution Guide

This guide helps you understand the codebase, run it locally, add new features, and submit pull requests.

1. Code Organization

  • worker.js – Main Cloudflare Worker. Routes requests, aggregates data from GitHub, D1, and AI, then serves JSON or HTML.
  • badge.js – Checks GitHub achievement badges via HEAD requests; exports badge asset mapping and status checker.
  • contri-graph.js – Fetches contribution data via GraphQL and renders an SVG heatmap.
  • count.js – Provides /cnt and /add endpoints to track global and per-user hit counts in D1.
  • README.md – High-level overview, setup, and available API routes.

2. Prerequisites

  • Node.js 16+
  • Wrangler 2.x (npm install -g wrangler)
  • A GitHub account and Personal Access Tokens (for GraphQL and API rate limits)
  • (Optional) Cloudflare account with a D1 database

3. Local Setup

  1. Fork and clone the repo:
    git clone https://github.com/<your-user>/github-profile-analyzer.git
    cd github-profile-analyzer
    
  2. Install dependencies:
    npm install
    
  3. Copy environment template and populate values:
    cp .env.example .env
    
    # .env
    GITHUB_TOKENS=token1,token2      # comma-separated GitHub PATs
    FRONTEND_ORIGIN=https://app.example.com
    D1_DB_BINDING=GPA_D1_DB          # name used in wrangler.toml
    
  4. Configure wrangler.toml (example):
    name = "github-profile-analyzer"
    main = "worker.js"
    compatibility_date = "2025-01-01"
    
    [vars]
    GITHUB_TOKENS = "${GITHUB_TOKENS}"
    FRONTEND_ORIGIN = "${FRONTEND_ORIGIN}"
    
    [[d1_databases]]
    binding = "GPA_D1_DB"
    database_name = "profile_counts"
    

4. Running Locally

Start the worker in dev mode:

wrangler dev --env .env
  • Default bind: http://127.0.0.1:8787
  • Test endpoints with cURL or browser:
    curl "http://127.0.0.1:8787/?username=octocat"
    curl "http://127.0.0.1:8787/contributions?username=octocat"
    curl "http://127.0.0.1:8787/cnt"
    curl -X POST "http://127.0.0.1:8787/add?username=octocat"
    

5. Adding New Features

  1. Define a route in the handleRequest function in worker.js:
    if (url.pathname === '/status') {
      return new Response(JSON.stringify({ version: '1.2.0' }), {
        headers: { 'Content-Type': 'application/json' }
      });
    }
    
  2. Implement logic in a new module (e.g., status.js), export a handler:
    // status.js
    export function getStatus() {
      return { uptime: Date.now() - START_TIME };
    }
    
  3. Import and invoke in worker.js:
    import { getStatus } from './status.js';
    
    // inside handleRequest
    if (url.pathname === '/status') {
      return new Response(JSON.stringify(getStatus()), {
        headers: { 'Content-Type': 'application/json' }
      });
    }
    
  4. Test locally via wrangler dev and cURL.

6. Extending Badge List

  • Open badge.js, update the badgeAssets map:
    badgeAssets['new-badge'] = 'https://github.githubassets.com/assets/new-badge-default-...png';
    
  • Ensure slug matches GitHub’s achievement URL pattern.
  • Deploy and test:
    curl "https://<your-worker>/?username=octocat"
    

7. Database & Counters

  • The D1 binding named in .env and wrangler.toml backs /cnt and /add.
  • To modify schema, use D1 migrations:
    wrangler d1 migrations apply GPA_D1_DB
    
  • Review count.js for table and query structure.

8. Contribution Workflow

  1. Branching
    • Use feature/<short-description> or fix/<short-description>.
  2. Commit Messages
    • Start with a verb: “Add”, “Fix”, “Update”.
  3. Pull Request
    • Target main branch of 0xarchit/github-profile-analyzer.
    • Include:
      • Feature overview
      • Setup changes
      • Testing instructions (cURL/browser)
  4. Review & Merge
    • Address review comments.
    • Squash commits when merging to keep history clean.

9. Submission Checklist

  • Code compiles and runs under wrangler dev
  • Environment variables documented in .env.example
  • New routes covered by manual tests
  • README.md updated with new endpoint(s)
  • PR description includes testing steps

Thank you for contributing!