AI agents in your chat
Add an AI agent to the conversations your users already have
An AI agent in TalkJS is one more participant in a conversation, next to your buyers and sellers, students or teammates. Your server gets each new message through a webhook, asks the model you choose for a reply, and posts it through the REST API as the agent. Everyone stays in one thread, with one history.
// TalkJS webhook handler on your server
// talkjs.com/docs/Webhooks/
if (event.type === "message.sent") {
const { sender, conversation, message, mentionedUserIds } =
event.data;
// Answer when mentioned, never answer itself
if (sender.id !== AGENT_ID &&
mentionedUserIds.includes(AGENT_ID)) {
replyAsAgent(conversation.id, message);
}
}How an AI agent joins a conversation
We don't ship the AI. You bring the model, and we give it a place in the conversation. It takes three steps:
- Create the agent once as a TalkJS user, with a name and an avatar, and add it as a participant to the conversations it should join. Like any new participant, it can read the messages sent before it joined.
- Turn on webhooks in your dashboard and select the
message.sentevent. For every new message, TalkJS then sends your server that event, with the sender, the conversation and the IDs of anyone mentioned. - Your server asks your model for an answer and posts it through the REST API, with the agent as the sender. Everyone in the conversation sees it in the same thread and gets the same notifications as for any other message.
The code here is your server's side of steps 2 and 3, in Node.js. For the details, read the AI agent interface docs, or start from a sample project for ChatGPT, Claude or Gemini.
// Node.js 18+ and Express, TalkJS REST API v1.
// Docs: talkjs.com/docs/Webhooks/
// talkjs.com/docs/REST_API/Messages/
const AGENT_ID = "assistant";
// In production, first check the X-TalkJS-Signature header
// against the raw request body:
// talkjs.com/docs/Features/Security/
app.post("/talkjs-webhook", express.json(), (req, res) => {
// Send the 200 first: TalkJS waits 5 seconds for it
res.sendStatus(200);
const event = req.body;
if (event.type !== "message.sent") return;
const { sender, conversation, message, mentionedUserIds } =
event.data;
// Never answer itself
if (sender.id === AGENT_ID) return;
// Only answer when mentioned
if (!mentionedUserIds.includes(AGENT_ID)) return;
replyAsAgent(conversation.id, message).catch(console.error);
});
async function replyAsAgent(conversationId, message) {
const url = "https://api.talkjs.com/v1/" + APP_ID +
"/conversations/" + conversationId + "/messages";
const headers = {
// An admin token: talkjs.com/docs/REST_API/
Authorization: "Bearer " + createAdminToken(),
"Content-Type": "application/json",
};
// Post "Thinking..." right away. With the incoming
// message's ID as idempotencyKey, a retried webhook
// can't post it twice.
const [placeholder] = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify([{
text: "_Thinking..._",
sender: AGENT_ID,
type: "UserMessage",
idempotencyKey: message.id,
}]),
}).then((res) => res.json());
// Your model: ChatGPT, Claude, Gemini, or your own
const answer = await askYourModel(message.text);
// Replace the placeholder with the answer
await fetch(url + "/" + placeholder.id, {
method: "PUT",
headers,
body: JSON.stringify({ text: answer }),
});
}Decide when and how the agent speaks
In a chat between people, an agent that answers every message gets in the way. Your handler decides when it speaks and how, and TalkJS already gives you what each of these rules needs:
- Answer when mentioned. Turn on Allow mentions on the Chat UI page of your dashboard, so people can type @ and pick the agent. Each
message.sentevent lists the mentioned users inmentionedUserIds. Reply only when the agent is in that list. (In a one-on-one chat with the agent, drop this rule.) - Never answer itself. Skip any event whose sender is the agent, so it doesn't reply to its own messages in a loop.
- Never post twice. TalkJS retries a webhook that doesn't get a 200 in time. Use the incoming message's ID as the
idempotencyKeyof the agent's message, and TalkJS sends it exactly once, however often the webhook arrives. - Show it's working. Models take a few seconds. Post a short "Thinking..." message as soon as the agent is asked, then edit it with the answer.
- Hand over to a person. When a seller or someone on your team takes over, remove the agent from the conversation with one REST call. Or have your handler stay quiet once someone from your team speaks: every event carries the sender's role and the list of participants.
To give your model context, your server can fetch the latest messages in the conversation from the REST API. Choose what your model sees, and treat your users' messages as text from people, not as instructions for your model. A buyer who types "ignore your previous instructions" is still a buyer.
Show the conversation in your app
Your users see the agent's replies in the same TalkJS chat UI as everyone else's. Tell us which conversation to display, who's chatting, and where to show it on the page.
Building in React? See how to build a chat UI for an AI agent in React.
import { Session, Chatbox } from "@talkjs/react";
<Session appId="t824ba8" userId="pete">
<Chatbox conversation="workshop" className="chatbox"/>
</Session>Where an AI agent helps your users
In a buyer-seller chat, the agent answers questions about the listing, delivery or an order when either side mentions it. The seller stays in the conversation and sees every answer.
In a community, team or class chat, people mention the agent when they need it: to look something up, summarize a long thread, or answer a question about the course.
Building a chatbot that talks to one user at a time? Use the same chat UI for a one-on-one assistant.
Customize everything and anything
TalkJS provides prebuilt themes you can use right away or customize to match your brand’s design and user experience.
Themes give you complete control over how your chat looks and feels—from overall layout and message styling to fonts, colors, and interactive elements. You can fine-tune every visual detail, extend functionality, or design a fully bespoke chat interface.
Whether you start from a default theme or build your own, TalkJS provides a flexible foundation to create a consistent and responsive chat experience within your product.
We didn‘t want to make our own chat widget as you guys already made a fantastic product that we can use out of the box. We want to focus on making AI answers excellent.
Use any model
The agent is your code, so it can call any model: a hosted LLM, an open model you run yourself, or your own retrieval pipeline. TalkJS only carries the messages.
Included on every plan
The AI agent interface, webhooks and the REST API come with every TalkJS plan. The Basic plan includes one webhook endpoint, and one is all an agent needs. And if you get stuck, you can chat directly with a TalkJS developer for hands-on support.
