移动客服 iOS SDK API

消息

发送文本消息

//创建文本消息体
      EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"content"];
      HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#环信username#> to:<#IM 服务号#> body:body];
    [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        //发送消息进度
    } completion:^(HMessage *aMessage, HError *aError) {
        //发送消息完成,aError为空则为发送成功
    }];

发送语音消息

EMVoiceMessageBody *body = [[EMVoiceMessageBody alloc] initWithLocalPath:"本地路径" displayName:@"显示名称"];
    body.duration = @"时间长度";
    HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#环信username#> to:<#IM 服务号#> body:body];
    [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        //发送消息进度
    } completion:^(HMessage *aMessage, HError *aError) {
        //发送消息完成,aError为空则为发送成功
    }];

发送图片消息

EMImageMessageBody *body = [[EMImageMessageBody alloc] initWithData:<#imagedata#> displayName:<#image name#>];
     HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#环信username#> to:<#IM 服务号#> body:body];
    [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        //发送消息进度
    } completion:^(HMessage *aMessage, HError *aError) {
        //发送消息完成,aError为空则为发送成功
    }];

发送地理位置

EMImageMessageBody *body = [[EMImageMessageBody alloc] initWithData:<#imagedata#> displayName:<#image name#>];
     HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#环信username#> to:<#IM 服务号#> body:body];
    [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        //发送消息进度
    } completion:^(HMessage *aMessage, HError *aError) {
        //发送消息完成,aError为空则为发送成功
    }];

发送透传消息

//机器人转人工的地方有用到,参数为具体的action
   EMCmdMessageBody *body = [[EMCmdMessageBody alloc] initWithAction:@"TransferToKf"];
   HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#环信username#> to:<#IM 服务号#> body:body];
   //参数为type;服务器传过来的参数中的id和serviceSessionId
   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; //需要时赋值
   hcont.arguments = arguments; //需要时赋值
   [message addCompositeContent:hcont];
   [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        //发送消息进度
    } completion:^(HMessage *aMessage, HError *aError) {
        //发送消息完成,aError为空则为发送成功
    }];

发送扩展消息

任何消息类型,均可发送扩展消息,某些功能是通过扩展消息实现(例如:指定技能组,指定客服,传递访客的昵称电话等)

message (HMessage *);
      NSDictionary *dic = @{@"key1":@"value1",
                            @"key2":@"value2"};
      [message addAttributeDictionary:dic];
      [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        //发送消息进度
    } completion:^(HMessage *aMessage, HError *aError) {
        //发送消息完成,aError为空则为发送成功
    }];

发送带访客属性的消息

当需要为客服提供访客属性(昵称,电话等)时,需要为消息带上访客属性扩展。例如:当发送文本消息时。

//属性可以缺省
VisitorInfo *visitor = [[VisitorInfo alloc] init];
visitor.name = @"小明儿";
visitor.qq = @"12345678";
visitor.phone = @"13636362637";
visitor.companyName = @"环信";
visitor.nickName = @"风口上的猪";
visitor.email = @"abv@126.com";
visitor.desc = @"环信移动客服";
HMessage *message = [....];//构造相关消息
[message addContent:visitor]; //传访客的属性
[[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        //发送消息进度
        } completion:^(HMessage *aMessage, HError *aError) {
        //发送消息完成,aError为空则为发送成功
}];

发送轨迹消息

EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@""];
  HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#环信username#> to:<#IM 服务号#> body:body];
  VisitorTrack *vst = [VisitorTrack new];
  vst.title = title;  //标题
  vst.price = price; //价格
  vst.desc = desc;//描述
  vst.imageUrl = imageUrl; //图片url
  vst.itemUrl = itemUrl; //点击图片的链接
  [message addContent:vt];
  [[HChatClient sharedClient].chat sendMessage:message progress:^(int progress) {
        //发送消息进度
    } completion:^(HMessage *aMessage, HError *aError) {
        //发送消息完成,aError为空则为发送成功
    }];

发送订单消息

EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@""];
  HMessage *message = [[HMessage alloc] initWithConversationID:<#conversationId#> from:<#环信username#> to:<#IM 服务号#> 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) {
        //发送消息进度
    } completion:^(HMessage *aMessage, HError *aError) {
        //发送消息完成,aError为空则为发送成功
    }];

指定客服消息

HMessage *message = [....];//构造文字消息
[message addContent:[[AgentIdentityInfo alloc] initWithValue:@"客服名称"]];

指定技能组消息

调度时,指定某个技能组。

HMessage *message = [....];//构造文字消息
   [message addContent:[[QueueIdentityInfo alloc] initWithValue:@"分组名称"]];

接收消息

通过注册消息监听来接收消息。

//添加消息监控,第二个参数是执行代理方法的队列,默认是主队列
[[HChatClient sharedClient].chat addDelegate:self delegateQueue:nil];
//移除消息监控
[[HChatClient sharedClient].chat removeDelegate:self];
- (void)messagesDidReceive:(NSArray *)aMessages{
     //收到普通消息,格式:<HMessage *>
}
- (void)cmdMessagesDidReceive:(NSArray *)aCmdMessages{
     //收到命令消息,格式:<HMessage *>,命令消息不存数据库,一般用来作为系统通知,例如留言评论更新,
     //会话被客服接入,被转接,被关闭提醒
}
- (void)messageStatusDidChange:(HMessage *)aMessage error:(HError *)aError{
     //消息的状态修改,一般可以用来刷新列表,显示最新的状态
}
- (void)messageAttachmentStatusDidChange:(HMessage *)aMessage error:(HError *)aError{
    //发送消息后,会调用,可以在此刷新列表,显示最新的消息
}

检测消息类型

message.body.type == EMMessageBodyTypeText;  //文本消息
message.body.type == EMMessageBodyTypeImage; //图片消息
message.body.type == EMMessageBodyTypeVoice; //语音消息
message.body.type == EMMessageBodyTypeFile;  //文件消息
message.body.type == EMMessageBodyTypeCmd;   //命令消息

//当文本消息时,需要其他其他的检测,可能为其他类型的消息
[HjudgeTextMessageSubType isTrackMessage:<#HMessage *#>] == YES;   //轨迹消息
[HjudgeTextMessageSubType isOrderMessage:<#HMessage *#>] == YES;   //订单消息
[HjudgeTextMessageSubType isMenuMessage:<#HMessage *#>] == YES;    //菜单消息
[HjudgeTextMessageSubType isTransferMessage:<#HMessage *#>] == YES;//转接客服
[HjudgeTextMessageSubType isEvaluateMessage:<#HMessage *#>] == YES;//满意度评价

获取聊天记录

*  从数据库获取指定数量的消息,取到的消息按时间排序,并且不包含参考的消息,如果参考消息的ID为空,则从最新消息取
 *
 *  @param aMessageId       参考消息的ID
 *  @param count            获取的条数
 *  @param aDirection       消息搜索方向
 *  @param aCompletionBlock 完成的回调
_conversation = [[HChatClient sharedClient].chat getConversation:<IM 服务号>];
[_conversation loadMessagesStartFromId:<#messageId#> count:<#(int)count#> searchDirection:<#HMessageSearchDirectionUp#> completion:^(NSArray *aMessages, HError *aError) {
        if (!aError && [aMessages count]) {
            //获取到消息aMessages
        }
    }];

会话

获取所有会话

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

删除会话及聊天记录

//删除一个会话;参数:会话ID,是否删除相关的消息
[[HCHatClient shareClient].chat deleteConversation:<#conversationId#> deleteMessages:YES];
HConversation *conversation = [[HConversation alloc] initWithConversation:<#conversationId#>];
//删除会话中的一条消息记录;参数:消息Id,错误指针
[conversation deleteMessageWithId:<#messageId#> error:<#(HError **)#>];
//删除会话中的所有消息(不删除会话)
[conversation deleteAllMessages:<#(HError **)#>];

获取会话未读消息数

Hconversation *conversation = [[HChatClient sharedClient].chat getConversation:<#IM 服务号#>];
 int unreadCount = conversation.unreadMessagesCount; //获取指定会话的未读消息数

未读消息数清零

Hconversation *conversation = [[HChatClient sharedClient].chat getConversation:<#IM 服务号#>];
  [conversation markAllMessagesAsRead:nil];

留言

获取所有留言

/*
 @param tenantId    租户Id
 @param cname       IM 服务号
 @param projectId   留言的Project ID
 @param page        第几页,从0开始,默认为第0页
 @param pageSize    每一页的大小,默认为10,最大不能超过100
*/
[[HLeaveMsgManager shareInstance] asyncGetMessagesWithTenantId:<#tenantId#> projectId:<#projectId#> cname:<#NSString *#> page:<#page#> pageSize:<#pageSize#> completion:^(id responseObject, NSError *error) {
        if(!error) { //请求成功
        } else { //请求失败
        }
    }];

创建一个新的留言

//留言包括:创建者信息、附件[数组]以及其他属性
Creator *creator = [Creator new];
creator.name = <#创建者名称#>;
creator.avatar = <#头像地址#>;
creator.email = <#邮箱#>;
creator.phone = <#电话号码#>;
creator.qq = <#qq号码#>;
creator.companyName = <#公司#>;
creator.desc = <#备注#>;
//附件(附件可以没有,也可以是多个)
LeaveMsgAttachment *attachment = [LeaveMsgAttachment new];
attachment.name = <#文件名#>;
attachment.type = <#类型 AttachmentType#>;
attachment.url = <#url#>;
LeaveMsgRequestBody *body = [[LeaveMsgRequestBody alloc] init];
body.subject = <#主题#>;
body.content = <#内容#>;
body.status = <#默认处理状态#>;
body.creator = creator;
NSArray *attachments = @[attachment];
body.attachments = attachments;
/*
 @param tenantId    租户Id
 @param projectId   留言的Project ID
 @param cname       IM服务号
 @param requestBody 留言参数
*/
[[HLeaveMsgManager shareInstance] asyncCreateMessageWithTenantId:<#NSString *#> projectId:<#NSString *#> cname:<#NSString *#> requestBody:<#LeaveMsgRequestBody *#> completion:^(id responseObject, NSError *error) {
        if(error == nil){ //发送留言成功
        } else {//发送留言失败
        }
    }];

获取留言详情

/*
 @param tenantId    租户Id
 @param projectId   留言的Project ID
 @param cname       IM服务号
 @param tickedId    留言Id
*/
[[HLeaveMsgManager shareInstance] asyncGetLeaveMessageDetailWithTenantId:<#NSString *#> projectId:<#NSString *#> cname:<#NSString *#> ticketId:<#NSString *#> completion:^(id responseObject, NSError *error) {
     if(error == nil){ //获取成功
        } else {//获取失败
        }
}];

获取一个留言的所有评论

/*
 @param tenantId    租户Id
 @param projectId   留言的Project ID
 @param cname       IM服务号
 @param tickedId    留言Id
 @param page        第几页,从0开始,默认为第0页
 @param pageSize    每页数据数目,每一页的大小,默认为10,最大不能超过100
*/
[[HLeaveMsgManager shareInstance] asyncGetLeaveMessageAllCommentsWithTenantId:<#(NSString *)#> projectId:<#(NSString *)#> cname:<#NSString *#> ticketId:<#(NSString *)#> page:<#(NSUInteger)#> pageSize:<#(NSUInteger)#> completion:^(id responseObject, NSError *error) {
        if(error == nil){ //获取成功
        } else {//获取失败
        }
    }];

给一个留言添加评论

//回复包括:创建者信息、附件[数组]以及其他属性
Creator *creator = [Creator new];
creator.identity = <#可选,创建这个评论人的id#>;
creator.name = <#创建者名称#>;
creator.avatar = <#头像地址#>;
creator.email = <#邮箱#>;
creator.phone = <#电话号码#>;
creator.qq = <#qq号码#>;
creator.companyName = <#公司#>;
//附件(附件可以没有,也可以是多个)
LeaveMsgAttachment *attachment = [LeaveMsgAttachment new];
attachment.name = <#文件名#>;
attachment.type = <#类型 AttachmentType#>;
attachment.url = <#url#>;
LeaveMsgRequestBody *body = [[LeaveMsgRequestBody alloc] init];
body.subject = <#主题#>;
body.content = <#内容#>;
body.replyId = <#回复评论的Id#>
body.status = <#默认处理状态#>;
body.creator = creator;
NSArray *attachments = @[attachment];
body.attachments = attachments;

/*
 @param tenantId    租户Id
 @param projectId   留言的Project ID
 @param cname       IM服务号
 @param tickedId    留言Id
 @param requestBody  请求体
*/
[[HLeaveMsgManager shareInstance] asyncLeaveAMessageWithTenantId:<#租户id#> projectId:<#projectId#> cname:<#NSString *#> ticketId:<#留言id#> requestBody:<#LeaveMsgRequestBody*#> completion:^(id responseObject, NSError *error) {
       if(error == nil){ //回复成功
        } else {//回复失败
        }
    }];

获取工作状态

@param tenantId    租户Id
 [[HLeaveMsgManager shareInstance] getWorkStatusWithTenantId:<#(NSString *)#> completion:^(BOOL isWork, NSError *error) {
        if (error == nil) { //成功
            if (isWork) { //工作状态
            } else { //下班
            }
        } else { //请求失败
        }
    }];

实时音视频

实时通话相关

//注册实时通话回调
 [[HChatClient sharedClient].call addDelegate:self delegateQueue:nil]; //queue默认为main
 //移除实时通话回调
 [[HChatClient sharedClient].call removeDelegate:self];
 //收到一个视频通话请求
 - (void)callDidReceive:(HCallSession *)aSession;
 //通话通道建立完成
 - (void)callDidConnect:(HCallSession *)aSession;
//视频通话已经结束
- (void)callDidEnd:(HCallSession *)aSession reason:(HCallEndReason)aReason error:(HError *)aError;
//视频通话,对方数据流状态改变
- (void)callStateDidChange:(HCallSession *)aSession type:(HCallStreamingStatus)aType;
//视频通话,自己网络状态发生变化
- (void)callNetworkDidChange:(HCallSession *)aSession status:(HCallNetworkStatus)aStatus;
//HCallSession *callSession ,以下callSession是收到的音视频请求的参数HCallSession
//接受客服视频请求
[[HChatClient sharedClient].call answerIncomingCall:callSession.callId];
//拒绝客服视频请求
[[HChatClient sharedClient].call endCall:callSession.callId reason:HCallEndReasonDecline];
//视频通话中挂断
[[HChatClient sharedClient].call endCall:callSession.callId reason:HCallEndReasonDecline];
//切换镜头
[callSession switchCameraPosition: YES ]; //默认前置摄像头(YES)
//关闭麦克风
[callSession pauseVoice];
//打开麦克风
[callSession resumeVoice];
//关闭本地视频传输
 [callSession pauseVideo];
//打开本地视频传输
[callSession resumeVideo];

视频通话设置view

//设置远程的视频view
   callSession.remoteVideoView = [[HCallRemoteView alloc] initWithFrame:<#frame#>];
   //设置本地的视频view
   self.callSession.localVideoView = [[HCallLocalView alloc] initWithFrame:<#frame#>];