Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,7 @@
"ui-kit/react-native/threaded-messages-header",
"ui-kit/react-native/incoming-call",
"ui-kit/react-native/outgoing-call",
"ui-kit/react-native/ongoing-call",
"ui-kit/react-native/call-buttons",
"ui-kit/react-native/call-logs",
"ui-kit/react-native/ai-assistant-chat-history",
Expand All @@ -1211,6 +1212,7 @@
"ui-kit/react-native/guide-search-messages",
"ui-kit/react-native/guide-message-privately",
"ui-kit/react-native/guide-block-unblock-user",
"ui-kit/react-native/custom-message-types",
"ui-kit/react-native/custom-text-formatter-guide",
"ui-kit/react-native/mentions-formatter-guide",
"ui-kit/react-native/url-formatter-guide",
Expand Down
17 changes: 17 additions & 0 deletions sdk/react-native/campaigns.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@
description: "Fetch notification feed items, listen for real-time delivery, mark items as read/delivered, report engagement, and track push notifications using the CometChat React Native SDK."
---

{/* TL;DR for Agents and Quick Reference */}
<Accordion title="AI Integration Quick Reference">

| Field | Value |
| --- | --- |
| Package | `@cometchat/chat-sdk-react-native` |
| Import | `import { CometChat } from "@cometchat/chat-sdk-react-native";` |
| Key Methods | `addNotificationFeedListener()`, `getNotificationFeedItem()`, `getNotificationFeedUnreadCount()`, `markFeedItemAsRead()`, `markFeedItemAsDelivered()`, `markPushNotificationDelivered()`, `markPushNotificationClicked()`, `reportFeedEngagement()` |
| Key Classes | `NotificationFeedItem`, `NotificationFeedRequest`, `NotificationFeedRequestBuilder`, `NotificationCategoriesRequestBuilder`, `NotificationFeedListener`, `PushNotification` |
| Prerequisites | SDK initialized via [`CometChat.init()`](/sdk/react-native/setup-sdk) and a logged-in user via [`CometChat.login()`](/sdk/react-native/authentication-overview) · channels, categories, templates and campaigns configured in the [dashboard](/campaigns#setup-flow) |
| Primary output | `NotificationFeedRequest.fetchNext()` → `Promise<NotificationFeedItem[]>`; `getNotificationFeedItem()` → `Promise<NotificationFeedItem>`; `getNotificationFeedUnreadCount()` → `Promise<{ count: number }>`; the mark and report methods → `Promise<void>` |
| Constraints | Card messages are receive-only: they are created through the Platform API and the dashboard, never from the SDK. The cards library only renders a card — your own code decides what its actions do. Feed items carry Card Schema JSON, so render them with the cards library rather than reading the payload by hand. |
| Related | [Notification Feed component](/ui-kit/react-native/notification-feed) · [Dashboard setup](/campaigns#setup-flow) · [Card Builder](/card-builder/overview) · [Real-time Listeners](/sdk/react-native/real-time-listeners#message-listener) |
| Full reference | [NotificationFeedItem fields](#notificationfeeditem-fields) · [NotificationCategory fields](#notificationcategory-fields) |

</Accordion>

CometChat Campaigns lets you deliver targeted, rich notifications to users via an in-app notification feed. Each notification is a **Card Schema JSON** — a structured layout rendered natively by the CometChat Cards library.

The SDK provides APIs to fetch feed items, listen for real-time delivery, mark items as read/delivered, report engagement, and retrieve unread counts.
Expand Down Expand Up @@ -153,7 +170,7 @@
<Tabs>
<Tab title="JavaScript">
```javascript
const categoriesRequest = new CometChat.NotificationCategoriesRequestBuilder()

Check warning on line 173 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L173

Did you really mean 'categoriesRequest'?
.setLimit(50)
.build();

Expand Down Expand Up @@ -389,7 +406,7 @@
<Tabs>
<Tab title="JavaScript">
```javascript
const pushNotification = new CometChat.PushNotification(pushPayloadJson);

Check warning on line 409 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L409

Did you really mean 'pushNotification'?

CometChat.markPushNotificationDelivered(pushNotification).then(
() => { /* Success */ },
Expand Down Expand Up @@ -485,10 +502,10 @@
// Open URL in browser
break;
case "chatWithUser":
// Navigate to chat with event.params.uid

Check warning on line 505 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L505

Did you really mean 'uid'?
break;
case "chatWithGroup":
// Navigate to group chat with event.params.guid

Check warning on line 508 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L508

Did you really mean 'guid'?
break;
}
}}
Expand All @@ -509,15 +526,15 @@

| Action Type | Parameters | Description |
| --- | --- | --- |
| `openUrl` | url, openIn | Open a URL in browser or webview |

Check warning on line 529 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L529

Did you really mean 'openIn'?

Check warning on line 529 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L529

Did you really mean 'webview'?
| `chatWithUser` | uid | Navigate to 1:1 chat |
| `chatWithGroup` | guid | Navigate to group chat |
| `sendMessage` | text, receiverUid, receiverGuid | Send a text message |

Check warning on line 532 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L532

Did you really mean 'receiverUid'?

Check warning on line 532 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L532

Did you really mean 'receiverGuid'?
| `copyToClipboard` | value | Copy text to clipboard |
| `downloadFile` | url, filename | Download a file |
| `initiateCall` | callType (audio/video), uid, guid | Start a call |

Check warning on line 535 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L535

Did you really mean 'callType'?

Check warning on line 535 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L535

Did you really mean 'uid'?

Check warning on line 535 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L535

Did you really mean 'guid'?
| `apiCall` | url, method, headers, body | Make an HTTP request |
| `customCallback` | callbackId, payload | App-specific logic |

Check warning on line 537 in sdk/react-native/campaigns.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/campaigns.mdx#L537

Did you really mean 'callbackId'?

---

Expand Down
12 changes: 12 additions & 0 deletions sdk/react-native/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
{/* TL;DR for Agents and Quick Reference */}
<Accordion title="AI Integration Quick Reference">

| Field | Value |
| --- | --- |
| Package | `@cometchat/chat-sdk-react-native` |
| Import | `import { CometChat } from "@cometchat/chat-sdk-react-native";` |
| Key Methods | `init()`, `login()`, `getLoggedinUser()` |
| Key Classes | `AppSettings`, `AppSettingsBuilder`, `User`, `CometChatException` |
| Prerequisites | An App ID, Region and Auth Key from the [CometChat Dashboard](https://app.cometchat.com) · React Native 0.63+, Android `minSdkVersion` 24, iOS 11.0 |
| Primary output | `init()` → `Promise<boolean>`; `login()` → `Promise<CometChat.User>`; `getLoggedinUser()` → `Promise<CometChat.User \| null>` |
| Constraints | Call `init()` once, before any other SDK call, and log a user in before sending or fetching anything. `getLoggedinUser()` resolves to `null` when nobody is logged in. Use the Auth Key for development only; log users in with an Auth Token in production. |
| Related | [Setup SDK](/sdk/react-native/setup-sdk) · [Authentication](/sdk/react-native/authentication-overview) · [Key Concepts](/sdk/react-native/key-concepts) · [Send a Message](/sdk/react-native/send-message) |
| Full reference | [`User`](/sdk/reference/entities#user) · [`CometChatException`](/sdk/reference/auxiliary#cometchatexception) |

```bash
npm install @cometchat/chat-sdk-react-native
```
Expand All @@ -31,7 +43,7 @@
```

**Credentials:** App ID, Region, Auth Key from [CometChat Dashboard](https://app.cometchat.com)
**Test UIDs:** `cometchat-uid-1` through `cometchat-uid-5`

Check warning on line 46 in sdk/react-native/overview.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/overview.mdx#L46

Did you really mean 'UIDs'?
</Accordion>

The CometChat React Native SDK lets you add real-time messaging, voice, and video calling to any React Native application.
Expand Down
12 changes: 12 additions & 0 deletions sdk/react-native/pin-conversation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
{/* TL;DR for Agents and Quick Reference */}
<Accordion title="AI Integration Quick Reference">

| Field | Value |
| --- | --- |
| Package | `@cometchat/chat-sdk-react-native` |
| Import | `import { CometChat } from "@cometchat/chat-sdk-react-native";` |
| Key Methods | `pinConversation()`, `unpinConversation()`, `isPinConversationEnabled()`, `getPinConversationLimit()`, `getSystemPinConversationLimit()` |
| Key Classes | `Conversation`, `ConversationsRequest`, `ConversationsRequestBuilder`, `CometChatException` |
| Prerequisites | SDK initialized via [`CometChat.init()`](/sdk/react-native/setup-sdk) and a logged-in user via [`CometChat.login()`](/sdk/react-native/authentication-overview) |
| Primary output | `pinConversation()` and `unpinConversation()` → `Promise<CometChat.Conversation>`; `isPinConversationEnabled()` → `Promise<boolean>`; `getPinConversationLimit()` and `getSystemPinConversationLimit()` → `Promise<number \| null>` |
| Constraints | Pin by the peer's UID or GUID plus the receiver type, not by conversation ID. The feature needs the `features.ux.conversations.pinned.enabled` flag, which no plan seeds — it must be mapped per app. A conversation that has never been messaged, or that is hidden, rejects with `ERR_CONVERSATION_NOT_ACCESSIBLE`. `setPinnedBy()` takes exact, case-sensitive strings and silently drops anything else. This SDK has no `ConversationListener`, so keep the list in sync yourself. |
| Related | [Retrieve Conversations](/sdk/react-native/retrieve-conversations) · [Pin a Message](/sdk/react-native/pin-message) · [Save a Message](/sdk/react-native/save-message) · [Delete a Conversation](/sdk/react-native/delete-conversation) |
| Full reference | [`Conversation`](/sdk/reference/entities#conversation) · [`CometChatException`](/sdk/reference/auxiliary#cometchatexception) |

```javascript
// Pin / unpin — addressed by peer + type, not by conversationId
await CometChat.pinConversation("UID", CometChat.RECEIVER_TYPE.USER);
Expand Down Expand Up @@ -178,7 +190,7 @@
<Tabs>
<Tab title="TypeScript">
```typescript
let conversationsRequest: CometChat.ConversationsRequest =

Check warning on line 193 in sdk/react-native/pin-conversation.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-conversation.mdx#L193

Did you really mean 'conversationsRequest'?
new CometChat.ConversationsRequestBuilder()
.setPinnedBy(["system", "me"])
.setLimit(30)
Expand Down Expand Up @@ -244,9 +256,9 @@
<Tabs>
<Tab title="TypeScript">
```typescript
const isPinned: boolean = conversation.getPinnedAt() !== undefined;

Check warning on line 259 in sdk/react-native/pin-conversation.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-conversation.mdx#L259

Did you really mean 'isPinned'?

if (isPinned) {

Check warning on line 261 in sdk/react-native/pin-conversation.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-conversation.mdx#L261

Did you really mean 'isPinned'?
console.log("Pinned at:", conversation.getPinnedAt());
console.log("Pinned by:", conversation.getPinnedBy());

Expand Down Expand Up @@ -277,7 +289,7 @@
| Method | Returns |
| ----------------- | ------------------------------------------------------------------------------- |
| `getPinnedAt()` | The pin timestamp, or `undefined` when the conversation is not pinned. |
| `getPinnedBy()` | The pinner's UID, or `"app_system"` for an admin/global pin, or `undefined`. |

Check warning on line 292 in sdk/react-native/pin-conversation.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-conversation.mdx#L292

Did you really mean 'pinner's'?

## Keeping the List in Sync

Expand Down Expand Up @@ -323,7 +335,7 @@
<Tab title="TypeScript">
```typescript
let limit: number | null = await CometChat.getPinConversationLimit();
let systemLimit: number | null = await CometChat.getSystemPinConversationLimit();

Check warning on line 338 in sdk/react-native/pin-conversation.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-conversation.mdx#L338

Did you really mean 'systemLimit'?
```

</Tab>
Expand Down
12 changes: 12 additions & 0 deletions sdk/react-native/pin-message.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
{/* TL;DR for Agents and Quick Reference */}
<Accordion title="AI Integration Quick Reference">

| Field | Value |
| --- | --- |
| Package | `@cometchat/chat-sdk-react-native` |
| Import | `import { CometChat } from "@cometchat/chat-sdk-react-native";` |
| Key Methods | `pinMessage()`, `unpinMessage()`, `isPinMessageEnabled()`, `getPinMessageLimit()`, `addMessageListener()`, `removeMessageListener()` |
| Key Classes | `BaseMessage`, `MessagesRequest`, `MessagesRequestBuilder`, `MessageListener`, `CometChatException` |
| Prerequisites | SDK initialized via [`CometChat.init()`](/sdk/react-native/setup-sdk) and a logged-in user via [`CometChat.login()`](/sdk/react-native/authentication-overview) |
| Primary output | `pinMessage()` and `unpinMessage()` → `Promise<CometChat.BaseMessage>`; `isPinMessageEnabled()` → `Promise<boolean>`; `getPinMessageLimit()` → `Promise<number \| null>` |
| Constraints | Pinning is a moderation action: only an admin, moderator or group owner may pin or unpin, and the server is the authority. A just-sent message may not be pinnable yet while moderation is pending. On a cap breach the rejection carries the server-owned ceiling in `errorParams.limit`. There is no `isPinned()` or `isSystemPinned()` in this SDK — read `getPinnedAt()`. Fetch the pinned list with `setPinnedOnly(true)`, scoped to one conversation. |
| Related | [Save a Message](/sdk/react-native/save-message) · [Pin a Conversation](/sdk/react-native/pin-conversation) · [Real-time Listeners](/sdk/react-native/real-time-listeners) · [Message Filtering](/sdk/react-native/additional-message-filtering) |
| Full reference | [`BaseMessage`](/sdk/reference/messages#basemessage) · [`CometChatException`](/sdk/reference/auxiliary#cometchatexception) |

```javascript
// Pin / unpin a message
const pinned = await CometChat.pinMessage(messageId);
Expand Down Expand Up @@ -45,7 +57,7 @@
<Tabs>
<Tab title="TypeScript">
```typescript
let messageId: number = 100;

Check warning on line 60 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L60

Did you really mean 'messageId'?

CometChat.pinMessage(messageId).then(
(message: CometChat.BaseMessage) => {
Expand Down Expand Up @@ -77,10 +89,10 @@

</Tabs>

Pinning is **idempotent**, and a message has a single pinner: re-pinning an already pinned message updates `pinnedBy` and `pinnedAt` to the most recent pinner rather than failing.

Check warning on line 92 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L92

Did you really mean 'pinner'?

Check warning on line 92 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L92

Did you really mean 'pinner'?

<Warning>
**A just-sent message may not be pinnable or savable yet.** On an app with

Check warning on line 95 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L95

Did you really mean 'pinnable'?
moderation enabled, the server stamps a new message `moderation.status:
"pending"` and clears it to `"approved"` a moment later. While it is pending,
`pinMessage()` rejects with `403 ERR_MESSAGE_NO_ACCESS` — the **same code it returns
Expand Down Expand Up @@ -143,7 +155,7 @@
<Tabs>
<Tab title="TypeScript (User)">
```typescript
let messagesRequest: CometChat.MessagesRequest =

Check warning on line 158 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L158

Did you really mean 'messagesRequest'?
new CometChat.MessagesRequestBuilder()
.setUID("cometchat-uid-1")
.setPinnedOnly(true)
Expand Down Expand Up @@ -184,7 +196,7 @@

<Tab title="TypeScript (Group)">
```typescript
let messagesRequest: CometChat.MessagesRequest =

Check warning on line 199 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L199

Did you really mean 'messagesRequest'?
new CometChat.MessagesRequestBuilder()
.setGUID("cometchat-guid-1")
.setPinnedOnly(true)
Expand Down Expand Up @@ -238,9 +250,9 @@
<Tabs>
<Tab title="TypeScript">
```typescript
const isPinned: boolean = message.getPinnedAt() !== undefined;

Check warning on line 253 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L253

Did you really mean 'isPinned'?

if (isPinned) {

Check warning on line 255 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L255

Did you really mean 'isPinned'?
console.log("Pinned at:", message.getPinnedAt());
console.log("Pinned by:", message.getPinnedBy());

Expand Down Expand Up @@ -273,7 +285,7 @@
| Method | Returns |
| ----------------- | ------------------------------------------------------------------- |
| `getPinnedAt()` | The pin timestamp, or `undefined` when the message is not pinned. |
| `getPinnedBy()` | The UID of the most recent pinner, or `undefined`. |

Check warning on line 288 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L288

Did you really mean 'pinner'?

<Warning>
Do not port `isPinned()` or `isSystemPinned()` from the JavaScript SDK — they
Expand Down Expand Up @@ -324,7 +336,7 @@

Each callback receives the **full updated message**, so `getPinnedAt()` and `getPinnedBy()` are readable without a follow-up fetch — replace the message in your list directly.

Remove the listener when the screen unmounts:

Check warning on line 339 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L339

Did you really mean 'unmounts'?

<Tabs>
<Tab title="TypeScript">
Expand All @@ -351,9 +363,9 @@
<Tab title="TypeScript">
```typescript
let limit: number | null = await CometChat.getPinMessageLimit();
let systemLimit: number | null = await CometChat.getSystemPinMessageLimit();

Check warning on line 366 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L366

Did you really mean 'systemLimit'?

if (limit !== null && pinnedCount >= limit) {

Check warning on line 368 in sdk/react-native/pin-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/pin-message.mdx#L368

Did you really mean 'pinnedCount'?
// Disable the pin control instead of letting the user hit the error
}
```
Expand Down
12 changes: 12 additions & 0 deletions sdk/react-native/save-message.mdx
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
---
title: "Save A Message"
sidebarTitle: "Save A Message"
description: "Save and unsave messages privately, fetch the saved list across conversations, and listen for save events with the CometChat React Native SDK."

Check warning on line 4 in sdk/react-native/save-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/save-message.mdx#L4

Did you really mean 'unsave'?
---

{/* TL;DR for Agents and Quick Reference */}
<Accordion title="AI Integration Quick Reference">

| Field | Value |
| --- | --- |
| Package | `@cometchat/chat-sdk-react-native` |
| Import | `import { CometChat } from "@cometchat/chat-sdk-react-native";` |
| Key Methods | `saveMessage()`, `unsaveMessage()`, `isSaveMessageEnabled()`, `getSaveMessageLimit()`, `addMessageListener()` |
| Key Classes | `BaseMessage`, `MessagesRequest`, `MessagesRequestBuilder`, `MessageListener`, `CometChatException` |
| Prerequisites | SDK initialized via [`CometChat.init()`](/sdk/react-native/setup-sdk) and a logged-in user via [`CometChat.login()`](/sdk/react-native/authentication-overview) |
| Primary output | `saveMessage()` and `unsaveMessage()` → `Promise<CometChat.BaseMessage>`; `isSaveMessageEnabled()` → `Promise<boolean>`; `getSaveMessageLimit()` → `Promise<number \| null>` |
| Constraints | Saves are private and per-viewer: `savedAt` is only ever set in the acting user's own context. They are account-wide, so do not combine `setSavedOnly(true)` with `setUID()` or `setGUID()`. There is no `isSaved()` in this SDK — read `getSavedAt()`. The real-time callbacks fire for saves made on your other devices, not on the one that performed the save. |
| Related | [Pin a Message](/sdk/react-native/pin-message) · [Pin a Conversation](/sdk/react-native/pin-conversation) · [Retrieve Conversations](/sdk/react-native/retrieve-conversations) · [Message Filtering](/sdk/react-native/additional-message-filtering) |
| Full reference | [`BaseMessage`](/sdk/reference/messages#basemessage) · [`CometChatException`](/sdk/reference/auxiliary#cometchatexception) |

```javascript
// Save / unsave a message
const saved = await CometChat.saveMessage(messageId);
Expand Down Expand Up @@ -44,7 +56,7 @@
<Tabs>
<Tab title="TypeScript">
```typescript
let messageId: number = 100;

Check warning on line 59 in sdk/react-native/save-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/save-message.mdx#L59

Did you really mean 'messageId'?

CometChat.saveMessage(messageId).then(
(message: CometChat.BaseMessage) => {
Expand Down Expand Up @@ -79,7 +91,7 @@
Saving is idempotent — saving an already saved message succeeds rather than failing. There is no role gate. On a cap breach the rejection carries the server-owned ceiling in `errorParams.limit`.

<Warning>
**A just-sent message may not be pinnable or savable yet.** On an app with

Check warning on line 94 in sdk/react-native/save-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/save-message.mdx#L94

Did you really mean 'pinnable'?
moderation enabled, the server stamps a new message `moderation.status:
"pending"` and clears it to `"approved"` a moment later. While it is pending,
`saveMessage()` rejects with `403 ERR_MESSAGE_NO_ACCESS` — the **same code it returns
Expand All @@ -94,7 +106,7 @@
reproduces on an app that has it switched off.
</Warning>

## Unsave a Message

Check warning on line 109 in sdk/react-native/save-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/save-message.mdx#L109

Did you really mean 'Unsave'?

<Tabs>
<Tab title="TypeScript">
Expand Down Expand Up @@ -136,7 +148,7 @@
<Tabs>
<Tab title="TypeScript">
```typescript
let messagesRequest: CometChat.MessagesRequest =

Check warning on line 151 in sdk/react-native/save-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/save-message.mdx#L151

Did you really mean 'messagesRequest'?
new CometChat.MessagesRequestBuilder()
.setSavedOnly(true)
.setLimit(50)
Expand Down Expand Up @@ -223,9 +235,9 @@
<Tabs>
<Tab title="TypeScript">
```typescript
const isSaved: boolean = message.getSavedAt() !== undefined;

Check warning on line 238 in sdk/react-native/save-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/save-message.mdx#L238

Did you really mean 'isSaved'?

if (isSaved) {

Check warning on line 240 in sdk/react-native/save-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/save-message.mdx#L240

Did you really mean 'isSaved'?
console.log("Saved at:", message.getSavedAt());
}
```
Expand Down Expand Up @@ -256,7 +268,7 @@

## Real-time Save Events

Save and unsave are **private multi-device** events: they are delivered to the user's other logged-in sessions so a save on the phone shows up on the desktop. Add the callbacks to your existing `MessageListener`.

Check warning on line 271 in sdk/react-native/save-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/save-message.mdx#L271

Did you really mean 'unsave'?

<Tabs>
<Tab title="TypeScript">
Expand Down Expand Up @@ -311,7 +323,7 @@
```typescript
let limit: number | null = await CometChat.getSaveMessageLimit();

if (limit !== null && savedCount >= limit) {

Check warning on line 326 in sdk/react-native/save-message.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/save-message.mdx#L326

Did you really mean 'savedCount'?
// Disable the save control instead of letting the user hit the error
}
```
Expand Down
12 changes: 12 additions & 0 deletions sdk/react-native/thread-subscription.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
{/* TL;DR for Agents and Quick Reference */}
<Accordion title="AI Integration Quick Reference">

| Field | Value |
| --- | --- |
| Package | `@cometchat/chat-sdk-react-native` |
| Import | `import { CometChat } from "@cometchat/chat-sdk-react-native";` |
| Key Methods | `subscribeToThread()`, `unsubscribeFromThread()`, `getMessageDetails()`, `addMessageListener()` |
| Key Classes | `BaseMessage`, `MessageThread`, `ThreadsRequest`, `ThreadsRequestBuilder`, `MessageListener` |
| Prerequisites | SDK initialized via [`CometChat.init()`](/sdk/react-native/setup-sdk) and a logged-in user via [`CometChat.login()`](/sdk/react-native/authentication-overview) |
| Primary output | `subscribeToThread()` and `unsubscribeFromThread()` → `Promise<string>`; `ThreadsRequest.fetchNext()` → `Promise<MessageThread[]>` |
| Constraints | A thread is identified by its parent message ID, passed as a number. Unsubscribing hard-deletes the server row, so a thread inbox must drop that row rather than mark it unfollowed. A message that arrives over the socket carries no subscription flag and reads `false`, which does not mean the user is unsubscribed. `setThreadSubscribed()` only changes the object in memory and sends nothing to the server. `ThreadsRequestBuilder` spells its scope setters `setUid()` and `setGuid()`, unlike `MessagesRequestBuilder`. |
| Related | [Threaded Messages](/sdk/react-native/threaded-messages) · [Mentions](/sdk/react-native/mentions) · [Real-time Listeners](/sdk/react-native/real-time-listeners) · [Save a Message](/sdk/react-native/save-message) |
| Full reference | [`BaseMessage`](/sdk/reference/messages#basemessage) · [thread row fields](#reading-a-thread-row) |

```javascript
// Subscribe / unsubscribe — a thread is identified by its PARENT message id
await CometChat.subscribeToThread(100);
Expand Down Expand Up @@ -125,7 +137,7 @@

<Warning>
Unsubscribing **hard-deletes** the server row, so a thread inbox built with
`ThreadsRequest` must drop that row rather than mark it unfollowed. It is also

Check warning on line 140 in sdk/react-native/thread-subscription.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/thread-subscription.mdx#L140

Did you really mean 'unfollowed'?
**not sticky**: replying in the thread, or being @-mentioned in it,
re-subscribes the user.
</Warning>
Expand Down Expand Up @@ -173,7 +185,7 @@

That default is what makes the flag meaningful on your own messages. Since it starts out `true`, a `false` on a message **you sent** — read from a fetch, not the socket — is not silence. It means you unsubscribed, and nothing should quietly put you back.

This only holds for a message you sent and obtained from a fetch. On anyone else's message, or on anything socket-delivered, `false` still just means the server was not asked.

Check warning on line 188 in sdk/react-native/thread-subscription.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/thread-subscription.mdx#L188

Did you really mean 'else's'?

### Keeping your own copies in sync

Expand Down Expand Up @@ -259,7 +271,7 @@
<Tabs>
<Tab title="TypeScript">
```typescript
let threadsRequest: CometChat.ThreadsRequest =

Check warning on line 274 in sdk/react-native/thread-subscription.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/thread-subscription.mdx#L274

Did you really mean 'threadsRequest'?
new CometChat.ThreadsRequestBuilder()
.setParticipatedByMe(true)
.setLimit(30)
Expand Down
17 changes: 17 additions & 0 deletions sdk/react-native/upload-files.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@
description: "Upload files directly to storage with per-file progress, remove, and retry through an UploadFileRequest — then send them as one or more media messages with multiple attachments."
---

{/* TL;DR for Agents and Quick Reference */}
<Accordion title="AI Integration Quick Reference">

| Field | Value |
| --- | --- |
| Package | `@cometchat/chat-sdk-react-native` |
| Import | `import { CometChat } from "@cometchat/chat-sdk-react-native";` |
| Key Methods | `createUploadFileRequest()`, `getMaxAttachmentCount()`, `sendMediaMessage()` |
| Key Classes | `UploadFileRequest`, `UploadFileListener`, `Attachment`, `MediaMessage` |
| Prerequisites | SDK initialized via [`CometChat.init()`](/sdk/react-native/setup-sdk) and a logged-in user via [`CometChat.login()`](/sdk/react-native/authentication-overview) |
| Primary output | `createUploadFileRequest()` → `UploadFileRequest`, returned synchronously; uploads report through `UploadFileListener`; `getAttachments()` → `Attachment[]`; `getMaxAttachmentCount()` → `Promise<number>`; `sendMediaMessage()` → `Promise<CometChat.BaseMessage>` |
| Constraints | One request covers one destination and one batch, so create a separate request per conversation or thread. `receiverId` and `receiverType` must match the message you eventually send, because the upload-authorization endpoint enforces them. You supply `fileId` yourself; the SDK never generates one. `onFileError` means the request was rejected, which is not the same as an upload that failed midway. The attachment getters return uploaded files only. |
| Related | [Send a Message](/sdk/react-native/send-message) · [Multiple attachments](/sdk/react-native/send-message#multiple-attachments-in-a-media-message) · [Receive Messages](/sdk/react-native/receive-messages) · [Edit a Message](/sdk/react-native/edit-message) |
| Full reference | [`Attachment`](/sdk/reference/auxiliary#attachment) · [`MediaMessage`](/sdk/reference/messages#mediamessage) |

</Accordion>

`CometChat.createUploadFileRequest(receiverId, receiverType)` returns an **`UploadFileRequest`** — the entry point for uploading files **directly to storage** with **per-file progress, success, and failure**. Upload is **decoupled from sending**: each uploaded file yields an [`Attachment`](/sdk/reference/auxiliary#attachment) (carrying a hosted `url`), which you then attach to a [`MediaMessage`](/sdk/reference/messages#mediamessage) and send with [`sendMediaMessage()`](/sdk/react-native/send-message#media-message).

A request object is scoped to **one destination** (`receiverId` / `receiverType`) and **one upload batch**. This is the recommended way to build a **multi-attachment composer**: create a request, upload a batch of files, show a progress bar per file, let the user remove or retry individual files, then send them as a single media message with multiple attachments (or split across several).
Expand Down Expand Up @@ -56,7 +73,7 @@
| `receiverType` | `string` | `CometChat.RECEIVER_TYPE.USER` or `CometChat.RECEIVER_TYPE.GROUP`. | Yes |

<Warning>
**The recipient must match the message you'll eventually send.** `receiverId` / `receiverType` are sent to the upload-authorization (presign) endpoint, which enforces the sender's **role- and scope-based access control** for that conversation *before* any bytes transfer. If the sender isn't allowed to send media to that user or group, each file is **rejected** via `onFileError` — with `ERR_PERMISSION_DENIED` for an access-control denial, or `ERR_PRESIGN_REJECTED` for a billing / MIME-rule denial (neither is retryable). Pass the same recipient you'll set on the `MediaMessage` at send time.

Check warning on line 76 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L76

Did you really mean 'presign'?

Check warning on line 76 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L76

Did you really mean 'retryable'?
</Warning>

## Upload files
Expand Down Expand Up @@ -111,7 +128,7 @@
<Note>
**`fileId` is caller-supplied and required.** The SDK does not generate one — you provide a stable, unique id per file (echoed back unchanged on every event) so you can line each file up with its UI row. Re-uploading a `fileId` that is already in the batch **overwrites** its state and re-uploads it — this is exactly how you [retry a failed file](#remove-retry--clear); use a fresh `fileId` for each genuinely new file.

Validation, presigning, and the byte transfer all run **asynchronously** after `uploadAttachments()` returns — track outcomes through the listener.

Check warning on line 131 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L131

Did you really mean 'presigning'?
</Note>

## The UploadFileListener
Expand All @@ -122,12 +139,12 @@
| ---------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `onFileProgress` | `(fileId, loaded, total, percent) => void` | Transfer progress for a file. |
| `onFileUploaded` | `(fileId, attachment) => void` | A file finished uploading. `attachment` is a ready-to-send [`Attachment`](/sdk/reference/auxiliary#attachment). |
| `onFileError` | `(fileId, error) => void` | A file was **rejected** — **not retryable** (fix the input or permissions). |

Check warning on line 142 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L142

Did you really mean 'retryable'?
| `onFileFailure` | `(fileId, error) => void` | A file's transfer **failed** — **retryable** by re-uploading the same `fileId`. |

Check warning on line 143 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L143

Did you really mean 'retryable'?
| `onComplete` | `(result) => void` | The batch drained (no files in flight). Delivers an aggregate [`UploadResult`](#uploadresult). |

<Warning>
**Rejected vs. failed — the key distinction.** `onFileError` (rejected) means the request itself is unacceptable — invalid file object, over the size limit, not logged in, or the server declined the file at presign (permission / billing / role- and scope-based access control / MIME rules). Retrying won't help; the user must swap the file or you must fix the recipient/permissions. `onFileFailure` (failed) means a transient transport problem — a storage error, an expired presigned URL, a stalled upload, or an unreachable presign endpoint. These **can** be retried.

Check warning on line 147 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L147

Did you really mean 'presign'?

Check warning on line 147 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L147

Did you really mean 'presigned'?

Check warning on line 147 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L147

Did you really mean 'presign'?
</Warning>

### UploadResult
Expand All @@ -145,7 +162,7 @@

## Configuring the request

Chainable setters let you configure the batch before (or between) uploads:

Check warning on line 165 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L165

Did you really mean 'Chainable'?

```typescript
request
Expand All @@ -160,7 +177,7 @@
| `setConcurrency(count)` | How many files upload simultaneously. Default `1` (sequential). Applies from the next drain onward. |
| `setBatchId(batchId)` | Set the batch id all files share. Optional — the request auto-generates a UUID on first use. |
| `getBatchId()` | The effective batch id (app-set or auto-generated). |
| `setParentMessageId(id)` | Mark the batch as belonging to a thread — sent to the presign endpoint. Omit for a top-level message. |

Check warning on line 180 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L180

Did you really mean 'presign'?

<Note>
Each request owns exactly one batch. For separate destinations (e.g. a main conversation and a thread), create a **separate `UploadFileRequest`** for each — their file ids never cross.
Expand Down Expand Up @@ -204,7 +221,7 @@
| `getStatus()` | `UploadStatus` | `IN_PROGRESS` while any file is still uploading, else `IDLE` (a fresh or drained batch is `IDLE`). |

<Note>
The attachment getters (`getAttachment`, `getAttachments`, `getAttachmentsByType`) return **only uploaded** files, so they're safe to hand straight to `setAttachments()`. `getAttachmentCount()` counts every file regardless of state, so you can compare it against `getAttachments().length` to see how many are still pending.

Check warning on line 224 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L224

Did you really mean 'getters'?
</Note>

## Remove, retry & clear
Expand Down Expand Up @@ -316,24 +333,24 @@

## Error handling

Every error delivered to `onFileError` / `onFileFailure` (and rejections from `sendMediaMessage()`) is a [`CometChatException`](/sdk/reference/auxiliary#cometchatexception). Each non-successful file hits exactly one of `onFileError` (rejected — not retryable) or `onFileFailure` (failed — retryable). The upload-specific codes:

Check warning on line 336 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L336

Did you really mean 'retryable'?

Check warning on line 336 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L336

Did you really mean 'retryable'?

| Code | Surfaced via | Retryable | Meaning |

Check warning on line 338 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L338

Did you really mean 'Retryable'?
| --------------------------- | -------------------- | --------- | ------------------------------------------------------------------------------------------------------ |
| `ERR_INVALID_FILE_OBJECT` | `onFileError` | No | The file object is invalid or its size can't be determined. |
| `ERR_FILE_SIZE_EXCEEDED` | `onFileError` | No | The file is larger than `file.size.max`. |
| `ERR_UNAUTHENTICATED` | `onFileError` | No | No logged-in user — log in before uploading. |
| `ERR_PERMISSION_DENIED` | `onFileError` | No | The sender isn't allowed to upload media to this `receiverId` / `receiverType` (role/scope access control). |
| `ERR_PRESIGN_REJECTED` | `onFileError` | No | The server declined the file at presign — billing or MIME rules for this recipient. |

Check warning on line 344 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L344

Did you really mean 'presign'?
| `ERR_FILE_COUNT_EXCEEDED` | `sendMediaMessage()` | No | More attachments on the message than `file.count.max` allows. |
| `ERR_S3_UPLOAD_FAILED` | `onFileFailure` | Yes | Storage rejected the upload or the transport errored. |

Check warning on line 346 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L346

Did you really mean 'errored'?
| `ERR_PRESIGNED_URL_EXPIRED` | `onFileFailure` | Yes | The pre-signed URL expired (a retry re-presigns automatically). |
| `ERR_UPLOAD_STALLED` | `onFileFailure` | Yes | No progress for 30s; the upload was aborted. |
| `ERR_PRESIGN_FETCH_FAILED` | `onFileFailure` | Yes | Couldn't reach the presign endpoint (e.g. network drop). Retry when back online. |

Check warning on line 349 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L349

Did you really mean 'presign'?
| `ERR_UPLOAD_CANCELLED` | — | — | The upload was removed via `removeAttachment()`. |

<Note>
`ERR_PERMISSION_DENIED` and `ERR_PRESIGN_REJECTED` are returned by the server's presign check, so their exact code and message come from your backend.

Check warning on line 353 in sdk/react-native/upload-files.mdx

View check run for this annotation

Mintlify / Mintlify Validation (cometchat-22654f5b) - vale-spellcheck

sdk/react-native/upload-files.mdx#L353

Did you really mean 'presign'?
</Note>

## Next Steps
Expand Down
Loading
Loading