# Use in-meeting chat

<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

> The code on this page works with either the **default UI** or the **custom UI**.

The Meeting SDK lets you [use in-meeting chat](https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0064400) to communicate with other participants in the same meeting.

Handle chat functionality through the `InMeetingChatController` interface.

```swift
if let meetingChatController = ZoomSDK.shared().getMeetingService()?.getMeetingChatController() {

}
```

```objectivec
ZoomSDKMeetingChatController *meetingChatController = [[[ZoomSDK sharedSDK] getMeetingService] getMeetingChatController];
if (meetingChatController) {

}
```

## Control chat settings

Before you use in-meeting chat, check if the current meeting or webinar supports chat, and then look at which participants or attendees can use chat.

### Chat settings in a meeting

In a meeting, use ZoomSDKMeetingActionController.

```swift
if let meetingActionCtrl = ZoomSDK.shared().getMeetingService()?.getMeetingActionController() {
    if meetingActionCtrl.isParticipantsChatAllowed() {

    }

    // OR for more breakdown

    if let normalMeetingPrivilege = meetingActionCtrl.getChatStatus()?.getNormalMeetingPrivilege() {
        normalMeetingPrivilege.canChat
        normalMeetingPrivilege.canChatToAll
        normalMeetingPrivilege.canChatToIndividual
        normalMeetingPrivilege.isOnlyCanChatToHost
    }
}
```

```objectivec
ZoomSDKMeetingActionController *meetingActionCtrl = [[[ZoomSDK sharedSDK] getMeetingService] getMeetingActionController];
if (meetingActionCtrl) {
    if (meetingActionCtrl.isParticipantsChatAllowed) {

    }

    // OR for more breakdown
    ZoomSDKNormalMeetingChatPrivilege *normalMeetingPrivilege = [[meetingActionCtrl getChatStatus] getNormalMeetingPrivilege];
    if (normalMeetingPrivilege) {
        normalMeetingPrivilege.canChat;
        normalMeetingPrivilege.canChatToAll;
        normalMeetingPrivilege.canChatToIndividual;
        normalMeetingPrivilege.isOnlyCanChatToHost;
    }
}
```

The `ZoomSDKNormalMeetingChatPrivilege` has these values.

-   `canChat` - The user may use chat to send both private and public messages.
-   `canChatToAll` - The user may use chat, but private messages are not allowed.
-   `canChatToIndividual` - The user may use chat only to individual user.
-   `isOnlyCanChatToHost` - The user may use chat only to host.

If the current user is the meeting's host, they can control chat settings by specifying a `ZoomSDKChatPrivilegeType`.

```swift
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_To_Everyone)
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_To_Host)
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_Disable_Attendee_Chat)
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_Host_Public)
```

```objectivec
[meetingActionCtrl setParticipantsChatPrivilege: ZoomSDKChatPrivilegeType_To_Everyone];
[meetingActionCtrl setParticipantsChatPrivilege: ZoomSDKChatPrivilegeType_To_Host];
[meetingActionCtrl setParticipantsChatPrivilege: ZoomSDKChatPrivilegeType_Disable_Attendee_Chat];
[meetingActionCtrl setParticipantsChatPrivilege: ZoomSDKChatPrivilegeType_Host_Public];
```

### Chat settings in a webinar

In a webinar, use `ZoomSDKMeetingActionController` or `ZoomSDKWebinarController`.

```swift
if let webinarCtrl = ZoomSDK.shared().getMeetingService()?.getWebinarController() {
    // Attendee - ZoomSDKWebinarController doesn't seem to have a getAttendeeChatPriviledge  and only has getPanelistChatPrivilege

    // Panelist
    var panelistChatPriviledge: ZoomSDKPanelistChatPrivilege = ZoomSDKPanelistChatPrivilege_PanelistOnly
    if webinarCtrl.getPanelistChatPrivilege(&panelistChatPriviledge) == ZoomSDKError_Success {
        switch panelistChatPriviledge {
        case ZoomSDKPanelistChatPrivilege_PanelistOnly:
            // Allow panelists only to chat with each other
            return
        case ZoomSDKPanelistChatPrivilege_All:
            // Allow panelist to chat with everyone
            return
        default:
            // There won't be a default case
            return
        }
    }
}

// OR for more breakdown
if let meetingActionCtrl = ZoomSDK.shared().getMeetingService()?.getMeetingActionController() {
    // Attendee
    if let webinarAttendeeChatPrivilege = meetingActionCtrl.getChatStatus()?.getWebinarAttendeePrivilege() {
        webinarAttendeeChatPrivilege.canChat
        webinarAttendeeChatPrivilege.canChatToAllPanellist
        webinarAttendeeChatPrivilege.canChatToAllPanellistAndAttendee
    }

    // Panelist
    if let webinarPanelistChatPrivilege = meetingActionCtrl.getChatStatus()?.getWebinarPanelistPrivilege() {
        webinarPanelistChatPrivilege.canChatToIndividual
        webinarPanelistChatPrivilege.canChatToAllPanellist
        webinarPanelistChatPrivilege.canChatToAllPanellistAndAttendee
    }
}
```

```objectivec
ZoomSDKWebinarController *webinarCtrl = [[[ZoomSDK sharedSDK] getMeetingService] getWebinarController];
if (webinarCtrl) {
    // Attendee - ZoomSDKWebinarController doesn't seem to have a getAttendeeChatPriviledge  and only has getPanelistChatPrivilege

    // Panelist
    ZoomSDKPanelistChatPrivilege panelistChatPriviledge = ZoomSDKPanelistChatPrivilege_PanelistOnly;
    if ([webinarCtrl getPanelistChatPrivilege:&panelistChatPriviledge] == ZoomSDKError_Success) {
        switch (panelistChatPriviledge) {
            case ZoomSDKPanelistChatPrivilege_PanelistOnly:
                return;
            case  ZoomSDKPanelistChatPrivilege_All:
                // Allow panelists to chat with everyone
                return;

            default:
                // There won't be a default case
                return;
        }
    }
}

// OR for more breakdown
ZoomSDKMeetingActionController *meetingActionCtrl = [[[ZoomSDK sharedSDK] getMeetingService] getMeetingActionController];
if (meetingActionCtrl) {
    // Attendee
    ZoomSDKWebinarAttendeeChatPrivilege *webinarAttendeeChatPrivilege = [[meetingActionCtrl getChatStatus] getWebinarAttendeePrivilege];
    if (webinarAttendeeChatPrivilege) {
        webinarAttendeeChatPrivilege.canChat;
        webinarAttendeeChatPrivilege.canChatToAllPanellist;
        webinarAttendeeChatPrivilege.canChatToAllPanellistAndAttendee;
    }

    // Panelist
    ZoomSDKWebinarPanelistChatPrivilege *webinarPanelistChatPrivilege = [[meetingActionCtrl getChatStatus] getWebinarPanelistPrivilege];
    if (webinarPanelistChatPrivilege) {
        webinarPanelistChatPrivilege.canChatToIndividual;
        webinarPanelistChatPrivilege.canChatToAllPanellist;
        webinarPanelistChatPrivilege.canChatToAllPanellistAndAttendee;
    }
}
```

The `ZoomSDKWebinarAttendeeChatPrivilege` uses one of these values.

-   `canChat` - Attendee can send message to chat.
-   `canChatToAllPanellist` - Can send message to all the panelists.
-   `canChatToAllPanellistAndAttendee` - Can send message to all the panelists and attendees.

The `ZoomSDKWebinarPanelistChatPrivilege` uses one of these values.

-   `canChatToIndividual` - Can send message to individual attendee.
-   `canChatToAllPanellist` - Can send message to all the panelists.
-   `canChatToAllPanellistAndAttendee` - Can send message to all.

Update a webinar's chat settings by setting a `ZoomSDKChatPrivilegeType`.

```swift
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_To_Everyone)
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_To_All_Panelist)
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_Disable_Attendee_Chat)
```

```objectivec
[meetingActionCtrl setParticipantsChatPrivilege: ZoomSDKChatPrivilegeType_To_Everyone];
[meetingActionCtrl setParticipantsChatPrivilege: ZoomSDKChatPrivilegeType_To_All_Panelist];
[meetingActionCtrl setParticipantsChatPrivilege: ZoomSDKChatPrivilegeType_Disable_Attendee_Chat];
```

## Send messages

To send a public message in either a meeting or a webinar, instantiate a `ChatMessageBuilder` and set the content and message type.

```swift
if let meetingChatController = ZoomSDK.shared().getMeetingService()?.getMeetingChatController() {
    let chatMsgInfoBuilder = ZoomSDKChatMsgInfoBuilder()
    /*
     Receiver (userID parameter) -
     For sending to all or all panelist: 0
     For sending to a specific user: the user's userID

     MessageType (ZoomSDKChatMessageType) -
     ZoomSDKChatMessageType_To_All - Meeting = to everyone or Webinar = to all panelist and attendees
     ZoomSDKChatMessageType_To_All_Panelist - Webinar = to all panelists
     ZoomSDKChatMessageType_To_Individual_Panelist - Webinar = to individual panelist
     ZoomSDKChatMessageType_To_Individual - To individual user
     */
    chatMsgInfoBuilder.setContent("Hello World!").setReceiver(0).setMessageType(ZoomSDKChatMessageType_To_All)
    let chatInfo = chatMsgInfoBuilder.build()
    meetingChatController.sendChatMsg(to: chatInfo)
}
```

```objectivec
ZoomSDKMeetingChatController *meetingChatController = [[[ZoomSDK sharedSDK] getMeetingService] getMeetingChatController];
if (meetingChatController) {
    ZoomSDKChatMsgInfoBuilder *chatMsgInfoBuilder = [[ZoomSDKChatMsgInfoBuilder alloc] init];
    /*
     Receiver (userID parameter) -
     For sending to all or all panelist: 0
     For sending to a specific user: the user's userID

     MessageType (ZoomSDKChatMessageType) -
     ZoomSDKChatMessageType_To_All - Meeting = to everyone or Webinar = to all panelist and attendees
     ZoomSDKChatMessageType_To_All_Panelist - Webinar = to all panelists
     ZoomSDKChatMessageType_To_Individual_Panelist - Webinar = to individual panelist
     ZoomSDKChatMessageType_To_Individual - To individual user
     */
    [[[chatMsgInfoBuilder setContent:@"Hello World!"] setReceiver:0] setMessageType:ZoomSDKChatMessageType_To_All];
    ZoomSDKChatInfo *info = [chatMsgInfoBuilder build];
    ZoomSDKError error = [meetingChatController sendChatMsgTo:info];
}
```

To reply to an existing message in a thread, first get a `threadId` for the message being responded to. For more information on how to get the `threadId`, see [Receive messages](#receive-messages). Once you've retrieved the thread ID, pass it in and set the type based on whether the parent message is public or private.

```swift
if let meetingChatController = ZoomSDK.shared().getMeetingService()?.getMeetingChatController() {
    // 1. Identify the message (ZoomSDKChatInfo) you want to reply to and get its threadID
    let chatInfo: ZoomSDKChatInfo? = nil
    guard let chatInfo = chatInfo else { return }
    let threadID = chatInfo.getThreadID()

    // 2. Build ZoomSDKChatMsgInfoBuilder with threadID
    let threadReplyMessage = ZoomSDKChatMsgInfoBuilder().setThreadId(threadID).setContent("Reply to Hello World!").setMessageType(ZoomSDKChatMessageType_To_All).build()

    // 3. Send reply message
    meetingChatController.sendChatMsg(to: threadReplyMessage)
}
```

```objectivec
ZoomSDKMeetingChatController *meetingChatController = [[[ZoomSDK sharedSDK] getMeetingService] getMeetingChatController];
if (meetingChatController) {
    // 1. Identify the message (ZoomSDKChatInfo) you want to reply to and get its threadID
    ZoomSDKChatInfo *chatInfo = nil;
    if (!chatInfo) {
        return;
    }
    NSString *threadID = chatInfo.getThreadID;

    // 2. Build ZoomSDKChatMsgInfoBuilder with threadID
    ZoomSDKChatMsgInfoBuilder *chatMsgInfoBuilder = [[ZoomSDKChatMsgInfoBuilder alloc] init];
    ZoomSDKChatInfo *threadReplyMessage = [[[[chatMsgInfoBuilder setThreadId:threadID] setContent:@"Reply to Hello World!"] setMessageType:ZoomSDKChatMessageType_To_All] build];

    // 3. Send reply message
    ZoomSDKError error = [meetingChatController sendChatMsgTo:threadReplyMessage];
}
```

Messages sent from the SDK can also include quoted text. The quote position specifies the start and end characters in the quoted text string.

```swift
if let meetingChatController = ZoomSDK.shared().getMeetingService()?.getMeetingChatController() {
    // Using positionStart as 0 and positionEnd as 42 as an example
    let quoteMessage = ZoomSDKChatMsgInfoBuilder().setQuotePosition(0, positionEnd: 42).setContent("This is a sample message stylized as a quote").setMessageType(ZoomSDKChatMessageType_To_All).build()
    meetingChatController.sendChatMsg(to: quoteMessage)
}
```

```objectivec
ZoomSDKMeetingChatController *meetingChatController = [[[ZoomSDK sharedSDK] getMeetingService] getMeetingChatController];
if (meetingChatController) {
    // Using positionStart as 0 and positionEnd as 42 as an example
    ZoomSDKChatMsgInfoBuilder *chatMsgInfoBuilder = [[ZoomSDKChatMsgInfoBuilder alloc] init];
    ZoomSDKChatInfo *quoteMessage = [[[[chatMsgInfoBuilder setQuotePosition:0 positionEnd:42] setContent:@"This is a sample message stylized as a quote"] setMessageType:ZoomSDKChatMessageType_To_All] build];
    ZoomSDKError error = [meetingChatController sendChatMsgTo:quoteMessage];
}
```

## Receive messages

To display content from chat messages, the SDK provides a callback to get notified of when a new message is sent to the meeting. You can also use this callback to confirm that a message sent by the current user has successfully been posted to the meeting chat.

Confirm to the `ZoomSDKMeetingChatControllerDelegate` protocol first, then use the `chatInfo` parameter within `onChatMessageNotification` to get information about the chat message. Some data, like `receiverID`, will only be available for specific types of messages.

```swift
if let meetingChatController = ZoomSDK.shared().getMeetingService()?.getMeetingChatController() {
meetingChatController.delegate = self
}

func onChatMessageNotification(_ chatInfo: ZoomSDKChatInfo) {
    chatInfo.getMessageID() // A unique identifier assigned to this message.
    chatInfo.getMsgContent() // The content of the message that is visible to users in the meeting.
    chatInfo.getTimeStamp() // The time at which the message was sent.
    chatInfo.getSenderUserID() // The Zoom user ID of the user who sent the message.
    chatInfo.getSenderDisplayName() // The display name of the user who sent the message.
    chatInfo.getReceiverUserID() // The Zoom user ID of the user on the receiving end of a private message.
    chatInfo.getReceiverDisplayName() // The display name of the user on the receiving end of a private message.
    chatInfo.isChatToWaitingRoom() // Whether the message was sent to the waiting room.
    chatInfo.getChatMessageType() // The message type, see "ZoomSDKChatMessageType".
    chatInfo.isComment() // Whether the chat message is a comment responding to a thread.
    chatInfo.isThread() // Whether the chat message is a thread with comments.
    chatInfo.getThreadID() // The unique identifier associated with a thread
    chatInfo.getSegmentDetails() // Get the detailed attributes such as bold, italic, strikethrough and more.
}
```

```objectivec
// In your .h file
@interface ZMSDKWindow : NSWindowController <ZoomSDKMeetingChatControllerDelegate> {

}

// In your .m file
- (void)onChatMessageNotification:(ZoomSDKChatInfo *)chatInfo {
    [chatInfo getMessageID]; // A unique identifier assigned to this message.
    [chatInfo getMsgContent]; // The content of the message that is visible to users in the meeting.
    [chatInfo getTimeStamp]; // The time at which the message was sent.
    [chatInfo getSenderUserID]; // The Zoom user ID of the user who sent the message.
    [chatInfo getSenderDisplayName]; // The display name of the user who sent the message.
    [chatInfo getReceiverUserID]; // The Zoom user ID of the user on the receiving end of a private message.
    [chatInfo getReceiverDisplayName]; // The display name of the user on the receiving end of a private message.
    [chatInfo isChatToWaitingRoom]; // Whether the message was sent to the waiting room.
    [chatInfo getChatMessageType]; // The message type, see "ZoomSDKChatMessageType".
    [chatInfo isComment]; // Whether the chat message is a comment responding to a thread.
    [chatInfo isThread]; // Whether the chat message is a thread with comments.
    [chatInfo getThreadID]; // The unique identifier associated with a thread
    [chatInfo getSegmentDetails]; // Get the detailed attributes such as bold, italic, strikethrough and more.
}
```

## Delete messages

To delete a message sent by the current user, call the `deleteChatMessage` method under `ZoomSDKMeetingActionController` with the `msgId`. This will trigger the `onChatMsgDeleteNotification` callback under `ZoomSDKMeetingActionControllerDelegate`

```swift
if let meetingActionController = ZoomSDK.shared().getMeetingService()?.getMeetingActionController() {
    let msgID: String = ""
    if meetingActionController.isChatMessageCanBeDeleted(msgID) {
        meetingActionController.deleteChatMessage(msgID)
    }
}
```

```objectivec
- (void) deleteMessage {
    ZoomSDKMeetingActionController *meetingActionController = [[[ZoomSDK sharedSDK] getMeetingService] getMeetingActionController];
    if (meetingActionController) {
        NSString *msgID = @"";
        if ([meetingActionController isChatMessageCanBeDeleted:msgID]) {
            [meetingActionController deleteChatMessage:msgID];
        }
    }
}
```

## Parse text format

The SDK supports receiving various styles of chat messages such as bold, italic, quote, font color and size, and many more. The styles are included as a list of `ZoomSDKChatMsgSegmentDetails` objects under each of the `ZoomSDKChatInfo` object.

```swift
if let chatInfoSegmentDetails = chatInfo.getSegmentDetails() {
    for segment in chatInfoSegmentDetails {
        segment.strContent
        segment.boldAttrs
        segment.italicAttrs
        segment.underlineAttrs // and more
    }
}
```

```objectivec
NSArray<ZoomSDKChatMsgSegmentDetails *> *chatInfoSegmentDetails = [chatInfo getSegmentDetails];
if (chatInfoSegmentDetails) {
    for (ZoomSDKChatMsgSegmentDetails *segment in chatInfoSegmentDetails) {
        [segment strContent];
        [segment boldAttrs];
        [segment italicAttrs];
        [segment underlineAttrs]; // and more
    }
}
```

## Understanding all the chat callbacks

For chat related callbacks, there are 2 delegates to subscribe to.

Under `ZoomSDKMeetingActionControllerDelegate`, the callbacks are `onChatStatusChangedNotification` and `onChatMsgDeleteNotification`.

Under `ZoomSDKMeetingChatControllerDelegate`, the callbacks are `onChatMessageNotification` and `onChatMessageEditNotification`.

---
