Skip to content
Projects

nikosklms/FareBot has 48 GitHub stars and 2 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-15 03:24 UTC. Last push 2026-11-07.

How these counts are measured

Measured star growth

in 24h
0
in 7 days
Collecting history
in 15 days
Collecting history
in 1 month
Collecting history

Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.

About

A self-hosted Telegram bot that finds the cheapest flights, tracks fares, and alerts you when prices drop—so you can spend less time searching and more time planning your next trip.

Self-hosted

README.md

Original

FareBot


A Telegram bot that watches Google Flights for you. Search a route, track it until it drops under your budget, or scan a whole region for the best deals from your airport.

A FareBot price drop alert on an iPhone lock screen: SKG to London, 2 to 15 November

Running /explore from Budapest to Europe: the wizard, a live progress bar, the biggest discounts (€17 to Venice, 83% off), then that flight opened on Google Flights at the same price

What it does

  • /search finds the cheapest flights for a date or a date range and flags fares well below their usual price.
  • /track checks a route every 6, 12 or 24 hours and messages you when it drops under your budget.
  • /explore searches every destination in a region (Europe, Asia, the Greek islands and more) and ranks them by price or by discount.
  • /digest runs an explore search every week and sends you the results at a time you pick.
  • /mytracks lists your trackers and digests. You can edit, pause, share or delete them.

FareBot is meant to be self-hosted for yourself and a few friends. Anyone else who messages it sends you an access request, which you approve or deny with one tap. As the admin you also get /users to manage people and /stats for usage; by default everyone else can have 3 active trackers and digests and search up to 180 days at a time (see Admin tools). It doesn't need an API key: it reads the same data the Google Flights website shows, using fast-flights.

Setup

Get a bot token from @BotFather and your user ID from @userinfobot, then:

git clone https://github.com/nikosklms/FareBot.git && cd FareBot
cp .env.example .env    # add your token, user ID and timezone
docker compose up -d --build

The database is kept in ./data, and docker compose logs -f shows the log. Without Docker, on Python 3.10+:

pip install -r requirements.txt
python main.py
Variable Meaning
TELEGRAM_BOT_TOKEN Token from @BotFather.
ALLOWED_USERS Comma-separated Telegram user IDs with access. The first one is the admin. Changes apply without a restart.
TIMEZONE Your tz database name for digest times, e.g. Europe/Athens. Required with Docker.
FAREBOT_DB_PATH Optional. SQLite file, farebot.db by default.

Admin tools

As the admin you can change limits and manage everyone's trackers and digests from the chat.

  • /limits sets how many active trackers and digests people can have (1–20) and how many days ahead they can search (30–330), for everyone or for one person. The defaults are 3 and 180 days. Tap a number or type one. Lowering a limit doesn't pause anything people already have.
  • Anyone's trackers and digests: open a person in /limits, or send /mytracks ID, to pause, resume, edit or delete theirs. Their limits don't apply to you, and they get a message when you change something.
  • Shortcuts take the ID shown in /users: /limits ID active 5 days 90, /limits everyone days 120, /limits ID reset.

Shortcuts

Every command walks you through its options with buttons, or takes them in one line:

/search ATH LON 2026-09-01..2026-09-15 direct
/track ATH LON 2026-09-01 150 direct
/explore ATH europe 30 100 10 direct # origin, region, days ahead, budget (0 = any), results
/digest ATH europe 30 80 Sunday@15:00 10 direct

How it works

Each search is one request to Google Flights for one route and one day, so a single /explore can send hundreds. The bot runs 5 at a time, which comes to about 430 searches a minute without being rate-limited (measured with tools/benchmark.py). Long searches run in the background with a progress bar and a Stop button, so the bot keeps answering meanwhile. Repeated searches come from a cache (see Caching). If Google rate-limits the bot, every request pauses for a minute instead of retrying straight away, and the pause doubles (up to 15 minutes) while the blocks continue.

Trackers and digests are scheduled jobs that are reloaded from SQLite on startup.

Path Contents
bot/handlers/ One module per command. The wizards share steps from bot/wizard.py.
bot/formatting.py Message text.
daemon/scheduler.py Tracker checks, weekly digests and nightly cleanup.
database/ SQLite access, models and migrations.
providers/ Google Flights requests and parsing, the result cache and the request scheduler.
services/ Deal ranking, airport data, airport name search and progress estimates.

Caching

Results are kept for 15 minutes and shared between users, so when two people search the same route and day, or an /explore overlaps a tracker, Google is asked once. Prices on Google Flights change a few times a day at most, so a 15-minute-old result is still the price you'd see on the website.

  • An identical search that's already running is shared too: the second one waits for the first instead of sending its own request.
  • Failed searches aren't cached, and neither are partial ones (e.g. a city where one of its airports couldn't be searched), so the next search tries again.
  • A search is only stopped when nobody else is waiting for it, so pressing Stop doesn't cancel someone else's results.
  • The cache lives in memory, holds up to 8,000 results (about 100 MB at most) and starts empty after a restart.

Scheduling

The bot sends 5 requests at a time, and when several jobs compete for them, providers/slots.py uses a hybrid of shortest-remaining-time-first and round-robin:

  • /search and /explore go before digests and tracker checks.
  • 4 of every 5 slots go to the job with the fewest searches left; the 5th rotates through the rest, so no job stalls.
  • A search shared by two jobs runs at the more urgent job's pace (priority inheritance).

In simulations this cut the average wait by about a third against first come, first served. Progress bars follow the same schedule, so their countdowns account for the other jobs.

Development

pip install -r requirements-dev.txt
pytest                      # drives the real bot through a fake Telegram API, no token or network needed
pytest -m live              # also runs real Google Flights searches
ruff check .
python -m tools.benchmark   # searches per minute, request times and memory against Google Flights

Limitations

  • Google Flights has no public API. If Google changes its page format, searches come back empty until the parser is updated. To catch that early, the bot searches a busy route (and a second if needed) every day at 09:00 (retrying hourly, up to 3 times, if Google can't be reached) and messages the admin if it can't read the results, and once more when it can again. After a restart while it's broken, it checks again within 5 minutes, so you know right away if a fix worked.
  • Google limits how fast you can search, so trackers check every 6 hours at most.
  • One-way flights only.
  • FareBot isn't affiliated with Google. Use it for personal projects.

License

MIT