diff --git a/README.md b/README.md index b1c28ec..834426f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ - 机器人对话 - 技能组客服 - 一对一客服 -- 支持发送电商商品信息 +- 支持发送电商商品信息(支持点击商品回调) - 支持发送附言消息 - 对接APP用户信息(昵称/头像) - 获取当前客服在线状态 @@ -62,6 +62,252 @@ assets: | | | | | | | | +## 以下步骤为非必须步骤,开发者可根据需要调用 + +### 获取未读消息数目 + +用于访客端-查询访客所有未读消息数目 + +```dart +void _getUnreadCountVisitor() { + // 获取消息未读数目 + BytedeskKefu.getUnreadCountVisitor().then((count) => { + print('unreadcount:' + count), + setState(() { + _unreadMessageCount = count; + }) + }); +} +``` + +### 开启机器人 + +机器人会话仅针对技能组开启,指定会话不支持开启机器人 + +- 登录[管理后台](https://www.weikefu.net/admin) + +- 首先添加分类,其次添加问答 +- + + +- 在技能组开启机器人。 找到 “客服管理”-》技能组-》点击相应技能组“编辑”按钮 +- + + +- 找到“默认机器人”和“离线机器人”,选择“是” +- + + +- 开始测试使用机器人 + +### 对接电商商品信息 + +具体请参考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 @@ -84,11 +330,11 @@ bytedesk_kefu: - 技术支持QQ 3群: 825257535 -- [Flutter SDK](https://github.com/bytedesk/bytedesk-flutter) -- [UniApp SDK](https://github.com/bytedesk/bytedesk-uniapp) -- [iOS SDK](https://github.com/bytedesk/bytedesk-ios) -- [Android SDK](https://github.com/bytedesk/bytedesk-android) -- [Web端接口](https://github.com/bytedesk/bytedesk-web) -- [微信公众号/小程序接口](https://github.com/bytedesk/bytedesk-wechat) -- [服务器端接口](https://github.com/bytedesk/bytedesk-server) -- [机器人](https://github.com/bytedesk/bytedesk-chatbot) \ No newline at end of file +- [Flutter SDK](https://gitee.com/270580156/bytedesk-flutter) +- [UniApp SDK](https://gitee.com/270580156/bytedesk-uniapp) +- [iOS SDK](https://gitee.com/270580156/bytedesk-ios) +- [Android SDK](https://gitee.com/270580156/bytedesk-android) +- [Web 端接口](https://gitee.com/270580156/bytedesk-web) +- [微信公众号/小程序接口](https://gitee.com/270580156/bytedesk-wechat) +- [服务器端接口](https://gitee.com/270580156/bytedesk-server) +- [机器人](https://gitee.com/270580156/bytedesk-chatbot) diff --git a/bytedesk_kefu/example/ios/Podfile.lock b/bytedesk_kefu/example/ios/Podfile.lock index 7877ace..a9b2301 100644 --- a/bytedesk_kefu/example/ios/Podfile.lock +++ b/bytedesk_kefu/example/ios/Podfile.lock @@ -144,6 +144,7 @@ SPEC CHECKSUMS: Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2 image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 diff --git a/bytedesk_kefu/lib/http/bytedesk_user_api.dart b/bytedesk_kefu/lib/http/bytedesk_user_api.dart index 6ebdd80..5797d69 100755 --- a/bytedesk_kefu/lib/http/bytedesk_user_api.dart +++ b/bytedesk_kefu/lib/http/bytedesk_user_api.dart @@ -46,11 +46,9 @@ class BytedeskUserHttpApi extends BytedeskBaseHttpApi { // 验证码登录 Future 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'); - // BytedeskUtils.printLog("http api client: oauthUrl $oauthUrl"); + Map headers = { "Authorization": "Basic Y2xpZW50OnNlY3JldA==" }; @@ -126,7 +124,7 @@ class BytedeskUserHttpApi extends BytedeskBaseHttpApi { "client": client }); - // final initUrl = '$baseUrl/visitors/api/v1/register/mobile'; + final initUrl = Uri.http(BytedeskConstants.host, '/visitors/api/v1/register/mobile'); final initResponse = diff --git a/bytedesk_kefu/lib/ui/widget/chat_input.dart b/bytedesk_kefu/lib/ui/widget/chat_input.dart index 6893923..a1f4810 100644 --- a/bytedesk_kefu/lib/ui/widget/chat_input.dart +++ b/bytedesk_kefu/lib/ui/widget/chat_input.dart @@ -486,40 +486,41 @@ class _ChatInputState extends State with TickerProviderStateMixin { // buildLeftButton(), // input Expanded( - child: Shortcuts( - shortcuts: isAndroid || isIOS - ? { - LogicalKeySet(LogicalKeyboardKey.enter): - const NewLineIntent(), - LogicalKeySet(LogicalKeyboardKey.enter, - LogicalKeyboardKey.alt): - const NewLineIntent(), - } - : { - LogicalKeySet(LogicalKeyboardKey.enter): - const SendMessageIntent(), - LogicalKeySet(LogicalKeyboardKey.enter, - LogicalKeyboardKey.alt): - const NewLineIntent(), - LogicalKeySet(LogicalKeyboardKey.enter, - LogicalKeyboardKey.shift): - const NewLineIntent(), - }, - child: Actions( - actions: { - SendMessageIntent: - CallbackAction( - onInvoke: (SendMessageIntent intent) => - _handleSendPressed(), - ), - NewLineIntent: CallbackAction( - onInvoke: (NewLineIntent intent) => - _handleNewLine(), - ), - }, - child: _buildInputButton(context), - ), - ), + child: _buildInputButton(context), + // child: Shortcuts( + // shortcuts: isAndroid || isIOS + // ? { + // LogicalKeySet(LogicalKeyboardKey.enter): + // const NewLineIntent(), + // LogicalKeySet(LogicalKeyboardKey.enter, + // LogicalKeyboardKey.alt): + // const NewLineIntent(), + // } + // : { + // LogicalKeySet(LogicalKeyboardKey.enter): + // const SendMessageIntent(), + // LogicalKeySet(LogicalKeyboardKey.enter, + // LogicalKeyboardKey.alt): + // const NewLineIntent(), + // LogicalKeySet(LogicalKeyboardKey.enter, + // LogicalKeyboardKey.shift): + // const NewLineIntent(), + // }, + // child: Actions( + // actions: { + // SendMessageIntent: + // CallbackAction( + // onInvoke: (SendMessageIntent intent) => + // _handleSendPressed(), + // ), + // NewLineIntent: CallbackAction( + // onInvoke: (NewLineIntent intent) => + // _handleNewLine(), + // ), + // }, + // child: _buildInputButton(context), + // ), + // ), ), // emoji //buildEmojiButton(), diff --git a/bytedesk_kefu/lib/util/bytedesk_constants.dart b/bytedesk_kefu/lib/util/bytedesk_constants.dart index e9115a2..43b77d6 100755 --- a/bytedesk_kefu/lib/util/bytedesk_constants.dart +++ b/bytedesk_kefu/lib/util/bytedesk_constants.dart @@ -45,7 +45,7 @@ class BytedeskConstants { // static const String httpBaseUrliOS = 'http://' + mqttHost + ':8000'; // static const String httpUploadUrl = 'http://' + 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; diff --git a/bytedesk_kefu/pubspec.yaml b/bytedesk_kefu/pubspec.yaml index 3d0fa71..beac538 100644 --- a/bytedesk_kefu/pubspec.yaml +++ b/bytedesk_kefu/pubspec.yaml @@ -1,6 +1,6 @@ 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. -version: 1.4.3 +version: 1.4.4 homepage: https://www.weikefu.net environment: