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

# Events

> Reference for CometChat Angular UIKit events including conversation, user, group, message, call, and UI events.

Events provide decoupled communication between UIKit components using a publish/subscribe event bus pattern. Components emit events in response to user interactions or state changes, allowing other parts of your application to react without direct component references. In Angular, you subscribe to these events using RxJS observables and manage subscriptions through component lifecycle hooks.

## CometChatConversationEvents

`CometChatConversationEvents` emits events when the logged-in user acts on a conversation object.

| Event Name                | Description                                                                                         |
| ------------------------- | --------------------------------------------------------------------------------------------------- |
| **ccConversationDeleted** | Triggered when the user successfully deletes a conversation.                                        |
| **ccUpdateConversation**  | Triggered to update a conversation in the conversation list. Takes a Conversation object to update. |

## CometChatUserEvents

`CometChatUserEvents` emits events when the logged-in user acts on another user object.

| Event Name          | Description                                                 |
| ------------------- | ----------------------------------------------------------- |
| **ccUserBlocked**   | Triggered when the user successfully blocks another user.   |
| **ccUserUnblocked** | Triggered when the user successfully unblocks another user. |

## CometChatGroupEvents

`CometChatGroupEvents` emits events when the logged-in user acts on a group object.

| Event Name                    | Description                                                             |
| ----------------------------- | ----------------------------------------------------------------------- |
| **ccGroupCreated**            | Triggered when the user creates a group successfully.                   |
| **ccGroupDeleted**            | Triggered when the group member deletes the group successfully.         |
| **ccGroupLeft**               | Triggered when the group member leaves the group successfully.          |
| **ccGroupMemberScopeChanged** | Triggered when the group member's scope is updated successfully.        |
| **ccGroupMemberKicked**       | Triggered when a group member is kicked.                                |
| **ccGroupMemberBanned**       | Triggered when a group member is banned.                                |
| **ccGroupMemberUnbanned**     | Triggered when a group member is un-banned.                             |
| **ccGroupMemberJoined**       | Triggered when a user joins the group.                                  |
| **ccGroupMemberAdded**        | Triggered when a user is added to the group.                            |
| **ccOwnershipChanged**        | Triggered when the group ownership is assigned to another group member. |

## CometChatMessageEvents

`CometChatMessageEvents` emits events when the logged-in user acts on a message object. This category includes both UIKit-level events and CometChat SDK listener events.

### UIKit Events

| Event Name              | Description                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ccMessageSent**       | Triggered when the sent message is in transit and also when it is received by the receiver.                                                                                                                                                                                                                                                                                                                                  |
| **ccMessageEdited**     | Triggered when the user successfully edits a message.                                                                                                                                                                                                                                                                                                                                                                        |
| **ccReplyToMessage**    | Triggered when the user successfully replies to a message.                                                                                                                                                                                                                                                                                                                                                                   |
| **ccMessageDeleted**    | Triggered when the user successfully deletes a message.                                                                                                                                                                                                                                                                                                                                                                      |
| **ccMessageRead**       | Triggered when the sent message is read by the receiver.                                                                                                                                                                                                                                                                                                                                                                     |
| **ccCardActionClicked** | Triggered when a user taps an interactive element on a card (developer card or nested agent card). Carries an `ICardActionEvent` with the owning `message` (or `null` for a streaming card), the raw renderer `action`, and the originating `elementId`/`cardJson`. The UIKit forwards the action untouched and runs no behavior. See the [Card Messages guide](/ui-kit/angular/guides/card-messages#handling-card-actions). |

### SDK Listener Events

| Event Name                     | Description                                                                                                                                                                                 |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **onTextMessageReceived**      | Emitted when the CometChat SDK listener receives a text message.                                                                                                                            |
| **onMediaMessageReceived**     | Emitted when the CometChat SDK listener receives a media message.                                                                                                                           |
| **onCustomMessageReceived**    | Emitted when the CometChat SDK listener receives a custom message.                                                                                                                          |
| **onTypingStarted**            | Emitted when the CometChat SDK listener indicates that a user has started typing.                                                                                                           |
| **onTypingEnded**              | Emitted when the CometChat SDK listener indicates that a user has stopped typing.                                                                                                           |
| **onMessagesDelivered**        | Emitted when the CometChat SDK listener indicates that messages have been delivered.                                                                                                        |
| **onMessagesRead**             | Emitted when the CometChat SDK listener indicates that messages have been read.                                                                                                             |
| **onMessageEdited**            | Emitted when the CometChat SDK listener indicates that a message has been edited.                                                                                                           |
| **onMessageDeleted**           | Emitted when the CometChat SDK listener indicates that a message has been deleted.                                                                                                          |
| **onTransientMessageReceived** | Emitted when the CometChat SDK listener receives a transient message.                                                                                                                       |
| **onCardMessageReceived**      | Emitted when the CometChat SDK listener receives a developer card message (`category: "card"`). Carries a `CometChat.CardMessage`. The UIKit renders cards but never sends or creates them. |

## CometChatThreadEvents

`CometChatThreadEvents` emits events when this client's view of a thread's subscription changes — whether the change was made here, on another device, or by the server.

| Event Name                      | Description                                                                                                                                                          |
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ccThreadSubscriptionChanged** | Triggered when a thread is followed or unfollowed. Also fires for the auto-subscribe the backend performs when the user replies to a thread they were not following. |

**Payload (`IThreadSubscriptionChanged`)**

| Field             | Type      | Description                                            |
| ----------------- | --------- | ------------------------------------------------------ |
| `parentMessageId` | `number`  | The root message ID of the thread whose state changed. |
| `subscribed`      | `boolean` | Whether the logged-in user now follows the thread.     |

Every emission originates in the UI Kit — a manual toggle, its revert on failure, or a mirror of an auto-subscribe the server performed. The Chat SDK emits no subscription events of its own, so this subject is the only channel.

On a matching `parentMessageId`, re-render **and** stamp `subscribed` onto the message objects you hold, so your copy stays in step with the kit's.

This is the channel that keeps the thread header control and the message action sheet in agreement without a refetch. It is also the channel to subscribe to if you build your own threads list against `CometChat.ThreadsRequestBuilder`.

Prefer the typed helper over subscribing to the subject directly — pass a `DestroyRef` and it unsubscribes with the component:

```typescript theme={null}
import { DestroyRef, inject } from '@angular/core';
import { CometChatThreadEvents } from '@cometchat/chat-uikit-angular';

private destroyRef = inject(DestroyRef);

ngOnInit() {
  CometChatThreadEvents.onThreadSubscriptionChanged(({ parentMessageId, subscribed }) => {
    // re-render, and stamp `subscribed` onto your held copies
  }, this.destroyRef);
}
```

<Warning>
  Unfollowing hard-deletes the thread-list row server-side. A list of your own must **remove** the row rather than re-render it in an "unfollowed" style.
</Warning>

See the [Thread Subscription guide](/ui-kit/angular/guides/thread-subscription) for the full feature.

## CometChatPinSaveEvents

`CometChatPinSaveEvents` emits events when a message is pinned, unpinned, saved, or unsaved.

It publishes on **two tiers**, and the split is the point:

* **Server truth** — a confirmed write or a realtime frame. Authoritative.
* **This client's optimism** — the flip a surface applied before the server answered, and its reversal if the write failed. Not authoritative.

### Server truth

| Event Name            | Reach                 | Description                                                                                                             |
| --------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **ccMessagePinned**   | Broadcast             | Triggered when a message is pinned. A pin is conversation-wide, so everyone in the conversation receives it.            |
| **ccMessageUnpinned** | Broadcast             | Triggered when a message is unpinned.                                                                                   |
| **ccMessageSaved**    | Private, multi-device | Triggered when the logged-in user saves a message. A save is per-user, so this arrives only on that user's own devices. |
| **ccMessageUnsaved**  | Private, multi-device | Triggered when the logged-in user unsaves a message.                                                                    |

**Payload (`IPinSaveChanged`)**

| Field     | Type                    | Description               |
| --------- | ----------------------- | ------------------------- |
| `message` | `CometChat.BaseMessage` | The full updated message. |

### This client's optimism

| Event Name               | Payload        | Description                                                                                  |
| ------------------------ | -------------- | -------------------------------------------------------------------------------------------- |
| **ccMessagePinChanged**  | `IPinChanged`  | This client's own pin flip before the server confirms it, and its revert if the write fails. |
| **ccMessageSaveChanged** | `ISaveChanged` | The same, for save.                                                                          |

**Payload (`IPinChanged` / `ISaveChanged`)**

| Field              | Type                    | Description                                                                                                                                  |
| ------------------ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `message`          | `CometChat.BaseMessage` | The message acted on.                                                                                                                        |
| `pinned` / `saved` | `boolean`               | The state this client is **claiming**. One channel covers both directions: an optimistic pin publishes `true`, its revert publishes `false`. |

### Which to subscribe to

A surface almost always wants **both** tiers — the optimism for immediate feedback, the truth for correctness. Four merged observables pair them per direction, so you subscribe once and cannot drift out of step:

| Observable  | Emits when                                                 |
| ----------- | ---------------------------------------------------------- |
| `pinned$`   | Pinned, whether claimed locally or confirmed by the server |
| `unpinned$` | Unpinned, either tier                                      |
| `saved$`    | Saved, either tier                                         |
| `unsaved$`  | Unsaved, either tier                                       |

Prefer these over the raw subjects. Each has a typed helper that takes an optional `DestroyRef` and unsubscribes with your component:

```typescript theme={null}
import { DestroyRef, inject } from '@angular/core';
import { CometChatPinSaveEvents } from '@cometchat/chat-uikit-angular';

private destroyRef = inject(DestroyRef);

ngOnInit() {
  CometChatPinSaveEvents.onMessagePinned(({ message }) => {
    // swap your copy of `message` wholesale
  }, this.destroyRef);

  CometChatPinSaveEvents.onMessageUnpinned(({ message }) => { /* ... */ }, this.destroyRef);
  CometChatPinSaveEvents.onMessageSaved(({ message }) => { /* ... */ }, this.destroyRef);
  CometChatPinSaveEvents.onMessageUnsaved(({ message }) => { /* ... */ }, this.destroyRef);
}
```

### Conversation pins

Conversation pinning publishes on the same two tiers.

| Event Name                   | Tier         | Payload                       | Description                                                                              |
| ---------------------------- | ------------ | ----------------------------- | ---------------------------------------------------------------------------------------- |
| **ccConversationPinned**     | Server truth | `IConversationPinSaveChanged` | A conversation was pinned — a confirmed write or a realtime frame from another device.   |
| **ccConversationUnpinned**   | Server truth | `IConversationPinSaveChanged` | A conversation was unpinned.                                                             |
| **ccConversationPinChanged** | Optimistic   | `IConversationPinChanged`     | This client's own flip before the server confirms it, and its revert if the write fails. |

**Payloads**

| Interface                     | Fields                                                                                        |
| ----------------------------- | --------------------------------------------------------------------------------------------- |
| `IConversationPinSaveChanged` | `conversation: CometChat.Conversation`                                                        |
| `IConversationPinChanged`     | `conversation: CometChat.Conversation`, `pinned: boolean` — the state this client is claiming |

As with messages, prefer the merged pair over the raw subjects — `conversationPinned$` and `conversationUnpinned$`, or their typed helpers:

```typescript theme={null}
CometChatPinSaveEvents.onConversationPinned(({ conversation }) => {
  // re-order your own list
}, this.destroyRef);

CometChatPinSaveEvents.onConversationUnpinned(({ conversation }) => { /* ... */ }, this.destroyRef);
```

<Note>
  Two kinds of pin arrive on these channels, and the reach differs. A **personal** pin is private to the user and syncs across their own devices. An **app-wide** pin, made by an admin, carries `pinnedBy === "app_system"` and applies to everyone — so a frame can reach a session whose user did nothing. `conversation.isPinned()` is true for either; use `conversation.isSystemPinned()` to tell them apart rather than string-comparing `getPinnedBy()`. Where a personal and an app-wide pin both exist, the server resolves precedence.

  `CometChatConversations` re-orders itself without these events — subscribe when you keep a list of your own.
</Note>

<Note>
  The SDK does not echo a change back to the device that made it, so `CometChatConversations` publishes on its own confirmed toggle. That is why a surface should subscribe to the merged `conversationPinned$` / `conversationUnpinned$` rather than the raw subjects: they carry both this client's flip and everyone else's.
</Note>

<Warning>
  Each payload carries the **full updated message**, so swap your copy wholesale rather than patching fields. `pinnedAt` and `savedAt` are present-only-when-set and are cleared — never zeroed — on unpin and unsave, so a partial patch leaves a stale timestamp behind and the indicator never disappears.
</Warning>

See the [Pin and Save guide](/ui-kit/angular/guides/pin-and-save-messages) for the full feature.

## CometChatCallEvents

`CometChatCallEvents` emits events when the logged-in user acts on a call object.

| Event Name         | Description                                                    |
| ------------------ | -------------------------------------------------------------- |
| **ccOutgoingCall** | Triggered when the user initiates a voice/video call.          |
| **ccCallAccepted** | Triggered when the initiated call is accepted by the receiver. |
| **ccCallRejected** | Triggered when the initiated call is rejected by the receiver. |
| **ccCallEnded**    | Triggered when the initiated call successfully ends.           |

## UI Events

UI events are triggered when a user interacts with UIKit elements such as buttons, menus, or input fields.

| Event Name              | Description                                                    |
| ----------------------- | -------------------------------------------------------------- |
| **ccActiveChatChanged** | Triggered when the user navigates to a particular chat window. |

## Usage

Subscribe to events in `ngOnInit` and unsubscribe in `ngOnDestroy` to prevent memory leaks.

```typescript expandable theme={null}
import { Component, OnInit, OnDestroy } from '@angular/core';
import { CometChatMessageEvents } from '@cometchat/chat-uikit-angular';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-chat',
  standalone: true,
  template: `<!-- your template -->`
})
export class ChatComponent implements OnInit, OnDestroy {
  private messageSubscription?: Subscription;

  ngOnInit(): void {
    this.messageSubscription = CometChatMessageEvents.ccMessageSent.subscribe(
      ({ message, status }) => {
        // `status` reflects the send lifecycle: inprogress, success, or error.
        console.log('Message sent:', message, status);
      }
    );
  }

  ngOnDestroy(): void {
    this.messageSubscription?.unsubscribe();
  }
}
```

<Note>
  When subscribing to multiple events, consider using a `Subscription` container to manage all subscriptions together.
</Note>

```typescript expandable theme={null}
import { Component, OnInit, OnDestroy } from '@angular/core';
import {
  CometChatMessageEvents,
  CometChatConversationEvents,
  CometChatGroupEvents
} from '@cometchat/chat-uikit-angular';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-chat-listener',
  standalone: true,
  template: `<!-- your template -->`
})
export class ChatListenerComponent implements OnInit, OnDestroy {
  private subscriptions = new Subscription();

  ngOnInit(): void {
    this.subscriptions.add(
      CometChatMessageEvents.ccMessageSent.subscribe(({ message, status, parentMessageId }) => {
        // `status` reflects the send lifecycle: inprogress, success, or error.
        // `parentMessageId` is present for thread-scoped messages.
        console.log('Message sent:', message, status, parentMessageId);
      })
    );

    this.subscriptions.add(
      CometChatConversationEvents.ccConversationDeleted.subscribe((conversation) => {
        console.log('Conversation deleted:', conversation);
      })
    );

    this.subscriptions.add(
      CometChatGroupEvents.ccGroupMemberAdded.subscribe((data) => {
        console.log('Member added:', data);
      })
    );
  }

  ngOnDestroy(): void {
    this.subscriptions.unsubscribe();
  }
}
```
