# FF-Agent Ticker Gateway Receives **Einsätze** (operations/incidents) from FF-Agent via **webhook** and keeps a local JSON file for a ticker-style microsite. You can also **import** existing data from a CSV export. ## Requirements - Python 3.8+ - Dependencies: `flask`, `PyYAML`, `requests` (see `requirements.txt`) ## Installation ```bash pip install -r requirements.txt ``` ## Webhook receiver FF-Agent can push Einsatz details to a URL. Run the webhook server so it accepts POSTs and updates the JSON file. **Start the server (default: port 5000, data file `data/einsaetze.json`):** ```bash python webhook_receiver.py ``` **Options:** ```bash python webhook_receiver.py --host 0.0.0.0 --port 8080 --data data/einsaetze.json ``` | Option | Default | Description | |--------|---------|-------------| | `--host` | `0.0.0.0` | Bind address. | | `--port` | `5000` | Port. | | `--data` | `data/einsaetze.json` | Path to the JSON file to read/write. | **Environment:** Set `EINSATZ_JSON_PATH` to override the data file path without `--data`. **Endpoints:** - **POST `/webhook`** or **POST `/`** – Accepts JSON: - A single Einsatz object, or - `{ "einsaetze": [ ... ] }` with an array of Einsätze. - **GET `/`** or **GET `/health`** – Health check; returns `data_path` and status. **Merge behaviour:** Incoming records are merged by `operationId`. If an ID already exists, that record is updated; otherwise it is appended. The file is written after each successful POST. **Configuring FF-Agent:** In FF-Agent set the webhook URL to your server, e.g. `https://your-server.example.com/webhook`. Ensure the server is reachable (firewall, reverse proxy, HTTPS if needed). ### PHP webhook receiver A PHP script accepts POST requests with a JSON body and appends the payload to the same data file without assuming a fixed structure. **Run it:** Point your web server (Apache/Nginx) at `webhook_receiver.php` for the webhook URL, or use the built-in server for local testing: ```bash php -S 0.0.0.0:8080 ``` Then send POST requests to `http://localhost:8080/webhook_receiver.php` with `Content-Type: application/json`. **Behaviour:** The raw POST body is decoded as JSON and stored in `data/einsaetze.json` under the root key **`webhook_events`**: each event is `{ "received": "", "data": }`. The root key **`updated`** is set to the time of the last webhook write. The **`einsaetze`** array is left unchanged by the webhook. Set the environment variable `EINSATZ_JSON_PATH` to override the data file path (default: `data/einsaetze.json`). Request body is limited to 1 MB. ## CSV import To seed or replace data from an FF-Agent CSV export (semicolon-delimited): ```bash python import_einsaetze_csv.py Einsatzexport_2026-02-03-21-15-53.csv -o data/einsaetze.json ``` Same output format as the webhook (see below). You can run the CSV import once, then run the webhook receiver so new events update the same file. ## Output format Both the webhook and the CSV importer use this JSON structure: - **`einsaetze`** – Array of Einsatz objects (fields depend on FF-Agent / CSV columns). - **`updated`** – ISO 8601 timestamp (UTC) of the last write. - **`webhook_events`** – (PHP webhook only) Array of `{ "received": "", "data": }` for each POST. Example: ```json { "einsaetze": [ { "operationId": "T 1.1 260202 828", "keyword": "THL 1 T2714", "message": "klein Fahrzeug öffnen", "location": "Vimystraße 3", "district": "85356 Freising" } ], "updated": "2026-02-03T20:30:00.123456+00:00" } ``` The ticker service reads this file and uses `einsaetze`; `updated` can be used for display or cache invalidation. ## Files | File | Purpose | |------|--------| | `webhook_receiver.php` | PHP webhook: POST JSON → append to `webhook_events` in data file. | | `webhook_receiver.py` | Webhook server: POST → merge into JSON. | | `import_einsaetze_csv.py` | Import CSV export into the same JSON format. | | `requirements.txt` | Python dependencies. | | `data/einsaetze.json` | Data file (created/updated by webhook or import). | | `Dokumentation_WebAPI_ffagent.pdf` | FF-Agent WebAPI documentation. |