Business Messenger Webpush - SDK

Supports the following browsers caniuse.com/push-api.

Prerequisites
To proceed with the integration of HPRO Web Push SDK to your HTTPS website you must meet the following conditions:

  • Locate your formUuid from the HORISEN Business Messenger Application,
  • Download or use HPRO webpush SDK.

To use our Webpush, your site needs to have SSL certificate or you can use localhost domain during development.

1. Introduction

Webpush SDK is a javascript library that provides subscription mechanism for Webpush notifications for your website/domain.

After a visitor subscribes you will be able to notify him with updates using standard the Business Messenger campaigns.

The SDK can be configured either as a small subscription button widget or used directly from javascript so that you can build your own custom subscription forms and collect some other information to be populated per contact in the Business Messenger Contact Manager.

2. Requirements

  • Register your HORISEN PRO account and confirm it.
  • Gain access over the Business Messenger Application by contacting your administrator.
  • In the Business Messenger Application go to the Web > Webpush section, create a Webpush Rule and find SDK Parameters for your Rule (UUID and Webpush Public Key) which you will use later in configuring the SDK.

SDK parameters

3. Setup

Download SDK and Service worker files and put them on your server. You can download them separately or download hpro-wp.zip and extract it.

Version Bundle SDK Service Worker
1.3.0 hpro-wp.zip hpro-wp-sdk.min.js hpro-wp-sw.min.js
1.2.0 hpro-wp.zip hpro-wp-sdk.min.js hpro-wp-sw.min.js
1.1.0 hpro-wp-sdk.min.js hpro-wp-sw.min.js
1.0.0 hpro-wp-sdk.min.js hpro-wp-sw.min.js

Include SDK script in your page:

index.html

<script async type="text/javascript" src="hpro-wp-sdk.min.js" async></script>

3.1 Service Worker

Standalone

If you have no service worker defined, you can use our SDK as a standalone solution:

Put our hpro-wp-sw.min.js in the root of your website.

Existing

Edit your service-worker.js and import a script which you have downloaded.

service-worker.js

importScripts("hpro-wp-sw.min.js");

3.2 SDK

Initialize the Webpush SDK:

// initial code only done once in entire website
var hproWebPush = hproWebPush || []; 

// asynchronously initialize the sdk for the first time
hproWebPush.push(function () {
    // before all init first
    hproWebPush.init({
        workerFile: 'hpro-wp-sw.min.js', // or 'service-worker.js' in case you are using your own service worker
        apiUrlPrefix: 'https://api.YOUR_BM_DOMAIN',
        apiEndpointFormat: '/forms/{formUuid}/activities',
        formUuid: 'YOUR_FORM_UUID',
        applicationServerKey: 'YOUR_WEBPUSH_PUBLIC_KEY'
    }).then(function initSuccess(_successData) {
        // code if everything went fine
    }, function initError(_errorData) {
        // FrontEnd Subscription, Notification API's are not available
        // or some other error
    });
});

formUuid (YOUR_FORM_UUID) and applicationServerKey (YOUR_WEBPUSH_PUBLIC_KEY) parameters need to be replaced with real values for your Opt-in/Opt-out Rule from the Web > Webpush section of the Business Messenger app.

3.3 Webpush on Apple Mobile Devices (iOS, iPadOS)

Starting with iOS/iPadOS 16.4, Apple supports standard webpush notifications, but there are some specific steps required to get it working: tst

  1. Home Screen Web Apps: Notifications only work if your website is started as a so-called "Home Screen web apps".

  2. Manifest File:

  3. JavaScript Functions:

    • Your javascript logic and content should be adopted to support iOS use cases. You can use these helper function to achieve this:

      function isIOS() {
          const userAgent = navigator.userAgent || navigator.vendor || window.opera;    
          return /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream;
      }
      
      function isRunningAsWebApp() {
          return window.navigator.standalone === true;
      }
    • Then implement a similar flow (pseudo code ahead):

      let ios = isIOS()
      if (!ios || isRunningAsWebApp()) {
          // ... init webpush sdk normally
      } else if (ios){
          // present a banner to invite iOS/iPadOS users to add your webapp to the Home Screen and run from it, here are some UI ideas https://web.dev/articles/promote-install
      }

The iOS visitor is expected to:

  • Visit your website on your Safari browser on a mobile Apple device on 16.4+
  • Click on the "Share" button of their Safari browser on a mobile device.
  • Click on the "Add to home screen" option.
  • Save the app on their device.
  • Open it the app from the home screen.
  • Subscribe to notifications (they must click a subscribe button before a native permission prompt can be displayed).

4. Usage

Our SDK is defined in mind to be compatible with the JS Array structure.
Since SDK may not be available yet at the time of the calling method, Arrays allow us to postpone calling of those function when page is ready.
Every method is pushed to the array and executed in FIFO method. This is why you always use the .push method as a wrapper of set of methods.

Our SDK methods can be called in two ways.

4.1 Async Call

General usage:

hproWebPush.push(function () {
    hproWebPush.${functionName}(param1, param2);
});

Without Promise, and with callback arguments:

hproWebPush.push([
    'init', 
    hproWebPushConfig, 
    function initSuccess () { /*...*/}, 
    function initError () { /*...*/}, 
]);
// optional hproWebPush.push function call

4.2 Sync Call

General usage:

hproWebPush.push(['${functionName}', param1, param2]);

Method specific usage with callbacks:

hproWebPush.push(function () {
    hproWebPush.init(
        hproWebPushConfig,  
        function initSuccess () { /*...*/ }, 
        function initError () { /*...*/ }
    );
    // optional hproWebPush function call or any other
});

Method specific usage with Promise, without callbacks:

hproWebPush.push(function () {
    hproWebPush.init(
        hproWebPushConfig
    ).then(function initSuccess () { /*...*/})
     .catch(function initError () { /*...*/});
    // optional hproWebPush function call or any other
});

5. Configuration

Properties:

Property Type Usage Default Values Description
applicationServerKey String mandatory VAPID key
apiUrlPrefix String optional https://api.YOUR_BM_DOMAIN/news/v1 Example:
https://api.horisen.pro
apiEndpointFormat String optional /forms/{formUuid}/activities Example:
/services/{serviceUuid}/forms/{formUuid}/activities
apiTestEndpointFormat String optional /forms/{formUuid}/test
identifier String optional null | undefined If you can identify the user with contact UUID, before SDK initialization, you can set it up here.
serviceUuid String mandatory If used, provide the BM account UUID.
formUuid String mandatory Form UUID that is used to identify the subscription.
workerFile String mandatory service-worker.js File name of the service worker.

Example:
service-worker.js
data Object optional {} Custom data to send.
headers Object optional {} Custom headers to send.
whenUnsubscribed String optional keep_identity keep_identity

remove_identity
keep_identity or remove_identity

Default: keep_identity

By default, when unsubscribe is finished, in local storage, identifier exist. After subscription, contact will be updated.

When remove_identity is set, after unsubscribe local storage identifier will be deleted. After subscription, new contact will be created.
autoSubscribe Boolean optional false By default when SDK use notifyButton - autoSubscribe is true, in advanced mode is false

added in version 1.1.0
logEnable Boolean optional false Enable log which give use detailed subscription info

added in version 1.1.0
notifyButton Object optional null | undefined | false
Property Type Description
enable Boolean
hideAfterSubscribe Boolean If user is subscribed auto hide button.
tooltip Object Text when hover on button text.
Property Type Default Value
subscribe String Subscribe to notifications
unsubscribe String Unsubscribe to notifications
notification Object Notification info text after subscription success/error.
Property Type Default Value
subscribe String You are successfuly subscribed to notifications
unsubscribe String You have successfuly unsubscribed
error String Subscribed to notifications failed
dialog Object Dialog question when try to subscribe/unsubscribe
Property Type Default Value
subscribe String Subscribe to notifications
unsubscribe String Unsubscribe from notifications
position String or Object
String Object keys
top-left top
top-right left
bottom-left right
bottom-right bottom

Usage:

var hproWebPushConfig = {
    workerFile: 'service-worker.js',

    applicationServerKey: "BCmti7ScwxxVAlB7WAyxoOXtV7J8vVCXwEDIFXjKvD-ma-yJx_eHJLdADyyzzTKRGb395bSAtxlh4wuDycO3Ih4",

    apiUrlPrefix: 'https://api.YOUR_BM_DOMAIN',
    apiEndpointFormat: '/services/{serviceUuid}/forms/{formUuid}/activities',
    apiTestEndpointFormat: '/services/{serviceUuid}/forms/{formUuid}/test',

    formUuid: null,
    serviceUuid: null,
    identifier: null,
    data: {},
    headers: {}
};

6. Methods

6.1 init

init(config, successCallback, errorCallback)

Call this function from your page where you want to use hproWebPush.

  • Do not call this method twice
  • This call is required before any other method is called

Properties:

Property Type Usage Description
config Object mandatory Configuration
successCallback Function optional Success Callback
errorCallback Function optional Error Callback

Return:
Promise

Usage:

var hproWebPush = hproWebPush || [];

hproWebPush.push(function () {
    hproWebPush.init({
        formUuid: 'YOUR_FORM_UUID',
        applicationServerKey: 'YOUR_WEBPUSH_PUBLIC_KEY'
    }, function () {
        console.log('initialized');
    }, function(){
        console.log('Not initialized');
    });
});

Methods which are listed in documentation, can be used after init method is called and hproWebPush object is created.

6.2 subscribe

subscribe(contactData, customHeader, successCallback, errorCallback)

The method does a subscription process.

Properties:

Property Type Description
contactData Object
customHeader Object
successCallback Function Promise resolving.

successCallback(successResponse)

successResponse:
  • subscribed
    When a successful subscription is done.
errorCallback Function Promise rejection.

errorCallback(errorResponse)

errorResponse:
  • denied
    When notification permission state is denied.
  • notPermitted
    All other conditions.

Return:
Promise

Usage:

hproWebPush.subscribe().then(function (successResponse) {
    console.log('subscribed', successResponse);
}).catch(function (errorResponse) {
    console.log('not subscribed', errorResponse);
});

6.3 isSubscribed

isSubscribed(successCallback, errorCallback)

The method checks to see if you are already subscribed. Each callback will return the permission state.

Properties:

Property Type Description
successCallback Function Promise resolving.

successCallback(successResponse)

successResponse:
Resolves with notification permission status.
errorCallback Function Promise rejection.

errorCallback(errorResponse)

errorResponse:
Rejects with notification permission status.

Return:
Promise

Usage:

hproWebPush.isSubscribed().then(function (successResponse) {
    console.log('subscribed', successResponse);
}).catch(function (errorResponse) {
    console.log('not subscribed or no permission granted', errorResponse);
});

6.4 update

(contactData, customHeaders, successCallback, errorCallback)

The method updates current subscription.

Properties:

Property Type Description
contactData Object
customHeaders Object
successCallback Function Promise resolving.

successCallback(successResponse)

successResponse:
  • updated
    When a successful subscription is done.
errorCallback Function Promise rejection.

errorCallback(errorResponse)

errorResponse:
  • denied
    When notification permission state is denied.
  • notPermitted
    All other conditions.

Return:
Promise

Usage:

hproWebPush.update({ identifier: 'YOUR_CONTACT_ID' }).then(function (successResponse) {
    console.log('updated', successResponse);
}).catch(function (errorResponse) {
    console.log('not updated', errorResponse);
});

6.5 permit

permit(successCallback, errorCallback)

The method triggers the browsers notification permission dialog.

Properties:

Property Type Description
successCallback Function Promise resolving.

successCallback(successResponse)

successResponse:
Resolves with notification permission status.
errorCallback Function Promise rejection.

errorCallback(errorResponse)

errorResponse:
Rejects with notification permission status.

Return:
Promise

Usage:

hproWebPush.permit().then(function (successResponse) {
    console.log('permitted', successResponse);
}).catch(function (errorResponse) {
    console.log('not permitted', errorResponse);
});

6.6 unsubscribe

(contactData, customHeaders, successCallback, errorCallback)

The method unsubscribes current subscription.

Properties:

Property Type Description
contactData Object
customHeaders Object
successCallback Function Promise resolving.

successCallback(successResponse)

successResponse:
  • unsubscribed
    When a successful unsubscribe is done.
errorCallback Function Promise rejection.

errorCallback(errorResponse)

errorResponse:
Rejects with notification permission status.

Return:
Promise

Usage:

hproWebPush.unsubscribe().then(function (responseCode) {
    console.log('unsubscribed', responseCode);
}).catch(function (responseCode) {
    console.log('not unsubscribed', responseCode);
});

7. Examples

7.1 Contact Data and Auto Identifier

In this example we only require End-User to enter his name for subscription.

The end result is that after successful subscription user is provided with identifier which will be saved for later use in browser's local storage.

When subscription token is expired and identifier exists in browser's local storage, SDK can identify and it will update existing contact.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Webpush Basic Example</title>
</head>

<body>
    <button onclick="subscribe(event)">Subscribe</button>
    <button onclick="unsubscribe(event)">Unsubscribe</button>

    <script async type="text/javascript" src="hpro-wp-sdk.min.js" async></script>
    <script>
        var hproWebPush = hproWebPush || [];

        hproWebPush.push(function () {
            // before all init first
            hproWebPush.init({
                workerFile: 'hpro-wp-sw.min.js',
                whenUnsubscribed: 'remove_identity',
                formUuid: 'd44795cb-af37-4edb-b324-df9d0f720679',
                applicationServerKey: 'BIsHK3ZIGQ6qylk1TkdHuxGZ2f1qNdPIQd+y61J7UA1uFGlJw9IZK2yD4/uRi+rJItEBc6HV1OewS64932acGMs=',
                notifyButton: {
                    enable: true,
                    position: 'top-left'
                }
            }).then(function (successResponse) {
                console.log('initialized', successResponse);
            }, function (errorResponse) {
                console.log('Not initialized', errorResponse);
            });
        });

        function subscribe() {
            const _myFullname = prompt('John Doe');
            const _fullnameParts = _myFullname.split(' ');
            // webpush subscription
            hproWebPush.subscribe({
                first_name: _fullnameParts[0],
                last_name: _fullnameParts[1]
            }).then(function (successResponse) {
                console.log('subscribed', successResponse);
            }, function (errorResponse) {
                console.warn('denied', errorResponse);
            });
        }

        function unsubscribe() {
            hproWebPush.unsubscribe().then(function (successResponse) {
                console.log('unsubscribed', successResponse);
            }, function (errorResponse) {
                console.log('not unsubscribed', errorResponse);
            });
        }

    </script>
</body>
</html>

7.2 Existing Identifier

In this example we force SDK to use existing contact identifier (contact UUID). E.g. if you are building a user portal, you should store BM contact UUID along with other user profile information. This way you will be able to specify it in Webpush SDK parameters.

We have already identified the contact and we have initialized SDK with his identifier.

Identifier will also be saved for later use in browser's local storage.

The end result is that after successful subscription the same user is updated with latest subscription token.

When subscription token is expired, SDK can identify and refresh subscription token.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Webpush Basic Example</title>
</head>

<body>
    <button onclick="subscribe(event)">Subscribe</button>
    <button onclick="unsubscribe(event)">Unsubscribe</button>

    <script async type="text/javascript" src="hpro-wp-sdk.min.js" async></script>
    <script>
        var hproWebPush = hproWebPush || [];

        hproWebPush.push(function () {
            // before all init first
            hproWebPush.init({
                workerFile: 'hpro-wp-sw.min.js',
                whenUnsubscribed: 'remove_identity',
                identifier: 'd354fe67-87f2-4438-959f-65fde4628787',
                formUuid: 'd44795cb-af37-4edb-b324-df9d0f720679',
                applicationServerKey: 'BIsHK3ZIGQ6qylk1TkdHuxGZ2f1qNdPIQd+y61J7UA1uFGlJw9IZK2yD4/uRi+rJItEBc6HV1OewS64932acGMs=',
            }).then(function (successResponse) {
                console.log('initialized', successResponse);
            }, function (errorResponse) {
                console.log('Not initialized', errorResponse);
            });
        });

        function subscribe() {
            const _myFullname = prompt('John Doe');
            const _fullnameParts = _myFullname.split(' ');
            // webpush subscription
            hproWebPush.subscribe({
                first_name: _fullnameParts[0],
                last_name: _fullnameParts[1]
            }).then(function (successResponse) {
                console.log('subscribed', successResponse);
            }, function (errorResponse) {
                console.warn('denied', errorResponse);
            });
        }

        function unsubscribe() {
            hproWebPush.unsubscribe().then(function (successResponse) {
                console.log('unsubscribed', successResponse);
            }, function (errorResponse) {
                console.log('not unsubscribed', errorResponse);
            });
        }

    </script>
</body>
</html>

7.3 Auto Subscribe

Auto Subscribe will only work when user has given browser notification permissions and token has expired at some point.

It will not work on first user visit, because user needs to click on notification button to be asked for browser notification permissions, and grant them.

This all happens during the init procedure.

On every later visit user will be updated with the new subscription token.

It works in both cases: existing contact identifier or auto contact identifier.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Webpush Basic Example</title>
</head>

<body>
    <button onclick="subscribe(event)">Subscribe</button>
    <button onclick="unsubscribe(event)">Unsubscribe</button>

    <script async type="text/javascript" src="hpro-wp-sdk.min.js" async></script>
    <script>
        var hproWebPush = hproWebPush || [];

        hproWebPush.push(function () {
            // before all init first
            hproWebPush.init({
                workerFile: 'hpro-wp-sw.min.js',
                whenUnsubscribed: 'remove_identity',
                identifier: 'd354fe67-87f2-4438-959f-65fde4628787',
                autoSubscribe: true,
                formUuid: 'd44795cb-af37-4edb-b324-df9d0f720679',
                applicationServerKey: 'BIsHK3ZIGQ6qylk1TkdHuxGZ2f1qNdPIQd+y61J7UA1uFGlJw9IZK2yD4/uRi+rJItEBc6HV1OewS64932acGMs=',
            }).then(function (successResponse) {
                console.log('initialized', successResponse);
            }, function (errorResponse) {
                console.log('Not initialized', errorResponse);
            });
        });

        function subscribe() {
            const _myFullname = prompt('John Doe');
            const _fullnameParts = _myFullname.split(' ');
            // webpush subscription
            hproWebPush.subscribe({
                first_name: _fullnameParts[0],
                last_name: _fullnameParts[1]
            }).then(function (successResponse) {
                console.log('subscribed', successResponse);
            }, function (errorResponse) {
                console.warn('denied', errorResponse);
            });
        }

        function unsubscribe() {
            hproWebPush.unsubscribe().then(function (successResponse) {
                console.log('unsubscribed', successResponse);
            }, function (errorResponse) {
                console.log('not unsubscribed', errorResponse);
            });
        }

    </script>
</body>
</html>

8. Contact Data

"Contact Data" is data that you can send to our service when subscribe method is triggered. With that way of gathering data, you will have more information about your subscriber.

Key Type Values Description
first_name String First Name
last_name String Last Name
nick_name String Nick Name
second_name String Second Name
gender String male
female
Gender
Female or male
birthday String Birthday
Format: 2018-01-03
salutation String Salutation
fax String Fax
language String
(lowercase)
en.wikipedia.org/wiki/List_of_ISO_639-1_codes Language
Example: 'en' for English
nationality String
(lowercase)
en.wikipedia.org/wiki/ISO_3166-1 Nationality
Example: "GB" for United Kingdom
mobile String Mobile
Example: +41 78 123 45 67
phone String Phone
Example: +41 78 123 45 67
title String Title
zip String ZIP
address String Address
city String City
region String Region
country String
(uppercase)
en.wikipedia.org/wiki/ISO_3166-1 country
Example: "GB" for United Kingdom
b_address String Business address
b_city String Business city
b_company String Company name
b_country String
(uppercase)
en.wikipedia.org/wiki/ISO_3166-1 Business Country
Example: 'DE' for Germany
b_department String Business Department
b_email String Business Email
b_job_title String Job Title
b_mobile String Business Mobile
Example: +41 78 123 45 67
b_phone String Business Phone
Example: +41 78 123 45 67
b_reception_code String Business Reception code
b_region String Business Region
b_zip String Business ZIP

9. Change Log

9.1 v1.3.0

2024-07-25

  • Optimized subscribe flow
  • Optimized unsubscribe flow
  • Fixed button subscription state
  • Bundles are minimized

9.2 v1.2.0

2024-03-20

  • Removed Axios (http client) from bundle

9.3 v1.1.0

2020-02-10

  • General optimizations

9.4 v1.0.0

2018-01-15

  • Initial release