客服SDK集成文档(iOS-QMLineSDK)

1、SDK工作流程

Alt text

2、准备工作

2.1 文件说明

文件 说明
IMSDK-OC 使用Objective-C编写UI界面的demo, 快速集成可使用此demo
QMLineSDK 在线客服核心库、可以通过pod动态引用

2.2 开发环境

Xcode版本 -> 10.1(10A255)

QMLineSDK版本 -> 3.2.2

FMDB版本 -> 2.7.5

Qiniu版本 -> 7.2.5

HappyDNS版本 -> 0.3.15

3、快速集成

注: 集成和发布过程有问题,请看文档最后的常见问题

3.1 导入SDK

把IMSDK-OC中的Framework(QMLineSDK.framework)拷贝到工程路径下, 右键工程目录, 选择Add Files to "工程名"

3.2 集成Demo

QMChatRoom: 聊天界面及部分工具类

Resources: 表情资源文件

Assets: 其他图片资源

Vendors: 第三方库(FMDB、HappyDNS、QiniuSDk必须导入)

PrefixHeader: 头文件

注: FMDB、HappyDNS、QiniuSDK可以自行pod或者导入demo提供的

3.3 配置xcode(重要)

  • General配置

Embedded Binaries,展开 Embedded Binaries 后 点击展开后下面的 + 来添加framework

Alt text

  • Build Settings配置 (不支持bitcode)

Build Options -> Enable Bitcode 选择No

  • Info.plist配置 (允许http、获取权限)

Alt text

3.4 注册SDK

  • 初始化SDK

AppKey: 在后台SDK下载界面的下方, 是接入在线客服的唯一凭证 userName: 可以区分不同用户的用户名称, 可以显示在后台客服界面
userId: 可以区分不同用户接入在线客服, 不同用户用户ID一定不同

注: userId 只能使用字母、数字及下划线、否则会初始化失败, AppKey、userName、userId都是必填项[userId位数必须大于一位]

[QMConnect registerSDKWithAppKey:@"注册App的AppKey" userName:@"用户名" userId:@"1234"];
注:进行任何操作必须是注册AppKey成功的状态
  • AppKey获取方法

  • 监听注册状态

监听SDK初始化的状态需要注册广播:

CUSTOM_LOGIN_SUCCEED: 注册成功的时候广播的名字, SDK其他的接口操作都基于注册成功的状态才能进行, 如获取部门、或技能组的接口
CUSTOM_LOGIN_ERROR_USER: 注册失败时候广播的名字, 具体失败的原因提示:
1、accessId is Empty: appKey不可以为空值

2、userName is Empty: userName不可以为空值

3、userId is not match: userId不可以为空值

4、Create Socket Error: 建立连接失败

5、Connect Socket Error: 连接服务器失败

6、5: 服务器状态异常

7、400: appKey错误或不存在

8、服务端返回其他类型错误

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginSuccess:) name:CUSTOM_LOGIN_SUCCEED object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginFaile:) name:CUSTOM_LOGIN_ERROR_USER object:nil];

4、API接口

4.1 自建服务器设置网络地址

是不是自建服务器的用户不需要设置此项,此接口应在注册之前使用

[QMConnect setServerAddress:@"IP地址" tcpPort:@"端口" httpPost:@"TCP地址"];

4.2 获取渠道全局配置

获取全局配置,主要用于区分下一步操作日程管理技能组(如果不配置日程管理的可跳过此步骤,直接获取技能组信息)

[QMConnect sdkGetWebchatGlobleConfig:^(NSDictionary * _Nonnull scheduleDic) {
    //获取渠道全局配置字典
} failBlock:^{
    //获取信息失败
}];

注册成功自动获取后台配置信息并写入本地plist文件

4.3 获取配置信息(开启日程管理时用到)

[QMConnect sdkGetWebchatScheduleConfig:^(NSDictionary * _Nonnull scheduleDic) {
    //获取配置信息成功
} failBlock:^{
   //获取配置信息失败 
}];

4.4 获取部门信息(技能组)

后台可配置多个部门/技能组(如: 售前、售后等), SDK注册成功后, 调用此接口获取后台配置好的部门信息, 用户将选择对应的部门进行问题咨询,

[QMConnect sdkGetPeers:^(NSArray * _Nonnull peerArray) {
    // 获取部门信息的数组
 } failureBlock:^{
    // 获取信息失败
}];

技能组包含部门ID和部门Name两个属性, 只有一个部门可以不提示选择框, 直接进入聊天界面

4.5 开始会话

进入聊天界面, 首先调用开始会话接口, 成功后才能获取坐席状态, 及消息的收发, 参数为刚刚选择的部门ID, 回调是否开启评价选择项

[QMConnect sdkBeginNewChatSession:self.peerId successBlock:^(BOOL remark)   {
   // 开始会话成功, 评价开关
} failBlock:^{
    // 开始会话失败
}];

开始会话带专属坐席(不能配置机器人)

params 为扩展信息和专属坐席信息
扩展信息:
@"customField":@{@"扩展信息key":@"扩展信息value"}
专属坐席:
@"agent":@"坐席工号"
扩展信息+专属坐席:
@{@"customField":@{@"123":@"456"},@"agent":@"8000"}

[QMConnect sdkBeginNewChatSession:self.peerId params:@{@"": @""} successBlock:^(BOOL remark) {
    // 开始会话成功, 评价开关    
 } failBlock:^{
  // 开始会话失败
}];

开始会话(日程管理专用)

[QMConnect sdkBeginNewChatSessionSchedule: self.scheduleId processId: self.processId currentNodeId: self.currentNodeId params: @{@"":@""} successBlock:^(BOOL remark) {
    // 开始会话成功, 评价开关
 } failBlock:^{
    // 开始会话失败
 }];

会话状态(以广播的形式推送给移动端)

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(robotAction) name:ROBOT_SERVICE object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customOnline) name:CUSTOMSRV_ONLINE object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customOffline) name:CUSTOMSRV_OFFLINE object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customClaim) name:CUSTOMSRV_CLAIM object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customFinish) name:CUSTOMSRV_FINISH object:nil];

其他推送

排队数

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customQueue:) name:CUSTOMSRV_QUEUENUM object:nil];

坐席信息

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customAgentMessage:) name:CUSTOMSRV_AGENT object:nil];

满意度

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customInvestigate) name:CUSTOMSRV_INVESTIGATE object:nil];

专属坐席未在线

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(customVIP) name:CUSTOMSRV_VIP object:nil];

新消息通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getNewReload:) name:CHATMSG_RELOAD object:nil]

4.6 坐席信息

Object 说明 备注
exten 坐席工号 例:7000、8000
name 坐席名称 后台未配置显示工号
icon_url 坐席头像 后台未配置没有值
type 类型 robot(机器人)claim(人工)

4.7 消息结构

Object 说明 备注
_id 消息ID 记录每条消息的ID
device 设备类型 如:iphone5s、iphone6
message 消息内容
messageType 消息类型 如:text、image、voice、file、iframe(小网页)、richText(富文本)、Card(商品展示)、cardInfo(商品详情)
platform 平台类型 如:iOS、Android
sessionId 查询消息的ID 不同用户的sessionId不同、根据sesssionId查询数据库消息
accessid 查询消息的accessid AppKey下的全部数据,可查看该用户的同一个AppKey下的全部数据库消息
createTime 消息时间 创建消息的时间
fromType 消息来源 自己发送的为0、接收的消息为1
status 消息发送状态 发送成功为:0、发送失败为:1、正在发送中:2
recordSeconds 录音时间 语音消息录音时长
localFilePath 本地文件路径 文件上传或者下载后本地存储路径, 沙盒相对路径, 如:
remoteFilePath 远程文件路径 存储文件的网络路径,可以通过该路径下载各类文件
fileName 文件名
fileSize 文件大小
mp3FileSize mp3消息类型文件大小
downloadState 下载状态 已下载:0, 未下载:1, 下载中:2
width iframe类型webView宽度
height iframe类型webView高度
agentExten 坐席工号
agentName 坐席名称
agentIcon 坐席头像
isRobot 机器人消息
robotType 机器人类型
robotId 机器人id
isUseful 机器人帮助状态
questionId 机器人问题ID
richTextUrl 富文本地址
richTextPicUrl 图片地址
richTextTitle 标题
richTextDescription 描述
cardImage 商品信息左侧图片
cardHeader 商品信息标题
cardSubhead 商品信息副标题
cardPrice 商品信息价格
cardUrl 商品信息地址
userId 注册用户的userId 可查询同一个userId下的全部消息

4.8 获取未读消息数

此接口Appkey、userName、userId必须与注册用的保持一致

[QMConnect sdkGetUnReadMessage:@"AppKey"    userName:@"userName" userId: @"userId" successBlock:^(NSInteger) {
    // 获取未读消息数成功
} failureBlock:^{
    // 获取未读消息数失败
}];

获取未读消息数的AppKey、userName、userId必须和注册的保持一致

4.9 发送消息

发送文本消息

[QMConnect sendMsgText:@"文本消息" successBlock:^{
    // 文本消息发送成功
} failBlock:^{
    // 文本消息发送失败
}];

发送语音消息

[QMConnect sendMsgAudio:@"录音文件名" duration:@"录音时长" successBlock:^{
    // 语音消息发送成功
} failBlock:^{
    // 语音消息发送失败
}];

发送图片消息

[QMConnect sendMsgPic:image对象 successBlock:^{
   // 图片发送成功
} failBlock:^{
   // 图片发送失败
}];

发送文件消息

[QMConnect sendMsgFile:@"文件名字" filePath:@"文件路径" fileSize:@"文件大小" progressHander:^(float progress) {
    // 文件上传进度回调
} successBlock:^{
    // 文件上传成功
} failBlock:^{
   // 文件上传失败
}];

发送卡片消息

[QMConnect sendMsgCardInfo:dic successBlock:^{
    商品信息发送成功
} failBlock:^{
    商品信息发送失败
}];

消息重发

[QMConnect resendMessage:消息实例 successBlock:^{
    // 重新发送成功
} failBlock:^{
    // 重新发送失败
}];

4.10 数据库操作

获取同一个accessId下数据库的全部信息,参数number为每次从数据库取回的消息条数

[QMConnect getAccessidAllDataFormDatabase:number];

获取同一个userId下数据库的全部信息,参数number为每次从数据库取回的消息条数

[QMConnect getUserIdDataFormDatabase:number]

获取单次会话的数据库信息(客服主动关闭后在进入消息清空), 参数number为每次从数据库取回的消息条数, dataArray为消息数组

dataArray = [QMConnect getDataFromDatabase:number]

获取单条消息, 参数为消息ID, 返回值虽然为数组类型, 但只包含一条消息, 一般用于发送失败的消息重发

dataArray = [QMConnect getOneDataFromDatabase:@"消息ID"]

删除单条消息, 参数为消息ID, 只能删除本地数据库中的消息

[QMConnect removeDataFromDataBase:@"消息ID"];

修改语音状态接口,参数为消息ID

[QMConnect changeAudioMessageStatus:@"消息ID"];

撤回消息接口,该接口只用于客服撤回消息

 [QMConnect changeDrawMessageStatus:@"消息ID"];

查询MP3类型文件的消息的大小

[QMConnect queryMp3FileMessageSize:@"消息ID"];

修改MP3类型文件的消息的大小

[QMConnect changeMp3FileMessageSize:@"消息ID" fileSize:@"文件大小"];

插入商品信息卡片消息, 进入客服界面会出现该商品的消息

[QMConnect insertCardInfoData:消息字典];

删除商品信息卡片消息

 [QMConnect deleteCardTypeMessage];

修改商品信息卡片消息时间

[QMConnect changeCardTypeMessageTime:消息时间];

4.11 是否启用机器人

在线客服包含机器人客服和人工客服, 如配置有机器人客服, 如没配置直接进入人工

[QMConnect allowRobot];

4.12 转人工服务

[QMConnect sdkConvertManual:^{
   // 转人工客服成功
} failBlock:^{
   // 转人工客服失败
}];

如未配置机器人客服不需要调用此接口, 转人工客服失败, 则直接跳转至留言界面或退出

4.13 授权其他坐席

专属坐席未在线的情况下,是否接受其他坐席的服务

[QMConnect sdkAcceptOtherAgentWithPeer:self.peerId successBlock:^{
    // 授权成功
    // 需要再次调用beginSession接口
} failBlock:^{
    // 授权失败
}];

4.14 获取评价信息

[QMConnect sdkGetInvestigate:^(NSArray * _Nonnull investigateArray) {
    // 获取评价信息成功
} failureBlock:^{
    // 获取评价信息失败
}];

2.8.4新增接口(可获取满意度自定义标题和提示语)

[QMConnect newSDKGetInvestigate:^(Evaluation * _Nonnull evaluation) {
    // 获取评价信息成功
} failureBlock:^{
    // 获取评价信息失败
}];

4.15 提交评价

[QMConnect sdkSubmitInvestigate:@"评价名称" value:@"评价编号" successBlock:^{
    // 评价成功
} failBlock:^{
    // 评价失败
}];

4.16 机器人帮助评价

[QMConnect sdkSubmitRobotFeedback:isUseful questionId:@"机器人问题id" messageId:@"消息ID" robotType:@"机器人消息类型" robotId:@"机器人ID" successBlock:^{
    //机器人帮助评价成功 
} failBlock:^{
   //机器人帮助评价失败
}];

4.17 提交留言

[QMConnect sdkSubmitLeaveMessage:@"部门ID" phone: @"联系电话" Email:@"联系邮箱" message:@"留言内容" successBlock:^{
    // 留言成功
} failBlock:^{
    // 留言失败
}];

4.18 关闭服务

[QMConnect logout];

4.19 下载文件

[QMConnect downloadFileWithMessage:文件消息实例 localFilePath:@"存储文件的路径" progressHander:^(float progress) {
    // 文件下载进度
} successBlock:^{
    // 文件下载成功
} failBlock:^(NSString * _Nonnull error) {
    // 文件下载失败
}];

4.20 留言功能

留言功能

[QMConnect allowedLeaveMessage]

留言提示信息

[QMConnect leaveMessageAlert]

留言标题

[QMConnect leaveMessageTitle]

留言内容信息

[QMConnect leaveMessagePlaceholder]

自动关闭会话功能

[QMConnect allowedBreakSession]

自动关闭会话提示语

[QMConnect breakSessionAlert]

自动关闭会话时间

[QMConnect breakSessionDuration]

自动关闭提醒时间

[QMConnect breakSessionAlertDuration]

4.21 定时提醒和关闭会话(1.9.0以后不建议使用此接口)

QMConnect sdkChatTimerBreaking:^(NSDictionary * _Nonnull) {
    //获取定时提示信息成功
} failBlock:^{
    //获取定时提示消息失败
}];

4.22 更新deviceToken

每次启动应用都需要重新设置

[QMConnect setServerToken:deviceToken];

4.23 转人工按钮是否显示

[QMConnect manualButtonStatus];

常见问题

集成问题

编译问题

发布问题

逻辑问题

使用问题

推送问题

H5页面问题

集成问题

1 . 不显示表情

解决方案:

  • 查看demo导入工程的时候是否将表情图片同时导入
  • 查看对应表情的expressionImage.plist文件是否已经导入, 该文件在第三方库ExpressionView文件夹下
  • 查看显示表情的Cell中是否支持表情的富文本, demo中使用的是EmojiLabel第三方库

2 . 第三方库冲突

  • demo中的第三方库冲突可以二选一,将其中一个重复的删除
  • SDK中使用了FMDB, Qiniu, AFNetworking等第三方库, 容易出现冲突的是AFNetworking出现冲突时可以更新新版的Qiniu就可以解决此问题

3 . 使用iphone真机注册失败

  • 在蜂窝移动网络中,打开对应的网络管理

4 . pod search 不到最新的库

  • 更新本地的缓存 pod repo update
  • 检查pod版本

5 . SDK界面部分显示成英文

  • SDK支持国际化,导入代码的同时,需要在工程中建立创建多语言文件,Demo中的多语言文件名称为: Localizable.strings

6 . 已接入人工,导航栏仍显示 等待接入 (2.7.0版本之前显示的是等待连接)

  • 因为客服系统设置访客回复消息后才算接入会话, 修改方式看下图

Alt text

7 . 发布App Store包体积增到3-4MB,请到开发者账号下看具体的增大体积

编译问题

  1. Linker command failed

错误如下 Alt text

解决方案:

  • General --> Linked Frameworks and Libraries 下添加 libresolv.tbd

逻辑问题

  1. 跳转至聊天界面

  2. 现象一 跳转至聊天界面后,网络断开重新连接,又跳转一次聊天界面

    解决方案: 跳转界面根据注册SDK成功后,接收到相应的通知进行跳转,网络波动会导致后台重新连接,再次发出连接成功的通知,所以在跳转界面进行判断,在聊天界面的时候,接收连接成功的通知直接return不会跳转

  3. 现象二 应用将要进入后台的时候调用注销接口, 返回前台后收不到消息

解决方案: 需要重新注册和之前注册的AppKey、userName、userId需要保持一致

使用问题

  • 客服发送消息用户无法收到

    解决方案:登录后台系统需要使用google浏览器

  • 客服不在线、用户的会话接入到了该客服

    解决方案:客服登陆前、确保所有的待处理会话都已经结束

推送问题

1、 上传证书不离线推送

  • 检查客服系统中是否配置过 p12 文件,此证书是否与此app的 Bundle Identifier 关联的推送证书

  • 检查证书的线上、测试环境是否跟客服系统中配置的相同

  • 检查 appName 是否和客服系统中填写的“App名称”一致

  • 检查 provision profile 是否包含了推送证书

  • 检查代码调试是否可以获取到 devicetoken

  • 检查工程中的 Capablities 中是否开启了 Push Notifications

2、上传URL接收不到离线推送

  • 消息以json数据发送给客服系统中配置的URL,检查是否收到json数据

3、SDK以离线 app在线时接收到离线推送提示处理

  • 详见AppDelegate

4、关于离线推送会产生的问题

场景一、 APP退到后台 不能及时收到离线推送,大概3分钟之后才能正常收到离线推送

  • 系统判断会话是否离线是通过是否调用[QMConnect logout]来判断。
  • 正常的退到后台,并没有调用[QMConnect logout]方法,这时候系统并不能直接判断出改会话已经离线,会默认重连,大概3分钟的时间 如果没有重连成功就把改会话至为离线,在这之后方可才能正常收到客服发送过来的离线消息。
  • 如果想要应用退到后台就能马上收到离线消息,需要在AppDelegate下面代理方法中添加[QMConnect logout]。
    - (void)applicationDidEnterBackground:(UIApplication *)application {
       //断开连接
        [QMConnect logout];
    }
    

场景二、 APP在聊天界面退到后台能正常收到离线消息,再次返回前台之后,收不到客服发的消息,退出再次进入可以看到客服发的消息

  • APP后台之后就能马上收到离校消息,是因为AppDelegate中的下面代理方法添加了[QMConnect logout]

    - (void)applicationDidEnterBackground:(UIApplication *)application {
       //断开连接
        [QMConnect logout];
    }
    
  • 需要在AppDelegate再次返回前台的代理方法中重新注册,

    - (void)applicationWillEnterForeground:(UIApplication *)application {
        //需要使用之前一样的appKey、userName、userId
        [QMConnect registerSDKWithAppKey:@"" userName:@"" userId:@""];
    }
    

    这个方法在demo并没有展示出来,需要在添加离线推送 特别是在APP内部的聊天界面退到后台时调用了[QMConnect logout], 再次返回前台时一定需要再次进行注册,来确保与服务端建立连接,才能正常的收到客服发送的消息

场景三、 在APP内,不在聊天界面是否能收到离线推送

  • 在应用内部,当进入聊天界面之后,退出改页面时需要调用[QMConnect logout]方法,不论是点击返回按钮还是手势,都需要调用[QMConnect logout]方法。
  • 在应用内部是,收到离校推送会以UIAlertController弹框的形式呈现出来,具体代码可以参考demo中的AppDelegate

H5页面问题

  1. H5链接页面不显示

    NSString *filePath = @"kf.7moor.com";
    NSString *encodedString = [filePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL *weburl = [NSURL URLWithString:encodedString];
    [webView loadRequest:[NSURLRequest requestWithURL:weburl]];
    
  2. H5页面点击图片或文件不跳转

    - (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion{
      if (self.presentedViewController != nil) {
             [super dismissViewControllerAnimated:flag completion:completion];
        }
    }
    
  3. tabBar遮挡发送按钮

  4. 查看webView的frame的高度

代码改动

3.2.2代码更改

  • QMDateManager新增时间方法
  • QMChatRoomBaseCell 72行时间方法的调用
  • QMChatRoomViewController:新增circleViews,coverView,修改- (void)getNewReload: (NSNotification *)sender方法里面的内容,修改createEvaluationView方法增加判断,修改- (void)logoutAction方法事件操作,新增- (void)isShowEvaluateBtn:(BOOL)speek方法,修改- (void)beginNewChat方法部分内容,以及283行manualButotn转人工按钮是否显示的判断等
  • 主要更改的就是QMChatRoomViewController上述说到的方法,可以再demo中查阅一下

3.2.0代码更改

  • 主要更改了QMChatRoomViewController
  • 新增QMChatRoomEvaluationView和QMChatRoomRadioContentView两个类
  • QMChatTileView增加部分代码
  • QMChatRoomInputView 新增coverView
  • QMManager
  • 设计的代码太多,可能还设计其他类的代码,编译报错时对比demo即可修改,给您带来不便,抱歉。
  • 这次改动较多,增强了收发消息等一些列问题,

更新日志

版本更新3.2.2: 2019-05-30

  • 新增xbot机器人
  • 多次弹出满意度评价问题
  • 满意度评价增加坐席回复才能进行评价逻辑
  • 增加访客退出主动弹出满意度评价功能,提高参评率
  • 修改聊天时间展示问题
  • 修复无匹配日程产生无效会话问题
  • 修复重复离开接入,客服系统显示未读消息数的功能

版本更新3.2.0: 2019-03-21

  • 新增网络状态监控
  • 修复长时间后台在返回前台收不到客服消息问题
  • 在聊天界面客服关闭会话之后输入框更改
  • 新增排队文案配置

版本更新3.0.0: 2018-11-27

  • 修复商品信息卡片发送链接问题
  • 修复默认转人工按钮显示状态问题

版本更新2.8.4: 2018-11-22

  • 对应swift版本的2.8.4
  • 之前的功能全部包含在内