七鱼开发文档中心
总览服务端 APIWebiOSAndroid鸿蒙Uniapp微信小程序插件三方接入

会话消息

未读消息

企业可以使用ysf('onunread')来监听未读消息通知,也可以使用ysf('getUnreadMsg')获取当前的未读消息。七鱼提供的未读消息内容包括未读消息的总数、最后一条消息的类型和内容

代码示例

// 监听
ysf('onunread',  function(result){
  // todo
  console.log(result.total, result.type, result.message);
});

// 获取
var result = ysf('getUnreadMsg');
console.log(result.total, result.type, result.message);

七鱼只是暴露了unread事件读取未读消息,之后的处理逻辑由开发者自己定义。

设置机器人常见问题

访客进入咨询时,如果进入了机器人会话,企业可以通过设置常见问题,将一些用户可能需要问的问题首先发送给用户。通过高级自定义配置,可以给不同页面中的不同咨询入口设置不同的常见问题。

你可以在管理后台 -> 服务中心 -> 在线机器人 -> 设置 -> 导航菜单 -> 常见问题 -> 常见问题模板,可以查找到企业的常见问题模板及其id。

参数说明

名称类型必填说明
qtypenumber否常见问题模板 id

代码示例

ysf('config', {
  uid:"201609051809",
  name:'接入',
  email:'test@163.com',
  mobile:'13888888888',
  qtype: 1056         //常见问题模板id
});

设置机器人欢迎语

访客进入咨询时,如果进入了机器人会话,机器人会发送一句欢迎语给访客,通过高级自定义配置,可以给不同页面中的不同咨询入口设置不同的欢迎语。

你可以在管理后台 -> 服务中心 -> 在线机器人 -> 设置 -> 基础设置 -> 引导语设置 -> 欢迎语 中,查看和配置机器人的的欢迎语模板及其id。

参数说明

名称类型必填说明
welcomeTemplateIdnumber否欢迎语模板 id

代码示例

ysf('config', {
  uid:"201609051809",
  name:'接入',
  email:'test@163.com',
  mobile:'13888888888',
  welcomeTemplateId: 1024         //欢迎语模板id
});

1、卡片消息

商品/订单卡片

发起会话前,企业可以将用户正在查看的商品信息发送给客服,以便客服在后台及时预判访客需要咨询的内容。

注意,如果你在sdk初始化完成之前调用本接口,它将等待sdk初始化完成后执行

参数说明

名称类型必填说明
shownumber否0 | 1 是否在访客端展示发送的商品 0 不展示,1 展示
titlestring是商品标题
descstring是商品描述
picturestring否商品图片地址
notestring否备注
urlstring否跳转链接
successfunction否商品卡片信息上报成功的回调,建议在此回调中打开客服会话
errorfunction否商品信息上报失败的回调

代码示例

ysf('product', {
  show : 1, // 1为打开, 其他参数为隐藏(包括非零元素)
  title : '标题',
  desc : '商品描述',
  picture : '商品图片地址',
  note : '备注',
  url : '跳转链接'
})

ysf('product') 支持传入成功和失败回调函数(success、error)。当在ios的h5页面使用七鱼 sdk 时,设置商品链接是一个异步的过程;如果需要保证商品链接设置成功,则应该在成功回调中进行后续操作(如进行页面跳转、打开聊天窗口等)

代码示例

ysf('product', {
  show : 1, // 1为打开, 其他参数为隐藏(包括非零元素)
  title : '标题',
  desc : '商品描述',
  picture : '商品图片地址',
  note : '备注',
  url : '跳转链接',
  success: function(){     // 成功回调
    ysf('open');
  },
  error: function(){       // 错误回调
    // handle error
  }
})

注: show 参数用于控制访客端商品链接是否显示;对于客服端,只要接入就一定会显示商品链接信息

ysf('config')和ysf('product')接口都提供了回调方法,所以在同时使用config和product方法是需要注意回调逻辑。可以在config的success回调中调用product方法,之后再在product的success中处理开发者自己想要实现的逻辑;或者可以使用变量标记的方法。

默认情况下,配置的商品链接会在接入人工会话后自动发送给客服;如果需要控制发送的时机,可以传入sendByUser参数。当设置该参数为1时,七鱼访客端不会自动发送商品链接,而是提供对应的引导卡片,访客可根据自己的需要点击引导卡片,手动发送商品链接给客服。

参数说明

名称类型必填说明
sendByUsernumber否0 | 1, 是否由访客手动发送,1为是,其他参数为否; 不传默认自动发送。sendByUser设置为1时,show参数将失效(取默认值1)
actionTextstring否sendByUser 为 1 时候发送按钮的文案,默认是 ‘发送’
actionTextColorstring否sendByUser 为 1 时候发送按钮的文字颜色,默认跟随访客发送消息主题颜色

代码示例

ysf('product', {
  sendByUser: 1, // 是否由访客手动发送,1为是,其他参数为否
  actionText: '发送链接', // 发送按钮文案
  actionTextColor: '#000000', // 发送按钮文案颜色(16进制格式)
  title : '标题',
  desc : '商品描述',
  picture : '商品图片地址',
  note : '备注',
  url : '跳转链接'
})

当sendByUser设置为1时,show参数将失效(取默认值1);同样的,actionText和actionTextColor参数仅在sendByUser为1时有效

重置商品消息

ysf.clearProduct();

模版卡片

为支持不同场景下商品信息的展示,七鱼访客端根据传入的template字段来确定具体的解析方式,当前支持pictureLink(图片链接)模板和默认模板

参数说明

名称类型必填说明
templatestring否此参数如果为 pictureLink 则数图片和链接形式的卡片,title、desc、note 等字段都无效

代码示例

ysf('product', {
  show : 1, // 1为打开,其他参数为隐藏(包括非零元素)
  template: 'pictureLink', // 模板类型,不传为默认类型
  title : '标题',
  picture : '商品图片地址',
  url : '跳转链接'
})

当使用pictureLink模板时,只有title、picture、url字段生效

卡片按钮点击效果

商品链接消息提供了可配置的功能性按钮,可以实现两个功能:

  1. 支持主动定位到客服工作台的iframe页面,并通过postMessage的方式向iframe页面中发送配置的信息。
  2. 支持浏览器用新标签的方式打开配置的url。

tags 参数说明

名称类型必填说明
labelstring是展示在卡片上的 tag 的名称
urlstring否如果没有 focusIframe 字段,或者没有匹配到 iframe,就以新窗口打开这个链接
focusIframestring否定位到iframe的标识,以iframe的名称匹配
dataany否以 postMessage 形式发送的数据给指定的 iframe,数据格式不限

代码示例

ysf('product', {
  show : 1, // 1为打开, 其他参数为隐藏(包括非零元素)
  title : '标题',
  desc : '商品描述',
  picture : '商品图片地址',
  note : '备注',
  url : '跳转链接',
  tags: [{
    "label": "打开七鱼官网",  // 按钮名字
    "url": "https://qi.163.com", // 非必填,如果没有focusIframe字段,或者没有匹配到iframe,就以新窗口打开这个链接
    "focusIframe": "iframe名称", // 定位到iframe的标识,以iframe的名称匹配
    "data": {"name": "ss","sex": "男"}  // 以postMessage形式发送的数据,数据格式不限
  },{
    "label": "查询订单",
    "focusIframe": "订单",
    "data": {"orderId": "10000012","userName": "xxx"}
  }]
});

注: 使用此接口,移动端SDK也得更新到4.1版本。

支持发送的场景

访客端进线发送

ysf('product', {
 // 卡片消息配置参数
})

SDK主动发送(new)

ysf('sendProduct', config) 能够满足在会话过程中实时发送

发送条件

  1. 机器人会话(需设置 sendProToRobot)
  2. 人工会话

代码示例

ysf('sendProduct', {
    title : '标题',
    desc : '商品描述',
    picture : '商品图片地址',
    note : '备注',
    url : '跳转链接',
    sendByUser: 0,
    success: () => {
    	console.log('卡片发送成功');
    },
    error: (err) => { console.log(err) }
})

工作台iframe发送

网易七鱼对于已经接入客服工作台iframe的客户提供了可以发送自定义商品或者订单类、自定义模板类消息的功能。 用户可以通过在接入的iframe页面中将数据对象按找下面规则组装好后通过postMessage的方式发送到网易七鱼的系统。

代码示例

var data = {
  // 要发送到七鱼的商品或者订单的数据对象
}
window.parent.postMessage(data, '*'); // 将数据用postMessage的方式发送到七鱼

商品卡片示例

订单卡片示例

参数说明

名称类型必填支持场景说明
通用参数cardTypestring否全部卡片类型,共三种类型。商品: 0,订单: 1,自定义: 2,推荐填写
sendByUsernumber否SDK是否由访客手动发送,1为是,其他参数为否
shownumber否SDK访客是否可见,1可见,其他参数访客不可见(但客服都是可见的)sendByUser=1 时,show强制为1
actionTextstring否SDK发送按钮文案,需设置 sendByUser 生效
actionTextColorstring否SDK发送按钮文案颜色,需设置 sendByUser 生效
sendProToRobotnumber否SDK此字段为机器人会话是否发送商品卡片,为1展示机器人阶段发送商品卡片,为0则机器人阶段不发送商品卡片而是人工会话中发送
intentstring否SDK意图名称
sendKefuOfflinenumber否SDK人工客服不在线进留言的时候是否发送 1为是,0为否,默认为否
paramsobject否SDK流程参数
clearnumber否SDK设置 1 可以清除已设置的商品卡和订单片的信息,clear设置为1
showCustomMsgstring是工作台 iframe此字段为向七鱼发送自定义信息的标识,为1展示并接收此消息,为0则不接收此消息(此字段为必填项,没有七鱼则不会接收)
infostring否SDK​卡片附加信息,信息不展示在前端卡片中,长度限制为100字符,超过自动截断
agentIdnumber否SDK​支持指定Agent接待,不需要调起Agent则参数值上报为空即可。若同时命中intent的小模型意图时,会优先返回小模型答案
商品picturestring是全部商品的缩略图地址
titlestring是全部商品的展示标题
descstring否全部商品展示的简要描述
notestring否全部商品备注,展示位置同商品价格,优先级高于商品价格
pricestring否全部商品的价格(已废弃,请使用 note 替代)
goodsCIdstring否全部商品类目ID,长度限制为 100 字符,填写后有助于机器人识别商品和后续业务
goodsCNamestring否全部商品类目名称,长度限制为 10 字,如生鲜食品
goodsIdstring否全部商品ID, 长度限制为 100 字符,商品唯一标识符,填写后有助于机器人识别商品和后续业务,当卡片类型为商品时,推荐填写
tagsTag[]否全部订单类消息展示的功能按钮,tag每一项为{"label": "打开七鱼网址","url": "https://qi.163.com"},label为按钮的名称,url为打开的链接
urlstring否全部点击商品跳转到的链接地址
floatCardSendnumber否全部由访客手动发送的卡片是否是悬浮在聊天框上面,1为是,其他参数为否(需要同时配置了sendByUser = 1)
activitystring否工作台 iframe活动展示标题
activityHrefstring否工作台 iframe点击活动跳转到的地址
订单picturestring是全部商品的缩略图地址
titlestring是全部商品的展示标题
descstring否全部商品展示的简要描述
goodsIdstring否全部商品ID, 长度限制为 100 字符,商品唯一标识符,填写后有助于机器人识别商品和后续业务,当卡片类型为商品时,推荐填写
goodsCIdstring否全部商品类目ID,长度限制为 100 字符,填写后有助于机器人识别商品和后续业务
payMoneystring否全部商品支付的价格
orderIdstring是全部订单的id
orderTimestring否全部下单时间
orderSkustring否全部订单的sku描述信息
orderCountstring否全部订单中商品数量
orderStatusstring否全部订单交易状态
orderStageTypenumber否全部订单状态分类 售前阶段:10000 发货前阶段:20000 发货后阶段:30000 售后阶段:40000
tagsTag[]否全部订单类消息展示的功能按钮,tag每一项为{"label": "打开七鱼网址","url": "https://qi.163.com"},label为按钮的名称,url为打开的链接
urlstring否全部点击商品跳转到的链接地址
activitystring否工作台 iframe活动展示标题
activityHrefstring否工作台 iframe点击活动跳转到的地址
自定义模版templatestring是全部模板类型(当前支持"pictureLink"即图片链接模板)
picturestring是全部图片地址
urlstring否全部点击图片跳转到的链接地址

2、自定义卡片消息

通过开放的模板,可以在七鱼原有的访客端&客服端的页面上,展示半自定义的消息体样式。(不支持平台版企业)

目前只有新版访客端支持发送卡片消息,老版访客端不支持卡片消息

仅在线专业版及以上坐席支持

若访客端界面视觉UI需要自定义样式,请前往七鱼管理端-在线客服设置-访客端-样式设置中可自由配置

卡片类型定义

卡片消息【cards】支持所有的 10 种类型卡片,分别是:标题类型、富文本类型、副标题类型、图片类型、节点流程类型、商品类型、订单类型、按钮类型、跳转链接类型、标签类型。一条卡片消息可以包含多种类型的模板组合。

浮动卡片消息【floatCards】只支持商品类型、按钮类型和标签类型。

【建议内容长度在4000个字符以内,超过可能会有非预期表现】

type ICard =
  | TitleOptions
  | RichOptions
  | SubTitleOptions
  | ImageOptions
  | ProductOptions
  | OrderOptions
  | FlowOptions
  | ButtonOptions
  | LinkOptions
  | TagOptions;

type IFloatCard = ProductOptions | ButtonOptions | TagOptions;

enum MoudleType {
  TITLE = 'title',
  RICH = 'rich',
  SUBTITLE = 'subtitle',
  IMAGE = 'image',
  PRODUCT = 'product',
  ORDER = 'order',
  FLOW = 'flow',
  BUTTON = 'button',
  LINK = 'link',
  TAG = 'tag',
}

interface TitleOptions {
  type: MoudleType.TITLE;
  content: string; //内容
  url?: string; // 超链接
  img?: string; // 图片加文本的图片url
  style?: {
    fontSize?: string | number; // 文字大小,默认14px
    fontColor?: string; // 字体颜色
    divider?: 0 | 1; // 是否添加分割线默认有分割线,最后一个元素没有
    pt?: number; // 上边距
    pb?: number; // 下边距
    pl?: number; // 左边距
    pr?: number; // 右边距
  };
}

/**
 * 富文本模版的配置
 */
interface RichOptions {
  type: MoudleType.RICH; // 富文本
  content: string; // 内容,必须符合HTML规范,微信小程序view、image等标签请改成div、img
  style?: {
    pt?: number; // 上边距
    pb?: number; // 下边距
    pl?: number; // 左边距
    pr?: number; // 右边距
    divider?: 0 | 1; // 分割线
  };
}

/**
 * 副标题模版的配置
 */
interface SubTitleOptions {
  type: MoudleType.SUBTITLE;
  img?: string; // 图片url
  content: string;
  subContent?: string; // 显示在右侧的
  url?: string; // 跳转 url
  style?: {
    backgroundColor?: string; // 背景色
    divider?: 0 | 1; // 分割线
    fontSize?: number;
    fontColor?: string;
    subFontSize?: number;
    subFontColor?: string;
    pt?: number; // 上边距
    pb?: number; // 下边距
    pl?: number; // 左边距
    pr?: number; // 右边距
  };
}

/**
 * 图片模版的配置
 */
interface ImageOptions {
  type: MoudleType.IMAGE; // 图片
  img: string; // 图片url
  url?: string; // 跳转 url
  style?: {
    divider?: 0 | 1; // 分割线
    pt?: number; // 上边距
    pb?: number; // 下边距
    pl?: number; // 左边距
    pr?: number; // 右边距
  };
}

/**
 * 商品模版的配置
 */
export interface ProductOptions {
  type: MoudleType.PRODUCT; // 商品
  data: {
    id: string | number; // 商品id
    picture: string; // 商品图片
    desc: string; // 描述
    title: string; // 标题
    price: string; // 价格
    url?: string; // actions 0的情况 跳转链接
    action?: 0 | 1; // 0 点击跳转【默认】, 1 点击发送对应的商品卡片 (只试用于访客端)
  }[];
  style?: {
    divider?: 0 | 1; // 分割线
    pt?: number; // 上边距
    pb?: number; // 下边距
    pl?: number; // 左边距
    pr?: number; // 右边距
  };
}

/**
 * 订单模版的配置
 */
export interface OrderOptions {
  type: MoudleType.ORDER; // 订单
  orderId: string | number; // 订单id
  orderTime: string; // 下单时间
  data: {
    picture: string; // 商品图片
    desc: string; // 描述
    title: string; // 商品标题
    payMoney?: string; // 价格
    url?: string; // 跳转链接
    count?: string; // 订单商品数量 x 100
    sku?: string; // 商品sku描述
    status: string; // 交易状态
    action?: 0 | 1; // 0 点击跳转, 1 点击发送对应的订单卡片 (只试用于访客端)
  }[];
  style?: {
    divider?: 0 | 1; // 分割线
    pt?: number; // 上边距
    pb?: number; // 下边距
    pl?: number; // 左边距
    pr?: number; // 右边距
  };
}

/**
 * 节点流程的配置
 */
export interface FlowOptions {
  type: MoudleType.FLOW; // 流程
  data: {
    id: string | number; // 流程id
    title: string; // 标题
    subtitle?: string; // 副标题
    current?: 1 | 0; // 当前步骤
  }[];
  style?: {
    fontSize?: number; // 主标题大小
    fontColor?: string; // 主标题颜色 有默认
    subFontSize?: number; // 副标题大小
    subFontColor?: string; // 副标题颜色 有默认值
    divider?: 0 | 1; // 分割线
    pt?: number; // 上边距
    pb?: number; // 下边距
    pl?: number; // 左边距
    pr?: number; // 右边距
  };
}

/**
 * 按钮模版的配置 TODO
 */
export interface ButtonOptions {
  type: MoudleType.BUTTON; // 按钮
  numInRow?: number; // 一行显示几个按钮 默认1个【浮动组件不生效】
  data: {
    title: string; // 标题
    action?: 0 | 1; // 0 点击跳转链接, 1 点击发送配置的文字(仅限访客)
    url?: string; // 跳转链接
    content?: string; // 发送的文字 action === 1 需要配置此内容
  }[];
  style?: {
    backgroundColor?: string; // 背景色
    fontColor?: string; // 文字颜色
    fontSize?: number; // 文字大小
    divider?: 0 | 1; // 分割线
    pt?: number; // 上边距
    pb?: number; // 下边距
    pl?: number; // 左边距
    pr?: number; // 右边距
  };
}

/**
 * 卡片消息的配置
 */
export interface LinkOptions {
  type: MoudleType.LINK; // 链接
  content: string; // 标题
  url: string; // 跳转链接
  style?: {
    fontSize?: number; // 文字大小
    fontColor?: string; // 文字颜色
    divider?: 0 | 1; // 分割线
    pt?: number; // 上边距
    pb?: number; // 下边距
    pl?: number; // 左边距
    pr?: number; // 右边距
  };
}

/**
 * 标签
 */
export interface TagOptions {
  type: MoudleType.TAG; // 标签
  data: {
  	label: string; // 标签名称
    url?: string; // 非必填,如果没有 focusIframe 字段,或者没有匹配到 iframe,就以新窗口打开这个链接
    focusIframe?: string; // 定位到客服工作台右侧 iframe 的标识,以 iframe 的名称匹配
    data: any; // 以 postMessage 形式发送的数据,数据格式不限
  }[];
}

参数说明

所有模板类型支持上下左右边距调整 & 分割线,在具体参数说明当中不再重复

名称必填说明
uuid否消息唯一标识,可以实现访客端进线发送场景下多次发送卡片
cards是卡片消息内容
floatCards否浮动卡片消息内容
sendProToRobot否此字段为机器人会话是否发送自定义卡片,为1展示机器人阶段发送自定义卡片,为0则机器人阶段不发送自定义卡片而是人工会话中发送
intent否意图名称
params否流程参数

标题文本:

参数说明

名称必填类型说明
type是string固定值,title
content是string标题
img否string左侧图片URL
url否string链接跳转地址
style否object样式

style结构说明

名称必填类型说明
fontSize否number文字大小,默认14px
fontColor否string字体颜色,有默认值
pt否number上边距
pb否number下边距
pl否number左边距
pr否number右边距
divider否number是否需要分割线,0:不需要;1:需要

副标题文本:

参数说明

名称必填类型说明
type是string固定值,subtitle
content是string左侧文字内容
subContent否string右侧文字内容
img否string图片url地址,默认与文字等高
url否string跳转超链接
style否object样式

style结构说明

名称必填类型说明
backgroundColor否string背景色
fontSize否number左侧文字大小,有默认值
fontColor否string左侧文字字体颜色,有默认值
subFontSize否number右侧文字大小,有默认值
subFontColor否string右侧文字字体颜色,有默认值
pt否number上边距
pb否number下边距
pl否number左边距
pr否number右边距
divider否number是否需要分割线,0:不需要;1:需要

富文本:

参数说明

名称必填类型说明
type是string固定值,rich
content是string内容
style否object样式

style结构说明

名称必填类型说明
pt否number上边距
pb否number下边距
pl否number左边距
pr否number右边距
divider否number是否需要分割线,0:不需要;1:需要

图片:

参数说明

名称必填类型说明
type是string固定值,image
img是string图片地址
url否string跳转超链接
style否object样式

style结构说明

名称必填类型说明
pt否number上边距
pb否number下边距
pl否number左边距
pr否number右边距
divider否number是否需要分割线,0:不需要;1:需要

商品:

参数说明

名称必填类型说明
type是string固定值,product
data是array商品数据节点
style否object样式

data字段object结构

名称必填类型说明
id是string商品id
picture是string商品图片
desc是string描述
title是string标题
price是string价格
url否string跳转超链接,action为0的情况下的跳转链接
action否number2种类型,默认为0 (0 :点击跳转url, 1 :点击发送对应的商品卡片 (只适用于访客端))
tags否Tag[]订单类消息展示的功能按钮,tag每一项为{"label": "打开七鱼网址","url": "https://qi.163.com"},label为按钮的名称,url为打开的链接

style结构说明

名称必填类型说明
pt否number上边距
pb否number下边距
pl否number左边距
pr否number右边距
divider否number是否需要分割线,0:不需要;1:需要

tags字段结构说明

名称必填类型说明
label是string标签名称
url否string非必填,如果没有 focusIframe 字段,或者没有匹配到 iframe,就以新窗口打开这个链接
focusIframe否string定位到工作台右侧面板 iframe 的标识,以 iframe 的名称匹配
data否any以 postMessage 形式发送的数据,数据格式不限

订单:

参数说明

名称必填类型说明
type是string固定值,order
orderId是string订单ID
orderTime是string下单时间
data是array订单数据节点
style否object样式

data字段结构说明

名称必填类型说明
picture是string商品图片
desc是string描述
title是string商品标题
status是string交易状态
payMoney否string价格
url否string跳转超链接,action为0的情况下的跳转链接
count否string订单商品数量 x 100
sku否string商品sku描述
action否number2种类型,默认为0 (0 :点击跳转url, 1 :点击发送对应的订单卡片 (只适用于访客端))
tags否Tag[]订单类消息展示的功能按钮,tag每一项为{"label": "打开七鱼网址","url": "https://qi.163.com"},label为按钮的名称,url为打开的链接

style字段结构说明

名称必填类型说明
pt否number上边距
pb否number下边距
pl否number左边距
pr否number右边距
divider否number是否需要分割线,0:不需要;1:需要

tags字段结构说明

名称必填类型说明
label是string标签名称
url否string非必填,如果没有 focusIframe 字段,或者没有匹配到 iframe,就以新窗口打开这个链接
focusIframe否string定位到工作台右侧面板 iframe 的标识,以 iframe 的名称匹配
data否any以 postMessage 形式发送的数据,数据格式不限

节点流程:

参数说明

名称必填类型说明
type是string固定值,flow
data是array流程数据节点
style否object样式

data字段结构说明

名称必填类型说明
id是string流程id
title是string标题
subtitle否string副标题
current否number2种状态 (0 :非当前步骤,1 :当前步骤)

style字段结构说明

名称必填类型说明
fontSize否number主标题文字大小,有默认值
fontColor否string主标题文字字体颜色,有默认值
subFontSize否number副标题文字大小,有默认值
subFontColor否string副标题文字字体颜色,有默认值
pt否number上边距
pb否number下边距
pl否number左边距
pr否number右边距
divider否number是否需要分割线,0:不需要;1:需要

操作按钮:

参数说明

名称必填类型说明
type是string固定值,button
numInRow否number一行显示几个按钮 默认1个(悬浮组件不生效)
data是array按钮数据节点
style否object样式

data字段结构说明

名称必填类型说明
title是string商品标题
action否number2种类型,默认为0 (0 点击跳转链接, 1 点击发送配置的文字 (只适用于访客端))
url否string跳转超链接,action为0的情况下的跳转链接
content否string发送内容,action为1的情况下的发送内容

style字段结构说明

名称必填类型说明
backgroundColor否string背景色
fontSize否number文字大小,有默认值
fontColor否string文字字体颜色,有默认值
pt否number上边距
pb否number下边距
pl否number左边距
pr否number右边距
divider否number是否需要分割线,0:不需要;1:需要

跳转链接:

参数说明

名称必填类型说明
type是string固定值,link
content是string标题
url是string跳转链接
style否object样式

style字段结构说明

名称必填类型说明
fontSize否number文字大小,有默认值
fontColor否string文字字体颜色,有默认值
pt否number上边距
pb否number下边距
pl否number左边距
pr否number右边距
divider否number是否需要分割线,0:不需要;1:需要

标签:

参数说明

名称必填类型说明
type是string固定值,tag
data是Tag[]标签数据

Tag 类型参数说明

名称必填类型说明
label是string标签名称
url否string非必填,如果没有 focusIframe 字段,或者没有匹配到 iframe,就以新窗口打开这个链接
focusIframe否string定位到工作台右侧面板 iframe 的标识,以 iframe 的名称匹配
data否any以 postMessage 形式发送的数据,数据格式不限

组合效果展示

可以通过以上开放的模板进行自由组合,生成半自定义的消息体样式,一条卡片消息可以包含多种类型的卡片。 以下为部分举例示意:

支持发送的场景

目前仅支持人工会话过程中发送响应自定义卡片

访客端进线发送

代码示例

ysf('cardMessage', {
      sendByUser?: 0, // 0 进线自动发送,1 手动发送  默认0
      actionText? :string // 发送按钮文案
      actionTextColor?: string // 发送按钮颜色
      hideAction?: number; // 是否展示action按钮 默认0;用于sendByUser=1隐藏发送按钮
      cards: ICard[]; // 这里是消息的配置,至少一个 ,看卡片类型定义
      floatCards?: IFloatCard[] // 这里是消息的配置,看卡片类型定义
      clear?:number;// 设置为1时可以清除已设置的卡片,设为1时cards需设置为[{}]
      success?: () => {}
      error?: () => {}
	}
})

重置访客端进线发送的自定义卡片消息

ysf.clearCustomCard() 

SDK主动发送(new)

ysf('sendCardMessage', config) 能够满足在会话过程中实时发送

发送条件:人工会话

​

代码示例

ysf('sendCardMessage', {
    type: 'cardMessage',
    sendByUser: 0,
    cards: [],
    floatCards: [],
    success: () => {
    	console.log('卡片发送成功');
    },
    error: (err) => { console.log(err) }
})

工作台iframe发送

网易七鱼对于已经接入客服工作台iframe的客户提供了可以发送自定义卡片消息的功能。 用户可以通过在接入的iframe页面中将数据对象按找下面规则组装好后通过postMessage的方式发送到网易七鱼的系统。

代码示例

var data = {
  msgtype: 'cardMessage',
  cards: ICard[]; // 这里是消息的配置,至少一条,具体配置看卡片类型定义
  floatCards?: IFloatCard[] // 这里是消息的配置,具体配置看卡片类型定义
}
// 将数据用postMessage的方式发送到七鱼
window.parent.postMessage(data, '*');

通过接口开发者服务器替用户向客服发送消息

接口对接请见 -给七鱼发送消息

通过接口开发者服务器替客服向访客发送消息

接口对接请见 -给访客发送消息

3、自定义组件消息

通过代码开发自定义渲染组件,可以在七鱼原有的访客端的页面上,展示完全自定义的消息体样式。(不支持平台版企业)

目前只有新版访客端支持发送自定义消息(仅 web/h5),老版访客端不支持

仅在线专业版及以上坐席支持

开发流程

获取消息组件开发模版:https://github.com/NSFI/tpl-message-react

组件开发完成后,请联系七鱼客服人员进行上传

支持发送的场景

目前仅支持人工会话过程中发送自定义消息

访客端进线发送

代码示例

ysf('customMessage', {
  data: any, // 用户自定义数据,不限制格式
  description: string, //  必填,客服工作台展示该字段
  
  sendByUser?: number, // 0 进线自动发送,1 手动发送  默认0
  actionText?:string, // 发送按钮文案 [new]
  actionTextColor?: string, // 发送按钮颜色[new]
  hideAction: number, // 是否展示action按钮 默认0,sendByUser=1的时候会展示发送卡片按钮 [new]
  succsess: () => {},
  error: () => {},
});

SDK主动发送(new)

ysf('sendCustomMessage', config) 能够满足在会话过程中实时发送

发送条件

  1. 人工会话
  2. 开通自定义组件消息权限

代码示例

ysf('sendCustomMessage', {
    data: any, // 用户自定义数据,不限制格式
    description: string, //  必填,客服工作台展示该字段
    sendByUser: 0,
    success: () => {
    	console.log('卡片发送成功');
    },
    error: (err) => { console.log(err) }
})

工作台iframe发送

网易七鱼对于已经接入客服工作台iframe的客户提供了可以发送自定义卡片消息的功能。 用户可以通过在接入的iframe页面中将数据对象按找下面规则组装好后通过postMessage的方式发送到网易七鱼的系统。

代码示例

var data = {
  msgtype: 'customMessage'; // 消息类型
  data: any; // 组件接收数据类型
  description: string; // 客服工作台、消息记录展示文案
};
// 将数据用postMessage的方式发送到七鱼
window.parent.postMessage(data, '*');

通过接口开发者服务器替用户向客服发送消息

接口对接请见 -给七鱼发送消息

通过接口开发者服务器替客服向访客发送消息

接口对接请见 -给访客发送消息

参数说明

名称类型必填说明
uuidstring否消息唯一标识,可以实现访客端进线发送场景下多次发送卡片
dataany否用户自定义数据,不限制格式
descriptionstring是客服工作台展示该字段

会话管理

分配客服&客服组

网易七鱼客服系统默认会按照智能方式分配客服, 如果想让访客分配给指定的客服组或者客服,则需要使用访客分流功能

你可以在管理后台 -> 服务中心-> 在线系统-> 设置 -> 会话流程 -> 会话分配 ->分配规则-> ID查询, 可以查找到相应的客服id和客服组id。

你可以在管理后台 -> 服务中心 -> 在线系统-> 设置 -> 会话流程 -> 会话分配 -> 分配规则 -> 高级自定义分配(WEB端)-> Web端自定义链接分配,可以直接复制链接地址接入

代码示例

ysf('config', {
  uid:"1442286211167",
  name:'test',
  email:'test@163.com',
  mobile:'13888888888',
  staffid:'123', // 客服id
  groupid: '123' // 客服组id
});

代码优先级高于后台配置,所以当代码中指定了staffid或者groupid后,后台的web端访客分流配置将无效。staffid和groupid只要传一个就可以了,没必要两个参数都传(同时传了staffid和groupid,忽略groupid)。

分配机器人

在3.1版本中,增加了robotShuntSwitch参数,该参数取值为0或1,在指定了访客分流时有效;如果robotShuntSwitch为1,访客会先由机器人接待,当转人工咨询时再分配给设置的分流客服

代码示例

ysf('config', {
  uid:"1442286211167",
  name:'test',
  email:'test@163.com',
  mobile:'13888888888',
  staffid:'123',
  robotShuntSwitch: 1 // 机器人优先开关
});

对于开通了多机器人的企业,对于不指定robotId的访客入口,网易七鱼系统会在机器人开关打开的情况下自动匹配当前的默认机器人,如果想让指定的机器人服务访客,则需要使用多机器人接入功能指定robotId。

开通了多个机器人的企业,在管理后台-> 服务中心 -> 在线机器人 -> 机器人列表中找到对应的机器人ID。 在管理后台 -> 服务中心 -> 在线系统 -> 设置 -> 会话流程 -> 会话分配 ->分配规则->高级自定义分配(WEB端)-> Web端自定义链接分配,可以直接复制链接地址接入

代码示例

ysf('config', {
  uid:"usr18398492039",
  name:'mixRobotTestUser',
  email:'test@163.com',
  mobile:'13888888888',
  robotId: '12345'  // 机器人ID
});

关闭挽留邀评

app webview嵌入H5访客端,点击app自己的返回时,可以配置关闭挽留邀请评价

参数说明

名称类型必填说明
APPbackPopnumber否APP点击返回的时候是否弹出 关闭挽留弹窗(同时需要APP调用JS window.checkCloseYSFClient(data))
0:不弹起 1:只弹起关闭挽留弹窗 2: 弹起关闭挽留弹窗和满意度评价弹窗

代码示例

ysf('config', {
  APPbackPop: 2  // 0不弹起挽留弹窗 1:弹关闭挽留弹窗 2: 关闭挽留弹窗和评价挽留弹窗
});

提供APP调用H5方法

方法名称类型说明
checkCloseYSFClient(data:JSONString) => VoidAPP点击返回的时候需要调用H5的方法,通知H5去处理挽留弹窗和挽留评价操作(注意:checkCloseYSFClient 方法是七鱼会话窗口的 window 上的方法,如果使用浮层等模式接入的时候直接在 webview 的 window 上获取不到该方法 )

H5和webview通信

Android示例

APP调用H5的方法

// 在需要关闭七鱼访客端界面的地方,加入下面的代码
String js = "javascript:" + "checkCloseYSFClient" + "()";
WebView.loadUrl(js);

H5操作完数据,需要通知APP进行返回,我们通过postMessage的方式发送消息通知到APP

定义receiveYSFMessage方法

代码示例

// 自定义addJavascriptInterface接口
public class JavaScriptInterface {
    @JavascriptInterface
    public void receiveYSFMessage(String message) {
        // 在这里处理从H5页面传来的消息
        Log.e("receiveYSFMessage: ", "从js--> " + message);
    }
}

需要定义postmessage为postH5Message防止重写了H5自己的postmessage

代码示例

//webView 然后设置 setJavaScriptEnabled 为 true
WebView.setJavaScriptEnabled(true);
//添加 addJavascriptInterface 监听,设置全局的 JavaScript 方法处理 postH5Message 。
WebView.addJavascriptInterface(new JavaScriptInterface(), "postH5Message");

IOS示例代码

#import "TestViewController.h"
#import <WebKit/WebKit.h>

@interface TestViewController ()<WKScriptMessageHandler,WKNavigationDelegate,WKUIDelegate>
@property (nonatomic, strong) WKWebView *webView;
@end

@implementation TestViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect rect = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds));
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    config.preferences = [[WKPreferences alloc] init];
    config.preferences.minimumFontSize = 10;
    config.preferences.javaScriptEnabled = YES;
    config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
    config.userContentController = [[WKUserContentController alloc] init];
    config.processPool = [[WKProcessPool alloc] init];
    config.userContentController = [WKUserContentController new];
    //在创建wkWebView时,需要将被js调用的方法注册进去,oc与js端对应实现
    [config.userContentController addScriptMessageHandler:self name:@"receiveYSFMessage"];
    WKWebView *wkWebView = [[WKWebView alloc]initWithFrame:rect configuration:config];
    self.webView = wkWebView;
    wkWebView.navigationDelegate = self;
    wkWebView.UIDelegate = self;
    NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:@"http://6669.qytest.netease.com/sdk/r/demo-debug.html"]];
    [wkWebView loadRequest:request];
    [self.view addSubview:wkWebView];
    UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    backBtn.frame = CGRectMake(100, 100, 100, 100);
    [backBtn setTitle:@"返回" forState:UIControlStateNormal];
    [self.view addSubview:backBtn];
    [backBtn setTitleColor:UIColor.blackColor forState:UIControlStateNormal];
    [backBtn addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];

}
- (void)onBack {
    [self nativeCallJS];
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:@"receiveYSFMessage"]) {
        NSLog(@"JS调用原生,参数:%@",message.body);
        [self.navigationController popViewControllerAnimated:YES];
    }
}
- (void)nativeCallJS {
    [self.webView evaluateJavaScript:@"checkCloseYSFClient()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
      //TODO
        NSLog(@"");
     }];
}

@end

相册、视频、文件权限通信

app webview嵌入H5访客端,点击相册、视频、文件获取APP权限(浮层模式不支持,不能跨域访问访客端方法),仅支持IOS

注意:android以标准的WebView接入方式来完成权限调用,在WebChromeClient的onShowFileChooser方法中判断权限有没有调用,视频客服则需要通过onPermissionRequest方法来判断

接入说明

名称类型必填说明
APPBridgePermissionnumber否1: 获取app相机、文件权限 0: 不获取权限(浮层模式不支持)

代码示例

ysf('config', {
  APPBridgePermission: 1  // 0:不获取权限 1:获取app权限,需要app客户端配合开发
});

提供APP调用H5方法

方法名称类型说明
ysfAppBridge(data:{ seq: 1, type: 'imagePermission' }) => voidAPP主动调用H5的方法,通知H5获取权限问题
(传会的参数,就是H5请求带的参数,即下面H5和webview通信中讲到的参数)

H5和webview通信

receiveYSFMessage h5主动传递给客户端的类型

参数说明

权限类型类型说明
imagePermissionstring获取图片权限
videoPermissionstring获取视频权限
filePermissionstring获取文件权限
requestImagePermissionstring请求图片权限(让APP去请求相册权限,弹出对应的权限弹窗)
requestVideoPermissionstring请求视频权限(让APP去请求视频权限,弹出对应的权限弹窗)
requestFilePermissionstring请求文件权限(让APP去请求文件权限,弹出对应的权限弹窗)

IOS示例代码

//
//  TestViewController.m
//  QYSDKDemo
//
//  Created by zhongzhida on 2023/4/19.
//  Copyright © 2023 Netease. All rights reserved.
//

#import "TestViewController.h"
#import <WebKit/WebKit.h>
#import <Photos/Photos.h>

@interface TestViewController ()<WKScriptMessageHandler,WKNavigationDelegate,WKUIDelegate>
@property (nonatomic, strong) WKWebView *webView;
@end

@implementation TestViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect rect = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds));
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    config.preferences = [[WKPreferences alloc] init];
    config.preferences.minimumFontSize = 10;
    config.preferences.javaScriptEnabled = YES;
    config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
    config.userContentController = [[WKUserContentController alloc] init];
    config.processPool = [[WKProcessPool alloc] init];
    config.userContentController = [WKUserContentController new];
    //在创建wkWebView时,需要将被js调用的方法注册进去,oc与js端对应实现
    [config.userContentController addScriptMessageHandler:self name:@"receiveYSFMessage"];
    WKWebView *wkWebView = [[WKWebView alloc]initWithFrame:rect configuration:config];
    self.webView = wkWebView;
    wkWebView.navigationDelegate = self;
    wkWebView.UIDelegate = self;
    NSURLRequest *request = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:@"http://10.221.149.18:8002/src/html/demo-debug.html"] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
    [wkWebView loadRequest:request];
    [self.view addSubview:wkWebView];
    
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:@"receiveYSFMessage"]) {
        NSLog(@"JS调用原生,参数:%@",message.body);
        NSString *body = message.body;
        NSData *jsonData = [message.body dataUsingEncoding:NSUTF8StringEncoding];

        NSError *error = nil;
        NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
        NSString *type = jsonDictionary[@"type"];
        NSInteger result = 0;
        if ([type isEqualToString:@"imagePermission"] || [type isEqualToString:@"videoPermission"]) {
            // 获取相册权限状态
            PHAuthorizationStatus photoLibraryAuthorizationStatus = [PHPhotoLibrary authorizationStatus];
            [self nativeCallJS:@{@"seq":jsonDictionary[@"seq"],@"type":type,@"result":@(photoLibraryAuthorizationStatus)}];
        } else if ([type isEqualToString:@"filePermission"]) {
            [self nativeCallJS:@{@"seq":jsonDictionary[@"seq"],@"type":type,@"result":@(1)}];
        } else if ([type isEqualToString:@"requestImagePermission"] || [type isEqualToString:@"requestVideoPermission"]) {
            // 获取相册权限状态
            PHAuthorizationStatus photoLibraryAuthorizationStatus = [PHPhotoLibrary authorizationStatus];
            if (photoLibraryAuthorizationStatus == PHAuthorizationStatusDenied ) {
                [[[UIAlertView alloc] initWithTitle:@"没有相册权限"
                                            message:@"请在iPhone的“设置-隐私-相册”选项中,允许访问你的相册。"
                                           delegate:nil
                                  cancelButtonTitle:@"确定"
                                  otherButtonTitles:nil] show];
            } else if (photoLibraryAuthorizationStatus == PHAuthorizationStatusNotDetermined) {
                // 请求访问相册的权限
                [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [self nativeCallJS:@{@"seq":jsonDictionary[@"seq"],@"type":type,@"result":@(status)}];
                    });
                }];
            }
            
        }
        
    }
}
- (void)nativeCallJS:(NSDictionary *)param {
    NSData *data = [NSJSONSerialization dataWithJSONObject:param
                                                   options:0
                                                     error:nil];
    NSString *str  = [[NSString alloc] initWithData:data
                                           encoding:NSUTF8StringEncoding];
    NSString *js = [NSString stringWithFormat:@"ysfAppBridge(%@)",str];
    [self.webView evaluateJavaScript:js completionHandler:^(id _Nullable response, NSError * _Nullable error) {
      //TODO
        NSLog(@"");
     }];
}

@end

这篇文档有帮助吗?

目录