====== CEC iOS SDK API ======
* [[#消息|消息]]
* [[#会话|会话]]
* [[#留言|留言]]
* [[#满意度评价|满意度评价]]
* [[#实时音视频|实时音视频]]
* [[#高级功能|高级功能]]
===== 消息 =====
==== 发送文本消息 ====
//toUser 为IM服务号
HDMessage *message = [HDMessage createTxtSendMessageWithContent:text to:toUser];
[[HDClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
//发送消息进度
} completion:^(HDMessage *aMessage, HDError *aError) {
//发送消息完成,aError为空则为发送成功
}];
==== 发送语音消息 ====
// duration为语音时长, toUser为IM服务号
HDMessage *message = [HDMessage createVoiceSendMessageWithLocalPath:localPath duration:duration to:toUser];
[[HDClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
//发送消息进度
} completion:^(HDMessage *aMessage, HDError *aError) {
//发送消息完成,aError为空则为发送成功
}];
==== 发送图片消息 ====
// toUser为IM服务号
HDMessage *message =[HDMessage createImageSendMessageWithData:imageData displayName:@"image" to:toUser];
[[HDClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
//发送消息进度
} completion:^(HDMessage *aMessage, HDError *aError) {
//发送消息完成,aError为空则为发送成功
}];
==== 发送地理位置 ====
//toUser为IM服务号 address为地址信息 latitude为纬度 longitude为经度
HDMessage *message = [HDMessage createLocationSendMessageWithLatitude:latitude longitude:longitude address:address to:toUser];
[[HDClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
//发送消息进度
} completion:^(HDMessage *aMessage, HDError *aError) {
//发送消息完成,aError为空则为发送成功
}];
==== 发送透传消息 ====
//机器人转人工的地方有用到,参数为具体的action
EMCmdMessageBody *body = [[EMCmdMessageBody alloc] initWithAction:@"TransferToKf"];
HDMessage *message = [[HDMessage 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];
[[HDClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
//发送消息进度
} completion:^(HDMessage *aMessage, HDError *aError) {
//发送消息完成,aError为空则为发送成功
}];
==== 发送扩展消息 ====
任何消息类型,均可发送扩展消息,某些功能是通过扩展消息实现(例如:指定技能组,指定客服,传递访客的昵称电话等)
message (HDMessage *);
NSDictionary *dic = @{@"key1":@"value1",
@"key2":@"value2"};
[message addAttributeDictionary:dic];
[[HDClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
//发送消息进度
} completion:^(HDMessage *aMessage, HDError *aError) {
//发送消息完成,aError为空则为发送成功
}];
==== 发送带访客属性的消息 ====
当需要为客服提供访客属性(昵称,电话等)时,需要为消息带上访客属性扩展。例如:当发送文本消息时。
//属性可以缺省
HDVisitorInfo *visitor = [[HDVisitorInfo alloc] init];
visitor.name = @"小明儿";
visitor.qq = @"12345678";
visitor.phone = @"13636362637";
visitor.companyName = @"环信";
visitor.nickName = @"风口上的猪";
visitor.email = @"abv@126.com";
visitor.desc = @"环信客服云";
HDMessage *message = [....];//构造相关消息
[message addContent:visitor]; //传访客的属性
[[HDClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
//发送消息进度
} completion:^(HDMessage *aMessage, HDError *aError) {
//发送消息完成,aError为空则为发送成功
}];
==== 发送轨迹消息 ====
// toUser为IM服务号
HDMessage *message = [HDMessage createTxtSendMessageWithContent:@"" to:toUser];
HDVisitorTrack *vst = [HDVisitorTrack new];
vst.title = title; //标题
vst.price = price; //价格
vst.desc = desc;//描述
vst.imageUrl = imageUrl; //图片url
vst.itemUrl = itemUrl; //点击图片的链接
[message addContent:vst];
[[HDClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
//发送消息进度
} completion:^(HDMessage *aMessage, HDError *aError) {
//发送消息完成,aError为空则为发送成功
}];
==== 发送订单消息 ====
//toUser为IM服务号
HDMessage *message = [HDMessage createTxtSendMessageWithContent:@"" to:toUser];
HDOrderInfo *ord = [HDOrderInfo new];
ord.title = title;
ord.orderTitle = orderTitle;
ord.price = price;
ord.desc = desc;
ord.imageUrl = imageUrl;
ord.itemUrl = itemUrl;
[message addContent:ord];
[[HDClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
//发送消息进度
} completion:^(HDMessage *aMessage, HDError *aError) {
//发送消息完成,aError为空则为发送成功
}];
==== 指定客服消息 ====
调度时,指定某个客服。
客服账号为客服的登录邮箱地址。
HDMessage *message = [....];//构造文字消息
[message addContent:[[HDAgentIdentityInfo alloc] initWithValue:@"客服账号"]];
==== 指定技能组消息 ====
调度时,指定某个技能组。
技能组名称须和客服系统设置的技能组名称完全一致,中英文均可。
HDMessage *message = [....];//构造文字消息
[message addContent:[[HDQueueIdentityInfo alloc] initWithValue:@"技能组名称"]];
==== 接收消息 ====
通过注册消息监听来接收消息。
//添加消息监控,第二个参数是执行代理方法的队列,默认是主队列
[[HDClient sharedClient].chatManager addDelegate:self delegateQueue:nil];
//移除消息监控
[[HDClient sharedClient].chatManager removeDelegate:self];
- (void)messagesDidReceive:(NSArray *)aMessages{
//收到普通消息,格式:
}
- (void)cmdMessagesDidReceive:(NSArray *)aCmdMessages{
//收到命令消息,格式:,命令消息不存数据库,一般用来作为系统通知,例如留言评论更新,
//会话被客服接入,被转接,被关闭提醒
}
- (void)messageStatusDidChange:(HDMessage *)aMessage error:(HDError *)aError{
//消息的状态修改,一般可以用来刷新列表,显示最新的状态
}
- (void)messageAttachmentStatusDidChange:(HDMessage *)aMessage error:(HDError *)aError{
//发送消息后,会调用,可以在此刷新列表,显示最新的消息
}
==== 检测消息类型 ====
message.body.type == EMMessageBodyTypeText; //文本消息
message.body.type == EMMessageBodyTypeImage; //图片消息
message.body.type == EMMessageBodyTypeVoice; //语音消息
message.body.type == EMMessageBodyTypeFile; //文件消息
message.body.type == EMMessageBodyTypeCmd; //命令消息
//当文本消息时,需要其他其他的检测,可能为其他类型的消息
[HDjudgeTextMessageSubType isTrackMessage:<#HDMessage *#>] == YES; //轨迹消息
[HDjudgeTextMessageSubType isOrderMessage:<#HDMessage *#>] == YES; //订单消息
[HDjudgeTextMessageSubType isMenuMessage:<#HDMessage *#>] == YES; //菜单消息
[HDjudgeTextMessageSubType isTransferMessage:<#HDMessage *#>] == YES;//转接客服
[HDjudgeTextMessageSubType isEvaluateMessage:<#HDMessage *#>] == YES;//满意度评价
==== 获取聊天记录 ====
* 从数据库获取指定数量的消息,取到的消息按时间排序,并且不包含参考的消息,如果参考消息的ID为空,则从最新消息取
*
* @param aMessageId 参考消息的ID
* @param count 获取的条数
* @param aDirection 消息搜索方向
* @param aCompletionBlock 完成的回调
_conversation = [[HDClient sharedClient].chatManager getConversation:];
[_conversation loadMessagesStartFromId:<#messageId#> count:<#(int)count#> searchDirection:<#HDMessageSearchDirectionUp#> completion:^(NSArray *aMessages, HDError *aError) {
if (!aError && [aMessages count]) {
//获取到消息aMessages
}
}];
===== 会话 =====
==== 获取所有会话 ====
NSArray *conversastions = [[HDClient sharedClient].chatManager loadAllConversations];
==== 删除会话及聊天记录 ====
//删除一个会话;参数:会话ID,是否删除相关的消息
[[HDClient shareClient].chatManager deleteConversation:<#conversationId#> deleteMessages:YES];
HDConversation *conversation = [[HDConversation alloc] initWithConversation:<#conversationId#>];
//删除会话中的一条消息记录;参数:消息Id,错误指针
[conversation deleteMessageWithId:<#messageId#> error:<#(HDError **)#>];
//删除会话中的所有消息(不删除会话)
[conversation deleteAllMessages:<#(HDError **)#>];
==== 获取会话未读消息数 ====
HDConversation *conversation = [[HDClient sharedClient].chatManager getConversation:<#IM 服务号#>];
int unreadCount = conversation.unreadMessagesCount; //获取指定会话的未读消息数
==== 未读消息数清零 ====
HDConversation *conversation = [[HDClient sharedClient].chatManager getConversation:<#IM 服务号#>];
[conversation markAllMessagesAsRead:nil];
===== 满意度评价 =====
==== 判断是否为评价消息 ====
HDExtMsgType extMsgType = [HDMessageHelper getMessageExtType:{message}];
//如类型为HDExtEvaluationMsg则为满意度评价消息
==== 评价此会话 ====
NSMutableDictionary *ctrlArgs = [NSMutableDictionary dictionaryWithDictionary:[weichat objectForKey:kMesssageExtWeChat_ctrlArgs]];
NSLog(@"ctrlArgs--%@", ctrlArgs);
NSMutableArray *evaluationDegree = [ctrlArgs objectForKey:kMesssageExtWeChat_ctrlArgs_evaluationDegree];
NSDictionary *appraiseTagsDict = [evaluationDegree objectAtIndex:0];
**详见**:SatisfactionViewController.m类
===== 留言 =====
==== 获取所有留言 ====
/*
@param tenantId 租户Id
@param cname IM 服务号
@param projectId 留言的Project ID
@param page 第几页,从0开始,默认为第0页
@param pageSize 每一页的大小,默认为10,最大不能超过100
*/
[[[HDClient sharedClient] leaveMsgManager] getLeaveMsgsWithProjectId:<#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 留言参数
*/
[[[HDClient sharedClient] leaveMsgManager] createLeaveMsgWithProjectId:<#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
*/
[[[HDClient sharedClient] leaveMsgManager] getLeaveMsgDetailWithProjectId: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
*/
[[[HDClient sharedClient] leaveMsgManager] getLeaveMsgCommentsWithProjectId:<#(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 请求体
*/
[[[HDClient sharedClient] leaveMsgManager] createLeaveMsgCommentWithProjectId:<#projectId#> cname:<#NSString *#> ticketId:<#留言id#> requestBody:<#LeaveMsgRequestBody*#> completion:^(id responseObject, NSError *error) {
if(error == nil){ //回复成功
} else {//回复失败
}
}];
==== 获取工作状态 ====
@param toUser IM服务号
[[[HDClient sharedClient] leaveMsgManager] getWorkStatusWithToUser:<#(NSString *)#> completion:^(BOOL isWork, NSError *error) {
if (error == nil) { //成功
if (isWork) { //工作状态
} else { //下班
}
} else { //请求失败
}
}];
===== 实时音视频 =====
==== 实时通话相关 ====
//接受视频邀请的设置
HDCallOptions *options = [[HDCallOptions alloc] init];
options.videoOff = NO; //是否关闭视频传输
options.mute = NO; //是否静音
options.nickName = <#(NSString *)#>; //昵称
options.previewView = <#(HCallLocalView*)#>; //本地预览View
[[HDClient sharedClient].callManager setCallOptions:options];
//注册实时通话回调
[[HDClient sharedClient].callManager addDelegate:<#(id)#> delegateQueue:nil]; //queue默认为main
//移除实时通话回调
[[HDClient sharedClient].callManager removeDelegate:<#(id)#>];
//收到一个视频通话请求,参数为请求者昵称
- (void)onCallReceivedNickName:(NSString *)nickName;
//有成员进入会话
- (void)onMemberJoin:(HDCallMember *)member;
//成员离开
- (void)onMemberExit:(HDCallMember *)member;
//有视频流进来
- (void)onStreamAdd:(HDCallStream *)stream;
//视频流被移除[不包括自己]
- (void)onStreamRemove:(HDCallStream *)stream;
//视频流刷新
- (void)onStreamUpdate:(HDCallStream *)stream;
//视频通话结束
- (void)onCallEndReason:(int)reason desc:(NSString *)desc;
- (void)onNotice:(HMediaNoticeCode)code arg1:(NSString *)arg1 arg2:(NSString *)arg2 arg3:(id)arg3;
//接受视频请求
[[HDClient sharedClient].callManager acceptCallCompletion:^(id obj, HDError *error) {
if (error == nil) { //接受成功
}
}];
//拒绝视频请求
[[HDClient sharedClient].callManager endCall];
//挂断视频请求
[[HDClient sharedClient].callManager endCall];
//切换镜头
[[HDClient sharedClient].callManager switchCameraPosition:YES]; //默认前置摄像头(YES)
//关闭麦克风
[[HDClient sharedClient].callManager pauseVoice];
//打开麦克风
[[HDClient sharedClient].callManager resumeVoice];
//关闭本地视频传输
[[HDClient sharedClient].callManager pauseVideo];
//打开本地视频传输
[[HDClient sharedClient].callManager resumeVideo];
//订阅成员视频
[[HDClient sharedClient].callManager subscribeStreamId:streamId view:topView completion:^(id obj, HDError *error) {
if (error == nil) {
} else {
}
}];
//取消订阅
[[HDClient sharedClient].callManager unSubscribeStreamId:streamId completion:^(id obj, HDError *error) {
if (error == nil) {
} else {
}
}];
===== 高级功能 =====
==== 显示排队人数 ====
首先,初始化时,需要调用''option.visitorWaitCount = YES;''打开待接入访客排队人数功能。 然后实现HDChatManagerDelegate中的''visitorWaitCount''方法。
-(void)visitorWaitCount:(int)count;
// 其中:count为前面有多少人正在排队, 一般大于0时,显示排队人数,当等于0,需要隐藏掉提示。在非等待状态,count均为0