Back to projects

Ambassade de France en Ouzbékistan

Real-Time Train Availability Tracker via Telegram

TypeScriptNode.jsRedisServer-Sent EventsWeb ScrapingNetworking
French Embassy in Uzbekistan

Getting train tickets in Uzbekistan under time pressure is unreliable. The official railway website is slow, unstable under load, and tickets disappear within seconds. For urgent travel, foreign missions often relied on overpriced grey-market resellers.

I built Chafouin, a real-time monitoring system that tracks railway seat availability and instantly notifies users via Telegram—no account, no website required.

Users subscribe to routes and dates, and receive alerts within seconds when a seat becomes available, bypassing both the official bottlenecks and reseller networks.


Core Capabilities

  • Real-time seat availability monitoring across railway routes
  • Instant alerts delivered via Telegram bot
  • Subscription system with filters (date, stations, train types)
  • No-login UX entirely within Telegram
  • Shared event stream powering both bot and API consumers

Key Results

  • Detected seat availability changes across 14 stations with ~30s latency
  • Delivered instant alerts for high-demand routes under heavy contention
  • Avoided IP-based blocking through per-route network isolation
  • Replaced manual and grey-market workflows with an automated system

Architecture Overview

Chafouin is a TypeScript monorepo built around distributed polling workers:

  • Polling Engine (Node.js)
    Tracks seat availability per route with dedicated workers running at fixed intervals
  • Tor-based Network Layer
    Each worker runs through its own Tor circuit (SOCKS5 proxy) to isolate traffic and avoid rate limits
  • API & Event Streaming (SSE)
    Workers expose real-time updates via Server-Sent Events to multiple consumers
  • Telegram Bot (Node.js + Redis)
    Handles subscriptions, user interaction, and alert delivery with persistent state

Technical Highlights

  • Designed per-worker Tor circuit isolation to prevent IP correlation and blocking
  • Implemented change detection using in-memory state (seat count transitions)
  • Built a shared SSE streaming layer reused by both bot and API clients
  • Created a pluggable provider interface to abstract railway data sources
  • Managed lifecycle of workers dynamically based on active subscriptions

My Role

Owned the system end-to-end:

  • Designed architecture and anti-blocking strategy
  • Built the polling engine and network layer
  • Implemented event streaming and subscription model
  • Developed Telegram bot UX and state management