Investu: Turning 8 Browser Tabs Into One Morning Brief
Mohammed Zabeeh·June 17, 2026·14 min read
A side project: the experience of a daily investment brief, and the Telegram bot behind it, replacing my eight-tab morning research routine with a single 8 AM digest at zero cost.
17
Telegram commands
7 free
Data sources
Rs. 0
Monthly cost
13
Build phases
Client
Personal Project
Role
Designer & Builder
Timeline
2026
Type
Consumer
Tools
Python, Gemini, Tavily, FMP +4
The Problem
Eight browser tabs. Every morning.Screener.in for Indian fundamentals. Yahoo Finance for US stocks. Moneycontrol for news. AMFI for mutual fund factsheets that look like they were laid out in 2007 because they were. NSE for IPOs. Chittorgarh for the IPOs NSE forgets. Zerodha Kite to actually buy things. And Groww because Kite makes me sad.Twenty minutes of real research buried under thirty of context-switching between pages with different formatting and different update frequencies. Most mornings I closed the laptop without buying anything, because by the time I had compared everything worth comparing, I was tired.Worth solving for myself, then. As a designer I had wanted to build something with my own hands, partly because I kept talking to engineers about products and noticing how often the conversation skips the boring decisions that actually shape how a thing feels. The only way to learn that for real was to make something where every decision was mine.
What It Does
Investu started as a single-user Telegram bot. Mine. It now serves a small, owner-curated allowlist of trusted friends too. It runs every morning at 8 AM IST. It screens 100+ Indian , the S&P 500 starter set, mutual funds, -eligible picks, and live . It ranks whatever passes a quality screen, surfaces a near-pass watchlist of stocks that almost qualified, and pulls sourced news on the top picks. Every URL it cites is a real URL.
Designing the Experience
Turning a chore into something I look forward to opening is an experience problem before it is an engineering one, so the design decisions led.Telegram, not a web app. The brief had to arrive where I already am, with no browser tab to open and no login to clear at 8 AM. Telegram also gives bots real formatting freedom that WhatsApp does not: inline keyboards, rich cards, scheduled messages, and no per-message cost. The whole interface is seventeen commands behind an inline keyboard menu, so the bot is browsable, not memorised.
One company per card, labels and values stacked, readable on a phone at 8 AM.Cards, not tables. The first thing I tried was a monospace table, and it was a disaster. Phone screens line-wrap monospace tables in the worst possible places, usually the price column, right when you cannot tell whether is 16.8% or 168%. The bot does not run on a database. It runs on a phone screen at 8 AM, and the person reading it has bedhead. So the formatter became cards: one company per card, labels and values stacked, message-limit splits that fall between cards and never cut one in half. A tiny-sounding call that changes how the output is composed at every layer.Honest labels. Every number the bot prints carries its timeframe and its source. current. ROE TTM. Revenue 3Y . Source: Screener.in. As of timestamp. When something is missing, the missingness gets a label too: "Market cap: n/a" is information, not an error. The bot has never lied to me about what it does not know, and that is the whole basis of trusting it.Decision support, not a verdict. The most useful idea in the product is the near-pass watchlist. The strict screen tells you what to buy this quarter. The near-pass list tells you what to check next quarter, showing exactly why a name missed, for example "Reliance: 3Y profit CAGR 8.4% against a 12% floor." A screen that only says yes or no throws away the most interesting half of the answer.A ritual, not a tool. The morning brief opens with a quote, a 43-strong rotating deck of Buffett, Munger, Naval, Damani, and Morgan Housel that never repeats until it has been through all of them. That single line is the difference between a tool I use and a tool I look forward to opening.
Trust by Design
The five screens tell me what to buy, not why this week is the right week, and that is what news research is for. It only earns its place if the honest-labels promise survives contact with an , so the pipeline is built around one rule: every URL the bot cites must be real.
The three-step research pipeline: Tavily searches, the model extracts, then code validates every URL.LLMs hallucinate URLs. The first time I asked GPT-4 for three recent articles about Reliance with sources, all three returned 404, not out of malice but because a URL is exactly the kind of detail a model will invent to satisfy a citation pattern. It knows what URLs look like. It does not know which ones exist.The pipeline that solved this has three steps. searches fire two focused queries per ticker (catalysts in the last 21 days, analyst targets) and return real snippets with their source URLs. Gemini extracts, feeding those snippets into Gemini 2.5 Flash-Lite with a fixed JSON schema that has no "growth potential" or "expected returns" field, so the model physically cannot emit speculation. Code validates, and this is the part that matters: I keep the set of URLs Tavily actually returned, and any URL in the model's output that is not in that set gets dropped.The model can hallucinate. The pipeline does not. In six weeks of running, not one fake URL has leaked into the output. The model is the cheapest part of this system. The expensive part is the engineering around it.
Phase by Phase
Phase one was a 250-line CLI printing screened large-caps straight to the terminal.Phase 1 was a 250-line Python CLI: no Telegram, no LLM, no scheduler, just a quality screen that printed Indian large-caps to the terminal. It loads a universe, checks fundamentals against a YAML rule set (market cap, revenue and profit CAGRs, ROE, debt-to-equity, PE), ranks the survivors, and records every check it ran so the near-pass watchlist can explain a miss.
Five screens share one contract: same caching, same three-step flow, same card formatting.Once that pattern held, the other four screens were a copy-the-shape exercise: US stocks on Financial Modeling Prep, mutual funds on MFAPI.in, SIPs as the fund screen with a minimum-amount filter, and the IPO calendar from NSE's official endpoint. Five screens, same three-step contract, same caching layer, same formatting pipeline.
At 8 AM the bot wakes itself and fans out all five screens.Phase 4 added the 8 AM digest as an in-process scheduled job, no Celery and no cron container: the bot wakes itself, fans out all five screens, and posts each as a card stack. One subtle problem followed. Indian fundamentals refresh only quarterly, so the same names surfaced every morning, technically correct and dead stale. The fix was a date-seeded daily rotation (deterministic and unit-testable) over a larger universe, plus an honest recalibration of the thresholds when a live run revealed the strict screen passed only 7 of 96 names. The brief now spotlights roughly eight different, still-qualified names a day.
Running at Zero Cost
One auto-detecting entrypoint runs across four hosts, from laptop to always-on cloud VM.Most side projects die between "it works on my laptop" and "it runs every morning whether I touch it or not." The first version ran on a Render free service woken by a GitHub Actions cron, and it failed twice over: cold starts outran the trigger, and GitHub's best-effort schedules fired hours late, so my "8 AM" brief routinely arrived at noon. So I stopped fighting it. The bot now runs always-on in polling mode on an Oracle Cloud Always Free VM, where the in-process scheduler fires at 08:00 IST exactly. The public IP got locked down: key-only SSH, no inbound ports, owner-only .env, quiet logs so the token stops leaking. A read-only deploy key plus a systemd timer make the VM self-update on every push, so the whole deploy workflow is a single git push.
Every data source and service sits inside its free tier, so monthly cost stays zero.Investu costs Rs. 0 a month at steady state because it caches aggressively: six-hour caching means a ticker is never re-searched within a business day, which keeps Tavily, Gemini, and FMP comfortably inside their free tiers. The shared cache is also what makes "a few friends" free, since every allowlisted user reads the same cached picks and the only quota-burning command is owner-only. "Free tier only" was a constraint I set upfront, not an outcome I stumbled into, and it was clarifying: the Rs. 500-a-month version would be more capable and worse-designed in every way that matters.
Living With It
Two more phases came from the only research method that never lies: using the thing every morning.The first was polish. Every message gained a visual hierarchy, bold titles and prices, monospace symbols, underlined section headers, metadata in italics, where before a company's name and its PE ratio looked identical. A plain "hi" now opens the full menu instead of a greeting, the boilerplate that used to trail every report moved into /help, and every source link became a tappable button under its card rather than a raw URL in the text. The digest also went concurrent: five screens that ran one after another now run at once, each report sent as it finishes behind a single status message that edits itself in place ("Running screens… 3/5 done"), and a quiet pre-warm job fifteen minutes before the digest means the 8 AM brief lands in seconds.The second asked a harder question: how do I know the numbers themselves are right? Three mechanisms answered it. Every displayed card is now cross-checked against a second source, Yahoo's quote endpoint, with agreement earning a quiet tick and a divergence beyond ten percent earning a bold warning that names the field and the gap, because the Indian fundamentals come from a scrape and scrapes drift silently. Every payload is stamped at fetch time, inside the cached data, so a card served from cache reports its real age instead of masquerading as fresh. And the mutual fund rules that had been aspirational for months, expense ratio and fund size, written in config but unenforceable because no free source exposed the data, became real when 's read-only API closed the gap, with excluded funds now listed alongside the reasons they missed.Building that verification exposed the most alarming bug of the project. Fourteen of the fifteen scheme codes in the curated seed file pointed at entirely different funds: "SBI Small Cap" had been serving Axis Small Cap's numbers. Every fund figure the bot had ever shown was a real value belonging to the wrong name, which is precisely the failure honest labels cannot catch, because the label lies with a straight face. Every code was re-resolved against records and verified by , and a permanent name-mismatch guard now fails any fund whose seed name disagrees with the record for its code. The bug class is dead, not just the bug.
Platform Evolution
Feb 2026
Phase 1: CLI script
A 250-line Python quality screen for Indian large-caps, printing to the terminal.
Feb 2026
Phase 2 + 3: Telegram bot and four more screens
Inline keyboards, plus US stocks, mutual funds, SIPs and the live IPO calendar.
Mar 2026
Phase 4: Daily 8 AM digest
The morning brief automated with an in-process scheduler.
Mar 2026
Phase 5 + 6: AI news research
Live IPO tracking from NSE and a Tavily pipeline whose every cited URL is validated.
Apr 2026
Phase 7: FMP migration
Yahoo started 429-ing cloud egress IPs, so the US screen moved to Financial Modeling Prep's free tier.
Apr 2026
Full month of testing
A month verifying data integrity before anything shipped to daily use.
Jun 2026
Phase 8: Bigger universe and daily rotation
The full Nifty 100, roughly 45 US caps, and a date-seeded daily rotation.
Jun 2026
Phase 9 + 11: Always-on, self-deploying VM
Render and the GitHub Actions cron retired for an Oracle Cloud VM that self-updates on every push.
Jun 2026
Phase 10: A few-friends allowlist
An owner-curated allowlist with opt-in digests and quota guardrails.
Aug 2026
Phase 12: The UX and speed pass
Visual hierarchy, tappable source links, a concurrent digest, and Gemini 2.5 Flash-Lite for extraction.
Aug 2026
Phase 13: The accuracy layer
Yahoo cross-checks, fetch-time stamps that survive caching, Kuvera fund rules, and ISIN identity verification.
Next
v1.1 enrichments
Promoter-pledge extraction, a comparison of PE against its own three-year median, and an Indian mid- and small-cap screen.
Lessons
Design the output before the screens
I nearly shipped a table-based formatter before realising it was unreadable at 8 AM on a phone.
The model is the cheapest part
The real work was the schema lock, URL validation, sanity ranges, and mode-specific prompts.
Constraints are clarifying
"Free tier only" shaped the product more than any feature idea did.
Verify identity, not just values
The seed file's scheme codes were checked by eye and wrong for months, so identity is now verified mechanically, ISIN against record, on every run.
FAQ
For a few trusted friends, yes. Investu runs an owner-curated allowlist with opt-in daily digests. It stays affordable because everyone reads the same shared-cache picks, so the fixed screens cost the same for one user or fifty, and the only quota-burning command is owner-only. Going fully public is intentionally not on the roadmap: public-scale scraping would breach Screener.in's terms, the free FMP and Tavily tiers would not survive the load, and distributing a financial screen at scale edges into regulated advice territory.
The cache absorbs it. If a ticker was fetched in the last six hours, the bot returns the cached result instead of calling the API again, so limits almost never trigger across a normal day.
Those apps are great products. They are also built for a general audience, which means the screens, defaults, and alerts reflect average preferences. Investu's quality criteria are specifically mine. The PE ceiling, the revenue CAGR floor, the near-pass watchlist, the Telegram format at 8 AM: none of that exists in a general-purpose app because none of it is generally useful.