Automatic content moderation with PENDING → APPROVED / DISAPPROVED flow
// Listen for real-time AI Agent events (streaming)CometChat.addAIAssistantListener("LISTENER_ID", { onAIAssistantEventReceived: (event) => console.log("Event:", event)});// Listen for persisted agentic messagesCometChat.addMessageListener("LISTENER_ID", new CometChat.MessageListener({ onAIAssistantMessageReceived: (msg) => console.log("Assistant reply:", msg), onAIToolResultReceived: (msg) => console.log("Tool result:", msg), onAIToolArgumentsReceived: (msg) => console.log("Tool args:", msg)}));// CleanupCometChat.removeAIAssistantListener("LISTENER_ID");CometChat.removeMessageListener("LISTENER_ID");
Prerequisites:CometChat.init() + CometChat.login() completed, AI features enabled in DashboardEvent flow: Run Start → Tool Call(s) → Text Message Stream → Run Finished
AI Agents enable intelligent, automated interactions within your application. They process user messages, trigger tools, and respond with contextually relevant information. For a broader introduction, see the AI Agents section.
Events are received via the onAIAssistantEventReceived method of the AIAssistantListener class as AIAssistantBaseEvent objects, in this general order:Events arrive via onAIAssistantEventReceived in this order:
Order
Event
Description
1
Run Start
A new run has begun
2
Tool Call Start
Agent decided to invoke a tool
3
Tool Call Arguments
Arguments being passed to the tool
4
Tool Call End
Tool execution completed
5
Tool Call Result
Tool’s output is available
6
Card Start
Agent started generating a card
7
Card
Full card payload is available
8
Card End
Card generation is complete
9
Text Message Start
Agent started composing a reply
10
Text Message Content
Streaming content chunks (multiple)
11
Text Message End
Agent reply is complete
12
Run Finished
Run finalized; persisted messages follow
Run Start and Run Finished are always emitted. Tool Call events only appear when tools are invoked — there can be multiple tool call cycles in a single run. Card events (Card Start → Card → Card End) only appear when the agent produces a card, and may repeat for each card. Text Message events are always emitted and carry the assistant’s reply incrementally.
When the agent generates a card, the run emits a card cycle (Card Start → Card → Card End). All three are AIAssistantBaseEvent subclasses delivered through the same onAIAssistantEventReceived callback — no separate listener is required.
The getToolCalls() method on AIToolArgumentMessage returns an array of AIToolCall objects, each with:
Getter
Return Type
Description
getId()
string
Unique tool call ID
getType()
string
Tool call type
getFunction()
AIToolCallFunction
Function object with getName() and getArguments()
getDisplayName()
string
Display name of the tool
getExecutionText()
string
Execution description text
TypeScript
JavaScript
const listnerId: string = "unique_listener_id";// Adding the MessageListenerCometChat.addMessageListener(listnerId, { onAIAssistantMessageReceived: (message: CometChat.AIAssistantMessage) => { console.log("AI Assistant message received successfully", message); }, onAIToolResultReceived: (message: CometChat.AIToolResultMessage) => { console.log("AI Tool result message received successfully", message); }, onAIToolArgumentsReceived: (message: CometChat.AIToolArgumentMessage) => { console.log("AI Tool argument message received successfully", message); },});// Removing the MessageListenerCometChat.removeMessageListener(listnerId);
const listnerId = "unique_listener_id";// Adding the MessageListenerCometChat.addMessageListener(listnerId, { onAIAssistantMessageReceived: (message) => { console.log("AI Assistant message received successfully", message); }, onAIToolResultReceived: (message) => { console.log("AI Tool result message received successfully", message); }, onAIToolArgumentsReceived: (message) => { console.log("AI Tool argument message received successfully", message); },});// Removing the MessageListenerCometChat.removeMessageListener(listnerId);
Always remove listeners when they’re no longer needed (e.g., on component unmount or page navigation). Failing to remove listeners can cause memory leaks and duplicate event handling.
Starting from React Native SDK 4.0.26, a persisted AIAssistantMessage carries its content as an ordered list of blocks via getElements(). This is the preferred render source — when present, walk the list in order and render each block. If the agent response contains only a card (no accompanying text), the text returned by getAssistantMessageData().getText() will be empty, so always prefer getElements().getElements() returns an array of AIAssistantElement (or null for older messages without elements). Each element exposes:
Method
Return Type
Description
getType()
string
The block type, e.g. "text" or "card". Determines the shape of getData().
getData()
string | object
The block’s raw body. "text" → string; "card" → { card, cardId }; other types → raw JSON value. The SDK never interprets this — it returns the value as-is.
TypeScript
JavaScript
function handleAIAssistantMessage(message: CometChat.AIAssistantMessage) { const elements = message.getElements(); if (elements && elements.length > 0) { // Preferred path: walk elements in order elements.forEach((element: CometChat.AIAssistantElement) => { switch (element.getType()) { case "text": console.log("Text block:", element.getData()); break; case "card": { const { card, cardId } = element.getData() as { card: object; cardId: string; }; console.log("Card block:", cardId); // Pass card to your card renderer break; } default: console.log("Unknown element type:", element.getType()); } }); } else { // Fallback for older messages without elements console.log("Message text:", message.getAssistantMessageData().getText()); }}
function handleAIAssistantMessage(message) { const elements = message.getElements(); if (elements && elements.length > 0) { elements.forEach((element) => { switch (element.getType()) { case "text": console.log("Text block:", element.getData()); break; case "card": { const { card, cardId } = element.getData(); console.log("Card block:", cardId); // Pass card to your card renderer break; } default: console.log("Unknown element type:", element.getType()); } }); } else { console.log("Message text:", message.getAssistantMessageData().getText()); }}