Line data Source code
1 : import 'package:chatwoot_client_sdk/chatwoot_callbacks.dart'; 2 : import 'package:chatwoot_client_sdk/chatwoot_client_sdk.dart'; 3 : import 'package:chatwoot_client_sdk/data/chatwoot_repository.dart'; 4 : import 'package:chatwoot_client_sdk/data/local/entity/chatwoot_contact.dart'; 5 : import 'package:chatwoot_client_sdk/data/local/entity/chatwoot_conversation.dart'; 6 : import 'package:chatwoot_client_sdk/data/local/entity/chatwoot_user.dart'; 7 : import 'package:chatwoot_client_sdk/data/remote/requests/chatwoot_action_data.dart'; 8 : import 'package:chatwoot_client_sdk/data/remote/requests/chatwoot_new_message_request.dart'; 9 : import 'package:chatwoot_client_sdk/di/modules.dart'; 10 : import 'package:chatwoot_client_sdk/chatwoot_parameters.dart'; 11 : import 'package:chatwoot_client_sdk/repository_parameters.dart'; 12 : import 'package:riverpod/riverpod.dart'; 13 : 14 : import 'data/local/local_storage.dart'; 15 : 16 : /// Represents a chatwoot client instance. All chatwoot operations (Example: sendMessages) are 17 : /// passed through chatwoot client. For more info visit 18 : /// https://www.chatwoot.com/docs/product/channels/api/client-apis 19 : /// 20 : /// {@category FlutterClientSdk} 21 : class ChatwootClient { 22 : late final ChatwootRepository _repository; 23 : final ChatwootParameters _parameters; 24 : final ChatwootCallbacks? callbacks; 25 : final ChatwootUser? user; 26 : 27 3 : String get baseUrl => _parameters.baseUrl; 28 : 29 3 : String get inboxIdentifier => _parameters.inboxIdentifier; 30 : 31 1 : ChatwootClient._(this._parameters, {this.user, this.callbacks}) { 32 2 : providerContainerMap.putIfAbsent( 33 2 : _parameters.clientInstanceKey, () => ProviderContainer()); 34 4 : final container = providerContainerMap[_parameters.clientInstanceKey]!; 35 4 : _repository = container.read(chatwootRepositoryProvider( 36 1 : RepositoryParameters( 37 3 : params: _parameters, callbacks: callbacks ?? ChatwootCallbacks()))); 38 : } 39 : 40 1 : void _init() { 41 : try { 42 3 : _repository.initialize(user); 43 0 : } on ChatwootClientException catch (e) { 44 0 : callbacks?.onError?.call(e); 45 : } 46 : } 47 : 48 : ///Retrieves chatwoot client's messages. If persistence is enabled [ChatwootCallbacks.onPersistedMessagesRetrieved] 49 : ///will be triggered with persisted messages. On successfully fetch from remote server 50 : ///[ChatwootCallbacks.onMessagesRetrieved] will be triggered 51 1 : void loadMessages() async { 52 2 : _repository.getPersistedMessages(); 53 3 : await _repository.getMessages(); 54 : } 55 : 56 : /// Sends chatwoot message. The echoId is your temporary message id. When message sends successfully 57 : /// [ChatwootMessage] will be returned with the [echoId] on [ChatwootCallbacks.onMessageSent]. If 58 : /// message fails to send [ChatwootCallbacks.onError] will be triggered [echoId] as data. 59 1 : Future<void> sendMessage( 60 : {required String content, required String echoId}) async { 61 1 : final request = ChatwootNewMessageRequest(content: content, echoId: echoId); 62 3 : await _repository.sendMessage(request); 63 : } 64 : 65 : ///Send chatwoot action performed by user. 66 : /// 67 : /// Example: User started typing 68 1 : Future<void> sendAction(ChatwootActionType action) async { 69 2 : _repository.sendAction(action); 70 : } 71 : 72 : ///Disposes chatwoot client and cancels all stream subscriptions 73 1 : dispose() { 74 4 : final container = providerContainerMap[_parameters.clientInstanceKey]!; 75 2 : _repository.dispose(); 76 1 : container.dispose(); 77 4 : providerContainerMap.remove(_parameters.clientInstanceKey); 78 : } 79 : 80 : /// Clears all chatwoot client data 81 1 : clearClientData() { 82 4 : final container = providerContainerMap[_parameters.clientInstanceKey]!; 83 4 : final localStorage = container.read(localStorageProvider(_parameters)); 84 1 : localStorage.clear(clearChatwootUserStorage: false); 85 : } 86 : 87 : /// Creates an instance of [ChatwootClient] with the [baseUrl] of your chatwoot installation, 88 : /// [inboxIdentifier] for the targeted inbox. Specify custom user details using [user] and [callbacks] for 89 : /// handling chatwoot events. By default persistence is enabled, to disable persistence use [enablePersistence] 90 1 : static Future<ChatwootClient> create( 91 : {required String baseUrl, 92 : required String inboxIdentifier, 93 : ChatwootUser? user, 94 : bool enablePersistence = true, 95 : ChatwootCallbacks? callbacks}) async { 96 : if (enablePersistence) { 97 2 : await LocalStorage.openDB(); 98 : } 99 : 100 1 : final chatwootParams = ChatwootParameters( 101 1 : clientInstanceKey: getClientInstanceKey( 102 : baseUrl: baseUrl, 103 : inboxIdentifier: inboxIdentifier, 104 1 : userIdentifier: user?.identifier), 105 : isPersistenceEnabled: enablePersistence, 106 : baseUrl: baseUrl, 107 : inboxIdentifier: inboxIdentifier, 108 1 : userIdentifier: user?.identifier); 109 : 110 : final client = 111 1 : ChatwootClient._(chatwootParams, callbacks: callbacks, user: user); 112 : 113 1 : client._init(); 114 : 115 : return client; 116 : } 117 : 118 : static final _keySeparator = "|||"; 119 : 120 : ///Create a chatwoot client instance key using the chatwoot client instance baseurl, inboxIdentifier 121 : ///and userIdentifier. Client instance keys are used to differentiate between client instances and their data 122 : ///(contact ([ChatwootContact]),conversation ([ChatwootConversation]) and messages ([ChatwootMessage])) 123 : /// 124 : /// Create separate [ChatwootClient] instances with same baseUrl, inboxIdentifier, userIdentifier and persistence 125 : /// enabled will be regarded as same therefore use same contact and conversation. 126 1 : static String getClientInstanceKey( 127 : {required String baseUrl, 128 : required String inboxIdentifier, 129 : String? userIdentifier}) { 130 1 : return "$baseUrl$_keySeparator$userIdentifier$_keySeparator$inboxIdentifier"; 131 : } 132 : 133 3 : static Map<String, ProviderContainer> providerContainerMap = Map(); 134 : 135 : ///Clears all persisted chatwoot data on device for a particular chatwoot client instance. 136 : ///See [getClientInstanceKey] on how chatwoot client instance are differentiated 137 1 : static Future<void> clearData( 138 : {required String baseUrl, 139 : required String inboxIdentifier, 140 : String? userIdentifier}) async { 141 1 : final clientInstanceKey = getClientInstanceKey( 142 : baseUrl: baseUrl, 143 : inboxIdentifier: inboxIdentifier, 144 : userIdentifier: userIdentifier); 145 2 : providerContainerMap.putIfAbsent( 146 0 : clientInstanceKey, () => ProviderContainer()); 147 2 : final container = providerContainerMap[clientInstanceKey]!; 148 1 : final params = ChatwootParameters( 149 : isPersistenceEnabled: true, 150 : baseUrl: "", 151 : inboxIdentifier: "", 152 : clientInstanceKey: ""); 153 : 154 3 : final localStorage = container.read(localStorageProvider(params)); 155 2 : await localStorage.clear(); 156 : 157 1 : localStorage.dispose(); 158 1 : container.dispose(); 159 2 : providerContainerMap.remove(clientInstanceKey); 160 : } 161 : 162 : /// Clears all persisted chatwoot data on device. 163 1 : static Future<void> clearAllData() async { 164 2 : providerContainerMap.putIfAbsent("all", () => ProviderContainer()); 165 2 : final container = providerContainerMap["all"]!; 166 1 : final params = ChatwootParameters( 167 : isPersistenceEnabled: true, 168 : baseUrl: "", 169 : inboxIdentifier: "", 170 : clientInstanceKey: ""); 171 : 172 3 : final localStorage = container.read(localStorageProvider(params)); 173 2 : await localStorage.clearAll(); 174 : 175 1 : localStorage.dispose(); 176 1 : container.dispose(); 177 : } 178 : }