概述
七鱼客服SDK可以帮助第三方网站及应用快速构建一个完善的客服系统生态圈,SDK提供较为完善的客服应用功能,及简洁的API接口。
SDK提供如下扩展功能:
- 自定义接入
- CRM对接
- 访客分流
- 商品链接
- 未读消息
- VIP接入支持
- 常见问题设置
- 机器人欢迎语设置
- 网站访问统计
- 多机器人接入
以下所有接入代码的例子都可以在 这里下载。
对接七鱼WEB-SDK,只需要在页面上添加七鱼后台提供的接入代码即可,代码需要加在body中。访客访问页面时,页面会执行代码,加载七鱼的JS文件。
API列表
| API | API说明 |
|---|---|
| ysf('onready', callback) | 设置sdk初始化成功回调 |
| ysf('product', info) | 设置商品链接 |
| ysf('logoff') | 用户登出 |
| ysf('open', options) | 打开客服聊天窗口 |
| ysf('url') | 获取打开聊天窗口的URL地址 |
| ysf('onunread', callback) | 设置未读消息通知回调 |
| ysf('getUnreadMsg') | 获取当前未读消息 |
| ysf('getConversation', callback) | 获取会话列表 |
| ysf('onConversation', callback) | 设置会话列表新消息通知回调,返回会话列表 |
| ysf('onSessionMessage', callback) | 设置会话列表新消息通知回调,返回当前收到的新的消息(单条消息) |
| ysf('config', options) | 配置企业及用户信息,嵌入七鱼客服SDK后可直接配置这些信息 |
其中 ysf('config', options) 的 options 参数说明如下:
| 参数 | 类型 | 描述 |
|---|---|---|
| options | Object | 企业配置信息 |
| options.uid | String | 企业当前登录用户标识,不传表示匿名用户 |
| options.name | String | 企业当前登录用户名称 |
| options.email | String | 企业当前登录用户邮箱 |
| options.mobile | String | 企业当前登录用户手机号 |
| options.bid | String | 当企业版本为平台版本的时候,用于指定咨询商户客服的商户id |
| options.data | String | 企业当前登录用户其他信息,JSON字符串,其中 avatar 字段用于设置访客头像;需包含 key,value,label 等信息;如果是头像,还需要 href;具体设置见下示例代码 |
| options.staffid | String | 指定客服id,非必填;如果同时存在 groupid,staffid 优先级更高 |
| options.groupid | String | 指定客服组id,非必填 |
| options.shuntId | String | 访客选择多入口分流模版id,非必填 |
| options.robotShuntSwitch | Number | 机器人优先开关(访客分配), 0 = 关闭,1 = 开启, 非必填 |
| options.level | Number | 企业当前登录用户vip等级,支持 1-10 级 |
| options.qtype | Number | 企业常见问题模板id,非必填 |
| options.welcomeTemplateId | Number | 机器人欢迎语模板id,非必填 |
| options.success | Function | 配置成功回调 |
| options.error | Function | 配置失败回调 |
| options.connectYunxin | Boolean | 配置sdk连接云信服务,限平台企业(在七鱼开头的是平台主账号子账号的方式)使用 |
| options.wxworkAppId | String | 配置企业微信id,用于语音功能,该字段需要进行加密,加密方式采用AES加密,加密代码参考如下实例,Aes Key为App Secret(系统管理-扩展与集成-开发者ID-AppSecret字段),使用老的授权方式绑定的企业微信应用,需要在应用中自行设置可信域名:qiyukf.com |
| options.spkf | Number | 主动发起视频邀请开关 |
| options.isShowBack | Number | 导航头是否显示返回按钮(浮层模式设置无效)0:不显示 1:显示 ;默认是 0 不显示 |
| options.language | String | 配置当前接入的语言,非必填,默认是 zh-cn 简体中文 |
| options.shortcutTemplateId | Number | 常见快捷入口模版id |
| options.layerSize | Object | PC端浮层模式窗口和输入框高度自定义设置,各项最小值:{ width: 360, height: 500, inputHeight: 150 } 只有配置大于最小值才生效,否则默认最小值;可以配置一项或者多项 |
| options.emojiPopoverWidth | string | 指定pc端表情悬浮窗宽度 |
| options.channelExtendInfo | string | 渠道扩展信息,其中baiduQuery,baiduKeyword,baiduChannel是固定百度渠道相关的key |
| options.allowNewTab | Number | 值为 1 时,图片、文本、PDF 文件支持在新标签页中打开;值为 0 时在当前浮层内直接打开。默认值为 0,非必填。 |
| options.alipayImagePermissionText | string | 支付宝相册权限文案 |
语言参数说明:
| 语言 | 字段 |
|---|---|
| 中文简体 | zh-cn |
| 中文繁体 | zh-tw |
| 英文 | en |
| 阿拉伯语(沙特) | ar |
| 德语 | de |
| 俄语 | ru |
| 法语 | fr |
| 菲律宾语 | tl |
| 韩语 | ko |
| 日语 | ja |
| 泰语 | th |
| 印尼语 | id |
| 越南语 | vi |
| 意大利语 | it |
| 波兰语 | pl |
使用范例
ysf('config', {
uid:"1442286211167",
name:'test',
email:'test@163.com',
mobile:'13888888888',
data:JSON.stringify([
{"key":"real_name", "value":"土豪"},
{"key":"mobile_phone", "hidden":true, "value":"13800000000"},
{"key":"email", "value":"13800000000@163.com"},
{"key":"avatar", "label":"头像", "value": "https://ysf.qiyukf.net/operation/080659b993a45dd546fbd71efd5ef000"}, // 访客头像
{"index":0, "key":"account", "label":"账号", "value":"zhangsan" , "href":"http://example.domain/user/zhangsan"},
{"index":1, "key":"sex", "label":"性别", "value":"先生"},
{"index":5, "key":"reg_date", "label":"注册日期", "value":"2015-11-16"},
{"index":6, "key":"last_login", "label":"上次登录时间", "value":"2015-12-22 15:38:54"}
]),
channelExtendInfo: JSON.stringify([
{"key":"baiduQuery", "value":"百度搜索词"},
{"key":"baiduKeyword", "value":"百度关键词"},
{"key":"baiduChannel", "value":"百度来源"},
])
staffid:'123',
groupid: '123',
shuntId: '123',
level: 1,
qtype: 1056,
welcomeTemplateId: 1024,
layerSize: { // 只对PC端的浮层模式有效
width: 360,
height: 500,
inputHeight: 150
},
success: function(){
// todo
},
error: function(){
// handle error
}
});AES加密代码参考
public final class AESEncryptUtil {
private static final ThreadLocal<Map<String, Cipher>> CIPHER_THREAD_LOCAL_EN_URS_COOKIE = new ThreadLocal<>();
private static final ThreadLocal<Map<String, Cipher>> CIPHER_THREAD_LOCAL_DE_URS_COOKIE = new ThreadLocal<>();
private AESEncryptUtil() {
}
public static String encrypt(String sSrc, String aesKey) {
validate(aesKey);
try {
return encrypt_(sSrc, aesKey);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String decrypt(String sSrc, String aesKey) {
validate(aesKey);
try {
return decrypt_(sSrc, aesKey);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void validate(String aesKey) {
if (strIsBlank(aesKey) || (16 != aesKey.length() && 24 != aesKey.length() && 32 != aesKey.length())) {
throw new RuntimeException("AES密钥长度只能是 16 24 32 字节");
}
}
/**
* 加密
*
* @param sSrc
* @return
* @throws Exception
*/
public static String encrypt_(String sSrc, String aesKey) throws Exception {
if (strIsBlank(sSrc) || strIsBlank(aesKey)) {
return null;
}
Map<String, Cipher> cipherMap = CIPHER_THREAD_LOCAL_EN_URS_COOKIE.get();
if (cipherMap == null) {
cipherMap = new HashMap<>(10);
CIPHER_THREAD_LOCAL_EN_URS_COOKIE.set(cipherMap);
}
Cipher aesCipher = cipherMap.get(aesKey);
if (aesCipher == null) {
byte[] raw = aesKey.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE, skeySpec);
cipherMap.put(aesKey, aesCipher);
}
return bytesToHexStr(aesCipher.doFinal(sSrc.getBytes("UTF-8")));
}
/**
* 解密
*
* @param sSrc
* @return
* @throws Exception
*/
public static String decrypt_(String sSrc, String aesKey) throws Exception {
if (strIsBlank(sSrc) || strIsBlank(aesKey)) {
return "";
}
Map<String, Cipher> cipherMap = CIPHER_THREAD_LOCAL_DE_URS_COOKIE.get();
if (cipherMap == null) {
cipherMap = new HashMap<>(10);
CIPHER_THREAD_LOCAL_DE_URS_COOKIE.set(cipherMap);
}
Cipher aesCipher = cipherMap.get(aesKey);
if (aesCipher == null) {
byte[] raw = aesKey.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.DECRYPT_MODE, skeySpec);
cipherMap.put(aesKey, aesCipher);
}
return new String(aesCipher.doFinal(hexStrToBytes(sSrc)), "UTF-8");
}
/**
* 将16进制字符串还原为字节数组.
*/
private static byte[] hexStrToBytes(String s) {
byte[] bytes;
bytes = new byte[s.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);
}
return bytes;
}
/**
* 将字节数组转换为16进制字符串的形式.
*/
private static String bytesToHexStr(byte[] bcd) {
StringBuffer s = new StringBuffer(bcd.length * 2);
for (byte aBcd : bcd) {
s.append(HEX_LOOKUP_STRING[(aBcd >>> 4) & 0x0f]);
s.append(HEX_LOOKUP_STRING[aBcd & 0x0f]);
}
return s.toString();
}
private static boolean strIsBlank(CharSequence cs) {
int strLen;
if (cs != null && (strLen = cs.length()) != 0) {
for (int i = 0; i < strLen; ++i) {
if (!Character.isWhitespace(cs.charAt(i))) {
return false;
}
}
return true;
} else {
return true;
}
}
private static final char[] HEX_LOOKUP_STRING = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
'd', 'e', 'f' };
public static void main(String[] args) {
String appId = "XXXXX"; // 企业微信appId
String aeskey = "XXXX"; //app secret key
System.out.println(AESEncryptUtil.encrypt(appId, aeskey));
}
}这篇文档有帮助吗?