Setting Up Identity Verification for Web and Mobile on Customerly

Raluca Stoica
Written by Raluca StoicaLast updated 16 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?