# Flight Price Monitor Daily flight price monitor that checks configured routes and alerts when prices drop below threshold. ## Features - ✈️ Monitor multiple flight routes (BER→EZE, etc.) - 🔔 OpenClaw alerts when prices drop below threshold - 📊 Extensible adapter pattern for multiple price sources - 📝 Full logging of all checks (hits and misses) - 🔧 Cron-friendly one-shot execution ## Setup ### 1. Install Dependencies ```bash pip install -r requirements.txt ``` ### 2. Get a Kiwi API Key 1. Sign up at https://tequila.kiwi.com/portal/login 2. Create an API key 3. Set environment variable: ```bash export KIWI_API_KEY="your-api-key-here" ``` Or create a `.env` file: ```bash KIWI_API_KEY=your-api-key-here ``` ### 3. Configure Routes Edit `config.json`: ```json { "routes": [ { "origin": "BER", "destination": "EZE", "trip_type": "round_trip", "threshold_eur": 700, "duration_weeks": [2, 3, 4], "preferred_months": [12, 1, 2, 3], "monitor_year_round": true } ], "check_interval": "daily" } ``` **Config Fields:** - `origin`, `destination`: IATA airport codes - `threshold_eur`: Alert if price drops below this (in EUR) - `duration_weeks`: Trip lengths to search (in weeks) - `preferred_months`: Months to prioritize (1-12) - `monitor_year_round`: `true` to search all months, `false` to only search `preferred_months` You can add multiple routes — the monitor will check them all. ### 4. Run ```bash python monitor.py ``` Logs are written to `monitor.log` and stdout. ## Scheduling (Cron) To run daily at 6 AM: ```bash crontab -e ``` Add: ``` 0 6 * * * cd /path/to/flight-monitor && /usr/bin/python3 monitor.py ``` Or use OpenClaw cron (recommended): ```bash openclaw cron add \ --schedule '0 6 * * *' \ --command 'cd /path/to/flight-monitor && python monitor.py' \ --name 'Flight Price Monitor' ``` ## Architecture ### Adapter Pattern The monitor uses an adapter pattern to support multiple price sources: ``` adapters/ base.py # Abstract FlightAdapter interface kiwi.py # Kiwi/Tequila API implementation ``` Each adapter implements: - `search_round_trip()` — returns normalized results - `get_name()` — adapter name All results follow this schema: ```python { "price_eur": float, "airline": str, "departure": datetime, "return": datetime, "link": str, # Booking URL "source": str # Adapter name } ``` ### Adding a New Adapter 1. Create `adapters/my_adapter.py`: ```python from adapters.base import FlightAdapter class MyAdapter(FlightAdapter): def get_name(self) -> str: return "MySource" def search_round_trip(self, origin, destination, departure_date, return_date, **kwargs): # Your implementation here # Must return list of normalized results (see schema above) pass ``` 2. Register in `adapters/__init__.py`: ```python from adapters.my_adapter import MyAdapter __all__ = [..., "MyAdapter"] ``` 3. Update `monitor.py` to use your adapter: ```python adapter = MyAdapter() ``` You can also make the adapter configurable via `config.json` if needed. ## Alerting When a price drop is detected, the monitor sends an alert via OpenClaw: ```bash openclaw system event --text "✈️ BER→EZE €650 on 2026-04-15 → 2026-04-29 (Lufthansa) — below €700! https://..." --mode now ``` This routes the alert to your configured OpenClaw channels (Telegram, Discord, Signal, etc.). ## Logs All checks are logged to `monitor.log` with timestamps: ``` 2026-03-21 18:00:00 [INFO] === Flight Monitor Starting === 2026-03-21 18:00:00 [INFO] Checking route BER→EZE (threshold: €700) 2026-03-21 18:00:01 [INFO] 2026-04-15 → 2026-04-29: €850 (Lufthansa) 2026-03-21 18:00:02 [INFO] 2026-05-01 → 2026-05-15: €620 (Air France) 2026-03-21 18:00:02 [INFO] Alert sent via OpenClaw 2026-03-21 18:00:03 [INFO] === Flight Monitor Complete === ``` ## Troubleshooting **"KIWI_API_KEY environment variable not set"** - Set the `KIWI_API_KEY` env var (see Setup step 2) - The monitor will exit gracefully (not crash) if the key is missing **No results returned** - Check `monitor.log` for API errors - Verify your IATA codes are correct (e.g., "BER" not "Berlin") - Try a broader date range (increase `duration_weeks` or `preferred_months`) **OpenClaw alert not sent** - Verify `openclaw` CLI is in PATH - Check OpenClaw is running: `openclaw status` - Look for error messages in `monitor.log` ## License MIT