CEC iOS SDK API

Send Text Message

// Create a text message body
      EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"content"];
      HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#Hyphenate username#> to:<#IM service ID#> body:body];
    [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        // progress of sending the message
    } completion:^(HMessage *aMessage, HError *aError) {
        // message sent. It is successful if aError is empty
    }];

Send Voice Message

EMVoiceMessageBody *body = [[EMVoiceMessageBody alloc] initWithLocalPath:"local path" displayName:@"diplay name"];
    body.duration = @"length of time";
    HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#Hyphenate username#> to:<#IM service ID#> body:body];
    [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        // progress of sending the message
    } completion:^(HMessage *aMessage, HError *aError) {
        // message sent. It is successful if aError is empty
    }];

Send Picture Message

EMImageMessageBody *body = [[EMImageMessageBody alloc] initWithData:<#imagedata#> displayName:<#image name#>];
     HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#Hyphenate username#> to:<#IM service ID#> body:body];
    [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        // progress of sending the message
    } completion:^(HMessage *aMessage, HError *aError) {
        // message sent. It is successful if aError is empty
    }];

Send Location Message

EMImageMessageBody *body = [[EMImageMessageBody alloc] initWithData:<#imagedata#> displayName:<#image name#>];
     HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#Hyphenate username#> to:<#IM service ID#> body:body];
    [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        // progress of sending the message
    } completion:^(HMessage *aMessage, HError *aError) {
        // message sent. It is successful if aError is empty
    }];

Send Transparent Message ====

// used in "chat with agent" scenarios. The parameter is the specific action
   EMCmdMessageBody *body = [[EMCmdMessageBody alloc] initWithAction:@"TransferToKf"];
   HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#Hyphenate username#> to:<#IM service ID#> body:body];
   // The parameter is type. The id and serviceSessionId in the parameters are passed by the server
   ControlType *type = [[ControlType alloc] initWithValue:[weichat valueForKey:@"ctrlType"] ];
   ControlArguments *arguments = [ControlArguments new]; 
   arguments.identity = [ctrlArgs valueForKey:@"id"]; 
   arguments.sessionId = [ctrlArgs valueForKey:@"serviceSessionId"];
   ControlMessage *hcont = [ControlMessage new];
   hcont.type = type; // assign when needed
   hcont.arguments = arguments; // assign when needed
   [message addCompositeContent:hcont];
   [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        // progress of sending the message
    } completion:^(HMessage *aMessage, HError *aError) {
        // message sent. It is successful if aError is empty
    }];

Send Extended Message

Extended messages are used to implement certain functions, such as specifying a team, specifying an agent, passing a customer profile.

message (HMessage *);
      NSDictionary *dic = @{@"key1":@"value1",
                            @"key2":@"value2"};
      [message addAttributeDictionary:dic];
      [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        // progress of sending the message
    } completion:^(HMessage *aMessage, HError *aError) {
        // message sent. It is successful if aError is empty
    }];

Pass Customer Profile

When you need to pass customer attributes (nickname, phone, etc.) to Hyphenate Customer Engagement Cloud, you need to put the attributes in an extended message. Example of an extended text message:

// these attributes can be default
HVisitorInfo *visitor = [[HVisitorInfo alloc] init];
visitor.name = @"Jane Doe";
visitor.qq = @"12345678";
visitor.phone = @"13636362637";
visitor.companyName = @"Hyphenate";
visitor.nickName = @"Jane";
visitor.email = @"abv@hyphenate.io";
visitor.desc = @"Hyphenate Customer Engagement Cloud";
HMessage *message = [....];// construct the message
[message addContent:visitor]; // pass the customer profile
[[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        // progress of sending the message
        } completion:^(HMessage *aMessage, HError *aError) {
        // message sent. It is successful if aError is empty
}];

Send Track Message

EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@""];
  HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#Hyphenate username#> to:<#IM service ID#> body:body];
  VisitorTrack *vst = [VisitorTrack new];
  vst.title = title;  // title
  vst.price = price; // price
  vst.desc = desc;// description
  vst.imageUrl = imageUrl; // image URL
  vst.itemUrl = itemUrl; // Link to jump to
  [message addContent:vt];
  [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        // progress of sending the message
    } completion:^(HMessage *aMessage, HError *aError) {
        // message sent. It is successful if aError is empty
    }];

Send Order Message

EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@""];
  HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#Hyphenate username#> to:<#IM service ID#> body:body];
  OrderInfo *ord = [OrderInfo new];
  ord.title = title;
  ord.orderTitle = orderTitle;
  ord.price = price;
  ord.desc = desc;
  ord.imageUrl = imageUrl;
  ord.itemUrl = itemUrl;
  [message addContent:ord];
  [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        // progress of sending the message
    } completion:^(HMessage *aMessage, HError *aError) {
        // message sent. It is successful if aError is empty
    }];

Specify Agent

Specify an agent to serve conversations.

The agent account is the agent's login email address.

HMessage *message = [....];// construct a message
[message addContent:[[HAgentIdentityInfo alloc] initWithValue:@"Agent account"]];

Specify Team

Specify a team to serve conversations.

The name of the team must be exactly the same as the name of the team set on the Hyphenate Customer Engagement Cloud.

HMessage *message = [....];// construct a message
   [message addContent:[[HQueueIdentityInfo alloc] initWithValue:@"Team name"]];

Receive Messages

Receive messages by registering listeners to the messages.

// Add a message listener. The second parameter is the queue to execute the delegate. It is the main queue by default.
[[HChatClient sharedClient].chat addDelegate:self delegateQueue:nil];
// Remove message listener
[[HChatClient sharedClient].chat removeDelegate:self];
- (void)messagesDidReceive:(NSArray *)aMessages{
     // receive a regular message, format: <HMessage *>
}
- (void)cmdMessagesDidReceive:(NSArray *)aCmdMessages{
     // receive a command message, format: <HMessage *>. Command messages are not saved in the database. They are used as system notifications, such as comment updates in notes,
     // and conversations served, transferred, and closed
}
- (void)messageStatusDidChange:(HMessage *)aMessage error:(HError *)aError{
     // message status updated. It is used to refresh the list and display the latest status
}
- (void)messageAttachmentStatusDidChange:(HMessage *)aMessage error:(HError *)aError{
    // Message sent. It is used to refresh the list and display the latest message
}

Detect Message Type

message.body.type == EMMessageBodyTypeText;  // text message
message.body.type == EMMessageBodyTypeImage; // image message
message.body.type == EMMessageBodyTypeVoice; // voice message
message.body.type == EMMessageBodyTypeFile;  // file message
message.body.type == EMMessageBodyTypeCmd;   // command message

// for a text message, you need to check its subtype
[HjudgeTextMessageSubType isTrackMessage:<#HMessage *#>] == YES;   // track message
[HjudgeTextMessageSubType isOrderMessage:<#HMessage *#>] == YES;   // order message
[HjudgeTextMessageSubType isMenuMessage:<#HMessage *#>] == YES;    // menu message
[HjudgeTextMessageSubType isTransferMessage:<#HMessage *#>] == YES;// specify agent
[HjudgeTextMessageSubType isEvaluateMessage:<#HMessage *#>] == YES;// satisfaction ratings

Get Conversation Details

* Retrieve a specified number of messages from the database. The retrieved messages are sorted by time and do not contain the reference message. If the reference message ID is empty, retrieve the latest messages.
*
*  @param aMessageId       reference message ID
*  @param count            number of messages
*  @param aDirection       search direction
*  @param aCompletionBlock callback when completed
_conversation = [[HChatClient sharedClient].chat getConversation:<IM service ID>];
[_conversation loadMessagesStartFromId:<#messageId#> count:<#(int)count#> searchDirection:<#HMessageSearchDirectionUp#> completion:^(NSArray *aMessages, HError *aError) {
        if (!aError && [aMessages count]) {
            //obtained messages aMessages
        }
    }];

Get All Conversations

NSArray<HConversation *> *conversastions = [[HChatClient sharedClient].chat loadAllConversations];

Delete Conversation and History

// delete a conversation. parameter: conversation ID, whether to delete its messages
[[HCHatClient shareClient].chat deleteConversation:<#conversationId#> deleteMessages:YES];
HConversation *conversation = [[HConversation alloc] initWithConversation:<#conversationId#>];
// delete a message from a conversation. parameter: message ID, error pointer
[conversation deleteMessageWithId:<#messageId#> error:<#(HError **)#>];
// delete all messages from a conversation (without deleting the conversation)
[conversation deleteAllMessages:<#(HError **)#>];

Get the Number of Unread Messages

Hconversation *conversation = [[HChatClient sharedClient].chat getConversation:<#IM service ID#>];
int unreadCount = conversation.unreadMessagesCount; // get the number of unread messages in a specified conversation

Clear the Number of Unread Messages

Hconversation *conversation = [[HChatClient sharedClient].chat getConversation:<#IM service ID#>];
  [conversation markAllMessagesAsRead:nil];

Get All Notes

/*
@param tenantId    tenant ID
@param cname       IM service ID
@param projectId  Note Project ID
@param page        Page number. It starts from 0. The default is 0.
@param pageSize    Size of each page. The default is 10. The maximum is 100.
*/
[[HLeaveMsgManager shareInstance] asyncGetMessagesWithTenantId:<#tenantId#> projectId:<#projectId#> cname:<#NSString *#> page:<#page#> pageSize:<#pageSize#> completion:^(id responseObject, NSError *error) {
        if(!error) { // request succeeded
        } else { // failed
        }
    }];

Create Note

// A note includes: creator information, attachment (array) and other attributes
Creator *creator = [Creator new];
creator.name = <#Creator name#>;
creator.avatar = <#Avatar address#>;
creator.email = <#Email#>;
creator.phone = <#Phone number#>;
creator.qq = <#QQ ID#>;
creator.companyName = <#Company#>;
creator.desc = <#Description#>;
// attachments (there may or may not be attachments)
LeaveMsgAttachment *attachment = [LeaveMsgAttachment new];
attachment.name = <#File name#>;
attachment.type = <#Attachment type#>;
attachment.url = <#URL#>;
LeaveMsgRequestBody *body = [[LeaveMsgRequestBody alloc] init];
body.subject = <#Subject#>;
body.content = <#Content#>;
body.status = <#Default status#>;
body.creator = creator;
NSArray *attachments = @[attachment];
body.attachments = attachments;
/*
@param tenantId    tenant ID
@param projectId  Note Project ID
@param cname       IM service ID
@param requestBody Note parameters
*/
[[HLeaveMsgManager shareInstance] asyncCreateMessageWithTenantId:<#NSString *#> projectId:<#NSString *#> cname:<#NSString *#> requestBody:<#LeaveMsgRequestBody *#> completion:^(id responseObject, NSError *error) {
        if(error == nil){ // note sent successfully
        } else {// failed to send note
        }
    }];

Get Note Details

/*
@param tenantId    tenant ID
@param projectId  Note Project ID
@param cname       IM service ID
@param ticketId Note id
*/
[[HLeaveMsgManager shareInstance] asyncGetLeaveMessageDetailWithTenantId:<#NSString *#> projectId:<#NSString *#> cname:<#NSString *#> ticketId:<#NSString *#> completion:^(id responseObject, NSError *error) {
     if(error == nil){ // succeeded
        } else {// failed
        }
}];

Get All Comments for a Note

/*
@param tenantId    tenant ID
@param projectId  Note Project ID
@param cname       IM service ID
@param ticketId Note id
@param page        Page number. It starts from 0. The default is 0.
@param pageSize    Size of each page. The default is 10. The maximum is 100.
*/
[[HLeaveMsgManager shareInstance] asyncGetLeaveMessageAllCommentsWithTenantId:<#(NSString *)#> projectId:<#(NSString *)#> cname:<#NSString *#> ticketId:<#(NSString *)#> page:<#(NSUInteger)#> pageSize:<#(NSUInteger)#> completion:^(id responseObject, NSError *error) {
        if(error == nil){ // succeeded
        } else {// failed
        }
    }];

Add a Comment to a Note

// A comment includes: creator information, attachment (array) and other attributes
Creator *creator = [Creator new];
creator.identity = <#optional, id of the person who comments#>;
creator.name = <#Creator name#>;
creator.avatar = <#Avatar address#>;
creator.email = <#Email#>;
creator.phone = <#Phone number#>;
creator.qq = <#QQ ID#>;
creator.companyName = <#Company#>;
// attachments (there may or may not be attachments)
LeaveMsgAttachment *attachment = [LeaveMsgAttachment new];
attachment.name = <#File name#>;
attachment.type = <#Attachment type#>;
attachment.url = <#URL#>;
LeaveMsgRequestBody *body = [[LeaveMsgRequestBody alloc] init];
body.subject = <#Subject#>;
body.content = <#Content#>;
body.replyId = <#ID of the person who replies to the comment#>
body.status = <#Default status#>;
body.creator = creator;
NSArray *attachments = @[attachment];
body.attachments = attachments;

/*
@param tenantId    tenant ID
@param projectId  Note Project ID
@param cname       IM service ID
@param ticketId Note id
@param requestBody  Request body
*/
[[HLeaveMsgManager shareInstance] asyncLeaveAMessageWithTenantId:<#tenant ID#> projectId:<#projectId#> cname:<#NSString *#> ticketId:<#note ID#> requestBody:<#LeaveMsgRequestBody*#> completion:^(id responseObject, NSError *error) {
       if(error == nil){ // succeeded
        } else {// failed
        }
    }];

Get Working Status

@param tenantId    tenant ID
[[HLeaveMsgManager shareInstance] getWorkStatusWithTenantId:<#(NSString *)#> completion:^(BOOL isWork, NSError *error) {
        if (error == nil) { // succeeded
            if (isWork) { // work hours
            } else { // non-work hours
            }
        } else { // failed
        }
    }];

Real-time Calling

// settings for accepting the video invitation
HCallOptions *options = [[HCallOptions alloc] init];
options.videoOff = NO; // whether to turn off the video transmission
options.mute = NO; // whether to mute
options.nickName = <#(NSString *)#>; // nickname
options.previewView = <#(HCallLocalView*)#>; // local preview View
[[HChatClient sharedClient].call setCallOptions:options];
// register for real-time call callback
[[HChatClient sharedClient].call addDelegate:<#(id<HCallManagerDelegate>)#> delegateQueue:nil]; //queue defaults to main
// remove real-time call callback
[[HChatClient sharedClient].call removeDelegate:<#(id<HCallManagerDelegate>)#>];
// receive a video call request with the nickname of the requester
- (void)onCallReceivedNickName:(NSString *)nickName;
// member joins the conversation
- (void)onMemberJoin:(HCallMember *)member;
// member leaves the conversation
- (void)onMemberExit:(HCallMember *)member;
// a video stream coming in
- (void)onStreamAdd:(HCallStream *)stream;
// a video stream is removed [not including yourself]
- (void)onStreamRemove:(HCallStream *)stream;
// video stream is updated
- (void)onStreamUpdate:(HCallStream *)stream;
// the video call ends
- (void)onCallEndReason:(int)reason desc:(NSString *)desc;
// video call is over
- (void)callDidEnd:(HCallSession *)aSession reason:(HCallEndReason)aReason error:(HError *)aError;

// accept video request
[[HChatClient sharedClient].call acceptCallCompletion:^(id obj, HError *error) {
        if (error == nil) { // accepted successfully
        }
}];
// reject video request
[[HChatClient sharedClient].call endCall];
// hang up the video request
[[HChatClient sharedClient].call endCall];
// switch camera
[[HChatClient sharedClient].call switchCameraPosition:YES]; // default front camera (YES)
// turn off the microphone
[[HChatClient sharedClient].call pauseVoice];
// turn on the microphone
[[HChatClient sharedClient].call resumeVoice];
// turn off local video transmission
[[HChatClient sharedClient].call pauseVideo];
// turn on local video transmission
[[HChatClient sharedClient].call resumeVideo];

// subscribe to member videos
[[HChatClient sharedClient].call subscribeStreamId:streamId view:topView completion:^(id obj, HError *error) {
    if (error == nil) {
    } else {
    }
}];
//unsubscribe
[[HChatClient sharedClient].call unSubscribeStreamId:streamId completion:^(id obj, HError *error) {
    if (error == nil) {
    } else {
    }
}];