Kids' café bookings in Telegram: from 3–4 to 5–7 parties a week
A kids' café took bookings by phone and in messengers. Parties, the playground, workshops: everything ran on calls and chats. I built a Telegram bot where clients book by themselves, staff see the schedule, and the owner changes prices herself and gets reminders and records in one place. The café used to have 3–4 parties a week. Now it's 5–7, and 4–5 of them are booked through the bot. Calls dropped by roughly 15–20%.

What was broken
Bookings came in by phone and messages, and nobody saw the full picture of what was taken. Two big parties renting the whole café could easily land at the same time.
Workshops had their own problem. They were often cancelled because not enough kids signed up. People did sign up, but nobody told them in time that the group had filled.
What the owner wanted
- Telegram only. No separate website or domain at the start.
- She changes prices and packages herself, without a developer.
- A warm tone, because it’s parents writing.
The solution
The first thing the bot does is figure out who’s writing: a client, someone from staff, or the admin. That decides which menu the person sees. Nobody sees anyone else’s menu.
- A client can book the playground, a party, a workshop or a table, register a child’s birthday, and check their bookings and details. Contacts include a map link.
- Staff see bookings for today and the next few days and mark them “done” or “no-show”. There’s a QR code of the bot for the reception desk. You can only get into this panel with a one-time code from the admin.
- The admin panel is where packages, prices, workshops, animators and tables are edited. All bookings are visible there and can be cancelled. It also has newsletters for those who opted in, stats and an error log.
- Between the menus and the database sits a service layer holding all the logic: prices, checking whether a slot is free, validating what the user typed. Buttons just call these functions. Otherwise one rule would have to be written in four places, and sooner or later the copies would drift apart.
- The database is SQLite: one file on disk, no separate database server needed. For one café that’s more than enough. Tests run on a separate database and never touch the live one.
- Anyone who signs up for a workshop gets two notifications: when the group has filled and when the class is on.
- A scheduler sends reminders a day before a booking and once a year wishes the kids a happy birthday.
Development story
Kick-off
The owner had no ready picture of how it should work. So we started with a spec: went through everything that hurts right now, decided what the bot should do, and built the skeleton from that.
An animator can't be at two parties
An animator physically can’t be at two parties at once, even when the café isn’t fully rented. The first version of the picker came out clumsy: either take every animator or cancel the booking. I redid it. Now the choice is per slot, there’s a “Don’t choose” button, and anyone busy at that time simply isn’t in the list.
Everyone gets their own menu
The admin and staff saw the client menu on top of their own. I made one function that detects the role at entry, and now everyone sees only their own panel.
Audit and refactoring
After a dozen phases, technical debt had piled up. The code audit came back with 157 findings, and it took eight phases to work through them. The four critical ones, all about data races, I closed in a separate phase.
Old menus after a restart
After every server restart, old menus were hanging in the admin’s chat. The reason was simple: the bot kept dialog state only in memory, and a restart wiped it. I moved the state into the same SQLite. Now it survives restarts, and the bot cleans up its old messages itself.
The admin didn't see new bookings
New-booking notifications weren’t reaching the admin. It turned out the notification logic knew about the owner and staff and simply forgot about the admin. Fixed.
Mini App mockup
On top of the working bot I put together a clickable Telegram Mini App mockup. Same flows, but instead of a chain of messages it’s one screen: calendar, cards, everything visible at once.







What I took away
- Over 700 green tests don’t mean the bot is comfortable to use. Almost every inconvenience I found by walking through the flows by hand myself.
- A commit after every phase is a must. Nearly every feature touched the data core, and without a rollback point one bad run would have eaten a day.
- Scope grows by itself. It started as a booking bot, and a week later it was a CRM with three roles. At some point I should have stopped and lived with the product instead of bolting on one more feature.
Result
Before the bot the café had 3–4 parties a week. Now it’s 5–7, and 4–5 of them come through the bot. People call less, by roughly 15–20%: they mostly book on their own now. And they come back noticeably more often.
The bot runs on a server as a system service: if it falls over, it gets itself back up. Clients book parties, the playground, workshops and tables. Staff see the schedule and mark who showed up. The admin manages prices and hears about failures in Telegram.