Connect your sign-in
Write the identify function that tells the helpdesk who is calling, from your own session, Better Auth, Auth.js, Clerk or Supabase Auth.
Better Helpdesk has no login of its own. On every request that needs to know who is calling, it calls identify(request), a function you write, and your function answers from your app's session. This guide writes it in lib/identify.ts and passes it to buildHelpdesk. Identity and trust explains what the helpdesk does with the answer.
What identify returns
identify returns null when nobody is signed in, and otherwise an identity:
type Identity = {
user: {
id: string;
email?: string | null;
emailVerified?: boolean;
name?: string | null;
locale?: string | null;
image?: string | null;
};
orgs: { id: string; name?: string }[];
isAgent: boolean;
};Three fields carry trust, and each has to be honest:
isAgent: trueopens the agent UI and every agent route. Nothing else in the helpdesk grants it, so set it from whatever marks your support team, such as a role.orgsdecides which shared conversations a customer can read. List only the organizations the user is an active member of: not one they were invited to and have not joined, and not one they have left.emailVerified: truetells the helpdesk your app has proven the address. Set it only when that is so, because the helpdesk trusts a verified address: it can merge contacts that share it, and messages from it count as proven.
Identity in the configuration reference describes every field.
Write identify
Read the session the way the rest of your app does. This example assumes a getSession that returns the user, with a role and the time their address was confirmed, and their memberships:
import type { Identity } from 'better-helpdesk';
import { getSession } from '@/lib/session';
export async function identify(request: Request): Promise<Identity | null> {
const session = await getSession(request);
if (!session) return null;
const { user } = session;
return {
user: {
id: user.id,
email: user.email,
emailVerified: user.emailVerifiedAt !== null,
name: user.name,
},
orgs: session.memberships
.filter(membership => membership.status === 'active')
.map(membership => ({ id: membership.orgId, name: membership.orgName })),
isAgent: user.role === 'support',
};
}user.id should be the id your app already uses for the person. The helpdesk keys their contact to it, so their conversations follow them from device to device.
Pass it to the helpdesk
import { identify } from '@/lib/identify';
export const helpdesk = buildHelpdesk({
// ...
identify,
});The helpdesk calls identify on every agent request and on nearly every widget request, so keep it to the lookups your own pages do. A change in your app, such as someone leaving an organization or the support team, takes effect on their next request.
Check it
Open the widget while signed in as a customer and send a message. The agent UI shows the conversation under that customer's name and the address identify returned. Then open /helpdesk/ as someone your identify makes an agent; anyone else gets no agent UI.
On another origin
identify sees your session because the widget's requests carry your session cookie. On another origin they do not, and identify returns null there. To let the widget know a signed-in customer on a marketing site or a separate frontend, follow Sign customers in from another origin.