feat: Add app-version to Chatwoot Contact Attributes (#2049)
Konstantin Ullrich committed
Feb 24, 2025 at 23:01 UTC
465ff7e78ca493c6775ad51ee66f10f9aef80e61
4 files changed
+50
-26
lib/di.dart
+2
-2
@@ -1256,7 +1256,7 @@ Future<void> setup({
1256
getIt.registerFactoryParam<OrderDetailsPage, Order, void>(
1257
(Order order, _) => OrderDetailsPage(getIt.get<OrderDetailsViewModel>(param1: order)));
1258
1259
- getIt.registerFactory(() => SupportViewModel());
1259
+ getIt.registerFactory(() => SupportViewModel(getIt.get<SettingsStore>()));
1260
1261
getIt.registerFactory(() => SupportPage(getIt.get<SupportViewModel>()));
1262
@@ -1418,4 +1418,4 @@ Future<void> setup({
1418
getIt.registerFactory(() => SeedVerificationPage(getIt.get<WalletSeedViewModel>()));
1419
1420
_isSetupFinished = true;
1421
-}
\ No newline at end of file
1421
+}
lib/src/screens/support_chat/support_chat_page.dart
+4
-7
@@ -3,10 +3,8 @@ import 'package:cake_wallet/generated/i18n.dart';
3
import 'package:cake_wallet/src/screens/base_page.dart';
4
import 'package:cake_wallet/src/screens/support_chat/widgets/chatwoot_widget.dart';
5
import 'package:cake_wallet/view_model/support_view_model.dart';
6
-import 'package:cw_core/utils/print_verbose.dart';
6
import 'package:flutter/material.dart';
7
9
-
8
class SupportChatPage extends BasePage {
9
SupportChatPage(this.supportViewModel, {required this.secureStorage});
10
@@ -23,17 +21,16 @@ class SupportChatPage extends BasePage {
21
Widget body(BuildContext context) => FutureBuilder<String>(
22
future: getCookie(),
23
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
26
- printV(snapshot.data);
24
if (snapshot.hasData)
25
return ChatwootWidget(
26
secureStorage,
30
- supportUrl: supportViewModel.fetchUrl(authToken: snapshot.data!)
27
+ supportUrl: supportViewModel.fetchUrl(authToken: snapshot.data!),
28
+ appVersion: supportViewModel.appVersion,
29
);
30
return Container();
31
},
32
);
33
36
- Future<String> getCookie() async {
37
- return await secureStorage.read(key: COOKIE_KEY) ?? "";
38
- }
34
+ Future<String> getCookie() async =>
35
+ await secureStorage.read(key: COOKIE_KEY) ?? "";
36
}
lib/src/screens/support_chat/widgets/chatwoot_widget.dart
+36
-15
@@ -1,46 +1,50 @@
1
import 'dart:convert';
2
3
import 'package:cake_wallet/core/secure_storage.dart';
4
-import 'package:cw_core/utils/print_verbose.dart';
4
import 'package:flutter/material.dart';
5
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
6
7
const COOKIE_KEY = 'chatwootCookie';
8
9
class ChatwootWidget extends StatefulWidget {
11
- ChatwootWidget(this.secureStorage, {required this.supportUrl});
10
+ const ChatwootWidget(
11
+ this.secureStorage, {
12
+ required this.supportUrl,
13
+ required this.appVersion,
14
+ });
15
16
final SecureStorage secureStorage;
17
final String supportUrl;
18
+ final String appVersion;
19
20
@override
21
ChatwootWidgetState createState() => ChatwootWidgetState();
22
}
23
24
class ChatwootWidgetState extends State<ChatwootWidget> {
21
- final GlobalKey _webViewkey = GlobalKey();
25
+ final GlobalKey _webViewKey = GlobalKey();
26
27
@override
28
Widget build(BuildContext context) => InAppWebView(
25
- key: _webViewkey,
26
- initialSettings: InAppWebViewSettings(
27
- transparentBackground: true,
28
- ),
29
+ key: _webViewKey,
30
+ initialSettings: InAppWebViewSettings(transparentBackground: true),
31
initialUrlRequest: URLRequest(url: WebUri(widget.supportUrl)),
32
onWebViewCreated: (InAppWebViewController controller) {
33
controller.addWebMessageListener(
34
WebMessageListener(
35
jsObjectName: 'ReactNativeWebView',
34
- onPostMessage: (WebMessage? message, WebUri? sourceOrigin, bool isMainFrame,
35
- PlatformJavaScriptReplyProxy replyProxy) {
36
+ onPostMessage: (WebMessage? message, WebUri? sourceOrigin,
37
+ bool isMainFrame, PlatformJavaScriptReplyProxy replyProxy) {
38
final shortenedMessage = message?.data.toString().substring(16);
37
- if (shortenedMessage != null && isJsonString(shortenedMessage)) {
39
+ if (shortenedMessage != null &&
40
+ _isJsonString(shortenedMessage)) {
41
final parsedMessage = jsonDecode(shortenedMessage);
42
final eventType = parsedMessage["event"];
43
if (eventType == 'loaded') {
44
final authToken = parsedMessage["config"]["authToken"];
42
- printV(authToken);
43
- storeCookie(authToken as String);
45
+ _storeCookie(authToken as String);
46
+ _setCustomAttributes(
47
+ controller, {"app_version": widget.appVersion});
48
}
49
}
50
},
@@ -49,7 +53,7 @@ class ChatwootWidgetState extends State<ChatwootWidget> {
53
},
54
);
55
52
- bool isJsonString(String str) {
56
+ bool _isJsonString(String str) {
57
try {
58
jsonDecode(str);
59
} catch (e) {
@@ -58,7 +62,24 @@ class ChatwootWidgetState extends State<ChatwootWidget> {
62
return true;
63
}
64
61
- Future<void> storeCookie(String value) async {
62
- await widget.secureStorage.write(key: COOKIE_KEY, value: value);
65
+ /// Add additional contact attributes to the chatwoot chat.
66
+ /// IMPORTANT: You have to add the attribute key in the chatwoot settings
67
+ /// under: settings/custom-attributes
68
+ Future<void> _setCustomAttributes(
69
+ InAppWebViewController controller,
70
+ Map<String, dynamic> customAttributes,
71
+ ) {
72
+ final attributeObject = {
73
+ "event": "set-custom-attributes",
74
+ "customAttributes": customAttributes,
75
+ };
76
+ return controller.postWebMessage(
77
+ message: WebMessage(
78
+ data: "chatwoot-widget:${jsonEncode(attributeObject)}",
79
+ ),
80
+ );
81
}
82
+
83
+ Future<void> _storeCookie(String value) =>
84
+ widget.secureStorage.write(key: COOKIE_KEY, value: value);
85
}
lib/view_model/support_view_model.dart
+8
-2
@@ -1,16 +1,19 @@
1
+import 'package:cake_wallet/.secrets.g.dart' as secrets;
2
import 'package:cake_wallet/generated/i18n.dart';
3
+import 'package:cake_wallet/store/settings_store.dart';
4
import 'package:cake_wallet/view_model/settings/link_list_item.dart';
5
import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
6
import 'package:cake_wallet/wallet_type_utils.dart';
7
import 'package:mobx/mobx.dart';
6
-import 'package:cake_wallet/.secrets.g.dart' as secrets;
8
9
part 'support_view_model.g.dart';
10
11
class SupportViewModel = SupportViewModelBase with _$SupportViewModel;
12
13
abstract class SupportViewModelBase with Store {
13
- SupportViewModelBase()
14
+ final SettingsStore settingsStore;
15
+
16
+ SupportViewModelBase(this.settingsStore)
17
: items = [
18
LinkListItem(
19
title: 'Email',
@@ -116,5 +119,8 @@ abstract class SupportViewModelBase with Store {
119
return supportUrl;
120
}
121
122
+ String get appVersion =>
123
+ "${isMoneroOnly ? "Monero.com" : "Cake Wallet"} - ${settingsStore.appVersion}";
124
+
125
List<SettingsListItem> items;
126
}