Real-time flight monitoring Telegram bot. Track flights, get instant alerts on delays, gate changes, boarding, and more.
- Track flights by flight number, natural language, or route (e.g.,
DAD to SIN today) - Real-time alerts β check-in open, delays, gate changes, boarding, departure, landing, cancellation
- Adaptive polling β every 15 min (far), 5 min (near), 1 min (imminent)
- Multi-user β multiple users can track the same flight with deduplicated API calls
- Auto-cleanup β expired flights are deactivated and removed automatically
- Live refresh fallback β FlightStats-first enrichment, then FlightAware as secondary fallback when data is still low-signal
- TypeScript + grammY (Telegram Bot framework)
- SQLite (via better-sqlite3 or Drizzle)
- Aviationstack API for flight data
# Install dependencies
bun install
# Configure environment
cp .env.example .env
# Set BOT_TOKEN and AVIATIONSTACK_API_KEY in .env# Run the bot
bun run startReady to deploy your bot? Check out the Hosting Guide for detailed instructions on deploying to:
- Fly.io (recommended) β with persistent SQLite volume
- Render β simple deployment with disk storage
- Railway β easy setup with volume support
The guide covers environment variables, database persistence, and troubleshooting.
# Run in development mode
bun run dev
# Type-check
bun run typecheck
# Lint
bun run lintjust dev
just db-generate
just db-migrate
just db-studioNote: drizzle-kit SQLite commands rely on better-sqlite3 at dev time for DB connectivity.
| Variable | Description |
|---|---|
BOT_TOKEN |
Telegram bot token from @BotFather |
AVIATIONSTACK_API_KEY |
API key from aviationstack.com |
| Command | Description |
|---|---|
/start |
Welcome message |
/track AA123 2026-03-15 |
Track a flight |
/flights |
List all tracked flights |
/status AA123 |
View current flight status + timeline |
/remove AA123 |
Stop tracking a flight |
/help |
Show available commands |
The bot also understands natural language:
Track my flight GA851 tomorrowDAD to SIN today
βββββββββββββββββββββββββββββββββββ
β Telegram Bot β
β (grammY β long polling) β
βββββββββββββββββββββββββββββββββββ€
β Message Parser / Router β
β (commands + natural language) β
ββββββββββββ¬βββββββββββββββββββββββ€
β Flight β Background Worker β
β Service β (adaptive polling) β
ββββββββββββ΄βββββββββββββββββββββββ€
β SQLite Database β
β flights | tracked_flights | β
β status_changes β
βββββββββββββββββββββββββββββββββββ
β
βΌ
Aviationstack API
β
βΌ (fallback when needed)
FlightStats parser + FlightAware parser
/statusrefreshes flight data when either condition is true:- Data is stale (
>= 15 minutessince last poll) - Data is low-signal (
scheduled/empty status and no delay) - Polling worker interval by time-to-departure:
> 3h: every15 minutes<= 3h: every5 minutes<= 1h: every1 minute
- Aviationstack response cache TTL:
15 minutes - Live refresh paths (
/status, polling worker) bypass cache to force fresh provider data
- Multi-result flight selection (route or ambiguous number) expires after
5 minutes - If expired, user must search/select again
- Primary source is Aviationstack
- Fallback is triggered only when Aviationstack is low-signal:
- Status is
scheduledor empty, and delay is missing/non-positive - Fallback order:
-
- FlightStats (status, delay, estimated departure/arrival, terminal, gate)
-
- FlightAware only if status/delay are still low-signal after FlightStats
/statusdisplay prefers live fallback estimated times over derivedscheduled + delay/statusalso shows arrival terminal/gate when available from fallback data- FlightAware fallback tries multiple identifiers (
ICAO,IATA, user input), e.g.TGW315thenTR315
- If both providers return no delay signal, bot will remain on scheduled/on-time data
- FlightAware fallback is HTML/bootstrap parsing, not an official FlightAware API
π€ Huynh Duc Dung
- Website: https://productsway.com/
- Twitter: @jellydn
- Github: @jellydn
Give a βοΈ if this project helped you!
MIT Β© Huynh Duc Dung