Use in-meeting chat
The code on this page works with either the default UI or the custom UI.
The Meeting SDK lets you use in-meeting chat to communicate with other participants in the same meeting.
Handle chat functionality through the InMeetingChatController interface.
if let meetingChatController = ZoomSDK.shared().getMeetingService()?.getMeetingChatController() {
}
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.
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
}
}
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.
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_To_Everyone)
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_To_Host)
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_Disable_Attendee_Chat)
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_Host_Public)
[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.
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
}
}
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.
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_To_Everyone)
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_To_All_Panelist)
meetingActionCtrl.setParticipantsChatPrivilege(ZoomSDKChatPrivilegeType_Disable_Attendee_Chat)
[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.
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)
}
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. Once you've retrieved the thread ID, pass it in and set the type based on whether the parent message is public or private.
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)
}
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.
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)
}
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.
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.
}
// 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
if let meetingActionController = ZoomSDK.shared().getMeetingService()?.getMeetingActionController() {
let msgID: String = ""
if meetingActionController.isChatMessageCanBeDeleted(msgID) {
meetingActionController.deleteChatMessage(msgID)
}
}
- (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.
if let chatInfoSegmentDetails = chatInfo.getSegmentDetails() {
for segment in chatInfoSegmentDetails {
segment.strContent
segment.boldAttrs
segment.italicAttrs
segment.underlineAttrs // and more
}
}
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.