Add and remove agents
Give someone the agent UI, and when they leave, stop their agent email, hand their conversations back to the team, and make sure they lose access.
Two things make someone an agent. Your app grants access: identify returns isAgent: true for them. The helpdesk keeps a record: the first time they open the agent UI, they join its team, and from then on they receive agent email and can be assigned conversations. Adding an agent takes the first; removing one means undoing both.
Add an agent
Return isAgent: true from identify for the user, by whatever role or flag your app keeps:
identify: async request => {
const user = await getSessionUser(request); // however your app does it
if (!user) return null;
return {
user: { id: user.id, email: user.email, name: user.name, image: user.avatarUrl },
orgs: [],
isAgent: user.role === 'support',
};
},Nothing else is needed. Their first request to the agent UI adds them to the team with the name, email address and image identify gives, and every later request brings those up to date. Until then they are not in the Team list and cannot be assigned. Connect your sign-in covers identify as a whole.
Roles
Every agent can do everything unless your identify says otherwise through role:
return {
user: { id: user.id, email: user.email, name: user.name },
orgs: [],
isAgent: user.role !== 'member',
role: user.role === 'support-lead' ? 'supervisor' : user.role === 'auditor' ? 'viewer' : 'agent',
};| Role | May |
|---|---|
agent | Work the queue: everything the agent UI offers. The default. |
supervisor | The same, and receives every SLA warning and breach. Once any supervisor exists, supervisors alone change Settings, remove agents and read the audit log. |
viewer | Read everything and change nothing. The agent UI says so at the top and shows no composer, no editable properties, no bulk bar and no create, edit or delete button anywhere; the routes refuse a change with 403 all the same. Their own away time, read marks and saved views still work. |
The role is read on every agent request, like the name, so a change in your app applies at once. The Audit log section lists every change made through the agent UI, with who made it, what it was, the conversation, contact or company it touched, and the names of the fields sent. It is grouped by day, and changes one agent made to one thing within half an hour share a row that opens to list each of them. It shows 25 entries a page, with Newer and Older to move between pages, and a menu narrows it to one team member. Typing indicators and read marks are not recorded. audit_log has the columns.
Take away access in your app
Stop returning isAgent: true for the user, by whatever role or flag your identify reads. From their next request on, the agent API refuses them with 403. Nothing in the helpdesk can take this step for you, because only your app knows who is on the team.
Remove them from the helpdesk's team
Call removeAgent with the user's id in your app, where you take the role away:
'use server';
import { helpdesk } from '@/lib/helpdesk';
export async function revokeSupportRole(userId: string) {
const me = await requireAdmin(); // your app's own check
if (!me) throw new Error('Forbidden');
await setUserRole(userId, 'member'); // however your app does it
await helpdesk.removeAgent(userId);
}A server action is a public POST endpoint that anyone can call with any userId, so it has to check who is calling before it changes a role.
An agent can do the same for a colleague in the agent UI: under Settings, in the Team list, choose Remove next to their name, then confirm with "Remove and unassign?". Agents cannot remove themselves there.
Removing someone:
- hands every conversation assigned to them back to the team, and records the change in each conversation's history;
- stops the emails about new conversations, reminders and mentions;
- takes them out of the Team list and the choices for assignee and deal owner;
- takes them out of the agents the widget and the receipt email show to customers.
It is safe to call for a user who never was an agent, or was removed already; nothing happens.
If they come back
Removal holds only while your app agrees. The next time the person makes a request to the agent UI with isAgent: true, they rejoin the team and start receiving agent email again. That is why taking away access in your app matters: removeAgent alone does not lock anyone out. Identity and trust explains why your app, not the helpdesk, decides who is an agent.
Someone who quietly stopped
A host cannot always tell that someone has stopped answering. As a backstop, an agent who has not opened the agent UI for 30 days receives no emails about new conversations or reminders until they open it again, and no longer appears to customers as one of the team. Mentions still reach them. Someone chosen as a recipient under Settings, as below, keeps receiving them.
Choose who gets emails about new requests
By default, emails about new conversations, reopened conversations and reminders go to every agent who opened the agent UI in the last 30 days. Under Settings, Who gets emails about new requests can name the team members instead. They then receive these emails however long ago they last opened the agent UI. Inboxes make no difference: the same people hear about every inbox.
Either way, an assigned conversation notifies only its assignee, and a mention only the colleague named. A team member appears in the list once they have opened the agent UI, and one without an email address cannot be picked. If everyone chosen has since been removed or has no email address, the emails go back to everyone who opened the agent UI in the last 30 days, so a new request never reaches nobody. Once any agent has the supervisor role, only supervisors change this.