Website Messenger API

With our messenger API you can control the Website Messenger’s behavior and integration beyond the options we provide in our Messenger settings. To go directly to the API’s full documentation on GitHub, click here.
The messenger API allows you to define the start and flow of your chat communication based on your website’s behavior, events and functions. A few potential use cases to give you a better idea:
  • Loading the Website Messenger only after a cookie consent
  • Triggering the chat in certain situations, e.g. a shopping cart exceeding a certain value
  • Loading and removing the Website Messenger on larger single page applications
When you use the JavaScript Widget code to load your Website Messenger, it’s loaded globally, as soon as the script tag is executed. The Messenger API gives you more control over the loading process by allowing you to “mount” and “unmount” Messengers (adding or removing them on the document).
The setup of the Messenger API is geared towards developers. This tutorial is meant to also give less technically versed users an overview of the Messenger API and its possibilities.
The canonical reference for the Messenger API is this GitHub repository, which contains its code.
The examples provided in this document use plain JavaScript. You might want to consider using utility libraries that help you handle promises more easily.

Using the API

In order to use commands with the API, you will need to create a messenger object, which can be done using the createMessenger function from the @userlike/messenger npm package. Here’s a simple way to do it, but we recommend to add error handling to your function in case something goes wrong or in case the API version you’re using has reached its end-of-life. First, make sure to import the required component from the npm package at the top of your file: import { createMessenger } from '@userlike/messenger';
You can now use createMessenger in your code:
async function createApi() { const result = await createMessenger({ version: 1, widgetKey: "WIDGET_KEY", }); const { api } = result.value; return api; };
Now assign this function, which returns a promise, to a variable. You can then use that to mount the messenger on the DOM, for example:
const userlike = createApi(); userlike.then(messenger => messenger.mount());
The above is a good example of how you could tie creating and mounting the messenger to a user's cookie consent choices by only calling createApi() after the user has selected the relevant option.
Only one messenger can be mounted to the DOM at a time, so please make sure you consider this in your logic, especially if you are aiming to switch between different widgets. If you try to mount a second widget even though there is already another one mounted, this will result in an error.

Using your own element to trigger the chat

In certain situations, you might want to use a custom element on your page to trigger opening the messenger instead of the widget's button. In that case, you will likely want to use the setVisibility function of the messenger API. Using setVisibility, you can define the visibility of main (the main window of the chat widget), button (the button itself) and notifications (notification bubbles such as the welcome bubble or the proactive bubble).
In combination with the maximize function, you could define your own element and define that the onClick event should trigger maximizing the messenger. Assuming you're using an HTML element with the ID myBtn, you could do something like this:
const userlike = createApi(); userlike.then( messenger => messenger.mount() .then(() => messenger.setVisibility({ main: true, button: false, notifications: false, })) ); const startChat = () => { userlike.then(m => m.maximize()); } document.getElementById('myBtn').addEventListener( "click", () => startChat() )
You could expand on this starting point by changing the above startChat() function to toggle the messenger's visibility between maximized and minimized or only display your custom button if the messenger is minimized. The messenger's current state can be retrieved using the API's getState() function, which we'll expand upon further in this tutorial. For more information on state tracking, please also refer to the code example in the Github repository.

Displaying the messenger based on certain conditions

The concept of changing the visibility or mounting the messenger as seen above can be applied to different scenarios where you'd like your own logic to determine when the button should be shown to your visitor.
For example, let's say you'd only like to display the button after the visitor has reached a certain point on your page, you'd just call the setVisibility() function with the relevant arguments:
/* Assuming you hid the messenger button when mounting the messenger and that you have a function 'scrollDepth' that returns the current scroll position on the page: */ window.addEventListener("scroll", function () { if (scrollDepth() > 50) { userlike.then(messenger => messenger.setVisibility( { main: true, button: true, notifications: true, } )) } }, false)
The same idea can be transferred to different scenarios, such as updating the visibility of the button once a customer has reached a certain cart value. Used judiciously, you can create different scenarios to boost chat engagement by offering the chat at just the right time..

Sending data to the messenger

The API provides two functions that allow you to send data to the messenger.
setContactInfo allows you to set the contact's name and email address. This is useful if you are offering the chat for users logged into your web application and you want to pass this information directly to Userlike.
The data should be passed to the function as a Javascript object containing the keys name and email with the corresponding values as strings.
Additional keys can be phone_number, mobile_number, company and external_customer_id
If you are using the widget in registration mode and you pass the contact's name and email to the messenger, the registration step when starting a conversation will be skipped.
The same logic can be used with the custom data function. Your custom data will show up in the Message Center. It can be updated by calling the setCustomData function again with an updated set of data. The data you pass to the messenger should be a Javascript object containing key-value pairs with the information you want to include.
The below example mounts the messenger, sets the contact's name and passes some custom data to the conversation.
let customData = { example: 1, test: "custom data", foo: "bar", id: 123456789, loggedIn: true, } userlike.then((messenger) => messenger .mount() .then(() => messenger.setContactInfo({ name: "Test Contact", email: "" }) .then(() => messenger.setCustomData(customData)) ) );

Getting the widget's current state

To retrieve the Messenger’s current state, use the API’s getState() function. It can return three different values:
  • hidden: when the Messenger hasn’t been mounted on the DOM, or when it has been mounted but it’s set to be hidden through the Messenger’s configuration. This would be the case if you’ve set the Messenger to be hidden when no operator is available in the Message Center. You can use this information to determine whether to show or hide certain elements on the page based on your operators’ availability.
  • minimized: the Messenger is mounted but minimized (the main Messenger window is not displayed).
  • maximized: the Messenger is mounted and maximized (the main Messenger window is displayed, just like after clicking on the Messenger button).
Instead of querying the state manually, you can also do this by subscribing to the state. For more information refer to the the GitHub repository.

Contact Authentication and Verification

Contact authentication and verification enable your Contacts to prove their identity. Once authenticated, they can access their ongoing and previous conversations. Contact authentication and verification are important for ensuring the security and integrity of your Contacts' conversations so that you are protected against impersonation attacks, prevent duplicate Contacts, and provide a seamless user experience.

Contact Authentication

A first-time visitor implicitly creates a new Contact for themselves. They are authenticated every time they visit the website, allowing them to access their ongoing and previous conversations. The credentials for a Contact are stored in the browser storage. However, if a Contact switches devices or clears the browser storage, they will implicitly create a new Contact for themselves again, losing access to their conversations from the other device.

Contact Verification

Contacts can verify their identity via their email address or when using Messenger API Contact Authentication via a unique identifier that you control and associate with a Contact. Verified Contacts reduce the possibility of duplicate Contacts and give Operators certainty that Contacts are who they claim to be. Operators can see the verification state and the kind of verification for a Contact via the verified Badge on Contact Avatars in the Message Center.

Email Verification

When a Contact has previously entered their email address, they can regain access to those conversations by either clicking the conversation link in the email that notifies them about unread operator messages or proactively request a "magic link" with a one-time authentication token to be sent to their email address.

Messenger API Contact Authentication

In addition to email verification, we offer a way to authenticate and verify a Contact using the Messenger API Contact authentication. This allows you to associate a unique identifier with a Contact, usually after they have logged into your system.

Implementing Messenger API Contact Authentication

To use Contact Authentication, you first need to create a secret "Messenger API authentication signing key" in your API settings. You then need to securely store that signing key in your system and create a service that uses that signing to create a JWT that we use to authenticate a Contact.
The JWT payload must be signed using your messenger signing key via HMAC-SHA256 and must have the following shape:
plain text
interface TokenPayload { sub: string; // a unique ID of your choice that you want to use to identify the Contact (max length: 255) iat: number; // issued at timestamp in seconds exp: number; // expires at timestamp in seconds }
You'll then have to pass an externalToken configuration when calling the mount() function of our Messenger API:
plain text
api.mount({ externalToken: { getToken: (){ // call your Service that returns the JWT }, onError: (e) { // callback to handle errors using Contact Authentication } } })
When the JWT is valid, your Contacts will have access to all their ongoing and previous conversations regardless of which browser, device, or platform they're using the Messenger on.
In case the JWT is invalid (for example when it expired or was signed incorrectly) the onError callback is called and your contacts won’t have access to their previous and ongoing conversations anymore.