Line data Source code
1 : 2 : import 'package:chatwoot_client_sdk/data/local/entity/chatwoot_contact.dart'; 3 : import 'package:chatwoot_client_sdk/data/local/entity/chatwoot_conversation.dart'; 4 : import 'package:chatwoot_client_sdk/data/local/local_storage.dart'; 5 : import 'package:chatwoot_client_sdk/data/remote/service/chatwoot_client_auth_service.dart'; 6 : import 'package:dio/dio.dart'; 7 : 8 : 9 : ///Intercepts network requests and attaches inbox identifier, contact identifiers, conversation identifiers 10 : /// 11 : /// Creates a new contact and conversation when no persisted contact is found 12 : /// Clears and recreates contact when a 401 (Unauthorized) response is returned from chatwoot api 13 : class ChatwootClientApiInterceptor extends Interceptor{ 14 : static const INTERCEPTOR_INBOX_IDENTIFIER_PLACEHOLDER = "{INBOX_IDENTIFIER}"; 15 : static const INTERCEPTOR_CONTACT_IDENTIFIER_PLACEHOLDER = "{CONTACT_IDENTIFIER}"; 16 : static const INTERCEPTOR_CONVERSATION_IDENTIFIER_PLACEHOLDER = "{CONVERSATION_IDENTIFIER}"; 17 : 18 : final String _inboxIdentifier; 19 : final LocalStorage _localStorage; 20 : final ChatwootClientAuthService _authService; 21 : 22 2 : ChatwootClientApiInterceptor( 23 : this._inboxIdentifier, 24 : this._localStorage, 25 : this._authService 26 : ); 27 : 28 : @override 29 1 : Future<void> onRequest(RequestOptions options, RequestInterceptorHandler handler) async{ 30 : RequestOptions newOptions = options; 31 3 : ChatwootContact? contact = _localStorage.contactDao.getContact(); 32 3 : ChatwootConversation? conversation = _localStorage.conversationDao.getConversation(); 33 : 34 : if(contact == null){ 35 : // create new contact from user if no token found 36 7 : contact = await _authService.createNewContact(_inboxIdentifier, _localStorage.userDao.getUser()); 37 5 : conversation = await _authService.createNewConversation(_inboxIdentifier,contact.contactIdentifier!); 38 4 : await _localStorage.conversationDao.saveConversation(conversation); 39 4 : await _localStorage.contactDao.saveContact(contact); 40 : } 41 : 42 : if(conversation == null){ 43 5 : conversation = await _authService.createNewConversation(_inboxIdentifier,contact.contactIdentifier!); 44 4 : await _localStorage.conversationDao.saveConversation(conversation); 45 : } 46 : 47 : 48 4 : newOptions.path = newOptions.path.replaceAll(INTERCEPTOR_INBOX_IDENTIFIER_PLACEHOLDER, _inboxIdentifier); 49 4 : newOptions.path = newOptions.path.replaceAll(INTERCEPTOR_CONTACT_IDENTIFIER_PLACEHOLDER, contact.contactIdentifier!); 50 5 : newOptions.path = newOptions.path.replaceAll(INTERCEPTOR_CONVERSATION_IDENTIFIER_PLACEHOLDER, "${conversation.id}"); 51 : 52 1 : handler.next(newOptions); 53 : 54 : } 55 : 56 : @override 57 1 : Future<void> onResponse(Response response, ResponseInterceptorHandler handler) async{ 58 6 : if(response.statusCode == 401 || response.statusCode == 403 || response.statusCode == 404){ 59 3 : await _localStorage.clear(); 60 : 61 : // create new contact from user if unauthorized,forbidden or not found 62 7 : final contact = await _authService.createNewContact(_inboxIdentifier, _localStorage.userDao.getUser()); 63 5 : final conversation = await _authService.createNewConversation(_inboxIdentifier,contact.contactIdentifier!); 64 4 : await _localStorage.contactDao.saveContact(contact); 65 4 : await _localStorage.conversationDao.saveConversation(conversation); 66 : 67 1 : RequestOptions newOptions = response.requestOptions; 68 4 : newOptions.headers.update("AUTHORIZATION", (value) => contact.pubsubToken, ifAbsent: () => contact.pubsubToken); 69 : 70 5 : handler.next(await _authService.dio.fetch(newOptions)); 71 : 72 : }else{ 73 1 : handler.next(response); 74 : } 75 : } 76 : 77 : } 78 : 79 : extension Range on num { 80 2 : bool isBetween(num from, num to) { 81 4 : return from < this && this < to; 82 : } 83 : }