User identity resolution for PLuG

My experience with identity resolution when integrating DevRev PLuG.

User identity resolution for PLuG

When implementing support systems at scale, one of the most critical challenges is maintaining consistent customer identity across multiple platforms. While it’s important for both the customer experience and business analytics, different systems have different requirements. In this post, I’ll share my experience integrating DevRev’s support platform at Orum, focusing specifically on the technical challenges around user identification and identity resolution.

Background

At Orum (case study), we provide an AI live conversation platform that helps Orum’s users (whom we call sales development representatives or reps) connect with their prospects. Our application integrates with various CRM systems like Salesforce, HubSpot, SalesLoft, Apollo, and Outreach. This multi-platform integration means that user identification becomes crucial for support of our customers.

When we decided to migrate from Zendesk to DevRev for our support system, one of our key requirements was maintaining consistent user identification. This was particularly important because our previous setup lacked direct identity connection between our application and the support system. Support requests would come into Zendesk with just an email address, making it challenging to connect these requests with specific user accounts in our system and therefore to understand what systemic challenges customers were encountering.

Data architecture

Orum’s primary source of user data is a database that contains user profiles and organization relationships. In addition, Orum (the company) uses Salesforce to identify and manage customer accounts (known as Orgs in the Orum application). It is how we track our customers during the sales process and how we manage payments, account status, and so on.

Before a new Org is created in the Orum application, a Salesforce Account object must already exist within Orum’s Salesforce CRM instance. When Orum colleagues create a new Org, they can select a Salesforce account with which to associate the new Org. The Salesforce Account ID is written to the Org database record at creation.

On top of these core systems, Zendesk contained historical support tickets and user interactions. There had always been a disconnect between the identity of a customer in our database and the identity of a presumptive customer who files a case in Zendesk.

One of the promises of DevRev is a 360 degree view of customers, which requires that support cases be associated with customer accounts. Customer data comprises several objects, like account, workspace, and contact. For our purposes, a user is uniquely identified by their email address and their Salesforce ID. The challenge of migration was to create a bridge between these systems that would maintain consistent user identity without creating duplicate records.

Migration and implementation

Orum’s primary integration surface with DevRev is the PLuG widget in our main web application. From PLuG, the reps who are Orum’s customers can get help.

I had originally thought it would be my responsibility to load users from Orum’s other user identity systems–object-relational DB, Salesforce, and Zendesk. As it turned out, DevRev already had utilities to deal with Zendesk and Salesforce, and part of their implementation services was to ingest the other account data.

One part of the learning curve was that some of the terminology wasn’t entirely clear at the outset. The “workspace” concept used to be called “rev org(anization)”. That term is no longer used, except in the rev-orgs API.

While the migration aspect was handled pretty thoroughly, what remained for me was to ensure that PLuG knew who the users were. Specifically, when a user starts a conversation in PLuG, pass their identity consisting of their email address to DevRev using the auth-tokens.create API call so that it can be associated with the customer organization. In the common case, where a user account already exists in DevRev, nothing else is required as DevRev handles the rest.

In another situation, when a conversation comes in from a user that does not already have an account in DevRev, we would want to create a user account and infer the organization from the email domain. The logic is pretty straightforward, but its implementation ended up being a little trickier than expected.

Identity resolution

The confusion arose with the behavior of auth-tokens.create. It was necessary to pass a rev_info object, which as the documentation states, “Carries info corresponding to the Rev user to be provisioned and/or issue a Rev session token” (emphasis mine). How did I know if a new user was provisioned, or if there was already a user? The response from auth-tokens.create does not include a reference to the DevRev user object, so it wasn’t clear. I most definitely did not want to create a bunch of duplicate user accounts that would degrade the usefulness of DevRev (and create a mess that I or someone else would have to clean up later). The answer was that DevRev reliably did the right thing, and I didn’t have to write defensive code around it.

Another question was about which rev_info properties needed to be included. There are numerous properties that are all marked optional, but clearly something is required. It turned out that just two were adequate (user_ref and account_ref), and DevRev could infer the rest from its knowledge graph.

Once the questions were answered, the code ended up being fairly straightforward.

const userRef = user.primaryEmail
let accountRef = org.salesforceAccountID
if (accountRef === null) {
    const domain = getDomainFromEmail(user.primaryEmail)
    if (typeof domain === "string" && domain !== "gmail.com") {
        accountRef = domain
    }
}
const response = await axy<unknown>({
    url: "https://api.devrev.ai/auth-tokens.create",
    method: "post",
    headers: {
Authorization: "Bearer.${DEVREV_APPLICATION_ACCESS_TOKEN}",
    },
    data: {
        rev_info: {
            user_ref: userRef,
            account_ref: accountRef,
        },
    }
})

const { access_token } = zDevRevAuthResponse.parse(response.data)

Conclusion

While the initial learning curve was steep, particularly around understanding the identity resolution patterns, the end result has been very positive. The DevRev integration provides our support team with much better user context and has significantly improved our support workflow.

The challenge of maintaining consistent user identity across multiple systems is complex, but modern platforms like DevRev are evolving to handle this complexity more elegantly.

essential