• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
tylersayshi

tylersayshi

bsky-follows-backend

backend for bsky-follows.info
Public
Like
bsky-follows-backend
Home
Code
4
.vtignore
deno.json
H
main.http.ts
plan.md
Branches
1
Pull requests
Remixes
History
Environment variables
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
plan.md
Code
/
plan.md
Search
11/6/2025
Viewing readonly version of main branch: v15
View latest version
plan.md

Implementation Plan Here's the comprehensive plan to add all the requested features:

  1. Blacklist & Whitelist System
  • Hardcoded blacklist: Any handle ending with bsky.app
  • Whitelist: pfrazee.com (allowed despite being in top500)
  • Dynamic blacklist: Sync from https://vqv.app/top500.json once per day
    • Filter out entries where is_ad: true
    • Exclude pfrazee.com
    • Store in SQLite blacklist table
  1. Compression for Large Accounts
  • Only cache accounts with followers >= 5000 OR follows >= 5000
  • Use pako (gzip) to compress JSON before storing
  • Decompress when retrieving from cache
  • This allows ~70-85% size reduction
  1. Database Schema -- Existing cache table (no changes needed) CREATE TABLE IF NOT EXISTS bsky_cache ( handle TEXT PRIMARY KEY, followData TEXT, -- Now compressed with gzip cacheHits INTEGER DEFAULT 0, lastCached INTEGER ); -- New blacklist table CREATE TABLE IF NOT EXISTS blacklist ( handle TEXT PRIMARY KEY, addedAt INTEGER, source TEXT -- 'top500' or 'manual' ); -- New sync tracking table CREATE TABLE IF NOT EXISTS sync_log ( syncType TEXT PRIMARY KEY, lastSynced INTEGER );
  2. Request Flow
  3. Check if handle ends with bsky.app → REJECT (403)
  4. Check if handle in blacklist table → REJECT (403)
    • Unless handle is in whitelist (pfrazee.com)
  5. Auto-sync top500 blacklist if >24hrs since last sync
  6. Fetch profile to get follower/following counts
  7. If counts < 5000 → Return fresh data (no caching)
  8. If counts >= 5000:
    • Check cache
    • If cached → decompress & return
    • If not → fetch, compress, store, return
  9. Key Functions to Add
  • isBlacklisted(handle) - Check against all blacklist rules
  • syncTop500Blacklist() - Fetch & update blacklist table
  • shouldSyncBlacklist() - Check if >24hrs since last sync
  • compressData(data) - Gzip compression using pako
  • decompressData(compressed) - Gzip decompression
  • shouldCache(followers, follows) - Check if >= 5000 threshold
  1. Error Messages { error: Access denied, message: This account is not available for querying, status: 403 } Benefits:
  • Protects your API from expensive queries on mega-accounts
  • Caches strategically only large accounts that need it
  • Saves storage with 70-85% compression
  • Auto-updates blacklist daily without manual intervention
  • Capacity: ~1,200-1,500 large cached accounts in 1GB Ready to implement when you are!
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.