# MOVE Generic Notifier

The generic notifier transmits all information that does not fit into the Timeline API. The SDK Backend sends a batch of notifications to a defined URL, which can be defined in the [MOVE Dashboard > Configuration > Notifier](https://dashboard.movesdk.com/admin/sdkConfig/receiver?selected=2). The request body is a list of notification items.

The definition of a notification item is:

| **Name**  | **Type**             | **Example**                            |
| --------- | -------------------- | -------------------------------------- |
| id        | String UUID          | "cdfac1e3-39dd-4312-aa2b-9e4b6b5f1b49" |
| projectId | Number               | 1000                                   |
| userId    | String               | "C2021030510"                          |
| time      | String (Instant)     | "2021-04-16T09:33:41.409927Z"          |
| type      | String               | "CustomeType"                          |
| data      | Map (String, String) | "data": { "test" : "t123"}             |

### POI event notifications

Each MOVE project can define its ["Points of Interest" in the MOVE Dashboard](https://dashboard.movesdk.com/admin/poi). Whenever a user device sends a Point of Interest (POI), this event will be sent through the Generic Notifier. The data is defined as such:

* **distance** - distance of the user device to the POI, when the POI triggered
* **inTrip** - whether or not the device was in a trip, when the POI triggered
* **name** - the POI name you defined in the MOVE Dashboard
* **lat/lon** - the position of the user
* **tags** - any tags you may have entered in the MOVE Dashboard

Example JSON:

```typescript
    "id": "cdfac1e3-39dd-4312-aa2b-9e4b6b5f1b49",
    "projectId": 1000,
    "userId": "2021030510",
    "time": "2021-04-16T09:33:41.409927Z",
    "type": "POI",
    "data": {
      "distance" : "15",
      "inTrip" : "false", 
      "name" : "Office", 
      "lon" : "15.167910010896458", 
      "lat" : "48.16988434573538"   
    }
```

### Weather Event

This notification warns users of extreme weather events that could affect their parked cars.

Example JSON:

```json
{
   "id": "cdfac1e3-39dd-4312-aa2b-9e4b6b5f1b49",
    "projectId": 1000,
    "userId": "2021030510",
    "time": "2021-04-16T09:33:41.409927Z",
    "type": "WEATHER_EVENT",
    "data": {
      "movementtype": "parked/LIO",
      "origin": "airflow-weather",
      "predictedtime": "1678078800",
      "weather": "Cold under 3 (1) between 06:00 and 09:00",
      "location": "3423 Sankt Andrä-Wördern (Tullner Straße 22)- Niederösterreich/Österreich" 
    }
}
```

This is a JSON object that contains data related to a weather event. The object has several key-value pairs that provide information about the event.

#### Key-Value Pairs

* **id**: A unique identifier for the event. It is a string value in the format of UUID.
* **projectId**: The project identifier associated with the event. It is an integer value.
* **userId**: The user identifier associated with the event. It is a string value.
* **time**: The time when the event occurred. It is a string value in the format of ISO 8601 with timezone.
* **type**: The type of the event. In this case, it is a weather event and the value is "WEATHER\_EVENT".
* **data**: A JSON object that contains additional data related to the event.
  * **movementtype**: The type of movement associated with the event. It is a string value.
  * **origin**: The source of the weather data. It is a string value.
  * **predictedtime**: The predicted time for the weather event. It is a string value in UNIX timestamp format.
  * **weather**: A description of the weather event. It is a string value.
  * **location**: The location where the weather event occurred. It is a string value that contains the address information in a specific format.

### Score Event

Whenever a user's score is calculated, a notification is sent to inform them of the newly calculated score. There are two distinct scores: Exposure to Risk and Move Score.

* score: current score value between 0 - 1000
* days: how many days were used for calculation (max. 365)
* type: ETR or MOVE

Example JSON:

```json
{
    "id": "cdfac1e3-39dd-4312-aa2b-9e4b6b5f1b49",
    "projectId": 1000,
    "userId": "2021030510",
    "time": "2021-04-16T09:33:41.409927Z",
    "type": "SCORE",
    "data": {
      "score": 918,
      "days": 155,
      "type": "ETR"
    }
}
```

### State

Sent when a user's device or permission state changes. The notification is debounced: if multiple state changes occur within a short window, only one notification is sent with the final state.

State notifications enable you to communicate with users when critical permissions are missing — for example, prompting them to grant "Location Access: Always" so that background trip detection works reliably.

The `type` for State notifications is `STATE_PERMISSON` .

The `data` map contains JSON-serialized objects under these keys:

| Key                              | Description                                          |
| -------------------------------- | ---------------------------------------------------- |
| `STATE_NOTIFIER`                 | Simplified permission summary (most common fields)   |
| `STATE_PERMISSION_DEVICE_STATUS` | Full device permission state                         |
| `STATE_PERMISSION_DYNAMIC`       | Dynamic device state (connectivity, GPS, power mode) |

**`STATE_NOTIFIER`**

A simplified view of the most important permissions. Parse the value as a JSON object:

```json
{
  "location": true,
  "bgDetection": false,
  "motion": true,
  "phone": null,
  "overlay": null,
  "health": null,
  "improvedLocationAccuracy": true,
  "ignoreBatteryOptimization": true,
  "keepUnusedAppPermission": true,
  "keepUnusedAppStorage": true
}
```

| Field                       | Type     | Description                                                                                                                                                   |
| --------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `location`                  | Boolean? | Location permission granted. Android: `ACCESS_FINE_LOCATION` or `ACCESS_COARSE_LOCATION`. iOS: `CLLocationManager` authorization.                             |
| `bgDetection`               | Boolean? | Background location access. Android: `ACCESS_BACKGROUND_LOCATION` (Android 10+). iOS: background location authorization. Required for passive trip detection. |
| `motion`                    | Boolean? | Motion/activity recognition permission. Android: `ACTIVITY_RECOGNITION` (Android 10+). iOS: `CMMotionActivityManager` authorization.                          |
| `phone`                     | Boolean? | Phone state permission (`READ_PHONE_STATE`). Android only; always null on iOS.                                                                                |
| `overlay`                   | Boolean? | Draw-over-other-apps permission. Android only; always null on iOS.                                                                                            |
| `health`                    | String?  | Health data permissions. Android: HealthConnect permission names (e.g. `"readSteps"`). iOS: HealthKit permission identifiers.                                 |
| `improvedLocationAccuracy`  | Boolean? | Enhanced location using WiFi/cell/Bluetooth. Android only; always null on iOS.                                                                                |
| `ignoreBatteryOptimization` | Boolean? | App exempt from battery optimization. Android only; always null on iOS. When false, background detection may be unreliable.                                   |
| `keepUnusedAppPermission`   | Boolean? | System will not auto-revoke permissions for unused apps (Android 11+). Android only.                                                                          |
| `keepUnusedAppStorage`      | Boolean? | System will not restrict storage for unused apps (Android 12+). Android only.                                                                                 |

**`STATE_PERMISSION_DEVICE_STATUS`**

The full device permission state. Parse as a JSON object.

| Field                        | Type     | Platform | Description                                                   |
| ---------------------------- | -------- | -------- | ------------------------------------------------------------- |
| `gyro`                       | Boolean? | Both     | Device has a functional gyroscope.                            |
| `accelerometer`              | Boolean? | Both     | Device has a functional accelerometer.                        |
| `magnetometer`               | Boolean? | Both     | Device has a functional magnetometer (compass).               |
| `bgDetection`                | Boolean? | Both     | Background location access granted.                           |
| `location`                   | Boolean? | Both     | Location permission granted.                                  |
| `motion`                     | Boolean? | Both     | Motion/activity recognition permission granted.               |
| `phone`                      | Boolean? | Android  | Phone state permission granted.                               |
| `overlay`                    | Boolean? | Android  | System overlay permission granted.                            |
| `improvedLocationAccuracy`   | Boolean? | Android  | Device using multiple location sources for enhanced accuracy. |
| `preciseLocationPermission`  | Boolean? | Both     | Fine/precise location access (vs. approximate only).          |
| `googlePlayLocationAccuracy` | Boolean? | Android  | Google Play Services providing high-accuracy location.        |
| `ignoreBatteryOptimization`  | Boolean? | Android  | App exempt from battery optimization restrictions.            |
| `keepUnusedAppPermission`    | Boolean? | Android  | Permissions not auto-revoked for unused apps (Android 11+).   |
| `keepUnusedAppStorage`       | Boolean? | Android  | Storage not restricted for unused apps (Android 12+).         |
| `postNotification`           | Boolean? | Both     | Notification posting permission (Android 13+, iOS always).    |
| `bluetoothConnect`           | Boolean? | Both     | Bluetooth device connection permission (Android 12+).         |
| `bluetoothScan`              | Boolean? | Both     | Bluetooth scanning permission (Android 12+).                  |
| `health`                     | String?  | Both     | Health data permission identifiers.                           |

**`STATE_PERMISSION_DYNAMIC`**

Dynamic device state reflecting current system settings and hardware status. Parse as a JSON object.

| Field                  | Type     | Platform | Description                                                              |
| ---------------------- | -------- | -------- | ------------------------------------------------------------------------ |
| `gps`                  | Boolean? | Both     | GPS/location services enabled on the device.                             |
| `mockProvider`         | Boolean? | Android  | An app with mock location capability is installed.                       |
| `mockProviderLocation` | Boolean? | Android  | Current location is from a mock provider (active spoofing).              |
| `wifi`                 | Boolean? | Both     | WiFi enabled.                                                            |
| `sim`                  | Boolean? | Android  | SIM card present.                                                        |
| `powerSaveMode`        | Boolean? | Both     | Device in low-power / battery-saver mode. May reduce sensor frequency.   |
| `playServicesVersion`  | String?  | Android  | Google Play Services version installed.                                  |
| `geofence`             | Boolean? | Both     | Geofencing operational (no initialization errors).                       |
| `locationPowerMode`    | Int?     | Android  | System location power save mode (Android 9+).                            |
| `standbyBucket`        | Int?     | Android  | App standby bucket; lower = less restricted (Android 9+).                |
| `bluetooth`            | Boolean? | Both     | Bluetooth hardware enabled.                                              |
| `online`               | Boolean? | Both     | Device has an active internet connection.                                |
| `mobileData`           | Boolean? | Both     | Cellular data available.                                                 |
| `healthConnectState`   | String?  | Android  | HealthConnect framework status: available, requires update, unavailable. |
| `healthApps`           | String?  | Android  | Installed health/fitness apps (comma-separated package names).           |
| `timeZone`             | String?  | Both     | Device timezone identifier (e.g. `"Europe/Berlin"`).                     |
