前提条件
了解在线客服相关术语及相关配置,并已完成以下步骤:添加客服、配置技能组、创建会话服务流,详情请参见 快速入门。
集成 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 一起使用)
插件引入
// 集成最新版本flutter pub add tencent_cloud_chat_customer_service_plugin
插件集成
步骤1:完成客服插件设置
步骤2:设置客服用户 ID 配置并获取客服虚拟号信息
// 客服号UserIDstatic const List<String> customerServiceUserList = ['客服号UserID',];// 通过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.dartif (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.dartTIMUIKitChat(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.dartTIMUIKitChat(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专用@overridevoid initState() {super.initState();if (IMDemoConfig.customerServiceUserList.contains(widget.selectedConversation.userID)) {// 当进入的聊天页面时在线客服用户时需要发送启动消息// 传入参数为发送消息的函数TencentCloudChatCustomerServicePlugin.sendCustomerServiceStartMessage(_chatController.sendMessage);}}// flutter uikit 宽屏UI专用@overridevoid 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.dartTIMUIKitChat(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.dartTIMUIKitChat(// 窄屏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.dartimport '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});@overrideState<StatefulWidget> createState() => _CardCreateExampleState();}class _CardCreateExampleState extends State<CardCreateExample> {@overrideWidget 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.dartTIMUIKitChat(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.dartTIMUIKitChat(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),]));