cd /news/ai-tools/the-tea-stall-granny-next-to-my-offi… · home › topics › ai-tools › article
[ARTICLE · art-153657] src=dev.to ↗ pub= topic=ai-tools verified=true sentiment=↑ positive

The tea stall granny next to my office runs on UPI, so I built a payment announcer that speaks Hindi

A developer built an open-source payment announcer that runs on a laptop and speaks Hindi, designed to let a small tea stall owner hear UPI payments instead of stopping to check her phone. The tool parses bank SMS with hand-written rules rather than a model, stores amounts as integer paise, and rejects spoofed senders, refunds, OTPs and duplicates; in a 16-message demo run it counted 8 payments totaling ₹5,716, and all 41 unit tests pass. Voice output uses the offline Piper hi_IN-pratham-medium voice, with an optional end-of-day summary from a local Gemma 3 4B model via Ollama that receives only parsed numbers, never raw SMS text.

by read5 min views1 publishedOct 20, 2026

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady

Next to my office there is a small tea stall. We call the woman who runs it Amma (Mother). By my rough count, on a normal day she sells about 100 cups of tea at ₹15 a glass, about 150 pieces of murukku at ₹5, about 100 bananas at ₹10, and about 75 samosas at ₹15 each - somewhere around ₹4,400 a day, across a counter the size of a desk.

Almost all of it is UPI now - about 95%. She prefers it that way: few customers carry exact change these days, and she does not keep change to give back.

The hard part is the checking. She is not very hands-on with her phone, and when you are serving tea and snacks all day, your hands are not clean. Every time a payment should have arrived, she has to stop, wipe her hands, pick up the phone, and read the SMS list to see whether the money actually came - and whether it came in the order she expects, so she can match payments to the people standing in front of her. At rush hour there are five to ten people at the counter at once. That is when it breaks.

Shops solve this with a soundbox, the little speaker that announces every payment out loud. A commercial one costs more than a stall this size can justify. So she wipes her hands and checks the phone.

This week's theme is Slow and Steady: build something that does the work so you don't have to. So I built the part she actually needs.

A payment announcer that runs on a laptop (as a POC) and speaks Hindi:

Judges cannot stand at her stall, so the demo looks like her phone: a phone-sized screen in the browser where SMS drop in like notifications, the payment shows as a big card, and one button feeds in a fake SMS - including the nasty ones. A spoofed sender, a refund, an OTP message: you can watch each one get rejected.

The safeguards are the point, not a footnote:

Real numbers from my test runs: the demo feeds 16 sample SMS through the parser. 8 are counted, 4 are rejected outright (a payment request, a debit, a failed payment and an OTP), 1 refund is recorded separately, 1 spoofed sender is flagged for review, and 2 duplicates are flagged without being counted a second time. The counted total is ₹5,716, and the ₹5,000 payment gets the large-amount warning. All 41 unit tests pass.

Run it yourself:

git clone https://github.com/viveknshah/payment-announcer cd payment-announcer

python app.py demo # 16 sample SMS, 8 counted, spoken aloud

python app.py serve # phone-frame UI on http://localhost:8000 python test_suite.py # 41 unit tests

Python 3.10 or newer. Nothing to pip install.

No hosted demo, on purpose: it is built to run on one machine with nothing sent anywhere, so the demo is the repo plus the video.

https://github.com/viveknshah/payment-announcer Plain Python, boring on purpose. The standard library only, no pip install. Piper (voice) and Ollama (summary) are optional extras.

The parser is rules, not a model. Bank SMS wording changes often enough that I trust code I can read over a model I cannot, and amounts are stored in paise as integers, so ₹15.00 never becomes 14.999. The rules follow two real Bank of Baroda SMS layouts - one UPI credit alert with a 12-digit reference, one plain credit with only an amount and a date. Every name, account number, reference and amount in the repo is fictional. No real message text is in it.

The voice is Piper with the hi_IN-pratham-medium voice: open-source and offline, with the operating system voice or plain text as fallback. The voice files are not in the repo (about 60 MB).

The end-of-day summary comes from a local Gemma model (Gemma 3, 4B) through Ollama's API. The model only gets the day's parsed numbers, never the raw SMS text. The division of labour is the same rule I used in my last project:

| Measured in code (facts) | Judged by the model (words) | 
|---|---|

| Today's total and payment count | How the summary is phrased | | Duplicate and uncertain matches | Which pending items to mention first | | Bill due dates from bills.json | The reminder wording |

Small models drift on money, so the summary cannot lie about it. The model's text is spoken only if every rupee amount matches the ledger, the exact total appears in digits, and no English wrapper text survives. Otherwise the template is spoken. The bills line always comes from bills.json, never from the model.

Languages are JSON packs. Hindi is complete. English and Kannada are stubs for now, and they run on templates so the demo still works.

Tests: 41 unit tests, all passing. Prior art, honestly: UPIPaymentAlert already parses Indian payment SMS and speaks them, and every payment company sells a soundbox. What this adds is the part after the beep: a summary that closes her day with the bills list, and language packs, so the next stall over can have Kannada without asking anyone's permission.

Others are working the same street this week, which is a good sign: Gazette turns any notification into a ledger with Gemma 1B on the phone, Kharcha reads Indian bank SMS with a 4B model on a laptop, and khata keeps a household ledger. None of them speaks each payment out loud in Hindi or closes the day with the bills list; that is the gap this fills.

The full build session, including the failed Gemma 4 load and the guard that catches a wrong total:

She serves tea; the phone does the checking. No wiping hands, no scrolling through SMS with five people waiting, no mental arithmetic at closing time. The announcements just happen, and at the end of the day one button sums it up and lists the bills that are due.

The soundbox companies built this for shops with margins. This is the sloth version for a stall that sells ₹5 murukku: it does the work, she does not have to, and it costs her nothing to keep.

python app.py watch fed by an SMS forwarder. Entering the overall judging and Best Use of Gemma: a local Gemma model (Gemma 3, 4B, through Ollama) writes the end-of-day summary, checked by code against the ledger.

── more in #ai-tools 4 stories · sorted by recency
── more on @piper 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/the-tea-stall-granny…] indexed:0 read:5min 2026-10-20 · —