← Blog

A Telegram-native booking system for SMEs in Myanmar and Thailand

How we built a multi-tenant appointment booking platform — clinics, salons, workshops can take bookings via Telegram with verified phone numbers, no SMS gateway, no app to install. Architecture, achievements, and what we'd do differently.

We built this for a real customer — a clinic in Myanmar that needed appointment booking — but the architecture works for any service business that takes appointments. Here’s what we shipped and how it works.

The problem

A clinic has two doctors, walk-in patients, and a phone that rings all day. The receptionist takes appointments in a notebook, calls customers when their turn comes, and loses bookings when someone forgets to show up.

Standard SaaS solutions don’t fit:

  • Calendly assumes Google Calendar and English-speaking clients with email
  • Most options require expensive POS hardware or charge per-SMS for confirmations
  • None of them speak Burmese or are designed for Telegram-first communication

We wanted: instant booking, verified phone numbers, multilingual replies, no app to install.

The architecture

Telegram ──► n8n ──► MCP server ──► HI backend ──► Postgres
   ▲                                      ▲
   │                                      │
   └─ customer talks to bot              └─ admin uses web dashboard

Four pieces:

  1. HI — the multi-tenant Next.js admin where the clinic owner manages doctors, sees today’s appointments, and updates “now serving #N”
  2. MCP server — a small Node service that exposes 7 booking tools (list_staff, create_booking, get_current_queue, etc.) via the Model Context Protocol
  3. n8n — wires Telegram to the MCP server with a gpt-4.1-mini AI agent, conversation memory, and a tool-using loop
  4. Telegram — the customer-facing surface. No app to install, already on every phone in Myanmar.

What it does

  • Customer chats the bot in Burmese or English. Asks “who’s working today?”, “book me Saturday”, “what’s the queue number now?”
  • Phone is verified via Telegram’s Share Contact button — single tap, no SMS code needed
  • Admin sees bookings in real-time on a web dashboard, marks customers as Checked In → In Progress → Complete, and the queue auto-advances
  • Broadcasts — admin can push a promo message to every past customer with one click
  • Multi-tenant — many businesses share one platform, each with isolated data and its own bot

The trick — free phone verification

The most expensive part of a booking system is usually OTP via SMS. You need to verify the customer’s phone is real before saving the booking, otherwise spammers ruin your day.

Telegram already verified the user’s phone when they signed up. We use that.

When the bot needs the phone, it sends a special message:

Bot: "Please tap the button below to share your verified phone number."

[📱 Share my number]   ← Telegram native button

One tap. Telegram sends the customer’s verified phone to the bot — signed by Telegram, can’t be spoofed. The bot saves it, creates the booking, replies with a queue number.

No SMS gateway needed. Stronger guarantee than a typed code — Telegram cryptographically signs the contact.

Multi-tenant security

The platform serves many businesses (clinics, salons, workshops, …) from one codebase. Each business needs:

  • Its own data
  • Its own bot
  • Tokens that can’t access other businesses’ data

We solved this with per-business MCP service tokens. The token is the business identity. When the MCP server calls the backend, the token alone tells HI which business to operate on — no X-Company-Code header, no shared secrets.

A leaked token affects exactly one business. The admin can rotate it from the dashboard in one click.

The same token works in:

  • The Telegram bot (n8n stores it)
  • Claude.ai web’s custom connector (paste URL → done)
  • Claude Desktop / Claude Code (config file)
  • Any MCP-compatible client now or in the future

FIFO vs parallel mode — one toggle

A clinic with one doctor wants strict FIFO: only one patient at a time, and when complete, auto-advance to next. A salon with three stations needs parallel: three customers being served simultaneously, no auto-advance because each stylist controls their flow.

Same database, same bot, one radio button in business settings:

  • Serialstatus='in-progress' count must be 0 before starting another. On Complete, auto-start next pending.
  • Parallel — no concurrency check. Admin clicks Start whenever a station frees up.

The Telegram bot reads the same data through the MCP server. The customer experience is identical. The admin behavior changes per business.

What we’d do differently

Three things we’d change with hindsight:

  1. Pick the model based on tool use, not size. We started with a smaller OpenAI model and saw it hallucinate tool arguments (calling list_staff with random past dates), claim bookings failed when they succeeded, and ignore the system prompt’s strict date rules. Switching to gpt-4.1-mini fixed most of it. For agentic flows, instruction adherence matters more than raw size.

  2. Bind Next.js to all interfaces from day one. Our backend listened only on host localhost, so Docker containers couldn’t reach it directly. We routed through Cloudflare instead, which adds latency but works. One config line we should have set right from the start.

  3. Always verify schema migrations actually ran. Twice during development a stale Next.js process kept holding the port, so the auto-restart silently failed and our new tables didn’t exist. The deploy “succeeded” but the new feature was broken. Now we always check tables exist after a deploy.

Open-sourcing the MCP server

The MCP layer (hi-mcp-server) is generic — it doesn’t know about clinics or salons specifically. Any service business that fits the schema (staff with weekly schedules, FIFO or parallel queue, customers booking by date) can use it.

Architecture stays the same; data shape stays the same. New verticals just need the right labels in the admin UI.

What’s next

For v2 we want:

  • Reminders — bot messages the customer the night before with a “Confirm or cancel” button
  • No-show tracking — automatic deposits required after N no-shows
  • Calendar export — let customers add their booking to their phone calendar
  • Web booking page — for businesses that want a Calendly-style URL too, sharing the same data

Try it live — chat the Pinlon booking bot on Telegram. Ask “who’s working today?”, “book me Saturday”, or “what’s the queue right now?”.

If you run a service business in Myanmar or Thailand and want this for yourself, reach out — we’ll set you up with your own bot and dashboard in about 10 minutes.