spamblock

Scans GitHub followers against configurable criteria (bio patterns, trivial repos) and blocks matches

spamblock

Scans your GitHub followers against configurable criteria and blocks the ones that match — cleans up follow-for-follow / star-farming spam accounts (e.g. "GIVE ME STARS TO MY REPOSITORIES AND BACK TO YOUR REPOSITORIES").

GitHub has no concept of a private profile or a follow request to approve — anyone can follow anyone at any time. Blocking is the only lever that actually prevents it (and removes the existing follow relationship), so this tool automates finding who to block instead of doing it by hand.

How it decides

Two independent criteria, configured in src/spamblock/patterns.yml:

bio_patterns:
  - "give me stars"
  - "follow main"

min_repo_bytes: 500
  1. Bio pattern — the follower's public bio contains any of the phrases above (case-insensitive substring). Near-zero false-positive risk: these phrases don't show up in a real bio by accident. A missing/nil bio never matches.
  2. Trivial repos — the follower has at least one non-fork repo, but every one of them has fewer than min_repo_bytes bytes of recognized source code (via GitHub's languages API — a cheap proxy for "about this many lines", not an exact count). Catches accounts padded with placeholder/empty repos to look active. Set to 0 to disable. Higher false-positive risk than the bio check (a brand-new or experimental account could trip this legitimately), which is why every report says which criterion fired for each match instead of a bare yes/no.

Add a line to either list, no code changes needed. Pass --config path/to/your.yml to use a different file entirely (e.g. to keep personal patterns out of this repo).

If you run into spam that trips neither signal, that's a new criterion to add to Criteria, not something either heuristic will catch as-is.

Usage

Requires the gh CLI, already authenticated (gh auth status) — spamblock shells out to it for every GitHub API call (pagination and auth are already solved there; no reason to re-solve them).

shards install
crystal build src/spamblock.cr -o bin/spamblock

./bin/spamblock scan                              # report matches, no action taken
./bin/spamblock block                              # scan, then block every match
./bin/spamblock scan --user someone                # preview someone else's followers
./bin/spamblock scan --report scan.md              # also write a Markdown report to disk

Commands

Command Effect
scan Scan followers against the criteria and print/report matches. Read-only — safe to run any time.
block Same scan, then blocks every match via gh api -X PUT user/blocks/<login>.

Options

Option Default Effect
--config PATH bundled src/spamblock/patterns.yml Use a different criteria file (e.g. to keep personal patterns out of this repo).
--user LOGIN the authenticated gh user Whose followers to scan. Preview-only: block still only ever blocks on your own account's list, regardless of this flag — you can only manage your own blocks.
--report PATH none (stdout only) Also write a Markdown report to PATH with the scanned user, the criteria used, and every flagged login with its reasons (plus block status, once block has actually run).
-h, --help Print usage and exit.

Combine freely, e.g.:

./bin/spamblock block --user someone --config my-patterns.yml --report block.md

scan is always safe to run — it only reads. block calls gh api -X PUT user/blocks/<login> for every match, which affects your own account's block list regardless of --user (you can only manage your own blocks). --report PATH writes a Markdown file with the scanned user, the criteria used, and every flagged login with its reasons (plus block status, once block has actually run) — useful as a record of what happened, or to review before deciding to run block.

Testing

crystal spec

Specs cover the pure logic directly — Criteria (bio/repo matching) and Report (rendering). The gh-API wrapper isn't unit-tested since it needs a live authenticated session — exercise it for real with scan first (read-only) before trusting block.

Repository

spamblock

Owner
Statistic
  • 0
  • 0
  • 0
  • 0
  • 0
  • about 1 hour ago
  • July 5, 2026
License

MIT License

Links
Synced at

Sun, 05 Jul 2026 17:28:06 GMT

Languages