- config.json: BER→EZE route, €700 threshold, 14-28 nights, Dec-Mar preferred - monitor.py: config-driven, multi-route, windowed date search, openclaw alerts - adapters/base.py: abstract FlightAdapter interface - adapters/kiwi.py: Kiwi/Tequila v2 adapter (stub until KIWI_API_KEY is set) - requirements.txt, cron-install.sh (daily 08:00 UTC), README.md
132 lines
2.9 KiB
Markdown
132 lines
2.9 KiB
Markdown
# ✈️ Flight Price Monitor
|
||
|
||
Monitors round-trip flight prices and fires alerts via OpenClaw when prices drop below configured thresholds.
|
||
|
||
## Features
|
||
|
||
- Config-driven: add as many routes as you like in `config.json`
|
||
- Swappable price adapters (currently: Kiwi/Tequila)
|
||
- Alerts via `openclaw send` when price < threshold
|
||
- Logs every check run to `monitor.log`
|
||
- Daily cron job, one-command install
|
||
|
||
## Setup
|
||
|
||
### 1. Install dependencies
|
||
|
||
```bash
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
### 2. Get a Kiwi API key (free)
|
||
|
||
1. Sign up at https://tequila.kiwi.com/
|
||
2. Create a solution and copy your API key
|
||
3. Set the environment variable:
|
||
|
||
```bash
|
||
export KIWI_API_KEY=your_key_here
|
||
```
|
||
|
||
Add it to your shell profile or a `.env` file to persist it.
|
||
|
||
> **Without a key:** the monitor still runs — it just returns no results and logs a reminder. No errors, no crashes.
|
||
|
||
### 3. Configure routes
|
||
|
||
Edit `config.json`:
|
||
|
||
```json
|
||
{
|
||
"routes": [
|
||
{
|
||
"id": "ber-eze",
|
||
"origin": "BER",
|
||
"destination": "EZE",
|
||
"threshold_eur": 700,
|
||
"min_nights": 14,
|
||
"max_nights": 28,
|
||
"preferred_months": [12, 1, 2, 3],
|
||
"monitor_year_round": true
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
| Field | Description |
|
||
|---|---|
|
||
| `id` | Unique route identifier |
|
||
| `origin` / `destination` | IATA airport or city codes |
|
||
| `threshold_eur` | Alert fires when price is below this |
|
||
| `min_nights` / `max_nights` | Stay duration range |
|
||
| `preferred_months` | Months to prioritise (1–12) |
|
||
| `monitor_year_round` | If `true`, searches all 12 months |
|
||
|
||
### 4. Add more routes
|
||
|
||
Just add another object to the `routes` array. Example — Berlin to NYC:
|
||
|
||
```json
|
||
{
|
||
"id": "ber-jfk",
|
||
"origin": "BER",
|
||
"destination": "JFK",
|
||
"threshold_eur": 400,
|
||
"min_nights": 7,
|
||
"max_nights": 14,
|
||
"preferred_months": [6, 7, 8],
|
||
"monitor_year_round": false
|
||
}
|
||
```
|
||
|
||
## Running manually
|
||
|
||
```bash
|
||
python monitor.py
|
||
# or explicitly choose adapter:
|
||
python monitor.py --adapter kiwi
|
||
```
|
||
|
||
Logs are written to `monitor.log` and stdout.
|
||
|
||
## Install the daily cron job
|
||
|
||
```bash
|
||
bash cron-install.sh
|
||
```
|
||
|
||
Installs: `0 8 * * * python /path/to/monitor.py` (08:00 UTC daily).
|
||
Run again to check if already installed — it won't duplicate.
|
||
|
||
## Alerts
|
||
|
||
When a price hits below threshold, OpenClaw receives:
|
||
|
||
```
|
||
✈️ Flight alert: BER→EZE €650 on 2026-12-15–2027-01-05! https://...
|
||
```
|
||
|
||
Sent via: `openclaw send --text "..."`
|
||
|
||
## Adapter architecture
|
||
|
||
```
|
||
adapters/
|
||
base.py ← abstract FlightAdapter interface
|
||
kiwi.py ← Kiwi/Tequila v2 implementation
|
||
```
|
||
|
||
To add a new source: subclass `FlightAdapter`, implement `search()`, register in `ADAPTER_MAP` in `monitor.py`.
|
||
|
||
## Files
|
||
|
||
| File | Purpose |
|
||
|---|---|
|
||
| `config.json` | Route configuration |
|
||
| `monitor.py` | Main script |
|
||
| `adapters/base.py` | Abstract adapter interface |
|
||
| `adapters/kiwi.py` | Kiwi/Tequila adapter |
|
||
| `requirements.txt` | Python dependencies |
|
||
| `cron-install.sh` | Cron job installer |
|
||
| `monitor.log` | Runtime log (created on first run) |
|