Deep-dive into issues related to Messaging Authentication and JWT User Mapping

Currently the authentication for Zendesk Messaging as described in my article below has some weird behaviours when it comes to matching to existing Zendesk User Profiles. There's also a rather long thread about these issues on the Zendesk Community.

Deep-dive into issues related to Messaging Authentication and JWT User Mapping
⁉️
Apparently old Zendesk accounts can be tagged with an internal flag that prevents External ID matching to work. Zendesk Support removed the flag from my account and External ID tagging now works as expected.

This means Email matching is still an issue, but External IDs do work!

Currently the authentication for Zendesk Messaging as described in my article below has some weird behaviours when it comes to matching to existing Zendesk User Profiles. There's also a rather long thread about these issues on the Zendesk Community.

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.

What you would expect is:
If a user logs into Messaging and already exists in Zendesk with the same email or external ID, the resulting conversation is mapped against the existing user.

So let's test a few scenario's and log their outcomes:

  1. New user that's never interacted with Zendesk
    A new user uses Messaging for the first time and is logged in via JWT.
    Result: --> A new end-user is created without an associated email address in Zendesk.
  2. An authenticated existing user with an email address that exists in Zendesk
    An existing end-user logs into Messaging and starts a conversation. Even though the email address matches an existing user, a new user is created in Zendesk.
  3. An unauthenticated existing user with an email address that exists in Zendesk
    An existing user uses messaging and is not logged in. They enter an email address in the Ask for Details step. This conversation is added as a ticket linked to the existing user in Zendesk that has a matching email address. (🥳 Finally a good result!)
  4. That same existing user that has now both messaging and email address linked, now logs into Messaging and starts chatting. This creates a new user without an email, unlinked from the existing user. 🤯

As you can see, none of the scenario's fully match the behaviour one would expect.

Only when you merge a newly created logged in Messaging user and the existing email user profile, you can achieve a mapping to the same user for any following tickets. But since Zendesk does not show the email address of the logged in Messaging anywhere in the interface, there is no way for an agent to know who to merge too.

Conversation API

⚠️
If you have access to Sunshine Conversations, you can use the Smooch API to do some lookups and retrieve the required values afterwhich you're able to merge the users.

Zendesk also enabled customers to generate a Sunshine Conversation API via de Admin Panel for Suite users.

Below are some example flows that show the actual data and API calls made for these tests.

If you encounter these same issues, please upvote or add a comment to this Community Post, so we can get this fixed.

Scenario 1: Test with a new user

Authenticated Messaging Flow via JWT

This is an example of the JWT token I generate. Note the External ID I use has the email address as part of it to make it show up somewhere in the UI for agents. IN real scenarios you'd use an actual ID here from your user database.

{
  "alg": "HS256",
  "typ": "JWT",
  "kid": "app_62965da0ae721700f5743234"
},
{
  "scope": "user",
  "name": "Peter Parker",
  "email": "peterparker@spiderman.example",
  "external_id": "user_peterparker@spiderman.example",
  "exp": 1682149431
}

Get User Identities in Zendesk

Since the Messaging account info  doesn't show up in the interface, I dove into the Identities API to see if something would show up. More info in this Developer article.

curl --location 'https://d3v-verschoren.zendesk.com/api/v2/users/11109600149778/identities/11109600154130' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic zendesk_token'

And yes, there is a messaging type in the profiles for these users. No UI in Agent Workspace, but retrievable via API.

{
    "identity": {
        "url": "https://d3v-verschoren.zendesk.com/api/v2/users/11109600149778/identities/11109600154130.json",
        "id": 11109600154130,
        "user_id": 11109600149778,
        "type": "messaging",
        "value": "425a9d0b802f5f2ca9cc7463",
        "verified": true,
        "primary": true,
        "created_at": "2023-04-21T07:44:07Z",
        "updated_at": "2023-04-21T07:44:07Z"
    }
}

Get User in Sunshine Conversations

At first glance this information is not really handy. The value on these profiles does not show up on the users, profiles or identities objects in Zendesk. It's only because I have Sunshine Conversations active that checking the value against user IDs in SunCo that actual information on the user showed up.

More info on this API can be found in the Smooch documentation.

🤔
This requires a user to have an active SunCo subscription for its account
curl --location 'https://api.smooch.io/v2/apps/5f8ecbf276da07000cb2a456/users/425a9d0b802f5f2ca9cc7463' \
--header 'Authorization: Basic sunco_token'
{
    "user": {
        "signedUpAt": "2023-04-21T07:39:09.052Z",
        "hasPaymentInfo": false,
        "identities": [],
        "id": "425a9d0b802f5f2ca9cc7463",
        "externalId": "user_peterparker@spiderman.example",
        "profile": {
            "surname": "Parker",
            "givenName": "Peter",
            "email": "peterparker@spiderman.example",
            "locale": "en-GB"
        },
        "metadata": {}
    }
}

Scenario 2: Start with an existing user that has a external ID

My previous article wrongly noted that creating an Authenticated Messaging user with an External ID that matches an existing Zendesk user would have the system match those users and correctly map the conversation.

Let's test this.

Create Test User

curl --location 'https://d3v-verschoren.zendesk.com/api/v2/users.json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic zendesk_token' \
--data-raw '{
    "user":{
        "name":"Green Goblin",
        "email": "greengoblin@spiderman.example",
        "external_id": "user_greengoblin@spiderman.example"
    }
}'
{
    "user": {
        "id": 11109844978962,
        "name": "Green Goblin",
        "email": "greengoblin@spiderman.example",
        "external_id": "user_greengoblin@spiderman.example",
        ...
    }
}

Authenticated Messaging Flow via JWT

I then did a new authenticated API call via https://jwt.internalnote.com with a user that matches the name, email and external ID of this new test user.

This still does not work, I still have two users. One with a Messaging Identity, and a regular Zendesk user.

A temporary solution

If you have Sunshine Conversations this could be a temporary solution:

  • Create a sidebar app that runs next to your tickets.
  • Have the app look up the identities of the current requester and get the type:messaging identity
  • Retrieve the value of that identity
  • Do a lookup in Sunshine Conversations for that user
  • Retrieve the email of that user with the information from its profile:{} payload
  • Search for a user in Zendesk with that same email, and if found merge into that user
  • If not found, update the profile of the Zendesk user with the information from its profile:{} payload.

You can find a repository that contains a proof of concept of this flow in the following GitHub repository:

GitHub - verschoren/messaging_user_merger: An app that merges Messaging and Email users in Zendesk
An app that merges Messaging and Email users in Zendesk - GitHub - verschoren/messaging_user_merger: An app that merges Messaging and Email users in Zendesk

Other remarks

There's also a weird bug: Any regular end-user with an external_id set, regardless of them having logged in or not, get a green checkmark with shows "Authenticated" when you hover over it 🤷‍♂️.