有奖:语音产品征文挑战赛火热进行中> HOT

前提条件

了解在线客服相关术语及相关配置,并已完成以下步骤:添加客服、配置技能组、创建会话服务流,详情请参见 快速入门
集成 IM SDK ,并跑通登录、发单聊消息等功能。请参见 Flutter(含 UI)

UI 插件介绍

您可以集成腾讯云即时通信官方提供的在线客服插件 tencent_cloud_chat_customer_service_plugin,集成后,您可以在 IM 应用中集成在线客服功能。在线客服功能包括解析在线客服自定义消息、发送卡片消息、主动评价客服等。Flutter 端与 Native 的在线客服能力互通。

环境与版本

本插件依赖插件以及环境
Fluter 3.10.0及以上
tencent_cloud_chat_uikit 2.1.3 及以上(建议与 flutter uikit 一起使用)

插件引入

通过 pub 可将在线客服插件引入到项目中,插件地址:
// 集成最新版本
flutter pub add tencent_cloud_chat_customer_service_plugin

插件集成

指引代码将展示插件如何与 flutter uikit 结合使用,如您为无 UI 开发,可通过参见代码,了解逻辑后根据 SDK 集成指引 自行接入。

步骤1:完成客服插件设置

首先请您完成客服插件的 管理端配置

步骤2:设置客服用户 ID 配置并获取客服虚拟号信息列表

在线客服对应的 IM 用户为一类特殊的 IM 用户,在进入此类用户的聊天页面时会有特殊的发送消息操作,因此我们建议将 IM 虚拟号的 IM User ID 列表当作配置保存起来,方便全局调用。
// IM渠道中的IM UserID
static const List<String> customerServiceUserList = [
'在线客服ID',
'iaUMZCHP******VSPWCG'
];
// 通过getCustomerServiceInfo获取客服虚拟号信息列表,并通过自定义的页面渲染
// demo中CustomerServicePage为事例代码,用户可在清楚逻辑后进行自定义构建客服列表页面
customerServiceInfoList =
await TencentCloudChatCustomerServicePlugin.getCustomerServiceInfo(
IMDemoConfig.customerServiceUserList);

步骤3:在线客服消息解析

在线客服的特殊消息,例如分支消息评价消息、卡片消息等,都是通过自定义消息实现,因此您需要在接收消息时判断消息类型并渲染。tencent_cloud_chat_customer_service_plugin 提供了 isCustomerServiceMessage 方法用于判断自定义消息是否属于在线客服的自定义消息,MessageCustomerService 组件用于渲染在线客服的自定义消息。使用方法如下:
// 在flutter uikit中使用 TIMUIKitChat 组件的 customMessageItemBuilder 属性实现
// 使用逻辑可见flutter uikit的demo 中 lib/utils/custom_message/custom_message_element.dart
if (TencentCloudChatCustomerServicePlugin.isCustomerServiceMessage(message)) {
return MessageCustomerService(
message: message,// 需要渲染的自定义消息
theme: theme,// uikit的主题
isShowJumpState: isShowJumpState,// uikit中的消息跳转状态
sendMessage: chatController.sendMessage,// sendMessage为发送消息的函数,用于处理在线客服的消息交互。
);
在线客服消息中有一些特殊的消息为标志消息,例如会话结束、会话开始、客服配置等,这一类消息不需要渲染在消息列表中。tencent_cloud_chat_customer_service_plugin 提供了 isCustomerServiceMessageInvisible 方法用于判断在线客服消息是否需要在消息列表中渲染。使用方法如下:
// 在flutter uikit中使用 TIMUIKitChat 组件的 lifeCycle 属性实现
// messageShouldMount 为flutter uikit 2.1.3的新配置,用于判断消息是否需要渲染在消息列表
// 使用逻辑可见flutter uikit的demo 中 lib/src/chat.dart
TIMUIKitChat(
lifeCycle: ChatLifeCycle(messageShouldMount: (V2TimMessage message) {
if (TencentCloudChatCustomerServicePlugin
.isCustomerServiceMessageInvisible(message) &&
TencentCloudChatCustomerServicePlugin.isCustomerServiceMessage(
message)) {
return false;
}
return true;
}),
);
在线客服消息中,评价消息因为不需要会话气泡且需要独占一行,因此, 此消息需要单独处理。tencent_cloud_chat_customer_service_plugin 提供了isRowCustomerServiceMessage 方法用于判断消息是否需要独占一行。使用方法如下:
// 在flutter uikit中使用 TIMUIKitChat 组件的 messageRowBuilder 属性实现
// 使用逻辑可见flutter uikit的demo 中 lib/src/chat.dart
TIMUIKitChat(messageItemBuilder: MessageItemBuilder(
messageRowBuilder: (message, messageWidget, onScrollToIndex,
isNeedShowJumpStatus, clearJumpStatus, onScrollToIndexBegin) {
if (TencentCloudChatCustomerServicePlugin.isRowCustomerServiceMessage(
message)) {
return messageWidget;
}
},
));

步骤4:主动发送启动消息

在进入在线客服用户的聊天时,需要发送一条特殊的自定义消息用于启动在线客服会话。tencent_cloud_chat_customer_service_plugin 提供了sendCustomerServiceStartMessage 方法用于快速发送启动消息。使用方法如下:
// 使用逻辑可见flutter uikit的demo 中 lib/src/chat.dart
// flutter uikit 窄屏UI专用
@override
void initState() {
super.initState();
if (IMDemoConfig.customerServiceUserList
.contains(widget.selectedConversation.userID)) {// 当进入的聊天页面时在线客服用户时需要发送启动消息
// 传入参数为发送消息的函数
TencentCloudChatCustomerServicePlugin.sendCustomerServiceStartMessage(
_chatController.sendMessage);
}
}
// flutter uikit 宽屏UI专用
@override
void didUpdateWidget(Chat oldWidget) {
super.didUpdateWidget(oldWidget);
final isWideScreen =
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
if (isWideScreen &&
IMDemoConfig.customerServiceUserList
.contains(widget.selectedConversation.userID)) {
TencentCloudChatCustomerServicePlugin.sendCustomerServiceStartMessage(
_chatController.sendMessage);
}
}

步骤5:给客服用户发送消息

在云联络中心中完成即时通讯 IM 渠道的客服配置,tencent_cloud_chat_customer_service_plugin 提供了 getCustomerServiceInfo 方法用于快速获取客服虚拟号的用户信息,获取信息后进入会话即可完成在线客服消息 UI 组件的接入渲染。
使用方法可见 lib/src/pages/customer_service_example/customerServicePage.dart.dart 文件。

获取在线客服输入状态(可选)

当座席端正在输入消息时,用户端可以收到下发的自定义消息用于确定客服的输入状态。tencent_cloud_chat_customer_service_plugin 提供了isTypingCustomerServiceMessage 方法用于快速确定输入状态。使用方法如下:
// 在flutter uikit中使用 TIMUIKitChat 组件的 lifeCycle、conversationShowName 属性实现
// 使用逻辑可见flutter uikit的demo 中 lib/src/chat.dart
TIMUIKitChat(
conversationShowName:
customerServiceTyping ?? conversationName ?? _getTitle(),
lifeCycle:
ChatLifeCycle(newMessageWillMount: (V2TimMessage message) async {
// ChannelPush.displayDefaultNotificationForMessage(message);
if (TencentCloudChatCustomerServicePlugin.isCustomerServiceMessage(
message)) {
if (TencentCloudChatCustomerServicePlugin
.isTypingCustomerServiceMessage(message)) {
setState(() {
// 确定为正在输入中时改变聊天页面名称
customerServiceTyping = TIM_t("对方正在输入中...");
});
}
} else {
setState(() {
customerServiceTyping = null;
});
}
return message;
}),
);

主动发送卡片消息(可选)

在与在线客服的对话中,用户端可主动发送带跳转地址的卡片消息。卡片消息包括名称、描述、图片、点击时的跳转地址四个属性。




1. 添加入快速操作栏

您可以将发送卡片消息的快捷按钮放在聊天页面中,我们以使用 flutter uikit 的 morePanelConfig、additionalDesktopControlBarItems 为例:
// 在flutter uikit 中使用 TIMUIKitChat 组件的 morePanelConfig、additionalDesktopControlBarItems 属性实现
// 使用逻辑可见 flutter uikit的demo 中 lib/src/chat.dart
TIMUIKitChat(
// 窄屏UI按钮
morePanelConfig: MorePanelConfig(
extraAction: [
MorePanelItem(
onTap: (c) {
_createCustomerServiceCardMessage();
},
icon: Container(
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
child: Icon(
Icons.card_giftcard,
color: hexToColor("5c6168"),
size: 32,
),
),
id: 'cardMessage',
title: TIM_t("卡片消息"),
)
],
),
// 宽屏UI按钮
config: TIMUIKitChatConfig(additionalDesktopControlBarItems: [
DesktopControlBarItem(
item: 'evaluate',
showName: TIM_t("卡片消息"),
onClick: (offset) {
_createCustomerServiceCardMessage();
},
icon: Icons.card_giftcard)
]));

2. 发送卡片消息

tencent_cloud_chat_customer_service_plugin 提供了 TencentCloudChatCardCreate 组件用于快速输入卡片消息并发送。按钮交互代码如下:
// 卡片消息按钮交互
// 使用逻辑可见 flutter uikit 的 demo 中 lib/src/chat.dart
_createCustomerServiceCardMessage() {
final isWideScreen =
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
if (isWideScreen) {
TUIKitWidePopup.showPopupWindow(
context: context,
title: TIM_t("请填写商品信息"),
operationKey: TUIKitWideModalOperationKey.custom,
width: 400,
height: 350,
child: (onClose) => CardCreateExample(
controller: _chatController,
onClosed: onClose,
),
);
} else {
return showModalBottomSheet<void>(
context: context,
isDismissible: false,
isScrollControlled: true,
builder: (BuildContext context) {
return Container(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 10),
margin: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
TIM_t("请填写商品信息"),
style: const TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w700),
),
TextButton(
onPressed: () => {Navigator.of(context).pop()},
child: Text(
TIM_t("关闭"),
style: const TextStyle(color: Colors.orange),
))
],
),
CardCreateExample(
controller: _chatController,
onClosed: () => {Navigator.of(context).pop()},
)
],
),
);
},
);
}
}
CardCreateExample 组件代码如下所示:
// 使用逻辑可见 flutter uikit 的 demo 中 lib/src/pages/customer_service_example/card_create_example.dart
import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_customer_service_plugin/tencent_cloud_chat_customer_service_plugin.dart';
import 'package:tencent_cloud_chat_uikit/ui/controller/tim_uikit_chat_controller.dart';
import 'package:tencent_cloud_chat_uikit/ui/utils/screen_utils.dart';

class CardCreateExample extends StatefulWidget {
final TIMUIKitChatController controller;
final Function onClosed;
const CardCreateExample(
{super.key, required this.controller, required this.onClosed});

@override
State<StatefulWidget> createState() => _CardCreateExampleState();
}

class _CardCreateExampleState extends State<CardCreateExample> {
@override
Widget build(BuildContext context) {
final isWideScreen =
TUIKitScreenUtils.getFormFactor(context) == DeviceType.Desktop;
return isWideScreen
? Container(
padding: const EdgeInsets.all(16),
child: TencentCloudChatCardCreate(
onClosed: widget.onClosed,
onSendCard: widget.controller.sendMessage,
isWide: true,
),
)
: TencentCloudChatCardCreate(
onClosed: widget.onClosed,
onSendCard: widget.controller.sendMessage,
isWide: false,
);
}
}


主动评价客服(可选)

当在在线客服的管理端设置了用户可主动评价座席时,用户端就可以主动拉取评价消息并评价。



tencent_cloud_chat_customer_service_plugin 提供了 isCanSendEvaluate 方法用于快速判断是否能主动发送评价,isCanSendEvaluateMessage 方法快速判断是否为发送评价配置消息,同时也提供了 getEvaluateMessage 方法拉取用户评价。使用方法如下:
// 在 flutter uikit 中使用 TIMUIKitChat 组件的 morePanelConfig、additionalDesktopControlBarItems、newMessageWillMount 属性实现
// 使用逻辑可见 flutter uikit 的 demo 中 lib/src/chat.dart
TIMUIKitChat(
lifeCycle: ChatLifeCycle(
newMessageWillMount: (V2TimMessage message) async {
// ChannelPush.displayDefaultNotificationForMessage(message);
if (TencentCloudChatCustomerServicePlugin.isCanSendEvaluateMessage(
message) &&
!TencentCloudChatCustomerServicePlugin.isCanSendEvaluate(
message) &&
canSendEvaluate == true) {
setState(() {
canSendEvaluate = false;
});
} else if (TencentCloudChatCustomerServicePlugin
.isCanSendEvaluateMessage(message) &&
TencentCloudChatCustomerServicePlugin.isCanSendEvaluate(
message) &&
canSendEvaluate == false) {
setState(() {
canSendEvaluate = true;
});
}
return message;
},
),
// 窄屏UI按钮
morePanelConfig: MorePanelConfig(
extraAction: [
if (canSendEvaluate)
MorePanelItem(
onTap: (c) {
// 点击拉取评价
TencentCloudChatCustomerServicePlugin.getEvaluateMessage(
_chatController.sendMessage);
},
icon: Container(
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
child: Icon(
Icons.comment,
color: hexToColor("5c6168"),
size: 32,
),
),
id: 'evaluate',
title: TIM_t("服务评价"),
),
],
),
// 宽屏UI按钮
config: TIMUIKitChatConfig(additionalDesktopControlBarItems: [
if (canSendEvaluate)
DesktopControlBarItem(
item: 'evaluate',
showName: TIM_t("服务评价"),
onClick: (offset) {
// 点击拉取评价
TencentCloudChatCustomerServicePlugin.getEvaluateMessage(
_chatController.sendMessage);
},
icon: Icons.comment),
]));

主动结束人工会话(可选)

当用户端进入 人工会话状态 时,可以发送一条约定好类型的自定义消息,发送后服务端会主动断开此次人工会话服务。
tencent_cloud_chat_customer_service_plugin 提供了 isInSession 方法用于快速判断是否在人工会话中,isInSessionMessage 方法快速判断是否为标识人工会话状态消息,同时也提供了 sendCustomerServiceEndSessionMessage 方法快速发送结束会话消息。使用方法如下:
// 在 flutter uikit 中使用 TIMUIKitChat 组件的 morePanelConfig、additionalDesktopControlBarItems、newMessageWillMount 属性实现
// 使用逻辑可见 flutter uikit 的 demo 中 lib/src/chat.dart
TIMUIKitChat(
lifeCycle: ChatLifeCycle(
newMessageWillMount: (V2TimMessage message) async {
// ChannelPush.displayDefaultNotificationForMessage(message);
if (TencentCloudChatCustomerServicePlugin.isInSessionMessage(
message) &&
!TencentCloudChatCustomerServicePlugin.isInSession(message) &&
canEndSession == true) {
setState(() {
canEndSession = false;
});
} else if (TencentCloudChatCustomerServicePlugin.isInSessionMessage(
message) &&
TencentCloudChatCustomerServicePlugin.isInSession(message) &&
canEndSession == false) {
setState(() {
canEndSession = true;
});
}
return message;
},
),
// 窄屏UI按钮
morePanelConfig: MorePanelConfig(
extraAction: [
if (canEndSession)
MorePanelItem(
onTap: (c) {
TencentCloudChatCustomerServicePlugin
.sendCustomerServiceEndSessionMessage(
_chatController.sendMessage);
},
icon: Container(
height: 64,
width: 64,
margin: const EdgeInsets.only(bottom: 4),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(5))),
child: Icon(
Icons.local_phone_outlined,
color: hexToColor("5c6168"),
size: 32,
),
),
id: 'endSession',
title: TIM_t("结束会话"),
),
],
),
// 宽屏UI按钮
config: TIMUIKitChatConfig(additionalDesktopControlBarItems: [
if (canEndSession)
DesktopControlBarItem(
item: 'evaluate',
showName: TIM_t("结束会话"),
onClick: (offset) {
TencentCloudChatCustomerServicePlugin.getEvaluateMessage(
_chatController.sendMessage);
},
icon: Icons.local_phone_outlined),
]));