# Setup

Source: https://docs.interop.io/browser/capabilities/notifications/setup/index.html

## Overview

The [Notifications API](https://docs.interop.io/browser/reference/javascript/notifications/api/index.md) provides a way to display native notifications with actions and to handle notification and action clicks. **io.Connect Browser** supports all available [`Notification`](https://developer.mozilla.org/en-US/docs/Web/API/Notification) settings as defined in the [DOM Notifications API](https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API).

The **io.Connect Browser** Notifications API extends the DOM Notifications API with the option to handle notification and action clicks using [Interop](https://docs.interop.io/browser/capabilities/data-sharing/interop/index.md#overview) methods.

## Notification Apps

The [Home App](https://docs.interop.io/browser/capabilities/home-app/overview/index.md) of **io.Connect Browser** provides an out-of-the-box Notification Panel and a Notification Settings panel for managing notifications and notification settings. You can use the components provided by the [`@interopio/home-ui-react`](https://www.npmjs.com/package/@interopio/home-ui-react) library to implement custom notification UIs for your **io.Connect Browser** project.

## Configuration

### General Notification Settings

Available since io.Connect Browser 3.2

To specify global notification settings, use the `notifications` property of the configuration object for initializing the [`@interopio/browser-platform`](https://www.npmjs.com/package/@interopio/browser-platform) library:

```javascript
import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    notifications: {
        enable: true,
        enableToasts: false,
        clearNotificationOnClick: false
    }
};

const { io } = await IOBrowserPlatform(config);
```

The `notifications` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `clearNotificationOnClick` | `boolean` | If `true` (default), will remove the notification from the notification list when the user clicks on it or on an action in it. *Available since **io.Connect Browser** 3.2.* |
| `enable` | `boolean` | If `true` (default), will enable all notifications - notification toasts and notifications in the Notification Panel. |
| `enableToasts` | `boolean` | If `true` (default), will enable notification toasts. |
| `sourceFilter` | `object` | Filter with names of apps that are allowed or not allowed to raise notifications. *Available since **io.Connect Browser** 3.2.* |

The `sourceFilter` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `allowed` | `string[]` | Names of apps allowed to raise notifications. Defaults to `["*"]`. |
| `blocked` | `string[]` | Names of apps not allowed to raise notifications. Defaults to `[]`. |

### Notifications with Actions

[Raising notifications](https://docs.interop.io/browser/capabilities/notifications/notifications-api/index.md#raising_notifications) without actions doesn't require any additional setup of the [Main app](https://docs.interop.io/browser/developers/browser-platform/overview/index.md) or the [Browser Client](https://docs.interop.io/browser/developers/browser-client/overview/index.md) apps.

If you want to raise a [notification with actions](https://docs.interop.io/browser/capabilities/notifications/notifications-api/index.md#notification_actions) however, your [Main app](https://docs.interop.io/browser/developers/browser-platform/overview/index.md) must register a [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API). There are two ways to register a Service Worker:

1. Use the `serviceWorker` property of the configuration object for initializing the [`@interopio/browser-platform`](https://www.npmjs.com/package/@interopio/browser-platform) library to provide the URL to the Service Worker file. The library will check the browser compatibility and register the Service Worker:

```javascript
import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    serviceWorker: {
        url: "/service-worker.js"
    }
};

const { io } = await IOBrowserPlatform(config);
```

Use this option if you don't need the Service Worker in your project for anything other than raising notifications with actions.

2. Use the `serviceWorker` property of the configuration object for the [`@interopio/browser-platform`](https://www.npmjs.com/package/@interopio/browser-platform) library to provide the [ServiceWorkerRegistration](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration) `Promise` returned from the registration of the Service Worker:

```javascript
import IOBrowserPlatform from "@interopio/browser-platform";

const swPromise = navigator.serviceWorker.register("/service-worker.js");

const config = {
    licenseKey: "my-license-key",
    serviceWorker: {
        registrationPromise: swPromise
    }
};

const { io } = await IOBrowserPlatform(config);
```

Use this option if you need access to the Service Worker in some other app-specific logic as well.

### Default Notification Handlers

In each [Browser Client](https://docs.interop.io/browser/developers/browser-client/overview/index.md) app (and also in the [Main app](https://docs.interop.io/browser/developers/browser-platform/overview/index.md)) you can define default handlers for notification and action clicks. The appropriate handlers will be called when the notification or the action is clicked. Use the `notification` property of the configuration object for the [`@interopio/browser`](https://www.npmjs.com/package/@interopio/browser) library to specify default notification handlers.

Browser Client apps:

```javascript
import IOBrowser from "@interopio/browser";

const config = {
    notifications: {
        defaultClick: (io, notificationDefinition) => console.log("The notification was clicked."),
        actionClicks: [
            {
                action: "openClientPortfolio",
                handler: (io, notificationDefinition) => console.log("A notification action was clicked.")
            }
        ]
    }
};

const io = await IOBrowser(config);
```

Main app:

```javascript
import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    browser: {
        notifications: {
            defaultClick: (io, notificationDefinition) => console.log("The notification was clicked."),
            actionClicks: [
                {
                    action: "openClientPortfolio",
                    handler: (io, notificationDefinition) => console.log("A notification action was clicked.")
                }
            ]
        }
    }
};

const { io } = await IOBrowserPlatform(config);
```

## io.Connect Browser Worker

Defining a Service Worker is specific for each app and is outside the scope of **io.Connect Browser**. In order for an **io.Connect Browser** project to be able to correctly process notification actions and their respective click logic, you must include the [`@interopio/browser-worker`](https://www.npmjs.com/package/@interopio/browser-worker) package in your Service Worker file.

### Initialization

The [`@interopio/browser-worker`](https://www.npmjs.com/package/@interopio/browser-worker) package exports a default factory function and additionally attaches it to the Service Worker global scope. This offers two options for consuming the library.

The first option is to use the [`importScripts()`](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts) function to add the io.Connect Browser Worker to the Service Worker scope and is suitable for basic Service Worker scripts:

```javascript
importScripts("/web.worker.umd.js");

self.IOWorker();
```

The second option is to import the [`@interopio/browser-worker`](https://www.npmjs.com/package/@interopio/browser-worker) package in a dedicated Service Worker project the output of which will be a ready Service Worker script:

```javascript
const IOWorker = require("@interopio/browser-worker");

IOWorker();
```

The `IOWorker()` function adds a listener to the [`notificationclick`](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/notificationclick_event) event and sets up the necessary communication between the worker and the [Browser Platform](https://docs.interop.io/browser/developers/browser-platform/overview/index.md). This enables the custom action click logic of **io.Connect Browser** notifications.

### Configuration

The `IOWorker()` function accepts an optional configuration object. Use it to specify handlers for notification and action clicks, as well as whether the worker should open the [Main app](https://docs.interop.io/browser/developers/browser-platform/overview/index.md) if it's closed when the user clicks the notification.

The configuration object has the following signature:

```javascript
interface WebWorkerConfig {
    platform?: {
        url?: string;
        openIfMissing?: boolean;
    };
    notifications?: {
        defaultClick?: (event: Event, isPlatformOpened: boolean) => Promise<void>;
        actionClicks?: IOConnectNotificationClickHandler[];
    };
};

interface IOConnectNotificationClickHandler {
    handler: (event: Event, isPlatformOpened: boolean) => Promise<void>;
    action: string;
};
```

The `WebWorkerConfig` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `notifications` | `object` | Allows you to specify custom logic that will be executed on notification or action click. Use the `defaultClick` property of the object to provide a function that will be executed when the user clicks the notification. Use the `actionClicks` property to provide a list of handlers that will be executed when the specified notification action is clicked. |
| `platform` | `object` | By default, the worker won't open the [Main app](https://docs.interop.io/browser/developers/browser-platform/overview/index.md) when a notification is clicked. This property allows you to instruct the worker to open the Main app if it's closed when the user clicks the notification. Use the `url` property of the object to provide the location of the Main app. Use the `openIfMissing` property to specify whether to open the Main app if it's closed when the notification is clicked. |

The `IOConnectNotificationClickHandler` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `action` | `string` | The title of the notification action for which the handler will be executed. |
| `handler` | `function` | Handler for the notification action. |

### Functionality

The [`@interopio/browser-worker`](https://www.npmjs.com/package/@interopio/browser-worker) package exposes two additional functions - `raiseIONotification()` and `openBrowserPlatform()`. Both are attached to the Service Worker global scope and exported from the library.

- `openBrowserPlatform()` - asynchronous function that accepts the URL to the [Main app](https://docs.interop.io/browser/developers/browser-platform/overview/index.md) as an argument and resolves with `void`. Opens the Main app and waits for the [`@interopio/browser-platform`](https://www.npmjs.com/package/@interopio/browser-platform) library to be fully initialized and configured.

- `raiseIONotification()` - this function has the same signature as the [`raise()`](https://docs.interop.io/browser/reference/javascript/notifications/api/index.md#API-raise) method of the [Notifications API](https://docs.interop.io/browser/capabilities/notifications/notifications-api/index.md). It's meant to be used if your project utilizes the [Web Push Protocol](https://www.w3.org/TR/push-api/). In such scenario, the Main app is likely not opened and therefore the Service Worker is responsible for displaying the notification.
