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

# Interactive Messages

> Send and receive interactive messages with embedded forms, buttons, and other UI elements using the CometChat Flutter SDK.

<Accordion title="AI Integration Quick Reference">
  | Field           | Value                                                                                                                 |
  | --------------- | --------------------------------------------------------------------------------------------------------------------- |
  | Key Classes     | `InteractiveMessage`, `InteractionGoal`, `Interaction`, `InteractionReceipt`                                          |
  | Key Methods     | `CometChat.sendInteractiveMessage()`, `CometChat.markAsInteracted()`                                                  |
  | Key Constants   | `InteractionGoalType.anyAction`, `InteractionGoalType.anyOf`, `InteractionGoalType.allOf`, `InteractionGoalType.none` |
  | Listener Events | `onInteractiveMessageReceived`, `onInteractionGoalCompleted`                                                          |
  | Prerequisites   | SDK initialized, user logged in                                                                                       |

  ```dart theme={null}
  // Create and send an interactive form message
  InteractiveMessage interactiveMessage = InteractiveMessage(
    interactiveData: interactiveData,  // Map<String, dynamic> with form fields
    receiverUid: "UID",
    type: "form",
    receiverType: CometChatReceiverType.user,
    allowSenderInteraction: true,
    interactionGoal: InteractionGoal(type: InteractionGoalType.none),
  );
  CometChat.sendInteractiveMessage(interactiveMessage,
    onSuccess: (InteractiveMessage message) {},
    onError: (CometChatException e) {},
  );

  // Mark as interacted
  CometChat.markAsInteracted(messageId, elementId,
    onSuccess: (String message) {},
    onError: (CometChatException e) {},
  );

  // Listen for interactive messages
  CometChat.addMessageListener("LISTENER_ID", this);
  // onInteractiveMessageReceived(InteractiveMessage message) { }
  // onInteractionGoalCompleted(InteractionReceipt receipt) { }
  ```
</Accordion>

Interactive messages embed UI elements like forms, buttons, and dropdowns directly within chat messages. Users can interact with these elements without leaving the conversation, enabling surveys, quick actions, and data collection.

<Note>
  **Available via:** SDK | [REST API](https://api-explorer.cometchat.com) | [UI Kits](/ui-kit/flutter/overview)
</Note>

## InteractiveMessage

The `InteractiveMessage` class extends `BaseMessage` and represents a message with embedded interactive content.

| Parameter                | Type                   | Description                                                   | Required              |
| ------------------------ | ---------------------- | ------------------------------------------------------------- | --------------------- |
| `receiverUid`            | `String`               | The UID of the user or GUID of the group                      | Yes                   |
| `receiverType`           | `String`               | `CometChatReceiverType.user` or `CometChatReceiverType.group` | Yes                   |
| `type`                   | `String`               | Type identifier (e.g., `"form"`, `"card"`)                    | Yes                   |
| `interactiveData`        | `Map<String, dynamic>` | JSON structure defining the interactive elements              | Yes                   |
| `allowSenderInteraction` | `bool`                 | Whether sender can interact with the message                  | No (default: `false`) |
| `interactionGoal`        | `InteractionGoal`      | Defines when the interaction is considered complete           | No (default: `none`)  |
| `tags`                   | `List<String>`         | Tags associated with the message                              | No                    |
| `muid`                   | `String`               | Unique message identifier for deduplication                   | No                    |
| `parentMessageId`        | `int`                  | ID of the parent message (for threads)                        | No                    |
| `metadata`               | `Map<String, dynamic>` | Custom metadata attached to the message                       | No                    |

## Send an Interactive Message

Use `CometChat.sendInteractiveMessage()` to send an interactive message.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    final Map<String, dynamic> interactiveData = {
      "title": "Survey",
      "formFields": [
        {
          "elementType":  "textInput" ,
          "elementId": "name",
          "optional": false,
          "label": "Name",
          "placeholder": {
            "text": "Enter text here"
            }
        },
        {
          "elementType":  "textInput",
          "elementId": "age",
          "optional": true,
          "label": "Age",
          "maxLines": 1,
          "placeholder": {
            "text": "Enter text here"
            }
        },
        {
          "elementType":  "Select",
          "elementId": "checkBox1",
          "optional": true,
          "label": "Check box element",
          "defaultValue":["chk_option_2"],
          "options" : [
            {
              "label": "Option 1",
              "value": "chk_option_1",
            },
            {
              "label": "Option 2",
              "value": "chk_option_2",
            }

          ]
        },
        {
          "elementType": "dropdown",
          "elementId": "gender",
          "optional": false,
          "label": "Gender",
          "defaultValue":"male",
          "options" : [
            {
              "label": "Male",
              "value": "male",
            },
            {
              "label": "Female",
              "value": "female",
            }

          ]
        },
      ],
      "submitElement": {
        "elementType": "button",
        "elementId": "submitButton",
        "buttonText": "Submit",
        "disableAfterInteracted": false,
        "action": {
          "actionType": "urlNavigation",
          "url": "https://www.cometchat.com/",
        }
      },
    };



    InteractiveMessage interactiveMessage =
    InteractiveMessage(interactiveData: interactiveData,
                       receiverUid: "cometchat-uid-3", //Replace this with receiver id
                       type: "form",
                       receiverType: "user",//replace this with receiver type
                       allowSenderInteraction: true,
                       muid: DateTime.now().millisecondsSinceEpoch.toString(),
                       interactionGoal: InteractionGoal(
                         type: InteractionGoalType.none
                       )
                      );


    CometChat.sendInteractiveMessage(interactiveMessage, onSuccess: (InteractiveMessage message){

    print(interactiveMessage);

    }, onError: (CometChatException excep){
    print(excep);
    });
    ```
  </Tab>
</Tabs>

The `sendInteractiveMessage()` method returns an `InteractiveMessage` object on success.

<Accordion title="Response">
  **On Success** — An `InteractiveMessage` object containing all details of the sent interactive message:

  <span id="send-interactive-message-object" style={{scrollMarginTop: '100px'}} />

  **InteractiveMessage Object:**

  | Parameter                | Type    | Description                                        | Sample Value                                     |
  | ------------------------ | ------- | -------------------------------------------------- | ------------------------------------------------ |
  | `id`                     | number  | Unique message ID                                  | `501`                                            |
  | `metadata`               | object  | Custom metadata attached to the message            | `{}`                                             |
  | `receiver`               | object  | Receiver user object                               | [See below ↓](#send-interactive-receiver-object) |
  | `editedBy`               | string  | UID of the user who edited the message             | `null`                                           |
  | `conversationId`         | string  | Unique conversation identifier                     | `"cometchat-uid-1_user_cometchat-uid-3"`         |
  | `sentAt`                 | number  | Epoch timestamp when the message was sent          | `1745554729`                                     |
  | `receiverUid`            | string  | UID of the receiver                                | `"cometchat-uid-3"`                              |
  | `type`                   | string  | Type of the message                                | `"form"`                                         |
  | `readAt`                 | number  | Epoch timestamp when the message was read          | `0`                                              |
  | `deletedBy`              | string  | UID of the user who deleted the message            | `null`                                           |
  | `deliveredAt`            | number  | Epoch timestamp when the message was delivered     | `0`                                              |
  | `deletedAt`              | number  | Epoch timestamp when the message was deleted       | `0`                                              |
  | `replyCount`             | number  | Number of replies to this message                  | `0`                                              |
  | `sender`                 | object  | Sender user object                                 | [See below ↓](#send-interactive-sender-object)   |
  | `receiverType`           | string  | Type of the receiver                               | `"user"`                                         |
  | `editedAt`               | number  | Epoch timestamp when the message was edited        | `0`                                              |
  | `parentMessageId`        | number  | ID of the parent message (for threads)             | `0`                                              |
  | `readByMeAt`             | number  | Epoch timestamp when read by the current user      | `0`                                              |
  | `category`               | string  | Message category                                   | `"interactive"`                                  |
  | `deliveredToMeAt`        | number  | Epoch timestamp when delivered to the current user | `0`                                              |
  | `updatedAt`              | number  | Epoch timestamp when the message was last updated  | `1745554729`                                     |
  | `interactiveData`        | object  | Structured data for the interactive element        | `{"title": "Survey", "formFields": [...]}`       |
  | `interactions`           | array   | List of user interactions with the message         | `[]`                                             |
  | `interactionGoal`        | object  | Intended outcome of interacting with the message   | `{"type": "none", "elementIds": []}`             |
  | `tags`                   | array   | List of tags associated with the message           | `[]`                                             |
  | `allowSenderInteraction` | boolean | Whether the sender can interact with the message   | `true`                                           |
  | `unreadRepliesCount`     | number  | Count of unread replies                            | `0`                                              |
  | `quotedMessageId`        | number  | ID of the quoted message                           | `null`                                           |

  ***

  <span id="send-interactive-sender-object" style={{scrollMarginTop: '100px'}} />

  **`sender` Object:**

  | Parameter       | Type    | Description                                    | Sample Value                                                            |
  | --------------- | ------- | ---------------------------------------------- | ----------------------------------------------------------------------- |
  | `uid`           | string  | Unique identifier of the sender                | `"cometchat-uid-1"`                                                     |
  | `name`          | string  | Display name of the sender                     | `"Andrew Joseph"`                                                       |
  | `link`          | string  | Profile link                                   | `null`                                                                  |
  | `avatar`        | string  | Avatar URL                                     | `"https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-1.webp"` |
  | `metadata`      | object  | Custom metadata                                | `{}`                                                                    |
  | `status`        | string  | Online status                                  | `"online"`                                                              |
  | `role`          | string  | User role                                      | `"default"`                                                             |
  | `statusMessage` | string  | Status message                                 | `null`                                                                  |
  | `tags`          | array   | User tags                                      | `[]`                                                                    |
  | `hasBlockedMe`  | boolean | Whether this user has blocked the current user | `false`                                                                 |
  | `blockedByMe`   | boolean | Whether the current user has blocked this user | `false`                                                                 |
  | `lastActiveAt`  | number  | Epoch timestamp of last activity               | `1745554700`                                                            |

  ***

  <span id="send-interactive-receiver-object" style={{scrollMarginTop: '100px'}} />

  **`receiver` Object:**

  | Parameter       | Type    | Description                                    | Sample Value                                                            |
  | --------------- | ------- | ---------------------------------------------- | ----------------------------------------------------------------------- |
  | `uid`           | string  | Unique identifier of the receiver              | `"cometchat-uid-3"`                                                     |
  | `name`          | string  | Display name of the receiver                   | `"Kevin Hart"`                                                          |
  | `link`          | string  | Profile link                                   | `null`                                                                  |
  | `avatar`        | string  | Avatar URL                                     | `"https://assets.cometchat.io/sampleapp/v2/users/cometchat-uid-3.webp"` |
  | `metadata`      | object  | Custom metadata                                | `{}`                                                                    |
  | `status`        | string  | Online status                                  | `"offline"`                                                             |
  | `role`          | string  | User role                                      | `"default"`                                                             |
  | `statusMessage` | string  | Status message                                 | `null`                                                                  |
  | `tags`          | array   | User tags                                      | `[]`                                                                    |
  | `hasBlockedMe`  | boolean | Whether this user has blocked the current user | `false`                                                                 |
  | `blockedByMe`   | boolean | Whether the current user has blocked this user | `false`                                                                 |
  | `lastActiveAt`  | number  | Epoch timestamp of last activity               | `1745550000`                                                            |
</Accordion>

<Accordion title="Error">
  | Parameter | Type   | Description                  | Sample Value                                                   |
  | --------- | ------ | ---------------------------- | -------------------------------------------------------------- |
  | `code`    | string | Error code identifier        | `"ERR_CHAT_API_FAILURE"`                                       |
  | `message` | string | Human-readable error message | `"Failed to send the interactive message."`                    |
  | `details` | string | Additional technical details | `"An unexpected error occurred while processing the request."` |
</Accordion>

## Interactive Elements

The `interactiveData` map defines the UI elements. Common element types:

| Element Type | Description                     |
| ------------ | ------------------------------- |
| `textInput`  | Single or multi-line text field |
| `dropdown`   | Single-select dropdown menu     |
| `Select`     | Multi-select checkbox group     |
| `button`     | Clickable button with action    |

### Text Input

```dart theme={null}
{
  "elementType": "textInput",
  "elementId": "name",
  "optional": false,
  "label": "Name",
  "maxLines": 1,  // Optional: limit to single line
  "placeholder": {"text": "Enter text here"}
}
```

### Dropdown (Single Select)

```dart theme={null}
{
  "elementType": "dropdown",
  "elementId": "country",
  "optional": false,
  "label": "Country",
  "defaultValue": "us",
  "options": [
    {"label": "United States", "value": "us"},
    {"label": "United Kingdom", "value": "uk"},
    {"label": "Canada", "value": "ca"}
  ]
}
```

### Checkbox (Multi Select)

```dart theme={null}
{
  "elementType": "Select",
  "elementId": "preferences",
  "optional": true,
  "label": "Preferences",
  "defaultValue": ["email"],
  "options": [
    {"label": "Email notifications", "value": "email"},
    {"label": "SMS notifications", "value": "sms"},
    {"label": "Push notifications", "value": "push"}
  ]
}
```

### Submit Button

```dart theme={null}
{
  "elementType": "button",
  "elementId": "submitBtn",
  "buttonText": "Submit",
  "disableAfterInteracted": true,
  "action": {
    "actionType": "urlNavigation",
    "url": "https://example.com/submit"
  }
}
```

## Interaction Goals

An `InteractionGoal` defines when the user's interaction with the message is considered complete. Use this to track engagement and trigger follow-up actions.

`InteractionGoal` Parameters:

| Parameter    | Type           | Description                                         | Required           |
| ------------ | -------------- | --------------------------------------------------- | ------------------ |
| `type`       | `String`       | The type of interaction goal (see goal types below) | Yes                |
| `elementIds` | `List<String>` | List of element IDs associated with this goal       | No (default: `[]`) |

| Goal Type       | Constant                        | Description                                                    |
| --------------- | ------------------------------- | -------------------------------------------------------------- |
| Any Interaction | `InteractionGoalType.anyAction` | Complete when any element is interacted with                   |
| Any of Specific | `InteractionGoalType.anyOf`     | Complete when any of the specified elements is interacted with |
| All of Specific | `InteractionGoalType.allOf`     | Complete when all specified elements are interacted with       |
| None            | `InteractionGoalType.none`      | Never considered complete (default)                            |

### Set an Interaction Goal

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    List<String> elementIds = ["name", "gender", "submitButton"];
    InteractionGoal interactionGoal = InteractionGoal(
      type: InteractionGoalType.allOf,
      elementIds: elementIds,
    );

    InteractiveMessage interactiveMessage = InteractiveMessage(
      interactiveData: interactiveData,
      receiverUid: "cometchat-uid-3",
      type: "form",
      receiverType: "user",
      interactionGoal: interactionGoal,
    );

    CometChat.sendInteractiveMessage(interactiveMessage,
      onSuccess: (InteractiveMessage message) {
        debugPrint("Interactive message sent successfully: $message");
      },
      onError: (CometChatException excep) {
        debugPrint("Interactive message sending failed with error: ${excep.message}");
      },
    );
    ```
  </Tab>
</Tabs>

You would be tracking every interaction users perform on an `InteractiveMessage` (captured as `Interaction` objects) and comparing those with the defined `InteractionGoal`. The completion of a goal can vary depending on the goal type.

This user interaction tracking mechanism provides a flexible and efficient way to monitor user engagement within an interactive chat session. By defining clear interaction goals and checking user interactions against these goals, you can manage user engagement and improve the overall chat experience in your CometChat-enabled application.

## Interactions

An `Interaction` represents a single user action on an interactive element.

| Property       | Type       | Description                                        |
| -------------- | ---------- | -------------------------------------------------- |
| `elementId`    | `String`   | Identifier of the interacted element               |
| `interactedAt` | `DateTime` | Timestamp indicating when the interaction occurred |

## Mark as Interacted

Use `CometChat.markAsInteracted()` to record when a user interacts with an element. This method marks a message as interacted by identifying it with the provided ID and logs the interactive element associated with the interaction.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    Future<void> recordInteraction() async {
      int messageId = 0; // set to your interactive message id
      String interactedElementId = ""; // set to the element id

      await CometChat.markAsInteracted(
        messageId,
        interactedElementId,
        onSuccess: (String message) {
          // after success
        },
        onError: (CometChatException excep) {
          // after error
        },
      );
    }
    ```
  </Tab>
</Tabs>

| Parameter             | Type     | Description                             | Required |
| --------------------- | -------- | --------------------------------------- | -------- |
| `messageId`           | `int`    | The ID of the interactive message       | Yes      |
| `interactedElementId` | `String` | The element ID that was interacted with | Yes      |

<Accordion title="Response">
  **On Success** — A `String` message confirming the interaction was recorded:

  | Parameter | Type   | Description                  | Sample Value                                   |
  | --------- | ------ | ---------------------------- | ---------------------------------------------- |
  | `message` | string | Success confirmation message | `"Message marked as interacted successfully."` |
</Accordion>

<Accordion title="Error">
  | Parameter | Type   | Description                  | Sample Value                                                   |
  | --------- | ------ | ---------------------------- | -------------------------------------------------------------- |
  | `code`    | string | Error code identifier        | `"ERR_CHAT_API_FAILURE"`                                       |
  | `message` | string | Human-readable error message | `"Failed to mark the message as interacted."`                  |
  | `details` | string | Additional technical details | `"An unexpected error occurred while processing the request."` |
</Accordion>

## Real-Time Events

Register a `MessageListener` to receive interactive message events.

### Receive Interactive Messages

The `onInteractiveMessageReceived` event listener is triggered when an `InteractiveMessage` is received.

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    class DemoClass with MessageListener{

    String listenerId = "UNIQUE_LISTENER_ID"; //Replace with unique listener id


    CometChat.addMessageListener(_listenerId, this);



      @override
    void onInteractiveMessageReceived(InteractiveMessage message){

      //TODO  implement onInteractiveMessageReceived event 
    }

    }
    ```
  </Tab>
</Tabs>

### Interaction Goal Completed

The `onInteractionGoalCompleted` event listener is invoked when an interaction goal is achieved.

`InteractionReceipt` Properties:

| Property       | Type                | Description                                  |
| -------------- | ------------------- | -------------------------------------------- |
| `messageId`    | `int`               | The ID of the interactive message            |
| `sender`       | `User`              | The user who completed the interaction       |
| `receiverType` | `String`            | Type of the receiver (`"user"` or `"group"`) |
| `receiverId`   | `String`            | UID or GUID of the receiver                  |
| `interactions` | `List<Interaction>` | List of interactions that satisfied the goal |

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    class DemoClass with MessageListener{

    String listenerId = "UNIQUE_LISTENER_ID"; //Replace with unique listener id


    CometChat.addMessageListener(_listenerId, this);



    @override
    void onInteractionGoalCompleted(InteractionReceipt receipt) {
      //TODO implement onInteractionGoalCompleted
    }

    }
    ```
  </Tab>
</Tabs>

These event listeners offer your application a way to provide real-time updates in response to incoming interactive messages and goal completions, contributing to a more dynamic and responsive user chat experience.

<Warning>
  Always remove listeners when they're no longer needed to prevent memory leaks.

  ```dart theme={null}
  CometChat.removeMessageListener("UNIQUE_LISTENER_ID");
  ```
</Warning>

## Allow Sender Interaction

By default, the sender cannot interact with their own interactive message. Set `allowSenderInteraction` to `true` to enable sender interaction:

<Tabs>
  <Tab title="Dart">
    ```dart theme={null}
    InteractiveMessage interactiveMessage = InteractiveMessage(
      interactiveData: interactiveData,
      receiverUid: "cometchat-uid-3",
      type: "form",
      receiverType: "user",
      allowSenderInteraction: true,
    );

    CometChat.sendInteractiveMessage(interactiveMessage,
      onSuccess: (InteractiveMessage message) {
        debugPrint("Interactive message sent successfully: $message");
      },
      onError: (CometChatException excep) {
        debugPrint("Interactive message sending failed with error: ${excep.message}");
      },
    );
    ```
  </Tab>
</Tabs>

***

## Next Steps

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

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

  <Card title="Transient Messages" icon="ghost" href="/sdk/flutter/transient-messages">
    Send ephemeral messages that aren't stored
  </Card>

  <Card title="Message Structure" icon="sitemap" href="/sdk/flutter/message-structure-and-hierarchy">
    Understand message types and hierarchy
  </Card>
</CardGroup>
