master
章文轩 2 years ago
parent 35c1130191
commit a40162d6da

@ -9,7 +9,7 @@
- 机器人对话 - 机器人对话
- 技能组客服 - 技能组客服
- 一对一客服 - 一对一客服
- 支持发送电商商品信息 - 支持发送电商商品信息(支持点击商品回调)
- 支持发送附言消息 - 支持发送附言消息
- 对接APP用户信息(昵称/头像) - 对接APP用户信息(昵称/头像)
- 获取当前客服在线状态 - 获取当前客服在线状态
@ -62,6 +62,252 @@ assets:
| <img src="./chat.png" width="250"> | <img src="./shop.png" width="250"> |<img src="./postscript.png" width="250"> | | <img src="./chat.png" width="250"> | <img src="./shop.png" width="250"> |<img src="./postscript.png" width="250"> |
| <img src="./status.jpeg" width="250"> |<img src="./userinfo.jpeg" width="250"> |<img src="./notice.jpeg" width="250"> | | <img src="./status.jpeg" width="250"> |<img src="./userinfo.jpeg" width="250"> |<img src="./notice.jpeg" width="250"> |
## 以下步骤为非必须步骤,开发者可根据需要调用
### 获取未读消息数目
用于访客端-查询访客所有未读消息数目
```dart
void _getUnreadCountVisitor() {
// 获取消息未读数目
BytedeskKefu.getUnreadCountVisitor().then((count) => {
print('unreadcount:' + count),
setState(() {
_unreadMessageCount = count;
})
});
}
```
### 开启机器人
机器人会话仅针对技能组开启,指定会话不支持开启机器人
- 登录[管理后台](https://www.weikefu.net/admin)
- 首先添加分类,其次添加问答
-
<img src="https://bytedesk.oss-cn-shenzhen.aliyuncs.com/images/20210416111451.png" width="250">
- 在技能组开启机器人。 找到 “客服管理”-》技能组-》点击相应技能组“编辑”按钮
-
<img src="https://bytedesk.oss-cn-shenzhen.aliyuncs.com/images/20210420110954.png" width="250">
- 找到“默认机器人”和“离线机器人”,选择“是”
-
<img src="https://bytedesk.oss-cn-shenzhen.aliyuncs.com/images/20210420111025.png" width="250">
- 开始测试使用机器人
### 对接电商商品信息
具体请参考bytedesk_demo/lib/page/chat_type_page.dart文件
- 演示代码:
```dart
// 商品信息type/title/content/price/url/imageUrl/id/categoryCode
// 注意长度不能大于500字符
var custom = json.encode({
"type": BytedeskConstants.MESSAGE_TYPE_COMMODITY, // 不能修改
"title": "商品标题", // 可自定义, 类型为字符串
"content": "商品详情", // 可自定义, 类型为字符串
"price": "9.99", // 可自定义, 类型为字符串
"url":
"https://item.m.jd.com/product/12172344.html", // 必须为url网址, 类型为字符串
"imageUrl":
"https://bytedesk.oss-cn-shenzhen.aliyuncs.com/images/123.webp", //必须为图片网址, 类型为字符串
"id": 123, // 可自定义
"categoryCode": "100010003", // 可自定义, 类型为字符串
"client": "flutter" // 可自定义, 类型为字符串
});
BytedeskKefu.startWorkGroupChatShop(
context, _workGroupWid, "技能组客服-电商", custom);
```
### 点击商品回调
- 可用于点击商品后,跳转自定义页面
```dart
// 商品信息type/title/content/price/url/imageUrl/id/categoryCode
// 注意长度不能大于500字符
var custom = json.encode({
"type": BytedeskConstants.MESSAGE_TYPE_COMMODITY, // 不能修改
"title": "商品标题", // 可自定义, 类型为字符串
"content": "商品详情", // 可自定义, 类型为字符串
"price": "9.99", // 可自定义, 类型为字符串
"url":
"https://item.m.jd.com/product/12172344.html", // 必须为url网址, 类型为字符串
"imageUrl":
"https://bytedesk.oss-cn-shenzhen.aliyuncs.com/images/123.webp", //必须为图片网址, 类型为字符串
"id": 123, // 可自定义
"categoryCode": "100010003", // 可自定义, 类型为字符串
"client": "flutter", // 可自定义, 类型为字符串
// 可自定义添加key:value, 客服端不可见,可用于回调原样返回
"other1": "", // 可另外添加自定义字段,客服端不可见,可用于回调原样返回
"other2": "", // 可另外添加自定义字段,客服端不可见,可用于回调原样返回
"other3": "", // 可另外添加自定义字段,客服端不可见,可用于回调原样返回
});
BytedeskKefu.startWorkGroupChatShopCallback(
context, _workGroupWid, "技能组客服-电商-回调", custom, (value) {
print('value为custom参数原样返回 $value');
// 主要用途:用户在聊天页面点击商品消息,回调此接口,开发者可在此打开进入商品详情页
});
```
### 自定义昵称、头像和备注
具体请参考bytedesk_demo//lib/page/user_info_page.dart文件
- 查询当前用户信息:昵称、头像、备注
```dart
void _getProfile() {
// 查询当前用户信息:昵称、头像
BytedeskKefu.getProfile().then((user) => {
setState(() {
_uid = user.uid!;
_username = user.username!;
_nickname = user.nickname!;
_avatar = user.avatar!;
_description = user.description!;
})
});
}
```
- 可自定义用户昵称-客服端可见
```dart
void _setNickname() {
// 可自定义用户昵称-客服端可见
String mynickname = '自定义APP昵称flutter';
BytedeskKefu.updateNickname(mynickname).then((user) => {
setState(() {
_nickname = mynickname;
}),
Fluttertoast.showToast(msg: "设置昵称成功")
});
}
```
- 可自定义用户备注信息-客服端可见
```dart
void _setDescription() {
// 可自定义用户备注-客服端可见
String description = '自定义用户备注';
BytedeskKefu.updateDescription(description).then((user) => {
setState(() {
_description = description;
}),
Fluttertoast.showToast(msg: "设置备注成功")
});
}
```
- 可自定义用户头像url-客服端可见
```dart
void _setAvatar() {
// 可自定义用户头像url-客服端可见,注意:是头像网址,非本地图片路径
String myavatarurl = 'https://bytedesk.oss-cn-shenzhen.aliyuncs.com/avatars/girl.png'; // 头像网址url
BytedeskKefu.updateAvatar(myavatarurl).then((user) => {
setState(() {
_avatar = myavatarurl;
}),
Fluttertoast.showToast(msg: "设置头像成功")
});
}
```
- 将设置昵称、头像、描述接口合并为一个接口
```dart
// 一次调用接口,同时设置:昵称、头像、备注
void _updateProfile() {
//
String mynickname = '自定义APP昵称flutter';
String myavatarurl =
'https://bytedesk.oss-cn-shenzhen.aliyuncs.com/avatars/girl.png'; // 头像网址url
String mydescription = '自定义用户备注';
BytedeskKefu.updateProfile(mynickname, myavatarurl, mydescription)
.then((user) => {
setState(() {
_nickname = mynickname;
_avatar = myavatarurl;
_description = mydescription;
}),
Fluttertoast.showToast(msg: "设置成功")
});
}
```
### 获取客服当前在线状态
具体请参考bytedesk_demo/lib/page/online_status_page.dart文件
- 获取技能组在线状态:当技能组中至少有一个客服在线时,显示在线, 其中workGroupWid为要查询技能组唯一wid
```dart
void _getWorkGroupStatus() {
// 获取技能组在线状态:当技能组中至少有一个客服在线时,显示在线
BytedeskKefu.getWorkGroupStatus(_workGroupWid).then((status) => {
print(status),
setState(() {
_workGroupStatus = status;
})
});
}
```
- 获取指定客服在线状态其中agentUid为要查询客服唯一uid
```dart
void _getAgentStatus() {
// 获取指定客服在线状态
BytedeskKefu.getAgentStatus(_agentUid).then((status) => {
print(status),
setState(() {
_agentStatus = status;
})
});
}
```
### 多用户切换
具体请参考bytedesk_demo/lib/page/switch_user_page.dart文件
- 执行登录之前请先判断是否有用户登录
```dart
if (BytedeskKefu.isLogin()) {
// Fluttertoast.showToast(msg: '请先退出登录');
return;
}
```
- 如果已经存在用户登录则先执行退出登录logout
```dart
void _userLogout() {
Fluttertoast.showToast(msg: '退出中');
BytedeskKefu.logout();
}
```
- 调用登录接口登录
```dart
void _initWithUsernameAndNicknameAndAvatar(String username, String nickname,
String avatar, String appKey, String subDomain) {
BytedeskKefu.initWithUsernameAndNicknameAndAvatar(username, nickname, avatar, appKey, subDomain);
}
```
### 自定义界面 ### 自定义界面
- 项目中创建文件夹: vendors - 项目中创建文件夹: vendors
@ -84,11 +330,11 @@ bytedesk_kefu:
<!-- - [下载 ApkDemo](https://bytedesk.oss-cn-shenzhen.aliyuncs.com/apk/bytedesk-android-sdk-demo.apk) --> <!-- - [下载 ApkDemo](https://bytedesk.oss-cn-shenzhen.aliyuncs.com/apk/bytedesk-android-sdk-demo.apk) -->
- 技术支持QQ 3群: 825257535 - 技术支持QQ 3群: 825257535
- [Flutter SDK](https://github.com/bytedesk/bytedesk-flutter) - [Flutter SDK](https://gitee.com/270580156/bytedesk-flutter)
- [UniApp SDK](https://github.com/bytedesk/bytedesk-uniapp) - [UniApp SDK](https://gitee.com/270580156/bytedesk-uniapp)
- [iOS SDK](https://github.com/bytedesk/bytedesk-ios) - [iOS SDK](https://gitee.com/270580156/bytedesk-ios)
- [Android SDK](https://github.com/bytedesk/bytedesk-android) - [Android SDK](https://gitee.com/270580156/bytedesk-android)
- [Web端接口](https://github.com/bytedesk/bytedesk-web) - [Web 端接口](https://gitee.com/270580156/bytedesk-web)
- [微信公众号/小程序接口](https://github.com/bytedesk/bytedesk-wechat) - [微信公众号/小程序接口](https://gitee.com/270580156/bytedesk-wechat)
- [服务器端接口](https://github.com/bytedesk/bytedesk-server) - [服务器端接口](https://gitee.com/270580156/bytedesk-server)
- [机器人](https://github.com/bytedesk/bytedesk-chatbot) - [机器人](https://gitee.com/270580156/bytedesk-chatbot)

@ -144,6 +144,7 @@ SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2 image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62

@ -46,11 +46,9 @@ class BytedeskUserHttpApi extends BytedeskBaseHttpApi {
// //
Future<OAuth> smsOAuth(String? mobile, String? code) async { Future<OAuth> smsOAuth(String? mobile, String? code) async {
//
// final oauthUrl = '$baseUrl/mobile/token';
// final oauthUrl = Uri.http(BytedeskConstants.host, '/mobile/token');
final oauthUrl = Uri.http(BytedeskConstants.host, '/mobile/token'); final oauthUrl = Uri.http(BytedeskConstants.host, '/mobile/token');
// BytedeskUtils.printLog("http api client: oauthUrl $oauthUrl");
Map<String, String> headers = { Map<String, String> headers = {
"Authorization": "Basic Y2xpZW50OnNlY3JldA==" "Authorization": "Basic Y2xpZW50OnNlY3JldA=="
}; };
@ -126,7 +124,7 @@ class BytedeskUserHttpApi extends BytedeskBaseHttpApi {
"client": client "client": client
}); });
// final initUrl = '$baseUrl/visitors/api/v1/register/mobile';
final initUrl = final initUrl =
Uri.http(BytedeskConstants.host, '/visitors/api/v1/register/mobile'); Uri.http(BytedeskConstants.host, '/visitors/api/v1/register/mobile');
final initResponse = final initResponse =

@ -486,40 +486,41 @@ class _ChatInputState extends State<ChatInput> with TickerProviderStateMixin {
// buildLeftButton(), // buildLeftButton(),
// input // input
Expanded( Expanded(
child: Shortcuts( child: _buildInputButton(context),
shortcuts: isAndroid || isIOS // child: Shortcuts(
? { // shortcuts: isAndroid || isIOS
LogicalKeySet(LogicalKeyboardKey.enter): // ? {
const NewLineIntent(), // LogicalKeySet(LogicalKeyboardKey.enter):
LogicalKeySet(LogicalKeyboardKey.enter, // const NewLineIntent(),
LogicalKeyboardKey.alt): // LogicalKeySet(LogicalKeyboardKey.enter,
const NewLineIntent(), // LogicalKeyboardKey.alt):
} // const NewLineIntent(),
: { // }
LogicalKeySet(LogicalKeyboardKey.enter): // : {
const SendMessageIntent(), // LogicalKeySet(LogicalKeyboardKey.enter):
LogicalKeySet(LogicalKeyboardKey.enter, // const SendMessageIntent(),
LogicalKeyboardKey.alt): // LogicalKeySet(LogicalKeyboardKey.enter,
const NewLineIntent(), // LogicalKeyboardKey.alt):
LogicalKeySet(LogicalKeyboardKey.enter, // const NewLineIntent(),
LogicalKeyboardKey.shift): // LogicalKeySet(LogicalKeyboardKey.enter,
const NewLineIntent(), // LogicalKeyboardKey.shift):
}, // const NewLineIntent(),
child: Actions( // },
actions: { // child: Actions(
SendMessageIntent: // actions: {
CallbackAction<SendMessageIntent>( // SendMessageIntent:
onInvoke: (SendMessageIntent intent) => // CallbackAction<SendMessageIntent>(
_handleSendPressed(), // onInvoke: (SendMessageIntent intent) =>
), // _handleSendPressed(),
NewLineIntent: CallbackAction<NewLineIntent>( // ),
onInvoke: (NewLineIntent intent) => // NewLineIntent: CallbackAction<NewLineIntent>(
_handleNewLine(), // onInvoke: (NewLineIntent intent) =>
), // _handleNewLine(),
}, // ),
child: _buildInputButton(context), // },
), // child: _buildInputButton(context),
), // ),
// ),
), ),
// emoji // emoji
//buildEmojiButton(), //buildEmojiButton(),

@ -45,7 +45,7 @@ class BytedeskConstants {
// static const String httpBaseUrliOS = 'http://' + mqttHost + ':8000'; // static const String httpBaseUrliOS = 'http://' + mqttHost + ':8000';
// static const String httpUploadUrl = 'http://' + mqttHost + ':8000'; // static const String httpUploadUrl = 'http://' + mqttHost + ':8000';
// static const String host = mqttHost + ':8000'; // static const String host = mqttHost + ':8000';
// static const String mqttHost = '192.168.0.104'; // static const String mqttHost = '192.168.0.102';
// 线 // 线
static const bool isDebug = false; // false; static const bool isDebug = false; // false;

@ -1,6 +1,6 @@
name: bytedesk_kefu name: bytedesk_kefu
description: the best app chat sdk in china, you can chat with the agent freely at anytime. the agent can chat with the visitor by web/pc/mac/ios/android client. description: the best app chat sdk in china, you can chat with the agent freely at anytime. the agent can chat with the visitor by web/pc/mac/ios/android client.
version: 1.4.3 version: 1.4.4
homepage: https://www.weikefu.net homepage: https://www.weikefu.net
environment: environment:

Loading…
Cancel
Save