I Built a Free AI Newsletter That Learns What I Like

The best things I've ever learned came from friends doing stuff and telling me about it. Not from courses, not from textbooks — from a friend casually explaining something they're obsessed with over coffee. That excited, effortless transfer of knowledge. A friend working on compiler optimizations explaining how branch prediction works. Someone in biophysics ranting about protein folding over lunch.

The problem: you can't scale that. Your friends work in 3–4 fields max. arXiv has 15,000 papers a day. Twitter/X is noise. RSS feeds are firehoses. And curated newsletters are written for someone else's taste.

So the question became: what if I could build a "friend" that reads arXiv every night, picks the interesting stuff across many fields, and explains it to me like an excited colleague — and actually learns what I care about over time?

What It Became — Broletter

A fully automated, personalized daily science newsletter. It runs on my laptop at 11 PM every night, costs $0/day, and delivers ~7 minutes of reading to my Telegram each morning. It fetches real papers from arXiv, generates the newsletter using Gemini 2.5 Flash (free tier), and sends it via Telegram.

Every issue has four sections:

  • Deep Curiosity — one fascinating topic explored in depth. Could be the physics of black holes, the history of Unix, or how deep-sea creatures see in the dark.
  • Research Spotlight — a real arXiv paper, explained clearly, with the actual researchers named, their labs, where they studied. Science is a community of real humans and the newsletter treats it that way.
  • Quick Bites — three mind-blowing facts from completely different fields.
  • Your Research Corner — tied directly to my thesis area (AI infrastructure, caching, scheduling), referencing real labs and ongoing debates.

On Sundays, there's a weekly recap that draws connections across everything covered that week — the kind of cross-disciplinary links that are the whole reason this thing exists.

The Feedback Loop

This is probably the part I'm most proud of. Each section arrives as a separate Telegram message with inline reaction buttons: Love it, Meh, Skip, and More of this tomorrow. The system gently adapts based on my reactions.

But here's the key design decision: exploration over exploitation. The adaptation weights are clamped to [0.85, 1.15] and they drift back toward 1.0 over time. A single "meh" doesn't kill a topic. A string of "love it" reactions on quantum computing doesn't turn your newsletter into a quantum computing gazette. The system is biased toward breadth because serendipity is the whole point.

After the last section, there's also a length feedback row — Shorter / Perfect / Longer — that shifts the target reading time by 0.3 minutes per vote, clamped to ±1.5 from your configured base.

Managing It From Telegram

I can add or remove interests, researchers, and topics without ever touching a config file. Just send casual messages to the bot:

  • /add_interest that crazy quantum bio stuff
  • /add_researcher that Italian prof at Stanford who made Spark
  • /remove_topic serverless
  • /config to see everything at a glance

The system uses Gemini to clean up casual input into proper config entries. You don't need to know the exact arXiv category name or a researcher's full affiliation — just describe what you mean.

Website & Public Channel

Every newsletter is automatically published to a static website on GitHub Pages. Each issue gets its own page with search and a knowledge map — a growing log of every topic, paper, and theme the newsletter has ever covered. It's becoming genuinely useful; I can go back and find "that paper about serverless MoE serving" in seconds.

There's also a public Telegram channel — @Broletter — where anyone can subscribe to read along.

How It Works

The architecture is straightforward:

config.yaml → fetcher.py → generator.py → bot.py → Telegram
                  ↑              ↑            ↓
              arXiv API     Gemini API    feedback.json
                                              ↓
                                     next day's generation adapts
  • Fetcher (fetcher.py) — queries the arXiv API for configured categories. Primary categories are always queried; two random secondary ones are added each day for variety. Free, no auth needed.
  • Generator (generator.py) — builds prompts from templates with tone rotation, sends them to Gemini 2.5 Flash. Uses your feedback weights to adjust section depth. About 5 API calls per newsletter.
  • Bot (bot.py) — sends each section as a separate Telegram message with inline reaction buttons. Also handles the config commands.
  • Store (store.py) — persists history (papers seen, themes used), feedback (reactions + weights), and the knowledge map.
  • Site builder (site_builder.py) — converts the markdown newsletters into a static HTML site with search and a knowledge map page.
  • Scheduler (scripts/install_schedule.py) — installs three macOS LaunchAgents: nightly generation at 11 PM, command sync every 30 minutes, and a morning reminder at login/wake.

No background processes. The LaunchAgents only run when the laptop is awake. If the Mac was asleep at 11 PM, it catches up at next wake with an idempotency guard — it skips if already delivered, retries send-only if generated but not sent (e.g. no WiFi last night). Zero battery impact.

Cost

ComponentCost
Gemini 2.5 FlashFree tier (1500 req/day, newsletter uses ~5)
arXiv APIFree, no authentication
Telegram Bot APIFree
macOS LaunchAgentBuilt-in

Total: $0/day.

Make Your Own

The whole project is open source on GitHub. Here's how to get your own running:

  1. Clone and install
    git clone https://github.com/landigf/Broletter.git
    cd Broletter
    python3 -m venv .venv && source .venv/bin/activate
    pip install -r requirements.txt
  2. Get a free Gemini API key from Google AI Studio.
  3. Create a Telegram bot via @BotFather.
  4. Edit config.yaml — this is the most important step. Set your name, background, thesis area, curiosity themes, arXiv categories, and thesis keywords. The config.example.yaml shows a physics setup as reference. My advice: make the curiosity themes wide. Put your research in, but also things you'd never allocate time to read about. Half the value is the unexpected.
  5. Register your chat: run python main.py listen, send /start to your bot in Telegram.
  6. Generate your first newsletter: python main.py generate
  7. Automate everything: python scripts/install_schedule.py

What I Learned

Building the feedback loop taught me that gentle adaptation beats aggressive optimization. Small deltas plus mean-reversion equals a system that respects your taste without becoming an echo chamber. The weights feel right at [0.85, 1.15] — enough range to notice, not enough to destabilize.

It replaced my morning Twitter scroll. Seven minutes of curated science beats an hour of algorithmic noise. And the knowledge map is becoming a genuine reference tool — months of papers searchable in one place.

Most importantly: it brought back the feeling of a friend excitedly telling me about something cool they read.

Links:

Back to Blog