Authenticate Zendesk Messaging

Zendesk recently added the ability to authenticate users in the Zendesk Messaging Web and Mobile SDK. This article shows how to set it up with sample code.

Authenticate Zendesk Messaging

Zendesk recently added the ability to authenticate users in the Zendesk Messaging Web and Mobile SDK. This article shows how to set it up with sample code.

Zendesk recently added the ability to authenticate users in the Zendesk Messaging Web and Mobile SDK. This allows any website or app that has logged in users to pass that information to Zendesk so that you're sure you're talking to the right person, and removes the need for your customer to enter any credentials.

Setting it up is easy, as long as you have a working JWT endpoint. If you haven't got one, this guide will show you how to set one up using Cloudflare Workers.

GitHub - verschoren/zendesk_jwt_example: Sample Code for the various Zendesk JWT Projects
Sample Code for the various Zendesk JWT Projects. Contribute to verschoren/zendesk_jwt_example development by creating an account on GitHub.

Note that this example code does not validate the user against any directory. It trust the input and returns a valid JWT for Zendesk to use.

How it works

Let's start at the end of the flow and show a working scenario.

  1. A user visits https://jwt.internalnote.com
  2. They enter their name/email and press login
  3. The website logs in the user and the widget authenticates
  4. Zendesk recognises the user, and starts a conversation.

If there's still an ongoing conversation from earlier, the widget will show the conversation regardless of the user having used that browser/device before.

When the agent opens the conversation in the Agent Workspace he notices a green checkbox next to the users' name showing them the user has logged in correctly.

💡
Note: Currently Zendesk doesn't always map Messaging against existing users.

A user john@example.com that has an existing profile via the email channel, will get a new profile for Messaging even when they use the same email address.

If your users in Zendesk have external ids thanks to an earlier import, you can pass that ID in your JWT payload and Zendesk will match and merge those users.

Setting up Authentication

Authenticating a user requires the following steps:

  1. Get a Secret and App ID from Zendesk
  2. Create a web service (e.g. via Cloudflare Workers) to generate a valid Valid JWT
  3. Have a function on your website that calls the web service when a user logs in and generates a JWT based on their email, name and ID
  4. Push that JWT Token to the Widget

Credentials

Setting up authentication for Messaging first requires generating a Secret and App ID. That's done via https://subdomain.zendesk.com/admin/account/security/end_users#messaging

App ID: app_12345abcde1234567890
Secret: some-very-long-string-with-digits-and-numbers

To generate a login for the web widget you'll also need a name, email and external ID for your user.

Generating the JWT

Based on the above items you can generate a working JWT. You can find an example below.

There's a few important caveats:

  • External ID has to be unique for each user, so use a GUID, UUID, or database ID
  • The credentials do not expire unless you set an expiration date
  • Our code does not validate if the user exists, it just accept whatever input is there.
var input = {
    "external_id":1906365876753,
    "user_email":"john@example.com",
    "user_name":"John Smith"
}

const app_id = "app_123";
const secret ="abc123";

const key = await crypto.subtle.importKey(
   "raw",
   utf8ToUint8Array(secret),
   { name: "HMAC", hash: "SHA-256" },
   false,
   ["sign"]
);

const header = JSON.stringify({ alg:"HS256", typ:"JWT", kid:app_id });

//We set the expiration date to 24h
const payload = JSON.stringify({
	scope: "user",
    name: json.user_name,
    email: json.user_email,
    external_id: external_id,
    exp: Math.floor(new Date().getTime() / 1000.0) + 86400,
});

const partialToken = `${base64URLStringify(utf8ToUint8Array(header))}.${base64URLStringify(utf8ToUint8Array(payload))}`;

const signature = await crypto.subtle.sign(
	"HMAC",
    key,
    utf8ToUint8Array(partialToken)
);

const jwt = `${partialToken}.${base64URLStringify(new Uint8Array(signature))}`;

For the example website above I created a Cloudflare Worker that handles the JWT scenario for both Messaging and the Classic Widget.

You can find a working code example via the link below.

GitHub - verschoren/zendesk_jwt_example: Sample Code for the various Zendesk JWT Projects
Sample Code for the various Zendesk JWT Projects. Contribute to verschoren/zendesk_jwt_example development by creating an account on GitHub.

Logging In

The end result is a JWT token that you pass to the widget via:

zE('messenger', 'loginUser', function (callback) { 
    callback(jwttoken);
});

Logging Out

If for any reason you wish to logout your user, you can use the code below.

zE('messenger', 'logoutUser');

What about Zendesk Guide?

You can also easily use the above example to authenticate Zendesk Guide.

  1. Open your Zendesk Guide Theme and edit its code
  2. Open document_head.hdbs and paste the following code at the bottom
  3. From now on, whenever a user logs into your Help Center, the widget will authenticate itself.