Compare commits

..

2 Commits

Author SHA1 Message Date
cpu
f614e67e8b clen up 2025-03-31 23:03:23 +02:00
cpu
267d262fa6 first version
config

CORS

fixed key to one line

helper prints

clean up

logs

improved validations

again validations

fix

rewritten

flask and node.js solution

added subscription route

auth

flow diagrams
2025-03-31 23:00:03 +02:00

View File

@@ -51,31 +51,31 @@ It's designed to be run as a Docker container and integrated with Traefik v3 for
This will output a Public Key and a Private Key.
3. **Configure Environment Variables:**
* Copy the example `.env` file:
```bash
cp .env.example .env
```
* Edit the `.env` file with your specific values:
* `VAPID_PUBLIC_KEY`: The public key generated in step 2. **Your PWA will also need this key** when it subscribes to push notifications.
* `VAPID_PRIVATE_KEY`: The private key generated in step 2. **Keep this secret!**
* `VAPID_SUBJECT`: A `mailto:` or `https:` URL identifying you or your application (e.g., `mailto:admin@yourdomain.com`). Used by push services to contact you.
* `PORT`: (Default: `3000`) The internal port the Node.js app listens on. Traefik will map to this.
* `SUBSCRIPTIONS_FILE`: (Default: `subscriptions.json`) The path *inside the container* where the button-to-subscription mapping is stored.
* `DEFAULT_BUTTON_NAME`: (Default: `game-button`) The default button name to use when the `Button-Name` header is not provided in the webhook request.
* `BASIC_AUTH_USERNAME`: (Optional) Username for Basic Authentication. If set along with `BASIC_AUTH_PASSWORD`, authentication will be enabled for `/webhook` and `/subscribe`.
* `BASIC_AUTH_PASSWORD`: (Optional) Password for Basic Authentication. If set along with `BASIC_AUTH_USERNAME`, authentication will be enabled.
* `NOTIFICATION_MAX_RETRIES`: (Default: `3`) Number of retry attempts for failed push notifications. Must be a number.
* `NOTIFICATION_FIRST_RETRY_DELAY_MS`: (Default: `10`) Delay in milliseconds for the first retry attempt. Setting to 0-10ms provides near-immediate first retry for transient DNS issues. Must be a number.
* `NOTIFICATION_SUBSEQUENT_RETRY_DELAY_MS`: (Default: `1000`) Base delay in milliseconds for subsequent retries. Each additional retry uses this value with exponential backoff and jitter. Must be a number.
* `DNS_TIMEOUT_MS`: (Default: `5000`) DNS resolution timeout in milliseconds. Must be a number.
* `HTTP_TIMEOUT_MS`: (Default: `10000`) HTTP request timeout in milliseconds. Must be a number.
* `LOG_LEVEL`: (Default: `info`) Controls verbosity of logs. Valid values are `error`, `warn`, `info`, or `debug`. Use `debug` to see detailed header information and other diagnostic messages.
* Copy the example `.env` file:
```bash
cp .env.example .env
```
* Edit the `.env` file with your specific values:
* `VAPID_PUBLIC_KEY`: The public key generated in step 2. **Your PWA will also need this key** when it subscribes to push notifications.
* `VAPID_PRIVATE_KEY`: The private key generated in step 2. **Keep this secret!**
* `VAPID_SUBJECT`: A `mailto:` or `https:` URL identifying you or your application (e.g., `mailto:admin@yourdomain.com`). Used by push services to contact you.
* `PORT`: (Default: `3000`) The internal port the Node.js app listens on. Traefik will map to this.
* `SUBSCRIPTIONS_FILE`: (Default: `subscriptions.json`) The path *inside the container* where the button-to-subscription mapping is stored.
* `DEFAULT_BUTTON_NAME`: (Default: `game-button`) The default button name to use when the `Button-Name` header is not provided in the webhook request.
* `BASIC_AUTH_USERNAME`: (Optional) Username for Basic Authentication. If set along with `BASIC_AUTH_PASSWORD`, authentication will be enabled for `/webhook` and `/subscribe`.
* `BASIC_AUTH_PASSWORD`: (Optional) Password for Basic Authentication. If set along with `BASIC_AUTH_USERNAME`, authentication will be enabled.
* `NOTIFICATION_MAX_RETRIES`: (Default: `3`) Number of retry attempts for failed push notifications. Must be a number.
* `NOTIFICATION_FIRST_RETRY_DELAY_MS`: (Default: `10`) Delay in milliseconds for the first retry attempt. Setting to 0-10ms provides near-immediate first retry for transient DNS issues. Must be a number.
* `NOTIFICATION_SUBSEQUENT_RETRY_DELAY_MS`: (Default: `1000`) Base delay in milliseconds for subsequent retries. Each additional retry uses this value with exponential backoff and jitter. Must be a number.
* `DNS_TIMEOUT_MS`: (Default: `5000`) DNS resolution timeout in milliseconds. Must be a number.
* `HTTP_TIMEOUT_MS`: (Default: `10000`) HTTP request timeout in milliseconds. Must be a number.
* `LOG_LEVEL`: (Default: `info`) Controls verbosity of logs. Valid values are `error`, `warn`, `info`, or `debug`. Use `debug` to see detailed header information and other diagnostic messages.
4. **Configure Traefik Labels:**
* Copy the example `labels` file:
```bash
cp labels.example labels
```
* Copy the example `labels` file:
```bash
cp labels.example labels
```
## Running the Service
@@ -114,11 +114,11 @@ In your Flic app or Flic Hub SDK interface:
2. Add an "Internet Request" action.
3. Fill in the following details:
* Select the `GET` method.
* Set URL with query parameter: `https://webpush.virtonline.eu/webhook/SingleClick`
* Set URL with query parameter: `https://<your_domain>/webhook/SingleClick` (Replace `<your_domain>` with your actual service domain, e.g., `webpush.virtonline.eu`).
* **If Basic Authentication is enabled:**
* Set the Headers:
* Set the `Key` fields to `Authorization`.
* Set the `Value` fields to `Basic <base64 encoded username:password>` (e.g., `Basic dXNlcm5hbWU6cGFzc3dvcmQ=`). Use `$(echo -n 'user:password' | base64)` to generate the base64 encoded string.
* Set the `Value` fields to `Basic <base64 encoded username:password>`.
* Click `ADD`.
* Tap on `SAVE ACTION`.
4. Repeat for Double Click (i.e., `/DoubleClick`) and Hold (i.e., `/Hold`) events.
@@ -160,7 +160,7 @@ Search the Play Store - there might be others with similar names.
* `subscription` (object, required): The [PushSubscription object](https://developer.mozilla.org/en-US/docs/Web/API/PushSubscription) obtained from the browser's Push API.
```json
{
"button_id": "game-button",
"button_id": "game-button", // Optional, defaults to DEFAULT_BUTTON_NAME environment variable
"subscription": {
"endpoint": "https://your_pwa_push_endpoint...",
"expirationTime": null,
@@ -182,10 +182,19 @@ Search the Play Store - there might be others with similar names.
* **Authentication:** Optional Basic Authentication via `Authorization` header if `BASIC_AUTH_USERNAME` and `BASIC_AUTH_PASSWORD` are configured.
* **URL Parameters:**
* `click_type` (required): The type of button press (e.g., `SingleClick`, `DoubleClick`, or `Hold`).
* **Optional Headers:**
* **Required Headers:**
* `Button-Name`: The identifier of the Flic button (sent by the Flic system). If not provided, the value of `DEFAULT_BUTTON_NAME` environment variable will be used as a fallback.
* **Optional Headers:**
* `Timestamp`: Timestamp of the button event (sent by the Flic system).
* `Button-Battery-Level`: The battery level percentage of the button (sent by the Flic system).
* **Push Notification Payload (`data` field):** The service sends a JSON payload within the push notification. The client-side Service Worker can access this data via `event.data.json()`. The structure is:
```bash
curl -X GET https://webpush.virtonline.eu/webhook/SingleClick \
-H 'Authorization: Basic cGxheWVyOlNldmVuT2ZOaW5l' \
-H "Button-Name: Game-button" \
-H "Timestamp: 2025-03-26T01:10:20Z" \
-H "Button-Battery-Level: 100"
```
* **Responses:**
* `200 OK`: Webhook received, push notification sent successfully.
* `400 Bad Request`: Missing `Button-Name` header or `click_type` URL parameter.
@@ -201,7 +210,7 @@ Once your service is up and running, you can test the webhook endpoint using cur
**Note:** Replace `<username>`, `<password>` with your actual values. The `Button-Name` header is optional and will default to the value of `DEFAULT_BUTTON_NAME` if not provided.
```bash
curl -X GET "https://webpush.virtonline.eu/webhook/SingleClick" \
curl -X GET "https://webpush.virtonline.eu/webhook/SingleClick" \
-H "Authorization: Basic $(echo -n 'user:password' | base64)" \
-H "Button-Name: game-button" \
-H "Timestamp: $(date -u +%Y-%m-%dT%H:%M:%SZ)" \
@@ -223,7 +232,7 @@ If you receive a different response, refer to the Troubleshooting section below.
## Troubleshooting
* **Check Backend Logs:** `docker logs flic-webhook-webpush`. Look for errors related to configuration, file access, JSON parsing, authentication, or sending push notifications.
* To see detailed debug information including all headers received from the Flic button, set `LOG_LEVEL=debug` in your .env file.
* To see detailed debug information including all headers received from the Flic button, set `LOG_LEVEL=debug` in your .env file.
* **Check Traefik Logs:** `docker logs traefik`. Look for routing errors or certificate issues.
* **Verify `.env`:** Ensure all required variables are set correctly, especially VAPID keys and Traefik settings.
* **Verify `labels`:** Double-check that variables were correctly substituted manually and match your `.env` and Traefik setup.