A self-hosted Telegram bot that watches your TooGoodToGo favourites and pings you the moment a bag drops.
Single process, no cloud lock-in β deploy it on any VPS with one command.
# Clone & install
git clone https://github.com/jordantete/TooGoodToMiss.git && cd TooGoodToMiss
python3 -m venv .venv
./.venv/bin/pip install -r requirements.txt
# Configure
cp .env.example .env # then fill in USER_EMAIL, TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID
# Run
./.venv/bin/python -m app.mainThe bot runs as a single long-lived process. run_polling() handles your Telegram commands, while monitoring runs as a job that reschedules itself after every pass.
- Watch β every few minutes, the bot fetches your TooGoodToGo favourites
- Notify β when a bag becomes available, you get a Telegram message
- Deduplicate β one notification per store per day, no spam
- Back off β if TooGoodToGo throws a CAPTCHA, the bot pauses itself and retries later
Polling intervals are deliberately randomized β 10β20 minutes in the morning window, 2β5 minutes in the afternoon, nothing on Sundays. This is anti-fingerprinting, not a config knob.
- Automated monitoring β randomized schedule that stays under TooGoodToGo's radar
- Telegram control β
/status,/pause,/wakeup,/settingsand inline buttons - Multi-language β English and French
- Self-hosted β one process, one file of state, no managed services
- One-command deploy β
./scripts/deploy.shsyncs, installs and restarts over SSH - Crash-safe state β atomic writes, so a power cut never leaves an unbootable bot
You need a bot token and your chat ID:
- Create the bot β open Telegram, talk to @BotFather, send
/newbotand follow the prompts. You get a bot token. - Find your chat ID β send any message to your new bot, then open:
The JSON response contains your
https://api.telegram.org/bot<YourBotToken>/getUpdateschat_id.
Put both in .env, alongside the USER_EMAIL of your TooGoodToGo account.
Fill in VPS_USER, VPS_HOST, VPS_BOT_PATH and SSH_KEY in .env, then:
./scripts/deploy.shThe script rsyncs the code, pushes the .env, installs dependencies in a remote virtualenv and restarts the toogoodtomiss tmux session.
ssh $VPS_USER@$VPS_HOST 'tail -f /root/toogoodtomiss/logs/app.log' # logs
ssh $VPS_USER@$VPS_HOST 'tmux attach -t toogoodtomiss' # attach./.venv/bin/pip install -r requirements.txt -r requirements-dev.txt
./.venv/bin/python -m pytest tests/ -qThis is expected. ACCESS_TOKEN, REFRESH_TOKEN, TGTG_COOKIE and USER_LANGUAGE are read from .env only once, when state.json is first created. After that state.json is the source of truth, and deploy.sh never pushes it β otherwise every deploy would overwrite the live session with a stale local copy, forcing a re-login and a CAPTCHA.
To force new tokens:
ssh $VPS_USER@$VPS_HOST "rm /root/toogoodtomiss/state.json"
./scripts/deploy.shCheck that the [job-queue] extra is installed. Without APScheduler, application.job_queue is None; app.main.build_application() raises an explicit RuntimeError in that case.
Contributions are welcome. See the contributing guide for the development workflow and the project invariants worth knowing before you touch the scheduler or the state layer. By participating you agree to the Code of Conduct.
If this bot saved you a few magic bags, you can buy me a coffee β
MIT β see LICENSE.txt.
TooGoodToMiss is an independent project and is not affiliated with, endorsed by, or officially connected to TooGoodToGo (TGTG) or any of its subsidiaries or affiliates. All product names, logos, and brands are property of their respective owners.