> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-rn-guide-message-privately.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# AI Moderation

> Automatically moderate chat messages using AI to detect and block inappropriate content in real-time.

<Accordion title="AI Integration Quick Reference">
  ```javascript theme={null}
  let textMessage = new CometChat.TextMessage("UID", "Hello", CometChat.RECEIVER_TYPE.USER);

  // Send message — check moderation status
  CometChat.sendMessage(textMessage).then(message => {
    const status = message.getModerationStatus();
    // CometChat.ModerationStatus.PENDING | APPROVED | DISAPPROVED
  });

  // Listen for moderation results
  CometChat.addMessageListener("MOD_LISTENER", new CometChat.MessageListener({
    onMessageModerated: (message) => {
      const status = message.getModerationStatus();
      // Handle APPROVED or DISAPPROVED
    }
  }));
  ```

  **Supported types:** Text, Image, Video messages only
  **Statuses:** `PENDING` → `APPROVED` or `DISAPPROVED`
</Accordion>

AI Moderation automatically reviews messages for inappropriate content in real-time. When a user sends a text, image, or video message, it's held in a `PENDING` state while the moderation service analyzes it, then marked as `APPROVED` or `DISAPPROVED` via the `onMessageModerated` event.

`getModerationStatus()` is available on [`TextMessage`](/sdk/reference/messages#textmessage) and [`MediaMessage`](/sdk/reference/messages#mediamessage) objects. Custom messages are not subject to moderation.

<Note>
  For configuring moderation rules and managing flagged messages from the dashboard, see the [Moderation Overview](/moderation/overview).
</Note>

## Prerequisites

1. Moderation enabled in the [CometChat Dashboard](https://app.cometchat.com)
2. Moderation rules configured under **Moderation > Rules**
3. CometChat SDK version that supports moderation

## How It Works

```mermaid theme={null}
sequenceDiagram
    participant App
    participant SDK
    participant CometChat
    participant Moderation

    App->>SDK: sendMessage()
    SDK->>CometChat: Send Message
    CometChat->>Moderation: Process Message
    CometChat-->>SDK: Message (status: PENDING)
    SDK-->>App: onMessageSent (PENDING)
    Moderation-->>CometChat: Moderation Result
    CometChat-->>SDK: onMessageModerated
    SDK-->>App: APPROVED or DISAPPROVED
```

| Step              | Description                                        |
| ----------------- | -------------------------------------------------- |
| 1. Send Message   | App sends a text, image, or video message          |
| 2. Pending Status | Message is sent with `PENDING` moderation status   |
| 3. AI Processing  | Moderation service analyzes the content            |
| 4. Result Event   | `onMessageModerated` event fires with final status |

## Supported Message Types

Moderation is triggered **only** for the following message types:

| Message Type    | Moderated | Notes                                   |
| --------------- | --------- | --------------------------------------- |
| Text Messages   | ✅         | Content analyzed for inappropriate text |
| Image Messages  | ✅         | Images scanned for unsafe content       |
| Video Messages  | ✅         | Videos analyzed for prohibited content  |
| Custom Messages | ❌         | Not subject to AI moderation            |
| Action Messages | ❌         | Not subject to AI moderation            |

## Moderation Status

The `getModerationStatus()` method returns one of the following values:

| Status      | Enum Value                               | Description                                     |
| ----------- | ---------------------------------------- | ----------------------------------------------- |
| Pending     | `CometChat.ModerationStatus.PENDING`     | Message is being processed by moderation        |
| Approved    | `CometChat.ModerationStatus.APPROVED`    | Message passed moderation and is visible        |
| Disapproved | `CometChat.ModerationStatus.DISAPPROVED` | Message violated rules and was blocked          |
| Unmoderated | `CometChat.ModerationStatus.UNMODERATED` | Message was not subject to moderation (default) |

## Implementation

### Step 1: Send a Message and Check Initial Status

When you send a text, image, or video message, check the initial moderation status:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const textMessage = new CometChat.TextMessage(
      receiverUID,
      "Hello, how are you?",
      CometChat.RECEIVER_TYPE.USER
    );

    CometChat.sendMessage(textMessage).then(
      (message: CometChat.TextMessage) => {
        // Check moderation status
        const status: string = message.getModerationStatus();
        
        if (status === CometChat.ModerationStatus.PENDING) {
          console.log("Message is under moderation review");
          // Show pending indicator in UI
        }
      },
      (error: CometChat.CometChatException) => {
        console.log("Message sending failed:", error);
      }
    );
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const textMessage = new CometChat.TextMessage(
      receiverUID,
      "Hello, how are you?",
      CometChat.RECEIVER_TYPE.USER
    );

    CometChat.sendMessage(textMessage).then(
      (message) => {
        // Check moderation status
        const status = message.getModerationStatus();
        
        if (status === CometChat.ModerationStatus.PENDING) {
          console.log("Message is under moderation review");
          // Show pending indicator in UI
        }
      },
      (error) => {
        console.log("Message sending failed:", error);
      }
    );
    ```
  </Tab>
</Tabs>

### Step 2: Listen for Moderation Results

Register a message listener to receive moderation results in real-time. The `onMessageModerated` callback receives a [`BaseMessage`](/sdk/reference/messages#basemessage) object:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const listenerID: string = "MODERATION_LISTENER";

    CometChat.addMessageListener(
      listenerID,
      new CometChat.MessageListener({
        onMessageModerated: (message: CometChat.BaseMessage) => {
          if (
            message instanceof CometChat.TextMessage ||
            message instanceof CometChat.MediaMessage
          ) {
            const status: string = message.getModerationStatus();
            const messageId: number = message.getId();

            switch (status) {
              case CometChat.ModerationStatus.APPROVED:
                console.log(`Message ${messageId} approved`);
                // Update UI to show message normally
                break;

              case CometChat.ModerationStatus.DISAPPROVED:
                console.log(`Message ${messageId} blocked`);
                // Handle blocked message (hide or show warning)
                handleDisapprovedMessage(message);
                break;
            }
          }
        }
      })
    );

    // Don't forget to remove the listener when done
    // CometChat.removeMessageListener(listenerID);
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const listenerID = "MODERATION_LISTENER";

    CometChat.addMessageListener(
      listenerID,
      new CometChat.MessageListener({
        onMessageModerated: (message) => {
          if (
            message instanceof CometChat.TextMessage ||
            message instanceof CometChat.MediaMessage
          ) {
            const status = message.getModerationStatus();
            const messageId = message.getId();

            switch (status) {
              case CometChat.ModerationStatus.APPROVED:
                console.log(`Message ${messageId} approved`);
                // Update UI to show message normally
                break;

              case CometChat.ModerationStatus.DISAPPROVED:
                console.log(`Message ${messageId} blocked`);
                // Handle blocked message (hide or show warning)
                handleDisapprovedMessage(message);
                break;
            }
          }
        }
      })
    );

    // Don't forget to remove the listener when done
    // CometChat.removeMessageListener(listenerID);
    ```
  </Tab>
</Tabs>

### Step 3: Handle Disapproved Messages

When a message is disapproved, you should handle it appropriately in your UI:

```javascript theme={null}
function handleDisapprovedMessage(message) {
  const messageId = message.getId();
  
  // Option 1: Hide the message completely
  hideMessageFromUI(messageId);
  
  // Option 2: Show a placeholder message
  showBlockedPlaceholder(messageId, "This message was blocked by moderation");
  
  // Option 3: Notify the sender (if it's their message)
  if (message.getSender().getUid() === currentUserUID) {
    showNotification("Your message was blocked due to policy violation");
  }
}
```

## Complete Example

Here's a complete implementation showing the full moderation flow:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
        class ModerationHandler {
          constructor() {
            this.pendingMessages = new Map();
            this.setupListener();
          }

          setupListener() {
            CometChat.addMessageListener(
              "MODERATION_LISTENER",
              new CometChat.MessageListener({
                onMessageModerated: (message) => this.onModerated(message)
              })
            );
          }

          async sendMessage(receiverUID, text) {
            const textMessage = new CometChat.TextMessage(
              receiverUID,
              text,
              CometChat.RECEIVER_TYPE.USER
            );

            try {
              const message = await CometChat.sendMessage(textMessage);
              const status = message.getModerationStatus();

              if (status === CometChat.ModerationStatus.PENDING) {
                // Track pending message
                this.pendingMessages.set(message.getId(), message);
                return { success: true, pending: true, message };
              }

              return { success: true, pending: false, message };
            } catch (error) {
              return { success: false, error };
            }
          }

          onModerated(message) {
            const messageId = message.getId();
            const status = message.getModerationStatus();

            // Remove from pending
            this.pendingMessages.delete(messageId);

            // Emit event for UI update
            this.emit("moderationResult", {
              messageId,
              status,
              approved: status === CometChat.ModerationStatus.APPROVED,
              message
            });
          }

          cleanup() {
            CometChat.removeMessageListener("MODERATION_LISTENER");
          }
        }

        // Usage
        const handler = new ModerationHandler();
        const result = await handler.sendMessage("user123", "Hello!");

        if (result.pending) {
          console.log("Message pending moderation...");
        }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
        class ModerationHandler {
          constructor() {
            this.pendingMessages = new Map();
            this.setupListener();
          }

          setupListener() {
            CometChat.addMessageListener(
              "MODERATION_LISTENER",
              new CometChat.MessageListener({
                onMessageModerated: (message) => this.onModerated(message)
              })
            );
          }

          async sendMessage(receiverUID, text) {
            const textMessage = new CometChat.TextMessage(
              receiverUID,
              text,
              CometChat.RECEIVER_TYPE.USER
            );

            try {
              const message = await CometChat.sendMessage(textMessage);
              const status = message.getModerationStatus();

              if (status === CometChat.ModerationStatus.PENDING) {
                // Track pending message
                this.pendingMessages.set(message.getId(), message);
                return { success: true, pending: true, message };
              }

              return { success: true, pending: false, message };
            } catch (error) {
              return { success: false, error };
            }
          }

          onModerated(message) {
            const messageId = message.getId();
            const status = message.getModerationStatus();

            // Remove from pending
            this.pendingMessages.delete(messageId);

            // Emit event for UI update
            this.emit("moderationResult", {
              messageId,
              status,
              approved: status === CometChat.ModerationStatus.APPROVED,
              message
            });
          }

          cleanup() {
            CometChat.removeMessageListener("MODERATION_LISTENER");
          }
        }

        // Usage
        const handler = new ModerationHandler();
        const result = await handler.sendMessage("user123", "Hello!");

        if (result.pending) {
          console.log("Message pending moderation...");
        }
    ```
  </Tab>
</Tabs>

<Warning>
  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.
</Warning>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Flag Message" icon="flag" href="/sdk/react-native/flag-message">
    Allow users to report inappropriate messages manually
  </Card>

  <Card title="AI Agents" icon="robot" href="/sdk/react-native/ai-agents">
    Build intelligent automated conversations with AI Agents
  </Card>

  <Card title="Send Messages" icon="paper-plane" href="/sdk/react-native/send-message">
    Send text, media, and custom messages
  </Card>
</CardGroup>
