> ## 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.

# Campaigns

> Fetch notification feed items, listen for real-time delivery, mark items as read/delivered, report engagement, and track push notifications using the CometChat JavaScript SDK.

<Accordion title="AI Integration Quick Reference">
  | Field | Value |
  | - | - |
  | Package | `@cometchat/chat-sdk-javascript` |
  | Import | `import { CometChat } from "@cometchat/chat-sdk-javascript";` |
  | Key methods | `CometChat.markFeedItemAsRead(feedItem)` · `CometChat.markFeedItemAsDelivered(feedItem)` · `CometChat.markFeedItemsAsDelivered(feedItems)` · `CometChat.reportFeedEngagement(feedItem, interactionString)` · `CometChat.getNotificationFeedUnreadCount()` · `CometChat.getNotificationFeedItem(id)` · `CometChat.markPushNotificationDelivered(pushNotification)` · `CometChat.markPushNotificationClicked(pushNotification)` |
  | Request builder | `new CometChat.NotificationFeedRequestBuilder().setLimit(limit).setReadState(state).setCategory(category).setChannelId(channelId).setTags(tags).build()` → `.fetchNext()` · also `NotificationCategoriesRequestBuilder().setLimit(limit).build()` → `.fetchNext()` |
  | Key classes | `CometChat.NotificationFeedItem` · `CometChat.NotificationCategory` · `CometChat.PushNotification` · `CometChat.CardMessage` |
  | Primary output | `NotificationFeedRequest.fetchNext()` resolves to `CometChat.NotificationFeedItem[]` (empty array when exhausted); `getNotificationFeedUnreadCount()` resolves to `{ count: number }`; mark/report methods resolve on success; all reject with `CometChat.CometChatException` |
  | Listeners registered | Notification feed listener via `CometChat.addNotificationFeedListener("feedListener", ...)` / `CometChat.removeNotificationFeedListener("feedListener")`; key callback `onFeedItemReceived`. Card chat messages arrive on `CometChat.MessageListener`'s `onCardMessageReceived` callback |
  | Prerequisites | SDK initialized via [`CometChat.init()`](/sdk/javascript/setup-sdk) and a logged-in user via [`CometChat.login()`](/sdk/javascript/authentication-overview); channels, categories, templates, and campaigns configured in the [Dashboard](/campaigns#setup-flow). Render cards with `@cometchat/cards-react` |
  | Constraints | Card messages are **receive-only** — created and sent exclusively via the Platform (REST) API or Dashboard Bubble Builder; the SDK exposes the raw Card Schema JSON via `getCard()`. The Cards library is a pure renderer and does not execute card actions — your app must handle action callbacks |
  | Related | [Card Messages](/sdk/javascript/card-messages) · [Receive a Message](/sdk/javascript/receive-message) · [All Real-Time Listeners](/sdk/javascript/all-real-time-listeners) · [Send a Message](/sdk/javascript/send-message) |
</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.

<Note>
  Before using the SDK, set up your channels, categories, templates, and campaigns in the CometChat Dashboard. See the [Dashboard Setup Guide](/campaigns#setup-flow) for step-by-step instructions.
</Note>

***

## Key Concepts

| Concept | Description |
| - | - |
| **NotificationFeedItem** | A single notification in the feed. Contains Card Schema JSON in its `content` field, a `category` for filtering, timestamps, and metadata. |
| **NotificationCategory** | A category label used for filter chips (e.g., "Promotions", "Updates"). |
| **Card Schema JSON** | The fully rendered card layout (images, text, buttons) inside `NotificationFeedItem.getContent()`. Passed directly to the CometChat Cards renderer. |
| **PushNotification** | Represents a campaign push notification payload received via FCM/APNs or Web Push. |

***

## How Cards Render in the Notification Feed

Each `NotificationFeedItem` has a `content` field containing an object — this is the **Card Schema JSON**. This JSON is passed directly to the **CometChat Cards** renderer library (`@cometchat/cards-react`).

The rendering flow:

1. Fetch feed items via `NotificationFeedRequestBuilder`
2. For each item, extract `item.getContent()` — this is the Card Schema JSON
3. Convert to string: `JSON.stringify(item.getContent())`
4. Pass to the Cards renderer (`CometChatCardView`)
5. The renderer produces a native DOM element from the JSON

### Card Schema JSON Structure

```json theme={null}
{
  "version": "1.0",
  "body": [
    {
      "type": "column",
      "backgroundColor": {
        "light": "transparent",
        "dark": "transparent"
      },
      "gap": 5,
      "items": [
        {
          "type": "text",
          "content": "📢 Announcement",
          "variant": "heading2",
          "id": "txt_99323141-2459-4e33-88d3-ca39c5fd2f50"
        },
        {
          "type": "text",
          "content": "Your announcement message here.",
          "variant": "body",
          "id": "txt_61a417bc-5e4a-4ba2-bfe7-b7bc64dbaf35"
        },
        {
          "type": "divider",
          "id": "div_80f5c7fb-fd10-41d1-8c2f-51498f0f62d0"
        },
        {
          "type": "button",
          "label": "Learn More",
          "backgroundColor": {
            "light": "transparent",
            "dark": "transparent"
          },
          "textColor": {
            "light": "#6C5CE7",
            "dark": "#6C5CE7"
          },
          "size": 40,
          "fontSize": 13,
          "borderRadius": 6,
          "padding": {
            "top": 0,
            "right": 16,
            "bottom": 0,
            "left": 16
          },
          "action": {
            "type": "openUrl",
            "url": ""
          },
          "id": "btn_9b87a3f1-b0c6-45b9-a4c2-e22ea590f17f"
        }
      ],
      "id": "col_98fed9bd-1a95-4cee-aa81-84a9016e41f2"
    }
  ],
  "fallbackText": "",
  "style": {
    "background": {
      "light": "#E8E8E8",
      "dark": "#E8E8E8"
    },
    "borderRadius": 16,
    "borderColor": {
      "light": "#DFE6E9",
      "dark": "#DFE6E9"
    },
    "padding": 12
  }
}
```

The `body` array contains elements (text, image, button, row, column, etc.) rendered top-to-bottom. Interactive elements like buttons emit actions via a callback — the consumer handles navigation, deep links, or API calls.

***

## Retrieve Notification Feed Items

Use `NotificationFeedRequestBuilder` to fetch a paginated list of feed items. Uses cursor-based pagination internally.

### Build the Request

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    const request = new CometChat.NotificationFeedRequestBuilder()
      .setLimit(20)
      .build();
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const request: CometChat.NotificationFeedRequest = new CometChat.NotificationFeedRequestBuilder()
      .setLimit(20)
      .build();
    ```
  </Tab>
</Tabs>

### Builder Parameters

| Method | Type | Default | Description |
| - | - | - | - |
| `setLimit(limit)` | number | 20 | Items per page (max 100) |
| `setReadState(state)` | FeedReadState | `"all"` | Filter by `"read"`, `"unread"`, or `"all"` |
| `setCategory(category)` | string | null | Filter by category label |
| `setChannelId(channelId)` | string | null | Filter by channel |
| `setTags(tags)` | string\[] | null | Filter by tags |
| `setDateFrom(date)` | string | null | ISO 8601 date — items sent on or after |
| `setDateTo(date)` | string | null | ISO 8601 date — items sent on or before |

### Fetch Items

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    request.fetchNext().then(
      (items) => {
        for (const item of items) {
          const cardJson = JSON.stringify(item.getContent());
          // Pass cardJson to CometChatCardView
        }
      },
      (error) => {
        console.error("Feed fetch error:", error.message);
      }
    );
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    request.fetchNext().then(
      (items: CometChat.NotificationFeedItem[]) => {
        for (const item of items) {
          const cardJson: string = JSON.stringify(item.getContent());
          // Pass cardJson to CometChatCardView
        }
      },
      (error: CometChat.CometChatException) => {
        console.error("Feed fetch error:", error.message);
      }
    );
    ```
  </Tab>
</Tabs>

Call `fetchNext()` repeatedly for pagination. When the server has no more items, subsequent calls return an empty array.

### NotificationFeedItem Fields

| Field | Type | Description |
| - | - | - |
| `getId()` | string | Unique item identifier |
| `getCategory()` | string | Notification category (e.g., "promotions") |
| `getContent()` | object | Card Schema JSON — pass to CometChat Cards renderer |
| `getReadAt()` | number \| null | Unix timestamp when read, or null if unread |
| `getDeliveredAt()` | number \| null | Unix timestamp when delivered, or null |
| `getSentAt()` | number | Unix timestamp when sent |
| `getMetadata()` | `Record<string, any>` | Custom key-value metadata |
| `getTags()` | string\[] | Tags for filtering |
| `getSender()` | string | Sender identifier |
| `getReceiver()` | string | Receiver identifier |
| `getReceiverType()` | string | Receiver type |
| `getIsRead()` | boolean | Whether the item has been read |

***

## Retrieve Notification Categories

Use `NotificationCategoriesRequestBuilder` to fetch available categories for filter chips.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    const categoriesRequest = new CometChat.NotificationCategoriesRequestBuilder()
      .setLimit(50)
      .build();

    categoriesRequest.fetchNext().then(
      (categories) => {
        for (const category of categories) {
          console.log("Category:", category.getLabel());
        }
      },
      (error) => {
        console.error("Categories fetch error:", error.message);
      }
    );
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const categoriesRequest: CometChat.NotificationCategoriesRequest =
      new CometChat.NotificationCategoriesRequestBuilder()
        .setLimit(50)
        .build();

    categoriesRequest.fetchNext().then(
      (categories: CometChat.NotificationCategory[]) => {
        for (const category of categories) {
          console.log("Category:", category.getLabel());
        }
      },
      (error: CometChat.CometChatException) => {
        console.error("Categories fetch error:", error.message);
      }
    );
    ```
  </Tab>
</Tabs>

### NotificationCategory Fields

| Field | Type | Description |
| - | - | - |
| `getId()` | string | Category identifier |
| `getLabel()` | string | Display name for filter UI |

***

## Real-Time Notification Feed Listener

Listen for new feed items arriving via WebSocket. This listener is independent from `MessageListener`, `GroupListener`, and `CallListener`.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    CometChat.addNotificationFeedListener("feedListener", {
      onFeedItemReceived: (feedItem) => {
        console.log("New item:", feedItem.getId());
        const cardJson = JSON.stringify(feedItem.getContent());
        // Insert at top of feed and render
      },
    });
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    CometChat.addNotificationFeedListener("feedListener", {
      onFeedItemReceived: (feedItem: CometChat.NotificationFeedItem) => {
        console.log("New item:", feedItem.getId());
        const cardJson: string = JSON.stringify(feedItem.getContent());
        // Insert at top of feed and render
      },
    });
    ```
  </Tab>
</Tabs>

Remove the listener when no longer needed:

```javascript theme={null}
CometChat.removeNotificationFeedListener("feedListener");
```

***

## Mark Feed Item as Read

Mark a single item as read. Idempotent — safe to call multiple times.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    CometChat.markFeedItemAsRead(feedItem).then(
      () => { console.log("Marked as read"); },
      (error) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    CometChat.markFeedItemAsRead(feedItem).then(
      () => { console.log("Marked as read"); },
      (error: CometChat.CometChatException) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>
</Tabs>

***

## Mark Feed Item as Delivered

Mark a single item as delivered. Idempotent.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    CometChat.markFeedItemAsDelivered(feedItem).then(
      () => { /* Success */ },
      (error) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    CometChat.markFeedItemAsDelivered(feedItem).then(
      () => { /* Success */ },
      (error: CometChat.CometChatException) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>
</Tabs>

### Mark Multiple Items as Delivered (Batch)

```javascript theme={null}
CometChat.markFeedItemsAsDelivered(feedItems).then(
  () => { /* Success */ },
  (error) => { console.error("Error:", error.message); }
);
```

***

## Report Engagement

Report that a user engaged with a feed item (e.g., viewed, clicked, interacted). Idempotent.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    CometChat.reportFeedEngagement(feedItem, "clicked").then(
      () => { /* Success */ },
      (error) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    CometChat.reportFeedEngagement(feedItem, "clicked").then(
      () => { /* Success */ },
      (error: CometChat.CometChatException) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>
</Tabs>

The `interactionString` parameter is a free-form string describing the engagement (e.g., `"viewed"`, `"clicked"`, `"interacted"`).

***

## Get Unread Count

Fetch the total number of unread notification feed items.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    CometChat.getNotificationFeedUnreadCount().then(
      (result) => { console.log("Unread:", result.count); },
      (error) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    CometChat.getNotificationFeedUnreadCount().then(
      (result: { count: number }) => { console.log("Unread:", result.count); },
      (error: CometChat.CometChatException) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>
</Tabs>

***

## Fetch Single Feed Item

Fetch a specific item by ID — useful for deep linking from push notifications.

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    CometChat.getNotificationFeedItem("item-id-123").then(
      (item) => {
        const cardJson = JSON.stringify(item.getContent());
        // Render the card
      },
      (error) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    CometChat.getNotificationFeedItem("item-id-123").then(
      (item: CometChat.NotificationFeedItem) => {
        const cardJson: string = JSON.stringify(item.getContent());
        // Render the card
      },
      (error: CometChat.CometChatException) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>
</Tabs>

***

## Push Notification Tracking

When a campaign push notification arrives via Web Push or FCM, use these methods to report delivery and click engagement.

### Mark Push Notification as Delivered

Call this when the push notification is received:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    const pushNotification = new CometChat.PushNotification(pushPayloadJson);

    CometChat.markPushNotificationDelivered(pushNotification).then(
      () => { /* Success */ },
      (error) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const pushNotification = new CometChat.PushNotification(pushPayloadJson);

    CometChat.markPushNotificationDelivered(pushNotification).then(
      () => { /* Success */ },
      (error: CometChat.CometChatException) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>
</Tabs>

### Mark Push Notification as Clicked

Call this when the user taps the push notification:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    CometChat.markPushNotificationClicked(pushNotification).then(
      () => { /* Success */ },
      (error) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    CometChat.markPushNotificationClicked(pushNotification).then(
      () => { /* Success */ },
      (error: CometChat.CometChatException) => { console.error("Error:", error.message); }
    );
    ```
  </Tab>
</Tabs>

### PushNotification Fields

| Field | Type | Description |
| - | - | - |
| `getId()` | string | Announcement ID from the push payload |
| `getAnnouncementId()` | string | Same as id (for clarity) |
| `getCampaignId()` | string \| null | Campaign ID if from a campaign |
| `getSource()` | string | Always `"campaign"` for notification feed pushes |

***

## FeedReadState

| Value | Description |
| - | - |
| `"read"` | Only read items |
| `"unread"` | Only unread items |
| `"all"` | All items (default) |

***

## Rendering Cards

The `content` field of each `NotificationFeedItem` is a Card Schema JSON object. To render it natively, use the CometChat Cards library.

### Add the Cards Dependency

```bash theme={null}
npm install @cometchat/cards-react
```

<Note>
  If you're using `@cometchat/chat-uikit-react` v6.5.0+, the cards library is included automatically as a dependency.
</Note>

### Render a Card from a Feed Item

```tsx lines theme={null}
import { CometChatCardView } from "@cometchat/cards-react";

function NotificationCard({ item }) {
  const cardJson = JSON.stringify(item.getContent());

  return (
    <CometChatCardView
      cardJson={cardJson}
      themeMode="auto"
      onAction={(event) => {
        const { action, elementId } = event;
        switch (action.type) {
          case "openUrl":
            // Open URL in browser
            window.open(action.url, "_blank");
            break;
          case "chatWithUser":
            // Navigate to chat with action.uid
            break;
          case "chatWithGroup":
            // Navigate to group chat with action.guid
            break;
        }
      }}
    />
  );
}
```

<Note>
  The Cards library is a pure renderer — it does not execute actions. Your code must handle action callbacks (opening URLs, navigating to chats, making API calls, etc.).
</Note>

***

## Supported Card Actions

When a user taps a button or link inside a card, the action callback receives one of these action types:

| Action Type | Parameters | Description |
| - | - | - |
| `openUrl` | url, openIn | Open a URL in browser or webview |
| `chatWithUser` | uid | Navigate to 1:1 chat |
| `chatWithGroup` | guid | Navigate to group chat |
| `sendMessage` | text, receiverUid, receiverGuid | Send a text message |
| `copyToClipboard` | value | Copy text to clipboard |
| `downloadFile` | url, filename | Download a file |
| `initiateCall` | callType (audio/video), uid, guid | Start a call |
| `apiCall` | url, method, headers, body | Make an HTTP request |
| `customCallback` | callbackId, payload | App-specific logic |

***

## Card Messages

Besides the notification feed, the **same Card Schema JSON** can arrive as a chat message. A `CardMessage` is a message with `category: "card"` — created and sent via the Platform (REST) API or the Dashboard Bubble Builder. The SDK only **receives** card messages; it does not send them.

<Tip>
  **Design cards visually with [Card Builder](/card-builder/overview).** Build your card messages in the CometChat Dashboard and export the Card Schema JSON — instead of writing it by hand.
</Tip>

Card messages are delivered through the `onCardMessageReceived` callback of the [`MessageListener`](/sdk/javascript/all-real-time-listeners#message-listener), not through the notification feed listener. The payload from `getCard()` is the same Card Schema JSON described above, so you render it with the same [`CometChatCardView`](#rendering-cards) and handle the same [card actions](#supported-card-actions). For the complete receive-and-render flow, see the [Card Messages guide](/sdk/javascript/card-messages).

### CardMessage Fields

| Method | Return Type | Description |
| - | - | - |
| `getCard()` | object | The raw Card Schema JSON payload. Pass directly to the Cards renderer. |
| `getText()` | string | Preview text for push notifications and the conversation list. |
| `getFallbackText()` | string | Fallback text from inside the card (`card.fallbackText`), used for accessibility or when the renderer fails. |
| `getTags()` | `Array<string>` | Tags associated with this message. |

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    CometChat.addMessageListener(
      "UNIQUE_LISTENER_ID",
      new CometChat.MessageListener({
        onCardMessageReceived: (cardMessage: CometChat.CardMessage) => {
          console.log("Card message received:", cardMessage.getId());
          const cardJson: string = JSON.stringify(cardMessage.getCard()); // same schema as feed cards
          const fallback: string = cardMessage.getFallbackText();
          const previewText: string = cardMessage.getText();
          // Pass cardJson to CometChatCardView
        },
      })
    );
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    CometChat.addMessageListener(
      "UNIQUE_LISTENER_ID",
      new CometChat.MessageListener({
        onCardMessageReceived: (cardMessage) => {
          console.log("Card message received:", cardMessage.getId());
          const cardJson = JSON.stringify(cardMessage.getCard()); // same schema as feed cards
          const fallback = cardMessage.getFallbackText();
          const previewText = cardMessage.getText();
          // Pass cardJson to CometChatCardView
        },
      })
    );
    ```
  </Tab>
</Tabs>

<Note>
  Card messages are **receive-only**. They are created and sent exclusively via the Platform (REST) API and Dashboard Bubble Builder. The SDK exposes the raw payload via `getCard()` — the CometChat Cards library is responsible for drawing the card UI.
</Note>


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