Setting Up Identity Verification for Web and Mobile on Customerly

Raluca Stoica
Written by Raluca StoicaLast updated 2 hours ago

Identity verification makes sure the person writing in your chat is really the logged-in user they claim to be. Customerly verifies users with an email hash: an HMAC-SHA256 of the user's email, signed with a secret only your server knows.

Step 1: get your verification secret

Contact support via chat to get your verification secret key. Store it as a server-side secret (for example CUSTOMERLY_IDENTITY_SECRET in your server environment or Supabase secrets). Never put it in client code, in a NEXT_PUBLIC_ or VITE_ variable, or in your repository.

Step 2: generate the hash on your server

Lower-case the email before hashing. Generate the hash only for the user who is logged in.

Node.js / Next.js (server component, route handler or API route)

import crypto from "node:crypto";

export function customerlyEmailHash(email: string) {
  return crypto
    .createHmac("sha256", process.env.CUSTOMERLY_IDENTITY_SECRET!)
    .update(email.toLowerCase())
    .digest("hex");
}

Supabase Edge Function (Deno)

import { createClient } from "jsr:@supabase/supabase-js@2";

Deno.serve(async (req) => {
  const supabase = createClient(
    Deno.env.get("SUPABASE_URL")!,
    Deno.env.get("SUPABASE_ANON_KEY")!,
    { global: { headers: { Authorization: req.headers.get("Authorization")! } } }
  );
  const { data: { user } } = await supabase.auth.getUser();
  if (!user?.email) return new Response("Unauthorized", { status: 401 });

  const key = await crypto.subtle.importKey(
    "raw",
    new TextEncoder().encode(Deno.env.get("CUSTOMERLY_IDENTITY_SECRET")!),
    { name: "HMAC", hash: "SHA-256" },
    false,
    ["sign"]
  );
  const sig = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(user.email.toLowerCase()));
  const email_hash = Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("");

  return Response.json({ email_hash });
});

Python

import hmac, hashlib, os

def customerly_email_hash(email: str) -> str:
    secret = os.environ["CUSTOMERLY_IDENTITY_SECRET"].encode()
    return hmac.new(secret, email.lower().encode(), hashlib.sha256).hexdigest()

PHP

hash_hmac("sha256", strtolower($email), $secret);

Step 3: pass the hash to the live chat

Add email_hash next to the email in load() or update().

customerly.load({
  app_id: "ADD YOUR PROJECT ID",
  user_id: "REPLACE WITH YOUR USER ID",
  name: "REPLACE WITH USER NAME",
  email: "REPLACE WITH USER EMAIL",
  email_hash: "HASH FROM YOUR SERVER"
});

React and Next.js (react-live-chat-customerly): update({ user_id, email, email_hash, name, attributes }). See Install Customerly in React and Next.js.

Step 4: turn verification on, in this order

  1. Deploy the code that sends email_hash for every logged-in user.

  2. Check a few conversations from logged-in users: they arrive with the right user information.

  3. Only then ask support to enable Identity Verification.

⚠️ Once Identity Verification is enabled, users without a valid email_hash can no longer authenticate in the chat.

Verify that it works

Start a new conversation as a logged-in, verified user and check in your inbox that it arrived with the right name, email and attributes.

Did this article help you solve your issue?