Every morning I open three dashboards, two newsletters, and one very long Slack thread. Then I close them all and forget what mattered.
So I built a bot that does the reading for me. It runs on a schedule, pulls a few feeds, and sends me one tight summary. Total cost: zero. Total code: about 60 lines.
Here's the part nobody tells you about free LLM quotas: they're perfect for scheduled jobs. A daily digest uses maybe 5,000 tokens a day. Even a 10-million-token monthly allowance (what MonkeyCode's free tier offered as of August 2026 — check the repo, quotas change) lasts you months of daily digests.
This is not a tutorial about summarization. This is a tutorial about making a free endpoint do useful work while you sleep.
The architecture
Three pieces:
- A fetcher — pulls RSS feeds or JSON endpoints
- A summarizer — sends the content to an LLM endpoint
- A notifier — pushes the result to Telegram, email, or a file
I run it with GitHub Actions on a cron schedule. No server to maintain, no cost, and the logs are right there in the Actions tab.
Step 1: The fetcher
Keep it boring. No framework, just urllib and xml.etree:
import urllib.request
import xml.etree.ElementTree as ET
def fetch_rss(url, limit=5):
req = urllib.request.Request(url, headers={"User-Agent": "digest-bot/0.1"})
with urllib.request.urlopen(req, timeout=15) as r:
root = ET.fromstring(r.read())
items = []
for item in root.iter("item")[:limit]:
title = item.findtext("title", "")
link = item.findtext("link", "")
items.append(f"- {title}\n {link}")
return "\n".join(items)
RSS is still the most reliable way to get content without API keys. If your source doesn't have RSS, use a JSON endpoint instead — same idea, different parser.
Step 2: The summarizer
The prompt matters more than the model. I spent a week tuning this:
import json, urllib.request
def summarize(content, endpoint, api_key, model):
prompt = f"""You are a technical news editor. Read these headlines and links.
Write a 3-bullet digest. For each bullet: what happened, why it matters, and one
question a developer should ask. Ignore anything that's pure marketing.
CONTENT:\n{content}"""
payload = {
"model": model,
"messages": [{"role": "user", "content": prompt}],
"max_tokens": 300,
"temperature": 0.3,
}
req = urllib.request.Request(
endpoint,
data=json.dumps(payload).encode(),
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}",
},
method="POST",
)
with urllib.request.urlopen(req, timeout=60) as r:
body = json.load(r)
return body["choices"][0]["message"]["content"]
Three prompt lessons from real failures:
- "Summarize" is a weak verb. "Write a 3-bullet digest" gives the model a structure to fill.
- Add a filter instruction. Without "ignore pure marketing," half your digest is press-release language.
- Ask for a question. It turns the digest from a recap into a thinking tool.
Step 3: The notifier
Telegram is the easiest free notification channel. Create a bot, get the chat ID, send a message:
import urllib.parse, urllib.request
def notify_telegram(text, bot_token, chat_id):
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
data = urllib.parse.urlencode({"chat_id": chat_id, "text": text}).encode()
urllib.request.urlopen(url, data=data, timeout=15)
No SDK needed. It's one HTTP call.
Step 4: The cron
GitHub Actions makes this trivial. Save as .github/workflows/digest.yml:
name: daily-digest
on:
schedule:
- cron: "0 7 * * *" # 7 AM UTC
workflow_dispatch: # manual trigger for testing
jobs:
digest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements.txt
- run: python digest.py
env:
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
Secrets go in the repo settings. Never commit keys.
Where MonkeyCode fits
I needed an endpoint that (a) was OpenAI-compatible so my code stayed portable, (b) had a free tier generous enough for daily runs, and (c) didn't require a credit card to start. MonkeyCode's free server checked all three boxes when I set this up. The 10-million-token monthly allowance meant I could run this bot daily for months without thinking about cost.
Disclosure: This article was prepared as part of MonkeyCode's product outreach.
Is it the best model for summarization? Probably not. Is it good enough for a morning digest? Absolutely. That's the tradeoff free tiers are actually good for: not production workloads, but personal automation that runs once a day and fails gracefully.
What I learned running it for 30 days
Failure #1: Timeouts. The first version had a 30-second timeout. A slow endpoint killed the whole job. Fix: raise it to 60 seconds and add a retry.
Failure #2: No deduplication. The same story appeared in three feeds. The digest had three near-identical bullets. Fix: keep a small JSON file of seen titles, skip duplicates.
Failure #3: Token waste. I was sending full article text when headlines were enough. Cutting content from 2,000 tokens to 400 tokens per source made the digest faster and cheaper.
The honest limitations
This bot is not a production system. It's a personal tool with three failure modes you should know about:
- It depends on a free tier that can change. The allowance I used in August 2026 might not exist next quarter. The code is portable — that's the point of using an OpenAI-compatible endpoint.
- It's only as good as its sources. Garbage in, confident-sounding garbage out.
- It can't catch nuance. A headline summary misses context. It's a filter, not a replacement for reading.
Who should not build this
Skip this approach if you need:
- Real-time alerts — cron jobs have latency by design
- Guaranteed delivery — free endpoints have no SLA
- Compliance-grade data handling — your prompts go to a third party
For everything else, a scheduled LLM job is the cheapest automation you'll ever run.
The takeaway
Free LLM quotas are usually wasted on chat windows. The real value is in unattended jobs: digests, monitors, classifiers, translators. A cron job doesn't care about latency. It doesn't care about rate limits. It just needs enough tokens and a stable API shape.
My digest bot has run for 30 days without a single manual intervention. That's 30 mornings I didn't spend scrolling. If you've got a free endpoint sitting idle, point it at something boring and repetitive — that's where the leverage is.
MonkeyCode provides free models that can run this workflow.
Top comments (0)