Today I had an interesting programming task involving Crisp chat integration. I thought would be difficult but was, in fact, extremely straightforward. The task was to 2-way bind Crisp profile email with user's email from the backend.

So, there were three scenarios:

  1. If email is set on Crisp, also set it on user's profile in the backend.
  2. If email is set in the backend, also set the same email for Crisp.
  3. If email is already set for both Crisp and backend, do not modify either.

I looked at Crisp docs but couldn't find anything useful for my use case until I accidentally stumbled upon this article - How to use $crisp JavaScript SDK?. However, the article was a bit lacking and I couldn't find where to obtain the SDK in question.

As it turns out, the JavaScript SDK comes by default once you integrate Crisp into a website. This is not mentioned anywhere in the docs and support staff not mention it either but now I'm telling you this so you can avoid wasting time searching for it like I did. The SDK is accessible through a global variable $crisp and all methods described in the article are available as part of the $crisp object.

So, the code for 2-way binding of backend email with Crisp user profile email would look similar to as below.

const bindEmail() {
    const crispEmail = window.$crisp.get("user:email");
    
    if (crispEmail & NO_BACKEND_EMAIL) {
        SET_BACKEND_EMAIL(crispEmail);
    } else if (!crispEmail & YES_BACKEND_EMAIL) {
        window.$crisp.push(["set", "user:email", [backendEmail]]);
    }
}

window.CRISP_READY_TRIGGER = () => {
    bindEmail();

    window.$crisp.push(["on", "user:email:changed", () => {
        bindEmail();
    }]);
};

Note how we have to wait for $crisp instance to load which is where CRISP_READY_TRIGGER is used.

We call bindEmail function, both, on $crisp instance load and when Crisp user profile email is changed. We listen for the email change via window.$crisp.push(["on", "user:email:changed", callback]) and update user's email via window.$crisp.push(["set", "user:email", [backendEmail]]) if email in the backend is already available. Else, we set backend email if email is already set on Crisp. We retrieve Crisp email via window.$crisp.get("user:email").

That's it, I have to give credit to Crisp of how well their JavaScript SDK is implemented. I wish all of them were such a joy to use.