The task
A solo barber or nail artist cannot answer a client who writes at 23:00 asking “any time tomorrow?”. The answer comes in the morning, when the client has already booked somewhere else. Bookings live in a notebook or in the head, hence two clients for the same hour and forgotten visits. Hiring an administrator does not pay for one person.
This is our own product, not a commission. We wanted to check whether solo professionals in Ukraine would buy a simple booking tool for $10 a month. From our market research, AI Beauty Bot costs $79-219 a month, Starta.one starts at 6 euro but is complicated, beautyTG on GitHub is free but cannot be set up without a developer. A solo professional in Telegram, in Ukrainian and Russian, for $10 looked like an almost empty spot.
Why, and what the idea was
The idea: the professional does not wait for us. They create a bot in @BotFather following a step-by-step illustrated guide, paste the token into the main bot, and the server picks their bot up immediately, with no restart. One process on the server holds an unlimited number of other people’s bots. The client in the professional’s bot never types free text: service, day, hour, all with buttons, and only free slots are shown.
The main decision we revised: in the first version Claude Haiku 4.5 answered clients’ free-text questions. After one day we removed it completely. The bot could say things about the professional’s prices and services that were not true, and for booking, accuracy matters more than a “smart” conversation. We removed the whole path, not just the button: leave a free-text handler in place and the risk stays. Price: $20 at first, then I lowered it to $10 as a starting price for Ukraine, for everyone including those already connected, with the first month free. Database: SQLite instead of PostgreSQL, simpler at the start, enough for roughly 500 professionals by our estimate.
How it went
| Stage | What happened |
|---|---|
| Day 1, evening | Concept, competitor research, an MVP plan for 1-2 weeks |
| Day 2 | 26 commits in a day: registration, services, calendar, referral program, CryptoCloud and LiqPay payments, trial protection, three critical bugs in the multi-bot scheme. In the evening, AI answers to free text removed |
| Day 3 | MVP on the server. Manual subscription grants with the /activate command, to sell without waiting for LiqPay to be connected |
| Day 5 | The professional’s dashboard in six languages, BotFather guide pictures in six languages, the server password removed from deploy.py |
| Day 6 | Days off, broadcast to clients, support. Price lowered from $20 to $10 for everyone. Project documentation |
| 2.5 months later | A check on request: the bot is alive. The double-booking hole closed, the first tests in the project |
| The next day | The payment intake hole closed, log rotation, a professional’s bot with someone else’s webhook switched off |
46 commits in total: 5 days of active development and two targeted sessions later on.
Tools and method
Python 3.11, aiogram 3.7, SQLAlchemy 2 with aiosqlite, APScheduler for reminders, an aiohttp server for payment postbacks. About 4,700 lines, the biggest files: professional registration 2,125 lines, translations 986, the client bot 813.
Many bots in one process: one shared aiogram dispatcher and one polling call with all bots at once. When a professional connects or leaves, the polling task restarts with the new list under an asyncio.Lock so that two simultaneous connections do not clobber each other. Database: SQLite, one file, tables for professionals, clients, bookings and a separate trial history table keyed by Telegram ID. Server: a VPS, a systemd service with autostart and auto-restart, deployment by git push plus a script, SSH key login.
Money and keys: secrets only in .env, outside git. A payment postback is accepted only with a signature (JWT HS256), the signature is bound to a specific invoice, LiqPay verifies its own signature separately. The price is set in one place in the code plus the texts in translations.
Result
The main bot for professionals: language choice, registration (specialty, services with prices, working hours, days off, address with a format hint), the BotFather guide with pictures, token entry. Dashboard: my bookings, settings, editing and deleting services, a broadcast to all your clients, a referral link (bring a professional, get a month free), support, payment by card via LiqPay or crypto via CryptoCloud. The new-booking notification has a “Message the client” button.
The professional’s bot for clients: language, service, day (a quick pick of 7 days or a custom date), hour. Only free slots are shown. A booking can be cancelled with a reason, a contact can be left. The reminder arrives a day before the visit. Languages: Ukrainian, Russian, English, Polish, Spanish, German. The landing page ai-bot.com.ua/masters in Ukrainian and English, with a demo conversation, the plan and FAQ. The bot itself: t.me/masterbooking_main_bot.
What we measured. Uptime: the service ran 2 months and 20 days without a restart, 180 MB of memory, 195 minutes of CPU in total, the queue of unprocessed Telegram messages empty. Tests: three files, 49 checks: 19 on taken slots, including a race between two simultaneous bookings, 13 on the real booking function, 17 on the payment postback signature. Every test failed on the old code first.
Honestly about the weak side. The product works technically, but there are no sales. In the database 5 professionals (one a test account), 9 bookings, and no new bookings after the first days. Zero payments in its whole history, three professionals’ trial month ended 21-55 days ago and they keep using it for free. Why the connected professionals stopped running bookings through the bot, we have not investigated, and without that answer fixing payments is premature. Five open defects at the last check, among them: nobody gets switched off for non-payment, the postback travels over HTTP without TLS, the client’s booking steps are still hardcoded in Russian while the professional’s dashboard is translated into six languages.
Mistakes and what we took from them





