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

# Message Structure and Hierarchy

> Understand the message categories, types, and hierarchy in the CometChat React Native SDK including text, media, custom, card, action, and call messages.

<Accordion title="AI Integration Quick Reference">
  Message categories and types:

  * **message** → `text`, `image`, `video`, `audio`, `file`
  * **custom** → Developer-defined types (e.g., `location`, `poll`)
  * **card** → `CardMessage` (receive-only rich cards)
  * **action** → `groupMember` (joined/left/kicked/banned), `message` (edited/deleted)
  * **call** → `audio`, `video`
</Accordion>

Every message in CometChat belongs to a category (`message`, `custom`, `card`, `action`, `call`) and has a specific type within that category.

## Message Hierarchy

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-llms-scoped-indexes/i4Q5Nw9DEcclqV3C/images/message-structure-hierarchy-card.svg?fit=max&auto=format&n=i4Q5Nw9DEcclqV3C&q=85&s=36e940e7efbfa17c8c803c9eb2cd88d3" width="1366" height="800" data-path="images/message-structure-hierarchy-card.svg" />
</Frame>

## Categories Overview

| Category | Types | Description |
| - | - | - |
| `message` | `text`, `image`, `video`, `audio`, `file` | Standard user messages |
| `custom` | Developer-defined | Custom data (location, polls, etc.) |
| `card` | `CardMessage` | Receive-only rich, structured cards |
| `action` | `groupMember`, `message` | System-generated events |
| `call` | `audio`, `video` | Call-related messages |

## Checking Message Category and Type

Use `getCategory()` and `getType()` to determine how to handle a received message:

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const category: string = message.getCategory();
    const type: string = message.getType();

    switch (category) {
      case CometChat.CATEGORY_MESSAGE:
        if (type === CometChat.MESSAGE_TYPE.TEXT) {
          const textMsg = message as CometChat.TextMessage;
          console.log("Text:", textMsg.getText());
        } else if (type === CometChat.MESSAGE_TYPE.IMAGE) {
          const mediaMsg = message as CometChat.MediaMessage;
          console.log("Image URL:", mediaMsg.getData().url);
        }
        break;
      case CometChat.CATEGORY_CUSTOM:
        const customMsg = message as CometChat.CustomMessage;
        console.log("Custom type:", type, "data:", customMsg.getData());
        break;
      case CometChat.CATEGORY_ACTION:
        console.log("Action:", message.getAction());
        break;
      case CometChat.CATEGORY_CALL:
        console.log("Call status:", message.getStatus());
        break;
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const category = message.getCategory();
    const type = message.getType();

    switch (category) {
      case CometChat.CATEGORY_MESSAGE:
        if (type === CometChat.MESSAGE_TYPE.TEXT) {
          console.log("Text:", message.getText());
        } else if (type === CometChat.MESSAGE_TYPE.IMAGE) {
          console.log("Image URL:", message.getData().url);
        }
        break;
      case CometChat.CATEGORY_CUSTOM:
        console.log("Custom type:", type, "data:", message.getData());
        break;
      case CometChat.CATEGORY_ACTION:
        console.log("Action:", message.getAction());
        break;
      case CometChat.CATEGORY_CALL:
        console.log("Call status:", message.getStatus());
        break;
    }
    ```
  </Tab>
</Tabs>

## Standard Messages (`message` Category)

Messages with category `message` are standard user-sent messages:

| Type | Description |
| - | - |
| `text` | Plain text message |
| `image` | Image attachment |
| `video` | Video attachment |
| `audio` | Audio attachment |
| `file` | File attachment |

## Custom Messages (`custom` Category)

Custom messages allow you to send data that doesn't fit the default categories. You define your own type to identify the message (e.g., `location`, `poll`, `sticker`).

```javascript theme={null}
// Example: Sending a location as a custom message
const customMessage = new CometChat.CustomMessage(
  receiverID,
  CometChat.RECEIVER_TYPE.USER,
  "location",
  { latitude: 37.7749, longitude: -122.4194 }
);
```

See [Send Message → Custom Messages](/sdk/react-native/send-message#custom-message) for details.

## Card Messages (`card` Category)

A message with category `card` is a [`CardMessage`](/sdk/react-native/campaigns#card-messages) — a rich, structured card rendered from Card Schema JSON.

Card messages are **receive-only**: they cannot be sent from the SDK. They are created and sent exclusively via the **Platform (REST) API** or the **Dashboard Bubble Builder**, and delivered through the `onCardMessageReceived` callback of the `MessageListener`.

| Method | Return Type | Description |
| - | - | - |
| `getCard()` | object | The raw Card Schema JSON payload. Pass it to the [`CometChatCardView`](/sdk/react-native/campaigns#rendering-cards) renderer. |
| `getText()` | string | Preview text for notifications and the conversation list. |
| `getFallbackText()` | string | Fallback text used for accessibility or when the renderer fails. |
| `getTags()` | `Array<string>` | Tags associated with the message. |

See [Receive Messages → Card Messages](/sdk/react-native/receive-messages#card-messages) and [Campaigns → Card Messages](/sdk/react-native/campaigns#card-messages) for details.

## Action Messages (`action` Category)

Action messages are system-generated events. They have a `type` and an `action` property:

**Type: `groupMember`** — Actions on group members:

* `joined` — Member joined the group
* `left` — Member left the group
* `kicked` — Member was kicked
* `banned` — Member was banned
* `unbanned` — Member was unbanned
* `added` — Member was added
* `scopeChanged` — Member's scope was changed

**Type: `message`** — Actions on messages:

* `edited` — Message was edited
* `deleted` — Message was deleted

## Call Messages (`call` Category)

Call messages track call events with types `audio` or `video`. The `status` property indicates the call state:

| Status | Description |
| - | - |
| `initiated` | Call started |
| `ongoing` | Call accepted and in progress |
| `canceled` | Caller canceled |
| `rejected` | Receiver rejected |
| `unanswered` | No answer |
| `busy` | Receiver on another call |
| `ended` | Call completed |

See [Default Calling](/sdk/react-native/default-call) or [Direct Calling](/sdk/react-native/direct-call) for implementation.

***

## Next Steps

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

  <Card title="Receive Messages" icon="envelope-open" href="/sdk/react-native/receive-messages">
    Listen for incoming messages in real time
  </Card>

  <Card title="Card Messages" icon="id-card" href="/sdk/react-native/campaigns#card-messages">
    Receive and render rich, structured card messages
  </Card>

  <Card title="Message Filtering" icon="filter" href="/sdk/react-native/additional-message-filtering">
    Advanced message filtering with RequestBuilder
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.