Skip to content

userlike/messenger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Official Userlike Messenger API

Install

npm install @userlike/messenger

ES modules

import { createMessenger } from '@userlike/messenger';

commonjs

const { createMessenger } = require('@userlike/messenger');

AMD loader (requirejs)

require(['userlike-messenger'], function (userlike) {
  userlike.createMessenger({ ... });
});

script tag

<!--
unpkg is an open source project. It's not affiliated with Userlike. Use it to quickly and easily load
messenger api without bundling it yourself. We highly advise against using unpkg for production.
-->
<script src="https://unpkg.com/@userlike/messenger/dist/browser/index.min.js"></script>
<script>
  UserlikeMessenger.createMessenger({ ... });
</script>

Upgrading to Version 2

Version 2 is a breaking change that adds support for widget routers on single page applications. If you are using version 1, we highly recommend upgrading to version 2 as soon as possible. See the migration guide.


Usage

See examples for further details on how to use createMessenger.

Usage with typescript

See the typescript playground.

Usage with javascript

See the javascript playground.

Usage with react + typescript

See the react playground.

Examples

Create the API

import { createMessenger, v1 } from "@userlike/messenger";

async function createApi(): Promise<v2.Api> {
  const result = await createMessenger({
    version: 2,
    widgetKey: "YOUR_WIDGET_SECRET",
  });

  if (result.kind === "error") throw new Error(result.error);

  const { api } = result.value;

  if (api === null) {
    throw new Error(
      "api reached end-of-life, please check documentation and upgrade."
    );
  }

  return api;
}

Create/destroy messenger

(api: v2.Api) => {
  const subscription = api.mount().subscribe(result => {
    if (result.kind === "error") {
      console.error(result.error);
      return;
    }

    if (result.value === null) {
      console.log("messenger is not mounted", result.reason);
      return;
    }

    const messenger = result.value;
  });

  // Unsubscribing would destroy the messenger
  subscription.unsubscribe();
};

Change visibility

// Hide button and notifications
async (messenger: v2.Messenger) => {
  await messenger.setVisibility({
    main: true,
    button: false,
    notifications: false,
  });
}

// Show everything
async (messenger: v2.Messenger) => {
  await messenger.setVisibility({
    main: true,
    button: true,
    notifications: true,
  });
}

Clear user session / Logout

async (messenger: v2.Messenger) => {
  await messenger.logout();
}

Maximize/Minimize

async (messenger: v2.Messenger) => {
  await messenger.maximize();
  await messenger.minimize();
};

Set custom data

async (messenger: v2.Messenger) => {
  await messenger.setCustomData({
    test: "test data",
  });
}

Set contact info

async (messenger: v2.Messenger) => {
  await messenger.setContactInfo({
    name: "Foo Bar",
    email: "[email protected]",
  });
}

Listen to changes

(messenger: v2.Messenger) => {
  const subscription = messenger.state$.subscribe({
    next: (state) => console.log("next", state),
    complete: () => console.log("complete"),
  });

  // unsubscribe when you don't need to listen to changes anymore
  subscription.unsubscribe();
}

Observables

Both api.mount() and messenger.state are observables. You can use rxjs, or other streaming libraries:

import * as Rx from "rxjs";
import * as $ from "rxjs/operators";
import { v1 } from "@userlike/messenger";

(api: v2.Api) => {
  const unreadMessageCount$ = Rx.pipe(
    api.mount(),
    $.filter((result) => result.kind === 'success'),
    $.map((result) => result.value),
    $.switchMap((messenger) => messenger.state$),
    $.map(v2.getUnreadMessageCount),
  );
}

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:

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" unix timestamp, in seconds
  exp: number; // "expires at" unix timestamp, in seconds
}

You can then then pass the externalToken configuration when calling the mount() function of our Messenger API:

api.mount({
  externalToken: {
    getToken: () => {
      // return a JWT created by your service
    },
    onError: (e) => {
      // callback to handle errors related to 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.

Error handling

Messenger API never throws an error. Instead it returns a Result which represents either a successful outcome or an erroneous outcome. In technical terms, Result is a tagged union of Success and Error, similar to Rust's Result<T, E>.

It's important to notice that the API function won't throw an error by itself, but you need to handle the Action Result and throw an error by yourself as you need it.

Versioning

Userlike Messenger API follows relatively short cycles of deprecations and end of lifes. The API versioning is designed in such a way to force its consumers to be prepared and to plan for an end-of-life situation. When end-of-life date is reached. that version of the API becomes unavailable; which is reflected in Typescript types.

We highly suggest you to use Typescript to consume Userlike Messenger API so to be able to handle unhappy code paths safely.

Dates

  • v2
    Deprecation: 2026-08-01
    End-of-life: 2027-08-01
  • v1
    Deprecation: 2025-08-01
    End-of-life: 2026-08-01