Flutter

最近更新时间:2025-08-29 09:59:01

我的收藏

介绍

专为客服场景定制的 Customer UIKit,提供针对性强的用户侧客服会话界面,满足客服场景需求。UI、交互及功能体验,均面向智能客服场景设计。
此外, Customer UIKit 让集成客服模块省去集成 IM,只需要简短的若干行代码,即可完成开发。

功能展示








您可扫码安装 Demo app 体验使用效果。


前提条件

了解在线客服相关术语及相关配置,并已完成以下步骤:创建腾讯云 IM 应用、开通智能客服、登录客服管理端、获取客服号 ID,详情请参见 快速入门

环境与版本

Flutter 版本: Flutter 3.24 - Flutter 3.27。
支持模拟器调试及真机运行。
说明:
1. 如果您的项目 Flutter 版本较低, 建议升级至 Flutter 3.24 使用。如果确实不方便升级, 可使用 旧版本 Flutter IM UIKit + 客服插件方案
2. 如果您使用 Flutter 3.29,请先降级至 Flutter 3.24 使用。使用 flutter downgrade 或 git 方式 checkout 管理
3. 对于 Flutter 项目,我们不建议使用 Webview 集成智能客服网站渠道,因 Flutter Webview 针对拉起媒体、拍摄场景,存在部分兼容性问题。因此,请尽量优先选用本 UIKit 方案。

快速集成

Demo 示例

建议您下载并参考下列步骤的 Demo 及其源码,配合阅读,以便更好的接入。

步骤1: 集成包

本 UIKit pub package 包名为 tencentcloud_ai_desk_customer。
flutter pub add tencentcloud_ai_desk_customer

步骤2: 权限配置

由于 Customer UIKit 运行,需要拍摄/相册/录音/网络等权限,需要您在 Native 层的文件中手动声明,才可正常使用相关能力。
Android
iOS
打开 android/app/src/main/AndroidManifest.xml ,在 <manifest></manifest>中,添加如下权限。
<uses-permission
android:name="android.permission.INTERNET"/>
<uses-permission
android:name="android.permission.RECORD_AUDIO"/>
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission
android:name="android.permission.VIBRATE"/>
<uses-permission
android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission
android:name="android.permission.CAMERA"/>
<uses-permission
android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission
android:name="android.permission.READ_MEDIA_VIDEO"/>
打开应用层的 build.gradle 文件,增加以下代码,以解决升级 Flutter 3.24 后,某些第三方库编译版本小于 31 导致的编译报错。放置位置可参见 Demo 示例代码
subprojects {
afterEvaluate { project ->
if (project.plugins.hasPlugin("com.android.application") ||
project.plugins.hasPlugin("com.android.library")) {
project.android {
compileSdkVersion 34
buildToolsVersion "34.0.0"
}
}
}
}
打开 ios/Podfile ,在文件末尾新增如下权限代码。并根据需要, 在 info.plist 文件中对应增加拍照、麦克风、相册等权限声明。
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
config.build_settings['ENABLE_BITCODE'] = 'NO'
config.build_settings["ONLY_ACTIVE_ARCH"] = "NO"
end
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)'
'PERMISSION_MICROPHONE=1'
'PERMISSION_CAMERA=1'
'PERMISSION_PHOTOS=1'
]
end
end
end
同时, 还需要在 ios/Runner/Info.plist 文件中(或直接使用 Xcode 打开工程后编辑 Info.plist), 声明相关上述媒体权限的申请提示, 您可按需修改如下描述.
<key>NSCameraUsageDescription</key>
<string>Tencent Customer UIKit needs access to your camera to take photos and videos.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Tencent Customer UIKit needs access to your location to provide accurate customer service.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Tencent Customer UIKit needs access to your microphone to record audio.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Tencent Customer UIKit needs permission to add photos to your photo library.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Tencent Customer UIKit needs access to your photo library to save photos and videos.</string>
<key>NSUserTrackingUsageDescription</key>
<string>Tencent Customer UIKit uses tracking to improve your customer service experience.</string>

步骤3: 登录与初始化

调用 init 方法完成 UIKit 初始化、登录及全局配置。
需要使用 IM 的初始化及登录参数, 具体可参见 即时通信 IM 登录鉴权
import 'package:tencentcloud_ai_desk_customer/tencentcloud_ai_desk_customer.dart';

TencentCloudAIDeskCustomer.init(
sdkAppID: SDKAppID// 腾讯云 IM 控制台创建应用的 SDKAppID
userID: userID, // 详情可参见腾讯云 IM 登录鉴权
userSig: userSig, // 详情可参见腾讯云 IM 登录鉴权
config: TencentCloudCustomerConfig()// 可选全局默认配置, 具体参数及使用方式可查看该类注释
builders: TencentCloudCustomerMessageBuilders(), // 可选全局默认自定义组件库, 具体参数及使用方式可查看该类注释
);
SDKAppID 信息,可在 即时通信 IM 控制台 单击应用管理 > 创建新应用,并选择客服服务 Desk > 智能客服开通智能客服 后获取。


userID 信息,可本地生成一个随机的字符串,例如 test-1234。
userSig 信息,可单击 即时通信 IM 控制台 > UserSig生成校验,填写创建的 userID,即可生成 userSig。


步骤4: 打开客服聊天页

调用 navigate 方法,跳转至客服聊天页面。
import 'package:tencentcloud_ai_desk_customer/tencentcloud_ai_desk_customer.dart';

TencentCloudAIDeskCustomer.navigate(
context: context, // BuildContext
customerServiceID: "@customer_service_account", // 可选, 如不配置多客服号或修改默认的客服号 UserID, 可无需传入. 客服号 UserID 可从智能客服管理端查看: https://desk.qcloud.com/
config: TencentCloudCustomerConfig(), // 可选针对该客服会话的特殊配置, 具体参数及使用方式可查看该类注释. 此处仅需手动指定相比全局配置的增项和修改项即可, 其余配置来自全局默认配置.
builders: TencentCloudCustomerMessageBuilders(), // 可选针对该客服会话的特殊自定义组件库, 具体参数及使用方式可查看该类注释. 此处仅需手动指定相比全局配置的增项和修改项即可, 其余自定义组件来自全局默认自定义组件库.
controller: TencentCloudDeskCustomerController(), // 可选的会话组件控制器, 可实例化一个 TencentCloudDeskCustomerController 类, 并传入. 可用于发送消息、更新消息列表、更新修改消息等能力.
);
至此,智能客服功能在 Flutter 端集成完成。

更多功能

多语言

如果您的 Desk 套餐包支持多语言,UIKit 可自动跟随系统语言或使用您指定的语言。
TencentCloudCustomerConfig 类中有一个可选配置项 language 用于指定需要的语言。既可 init 时全局配置,也可 navigate 时指定。
如果不指定,默认采用系统语言。若系统语言不支持,兜底使用简体中文(国内站)、英文(国际站)。具体语言支持如下。
版本说明:
本功能仅在 tencentcloud_ai_desk_customer: ^1.2.0 及后续版本提供。版本语言支持情况如下:
1.2.0:英语、简体中文、繁体中文、日语、印尼语。
import 'package:tencentcloud_ai_desk_customer/tencentcloud_ai_desk_customer.dart';
import 'package:tencent_desk_i18n_tool/language_json/strings.g.dart';

TencentCloudAIDeskCustomer.init(
...... // 其他配置项
config: TencentCloudCustomerConfig(
language: TDeskAppLocale.en, // 如果不手动指定,默认使用系统语言
),
);
// 或导航至某个客服会话时配置
TencentCloudAIDeskCustomer.navigate(
...... // 其他配置项
config: TencentCloudCustomerConfig(
language: TDeskAppLocale.en, // 如果不手动指定,默认全局配置或使用系统语言
),
);
语言枚举值如下:
import 'package:tencent_desk_i18n_tool/language_json/strings.g.dart';

enum TDeskAppLocale {
en, // 英语
id, // 印尼语
ja, // 日语
zhHans, // 简体中文
zhHant, // 繁体中文
}

注销或切换用户

如果您需要注销当前登录用户,或切换登录用户,请先 dispose 当前实例,具体代码示例如下:
版本说明:
本功能仅在 tencentcloud_ai_desk_customer: ^1.1.0 及后续版本提供。
import 'package:tencentcloud_ai_desk_customer/tencentcloud_ai_desk_customer.dart';

TencentCloudAIDeskCustomer.dispose();

用户端带昵称和头像登录

版本说明:
本功能仅在 tencentcloud_ai_desk_customer: ^1.5.0 及后续版本提供。
如果人工客服在工作台接待用户咨询时,希望能看到用户的昵称、头像等信息以提升沟通效率,效果如下图所示:

请在初始化时,补充传入昵称和头像即可。
import 'package:tencentcloud_ai_desk_customer/tencentcloud_ai_desk_customer.dart';

TencentCloudAIDeskCustomer.init(
nickName: '',
avatar: '',
// ... 其他配置, 可见 步骤3: 登录与初始化
);

自定义重写组件 Widget

版本说明:
本功能仅在 tencentcloud_ai_desk_customer: ^1.6.0 及后续版本提供。
如果您需要微调修改部分组件,可使用组件配套的 builder 来重写组件 Widget 进行定义。
可在 initnavigate 方法调用时,实例化 TencentCloudCustomerMessageBuilders 并传入 builders 参数中。
init 中调用:全局默认生效,对所有客服会话。
navigate 中调用:针对该客服会话生效,此处仅需手动指定相比 init 的全局配置的增项和修改项即可, 其余自定义组件来自全局配置的默认。
每个 Builder 提供的参数,普遍包含用于渲染重写该组件所需的数据及业务 API 方法,您只需关注 UI 实现即可。
自定义 Builder 的使用场景大致如下,但具体每个 Builder 的用法,请参见代码注释。


使用聊天控制器 (手动发送消息等能力)

版本说明:
本功能仅在 tencentcloud_ai_desk_customer: ^1.6.0 及后续版本提供。
如果您有其他额外的控制操作需求,可以使用组件配套的 TencentCloudDeskCustomerController 完成。
该 TencentCloudDeskCustomerController 提供了发送消息、重置消息列表、更新消息、删除历史消息等等能力,具体可参见类注释。
如需使用,可在您项目代码中,实例化一个 TencentCloudDeskCustomerController 类,并将该实例,传入 navigate 方法的 controller 参数中。
此后,即可使用该实例提供的 API 方法,来控制 UIKit。
final controller = TencentCloudDeskCustomerController();
TencentCloudAIDeskCustomer.navigate(
context: context,
customerServiceID: "@customer_service_account",
controller: controller, // 在这里传入
);
controller.clearHistory(); // 例如可以使用这个实例的 API 来删除历史消息. 请注意, 传入并调用 navigate 方法后, 才能使用.

自定义样式及能力

如快速集成部分的基础配置(TencentCloudCustomerConfig)、自定义重写组件 Widget及使用聊天控制器 (手动发送消息等能力), 无法满足您业务的自定义需求,您可参考本部分,本地引入源码,进行修改,后应用于项目中。

Fork 并 Clone 代码

1. 访问本工具包的 GitHub 仓库:tencentcloud_ai_desk_customer_flutter
2. 单击仓库页面右上角的 “Fork” 按钮。这将在您的 GitHub 账户下创建一个仓库副本。
3. 将 fork 的仓库克隆到本地机器上的一个目录中。您可以使用以下 Git 命令执行此操作:
git clone https://github.com/<your-username>/tencentcloud_ai_desk_customer_flutter.git
<your-username>替换为您的 GitHub 用户名。
4. 在您项目的pubspec.yaml文件中,将 fork 的仓库的本地路径添加到 dependencies 部分,并替代原线上版本依赖:
dependencies:
tencentcloud_ai_desk_customer_flutter:
path: /path/to/your/local/repository
/path/to/your/local/repository替换为本地机器上克隆的仓库的实际路径。
您可在当前 IDE 环境、也可新开一个 IDE 窗口,打开本地引入的 UIKit 源码目录文件夹,并进行修改。
以下是一些场景说明,您可不局限于下方说明,针对整个项目,所有代码都能进行修改。

修改图片资源

图片资源,可直接找到现有图片,替换为同名文件即可。
针对客服场景(如聊天背景、评分星星)的图片资源位于 lib/customer_service/assets 目录。
聊天通用(如菜单中icon)的图片资源位于images 目录。

修改聊天基础配置及操控

客服 Customer UIKit 的聊天模块,命名为 TencentCloudCustomerMessage。其大体基于 IM UIKit 的 Chat 组件,因此 IM 的众多基础配置,均可直接复用并修改。
因此,TencentCloudCustomerMessage 即为基于 IM UIKit Chat 组件 TIMUIKitChat 的客服场景适配版,用法基本一致。
您可在 lib/customer_service/widgets/tencent_cloud_customer_message_container.dart 文件中找到 TencentCloudCustomerMessage 的实现。
修改此文件,进行聊天能力基础配置 config: TIMUIKitChatConfig、toolTipsConfig: ToolTipsConfig、morePanelConfig: MorePanelConfig,聊天能力生命周期管理 lifeCycle: ChatLifeCycle,各类 UI 组件 Builder 如 inputTopBuilder tongueItemBuilder customAppBar messageItemBuilder。除此配置外,还可使用 _chatController 变量存储的 ChatController,控制该 Chat 组件
以上配置、Builder 及 Controller 的用法,均和 IM UIKit TIMUIKitChat 组件中同名参数的使用方式一致,您可参考对应注释,了解其用法;或参考下方内容,了解其与智能客服场景结合的案例。

客服消息自定义样式及渲染

智能客服的特殊消息,例如分支消息评价消息、卡片消息等,都是通过自定义消息实现,因此您需要在接收消息时判断消息类型并渲染。 isCustomerServiceMessage 方法用于判断自定义消息是否属于智能客服的自定义消息。使用方法如下:
// 使用 TencentCloudCustomerMessage 组件的 customMessageItemBuilder 属性实现
messageItemBuilder: MessageItemBuilder(
customMessageItemBuilder: (message, isShowJump, clearJump) {
if (TencentCloudChatCustomerServicePlugin.isCustomerServiceMessage(message)) {
return // 需要渲染的自定义消息
}
return null;
},
),
在线客服消息中有一些特殊的消息为标志消息,例如会话结束、会话开始、客服配置等,这一类消息不需要渲染在消息列表中。isCustomerServiceMessageInvisible 方法用于判断在线客服消息是否需要在消息列表中渲染。使用方法如下:
// 使用 TencentCloudCustomerMessage 组件的 lifeCycle 属性实现
TencentCloudCustomerMessage(
lifeCycle: ChatLifeCycle(messageShouldMount: (V2TimMessage message) {
if (TencentCloudChatCustomerServicePlugin
.isCustomerServiceMessageInvisible(message) &&
TencentCloudChatCustomerServicePlugin.isCustomerServiceMessage(
message)) {
return false;
}
return true;
}),
);
在线客服消息中,评价消息因为不需要会话气泡且需要独占一行,因此, 此消息需要单独处理。tencent_cloud_chat_customer_service_plugin 提供了isRowCustomerServiceMessage 方法用于判断消息是否需要独占一行。使用方法如下:
// 使用 TencentCloudCustomerMessage 组件的 messageRowBuilder 属性实现
TencentCloudCustomerMessage(messageItemBuilder: MessageItemBuilder(
messageRowBuilder: (message, messageWidget, onScrollToIndex,
isNeedShowJumpStatus, clearJumpStatus, onScrollToIndexBegin) {
if (TencentCloudChatCustomerServicePlugin.isRowCustomerServiceMessage(
message)) {
return messageWidget;
}
},
));

主动评价客服

isCanSendEvaluate 方法用于快速判断是否能主动发送评价,isCanSendEvaluateMessage 方法快速判断是否为发送评价配置消息,同时也提供了 getEvaluateMessage 方法拉取用户评价。使用方法如下:
// TencentCloudCustomerMessage 组件的 morePanelConfig、additionalDesktopControlBarItems、newMessageWillMount 属性实现
TencentCloudCustomerMessage(
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),
])
);

主动结束人工会话

当用户端进入 人工会话状态 时,可以发送一条约定好类型的自定义消息,发送后服务端会主动断开此次人工会话服务。
isInSession 方法用于快速判断是否在人工会话中,isInSessionMessage 方法快速判断是否为标识人工会话状态消息,同时也提供了 sendCustomerServiceEndSessionMessage 方法快速发送结束会话消息。使用方法如下:
// TencentCloudCustomerMessage 组件的 morePanelConfig、additionalDesktopControlBarItems、newMessageWillMount 属性实现
TencentCloudCustomerMessage(
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),
]));
完成修改源码后,可将变更提交至您 fork 的仓库。

同步更新本 UIKit 后续版本

Customer UIKit 的 GitHub 仓库中,每个版本,均通过 Tag 标记。您可同步最新代码到指定版本或位于 main 分支的最新版本。

如需将您 fork 的仓库同步官方仓库,可使用 pull upstream 操作。
以下是一个pull upstream的 Git 操作示例:
1. 首先,在您的本地仓库中添加上游(upstream)远程仓库:
git remote add upstream https://github.com/RoleWong/tencentcloud_ai_desk_customer_flutter.git
2. 拉取上游仓库的最新更改:
git fetch upstream
3. 将您的本地仓库切换到要更新的分支(例如mainmaster):
git checkout main
4. 将上游仓库的更改合并到您的本地仓库:
git merge upstream/main
5. 如果有冲突,请在编辑器中解决它们,确保各个 JSON 词条库是完整的。
6. 提交解决冲突后的更改:
git add .
git commit -m "Merge upstream changes and resolve conflicts"
7. 将更改推送到您的远程仓库:
git push origin main
现在,您的 fork 版本已经包含了线上版本的对应代码。