Line data Source code
1 : 2 : import 'dart:async'; 3 : import 'dart:convert'; 4 : 5 : import 'package:chatwoot_client_sdk/data/local/entity/chatwoot_contact.dart'; 6 : import 'package:chatwoot_client_sdk/data/local/entity/chatwoot_conversation.dart'; 7 : import 'package:chatwoot_client_sdk/data/local/entity/chatwoot_message.dart'; 8 : import 'package:chatwoot_client_sdk/data/remote/chatwoot_client_exception.dart'; 9 : import 'package:chatwoot_client_sdk/data/remote/requests/chatwoot_action.dart'; 10 : import 'package:chatwoot_client_sdk/data/remote/requests/chatwoot_action_data.dart'; 11 : import 'package:chatwoot_client_sdk/data/remote/service/chatwoot_client_api_interceptor.dart'; 12 : import 'package:chatwoot_client_sdk/data/remote/requests/chatwoot_new_message_request.dart'; 13 : import 'package:dio/dio.dart'; 14 : import 'package:web_socket_channel/web_socket_channel.dart'; 15 : 16 : abstract class ChatwootClientService{ 17 : 18 : final String _baseUrl; 19 : WebSocketChannel? connection; 20 : final Dio _dio; 21 : 22 1 : ChatwootClientService(this._baseUrl, this._dio); 23 : 24 : Future<ChatwootContact> updateContact( 25 : update 26 : ); 27 : 28 : Future<ChatwootContact> getContact(); 29 : 30 : Future<List<ChatwootConversation>> getConversations(); 31 : 32 : Future<ChatwootMessage> createMessage( 33 : ChatwootNewMessageRequest request 34 : ); 35 : 36 : Future<ChatwootMessage> updateMessage( 37 : String messageIdentifier, 38 : update 39 : ); 40 : 41 : Future<List<ChatwootMessage>> getAllMessages(); 42 : 43 : void startWebSocketConnection( 44 : String contactPubsubToken, 45 : {WebSocketChannel Function(Uri)? onStartConnection} 46 : ); 47 : 48 : void sendAction(String contactPubsubToken, ChatwootActionType action); 49 : 50 : } 51 : 52 : class ChatwootClientServiceImpl extends ChatwootClientService{ 53 : 54 1 : ChatwootClientServiceImpl( 55 : String baseUrl, 56 : { 57 : required Dio dio 58 : } 59 1 : ) : super(baseUrl, dio); 60 : 61 : 62 : @override 63 1 : Future<ChatwootMessage> createMessage( 64 : ChatwootNewMessageRequest request 65 : ) async{ 66 : try{ 67 3 : final createResponse = await _dio.post( 68 1 : "public/api/v1/inboxes/${ChatwootClientApiInterceptor.INTERCEPTOR_INBOX_IDENTIFIER_PLACEHOLDER}/contacts/${ChatwootClientApiInterceptor.INTERCEPTOR_CONTACT_IDENTIFIER_PLACEHOLDER}/conversations/${ChatwootClientApiInterceptor.INTERCEPTOR_CONVERSATION_IDENTIFIER_PLACEHOLDER}/messages", 69 1 : data: request.toJson() 70 : ); 71 2 : if((createResponse.statusCode ?? 0).isBetween(199, 300) ){ 72 2 : return ChatwootMessage.fromJson(createResponse.data); 73 : }else{ 74 1 : throw ChatwootClientException( 75 1 : createResponse.statusMessage ?? "unknown error", 76 : ChatwootClientExceptionType.SEND_MESSAGE_FAILED 77 : ); 78 : } 79 1 : } on DioError catch(e){ 80 1 : throw ChatwootClientException( 81 1 : e.message, 82 : ChatwootClientExceptionType.SEND_MESSAGE_FAILED 83 : ); 84 : } 85 : } 86 : 87 : @override 88 1 : Future<List<ChatwootMessage>> getAllMessages() async{ 89 : try{ 90 3 : final createResponse = await _dio.get( 91 : "public/api/v1/inboxes/${ChatwootClientApiInterceptor.INTERCEPTOR_INBOX_IDENTIFIER_PLACEHOLDER}/contacts/${ChatwootClientApiInterceptor.INTERCEPTOR_CONTACT_IDENTIFIER_PLACEHOLDER}/conversations/${ChatwootClientApiInterceptor.INTERCEPTOR_CONVERSATION_IDENTIFIER_PLACEHOLDER}/messages" 92 1 : ); 93 2 : if((createResponse.statusCode ?? 0).isBetween(199, 300) ){ 94 1 : return (createResponse.data as List<dynamic>) 95 3 : .map(((json)=>ChatwootMessage.fromJson(json))) 96 1 : .toList(); 97 : }else{ 98 1 : throw ChatwootClientException( 99 1 : createResponse.statusMessage ?? "unknown error", 100 : ChatwootClientExceptionType.GET_MESSAGES_FAILED 101 : ); 102 : } 103 1 : } on DioError catch(e){ 104 2 : throw ChatwootClientException(e.message,ChatwootClientExceptionType.GET_MESSAGES_FAILED); 105 : } 106 : } 107 : 108 : @override 109 1 : Future<ChatwootContact> getContact() async{ 110 : try{ 111 3 : final createResponse = await _dio.get( 112 : "public/api/v1/inboxes/${ChatwootClientApiInterceptor.INTERCEPTOR_INBOX_IDENTIFIER_PLACEHOLDER}/contacts/${ChatwootClientApiInterceptor.INTERCEPTOR_CONTACT_IDENTIFIER_PLACEHOLDER}" 113 1 : ); 114 2 : if((createResponse.statusCode ?? 0).isBetween(199, 300) ){ 115 2 : return ChatwootContact.fromJson(createResponse.data); 116 : }else{ 117 1 : throw ChatwootClientException( 118 1 : createResponse.statusMessage ?? "unknown error", 119 : ChatwootClientExceptionType.GET_CONTACT_FAILED 120 : ); 121 : } 122 1 : } on DioError catch(e){ 123 2 : throw ChatwootClientException(e.message,ChatwootClientExceptionType.GET_CONTACT_FAILED); 124 : } 125 : } 126 : 127 : @override 128 1 : Future<List<ChatwootConversation>> getConversations() async{ 129 : try{ 130 4 : final createResponse = await _dio.get("public/api/v1/inboxes/${ChatwootClientApiInterceptor.INTERCEPTOR_INBOX_IDENTIFIER_PLACEHOLDER}/contacts/${ChatwootClientApiInterceptor.INTERCEPTOR_CONTACT_IDENTIFIER_PLACEHOLDER}/conversations"); 131 2 : if((createResponse.statusCode ?? 0).isBetween(199, 300) ){ 132 1 : return (createResponse.data as List<dynamic>) 133 3 : .map(((json)=>ChatwootConversation.fromJson(json))) 134 1 : .toList(); 135 : }else{ 136 1 : throw ChatwootClientException( 137 1 : createResponse.statusMessage ?? "unknown error", 138 : ChatwootClientExceptionType.GET_CONVERSATION_FAILED 139 : ); 140 : } 141 1 : } on DioError catch(e){ 142 2 : throw ChatwootClientException(e.message,ChatwootClientExceptionType.GET_CONVERSATION_FAILED); 143 : } 144 : } 145 : 146 : @override 147 1 : Future<ChatwootContact> updateContact( 148 : update 149 : ) async{ 150 : try{ 151 3 : final updateResponse = await _dio.patch( 152 1 : "public/api/v1/inboxes/${ChatwootClientApiInterceptor.INTERCEPTOR_INBOX_IDENTIFIER_PLACEHOLDER}/contacts/${ChatwootClientApiInterceptor.INTERCEPTOR_CONTACT_IDENTIFIER_PLACEHOLDER}", 153 : data: update 154 : ); 155 2 : if((updateResponse.statusCode ?? 0).isBetween(199, 300) ){ 156 2 : return ChatwootContact.fromJson(updateResponse.data); 157 : }else{ 158 1 : throw ChatwootClientException( 159 1 : updateResponse.statusMessage ?? "unknown error", 160 : ChatwootClientExceptionType.UPDATE_CONTACT_FAILED 161 : ); 162 : } 163 1 : } on DioError catch(e){ 164 2 : throw ChatwootClientException(e.message,ChatwootClientExceptionType.UPDATE_CONTACT_FAILED); 165 : } 166 : } 167 : 168 : @override 169 1 : Future<ChatwootMessage> updateMessage( 170 : String messageIdentifier, 171 : update 172 : ) async{ 173 : try{ 174 3 : final updateResponse = await _dio.patch( 175 1 : "public/api/v1/inboxes/${ChatwootClientApiInterceptor.INTERCEPTOR_INBOX_IDENTIFIER_PLACEHOLDER}/contacts/${ChatwootClientApiInterceptor.INTERCEPTOR_CONTACT_IDENTIFIER_PLACEHOLDER}/conversations/${ChatwootClientApiInterceptor.INTERCEPTOR_CONVERSATION_IDENTIFIER_PLACEHOLDER}/messages/$messageIdentifier", 176 : data: update 177 : ); 178 2 : if((updateResponse.statusCode ?? 0).isBetween(199, 300) ){ 179 2 : return ChatwootMessage.fromJson(updateResponse.data); 180 : }else{ 181 1 : throw ChatwootClientException( 182 1 : updateResponse.statusMessage ?? "unknown error", 183 : ChatwootClientExceptionType.UPDATE_MESSAGE_FAILED 184 : ); 185 : } 186 1 : } on DioError catch(e){ 187 1 : throw ChatwootClientException( 188 1 : e.message, 189 : ChatwootClientExceptionType.UPDATE_MESSAGE_FAILED 190 : ); 191 : } 192 : } 193 : 194 1 : @override 195 : void startWebSocketConnection( 196 : String contactPubsubToken, 197 : {WebSocketChannel Function(Uri)? onStartConnection}) { 198 1 : if(this.connection == null){ 199 4 : final socketUrl = Uri.parse(_baseUrl.replaceFirst("http", "ws")+"/cable"); 200 2 : this.connection = onStartConnection == null ? WebSocketChannel.connect(socketUrl): onStartConnection(socketUrl); 201 : } 202 5 : connection?.sink.add(jsonEncode({ 203 : "command":"subscribe", 204 2 : "identifier": jsonEncode({ 205 : "channel":"RoomChannel", 206 : "pubsub_token": contactPubsubToken 207 : }) 208 : })); 209 : } 210 : 211 1 : @override 212 : void sendAction(String contactPubsubToken, ChatwootActionType actionType) { 213 : final ChatwootAction action; 214 2 : final identifier = jsonEncode({ 215 : "channel":"RoomChannel", 216 : "pubsub_token": contactPubsubToken 217 : }); 218 : switch(actionType){ 219 1 : case ChatwootActionType.subscribe: 220 0 : action = ChatwootAction( 221 : identifier: identifier, 222 : command: "subscribe" 223 : ); 224 : break; 225 : default: 226 1 : action = ChatwootAction( 227 : identifier: identifier, 228 1 : data: ChatwootActionData(action: actionType), 229 : command: "message" 230 : ); 231 : break; 232 : } 233 5 : connection?.sink.add(jsonEncode(action.toJson())); 234 : } 235 : 236 : 237 : }