| title: | GitHub Listening |
|---|---|
| description: | Find relevant people to talk to from your GitHub stargazers |
| pubDate: | 2025-01-09:00:00.000Z |
| author: | Steve Krouse |
A lot startup life is talking to users, but finding the right people to talk to is hard.
If you have a public GitHub repo with any traction, you already have a stream of people effectively walking in the door, but which of those should you pay attention to?
A bunch of Val Town customers asked us to help them write scripts to help with this, so we did, improving it each time, finally ending up with something simple enough to share as a template!
Template lives here: GitHub Leads
A val is a little TypeScript program that runs on Val Town’s servers: it can be a cron job, an API, a tiny web app, plus storage. You edit it in the browser, it deploys fast, and it just keeps running. (Think “GitHub Gist, but it runs.”)
It’s basically four composable pieces:
-
A cron that “listens” to GitHub org activity
We poll GitHub’s Events API, capture stars/forks/issues/PRs/etc, and group events by user so you don’t get duplicates. The code we’re happy with now is here: github.cron.ts. :contentReference[oaicite:1]{index=1}
One constraint: GitHub only gives you the most recent events, so this is meant to run continuously, not as a one-shot backfill. :contentReference[oaicite:2]{index=2} -
A little research agent that scores the person
When a new person shows up, an agent does lightweight research (GitHub profile, linked sites, etc.) and scores them against your prompt. The implementation is here: agent.ts. :contentReference[oaicite:3]{index=3}
Under the hood, this uses the OpenAI Agents SDK, which I’ve found unusually pleasant and “small primitive”-y. :contentReference[oaicite:4]{index=4} -
SQLite storage
Every lead gets stored in SQLite so you can browse history and rerun stuff. (This is built into Val Town templates like this one.) :contentReference[oaicite:5]{index=5} -
A tiny Hono app + mostly vibe-coded dashboard
The UI is intentionally small: “here are the leads, here’s the score, click to see the evidence.” :contentReference[oaicite:6]{index=6}
By default it sends a daily email digest (so this stays calm and human-scale). :contentReference[oaicite:7]{index=7}
This is part of a broader pattern I’ve been enjoying: assembling little internal tools from composable parts instead of buying a whole suite. Like using Notion as a CRM until you outgrow it.
AI makes this dramatically easier. People are already doing this with Cursor / Claude Code and deploying to Vercel/Railway; one of the more extreme versions of that vibe is described in this “agent era” writeup. :contentReference[oaicite:8]{index=8}
The tradeoffs are real. Sometimes you outgrow homegrown tools. Sometimes you never do. Either way, building the small version teaches you what the big version is actually buying you.
With great power, etc. This is not “spam more people.”
Treat this like: “thanks for stopping by.” If someone engages with your OSS or your org, you might respond with context, help, curiosity, a question. High-context, low-volume. If this starts making you louder instead of more thoughtful, you’ve broken it.
The main variable cost is the AI research step. Depending on the model and how much you ask it to do, it’s roughly “cents-ish per lead,” and you can dial it way down (or switch to cheaper models) and still get decent signal.
You can run this on a free Val Town account, but if you’re using it for a business, we’d really appreciate you signing up for Teams. Teams adds collaboration and production limits and starts at $166.67/mo on annual billing. :contentReference[oaicite:9]{index=9} (We’ve also been telling folks “$200/mo” as the simple mental model.)
We’re still doing the “pickle” thing: building vals with Teams customers by hand, then turning the best ones into templates. If you want something like this customized for your workflow, email steve@val.town. If you want the broader context for why we’re doing this, I wrote about it here: Pickling Compute. :contentReference[oaicite:10]{index=10}