Home / Projects / KAI Ticket Notifier — Automated Train Availability Monitor
Featured Project
KAI Ticket Notifier — Automated Train Availability Monitor
Go service that monitors official KAI booking results through queued Chromium automation and sends actionable Telegram alerts when matching seats appear.
Role
Backend & Automation Engineer
Duration
Ongoing personal project
Team
Solo developer
Tech Stack
Go · Chromium · Browser Automation · Telegram Bot API · Cloudflare Tunnel · SOCKS5 Proxy · YAML
Architecture Diagram
Click a node for the decision behind it
- A YAML monitor config
- YAML keeps routes, dates, and intervals operational — adding a monitor never requires a rebuild.
- B Go schedulers
- Schedulers start on staggered delays so several dates never hit the booking flow at the same moment.
- C Shared browser queue
- One shared queue serializes every search through a single persistent Chromium session. Throughput drops, but the monitor survives running unattended — that trade was deliberate.
- D Chromium + SOCKS5
- Proxy support is configured per provider, and startup verifies the browser actually exits through a different IP before any search runs.
- E Official BookingKAI
- Automation follows the official web flow rather than an undocumented private endpoint. It does not attempt to bypass CAPTCHA or interactive challenges — it backs off exponentially instead.
- F Availability filters
- Results are filtered by train, route, date, price, and departure window before anything is sent. Sold-out results stay quiet.
- G Telegram Bot API
- Notifications are availability-driven, so the chat only gets a message when a seat actually matches.
- H Cloudflare Tunnel
- Webhook mode runs through Cloudflare Tunnel, so Telegram can reach the bot without exposing an inbound port.
A practical automation service for a problem that is simple for one search but tedious across several travel dates: keep checking official KAI booking results and notify me when the right train becomes bookable.
Problem
Availability can change between checks. Manually reopening the booking page for several dates creates repetitive work, and a monitor that launches multiple browsers in parallel can trigger rate limits or destabilize the session.
Solution
I built a Go service with YAML-defined monitors. Each schedule submits work to a shared BookingKAI queue, which reuses one Chromium session and processes browser searches serially. Matching results are filtered by train, route, date, price, and departure window before Telegram is notified.
User Flow
- Define a train, route, date, interval, and provider in YAML.
- The service validates each configured train at startup.
- Schedulers submit searches to the shared browser queue with staggered starts.
- Chromium opens the official booking flow through an optional SOCKS5 proxy.
- The result is parsed and filtered; sold-out results stay quiet.
- Telegram receives an alert when matching availability appears.
- Bot commands can inspect, check, pause, resume, or temporarily sleep a monitor.
Architecture Decisions
- A single shared browser queue serializes BookingKAI requests, reducing concurrent browser pressure and keeping one persistent session.
- Schedulers start with staggered delays so several dates do not hit the booking flow at once.
- Browser automation is used for the official provider because the flow depends on a real browser session; the service does not attempt to bypass CAPTCHA or interactive challenges.
- Proxy support is configured per provider, and startup verifies that the browser actually exits through a different IP.
- YAML keeps route/date changes operational rather than requiring a rebuild.
- Webhook mode uses Cloudflare Tunnel, so Telegram can reach the bot without exposing an inbound server port.
- Notifications are availability-driven; challenge failures use backoff rather than flooding the chat.
Reliability Work
- Persistent Chromium profile support for session continuity
- Startup validation for every configured train
- Exponential backoff when BookingKAI presents a challenge
- Graceful scheduler staggering and shared-queue ownership
- Telegram commands for
/list,/check,/status,/history,/toggle, and timed/sleep - Ubuntu setup script that checks dependencies and builds the service reproducibly
Trade-offs
- Browser automation is heavier than a direct API, but it follows the official web result and avoids depending on an undocumented private endpoint.
- A serialized queue lowers throughput, but reliability matters more than parallel speed for a small set of personal monitors.
- A quick Cloudflare Tunnel URL is convenient for webhook mode, but a stable production deployment should use a named tunnel and persistent hostname.
What I Learned
The difficult part was not scheduling a loop. It was controlling browser lifecycle, concurrency, challenge backoff, proxy verification, and notification noise so the monitor could keep running unattended.