{ "version": 3, "sources": ["src/app/main/components/chat/chat.service.ts"], "sourcesContent": ["import { Injectable } from '@angular/core';\r\nimport { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Observable, of, throwError } from 'rxjs';\r\nimport { tap, catchError, map } from 'rxjs/operators';\r\nimport { environment } from 'src/environments/environment';\r\nimport { AccountDetail, ChatResponse } from '../../model';\r\nimport { CacheService } from '../../service/cache.service';\r\nimport { ActivityService } from '../../service/activity.service';\r\nimport { GaFieldsObject } from 'src/app/core/model';\r\nimport { GaInfo } from 'src/app/config/ga-info.constant';\r\nimport { features } from 'src/environments/features';\r\nimport { SpinnerSettings } from 'src/app/config/spinner-settings.constant';\r\nimport { Router } from '@angular/router';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ChatService {\r\n constructor(private httpClient: HttpClient, private cache: CacheService, private activity: ActivityService, private router: Router) {\r\n this.cache.subscribe(this.cache.items.userLinkedAccounts, res => this.setUserAccounts(res));\r\n }\r\n\r\n isChatLive = false;\r\n private areAccountsEligible = false;\r\n private accounts: AccountDetail[];\r\n private accessToken: string;\r\n private baseUri: string;\r\n private popUrl: string;\r\n private chatSessionId: string;\r\n private masterChatSessionId;\r\n private inContactId;\r\n private chatApiVersion: string;\r\n protected chatIsInitialized = false;\r\n private chatPollingTimeout = 60;\r\n\r\n get canShowChat(): boolean {\r\n return this.areAccountsEligible && features.chat;\r\n }\r\n\r\n getToken(): Observable {\r\n const acctId = this.getCurrentAcctId();\r\n const url = `${environment.apiEndpoint}api/chats?acctId=${acctId}`;\r\n return this.httpClient.post(url, {}, SpinnerSettings.hideSpinner())\r\n .pipe(tap((res: any) => {\r\n this.accessToken = res.accessToken;\r\n this.baseUri = res.resourceServerBaseUri.trim();\r\n this.popUrl = res.popUrl;\r\n this.chatSessionId = res.chatSessionId;\r\n this.masterChatSessionId = res.chatSessionId;\r\n this.inContactId = res.inContactId;\r\n this.chatApiVersion = res.chatApiVersion;\r\n\r\n this.isChatLive = true;\r\n this.chatIsInitialized = false;\r\n\r\n if (this.baseUri.lastIndexOf('/') === (this.baseUri.length - 1)) {\r\n this.baseUri = this.baseUri.slice(0, -1);\r\n }\r\n }))\r\n .pipe(catchError(err => {\r\n this.isChatLive = false;\r\n return throwError(err);\r\n }));\r\n }\r\n\r\n getChatText(): Observable {\r\n const url = `${this.baseUri}/services/${this.chatApiVersion}/contacts/chats/${this.chatSessionId}?timeout=${this.chatPollingTimeout}`;\r\n return this.httpClient.get(url, {headers: this.chatHeaders(false)})\r\n .pipe(map((res: any) => {\r\n return this.processAgentMessages(res);\r\n }))\r\n .pipe(catchError((err: any) => {\r\n if (this.isChatLive && err.statusText === 'No Messages') {\r\n return of(new ChatResponse());\r\n }\r\n\r\n const fieldObject: GaFieldsObject = {\r\n gaEvent: '_chat_',\r\n eventCategory: GaInfo.event.category.chat,\r\n eventAction: 'Chat Error',\r\n eventLabel: JSON.stringify(err)\r\n };\r\n\r\n this.activity.sendEvent(fieldObject);\r\n\r\n this.endChatSession();\r\n return of({ messageType: 'Timeout', messages: ['Due to inactivity, we are ending this chat']} as ChatResponse);\r\n }));\r\n }\r\n\r\n sendSingleChatMessage(message: string): Observable {\r\n if (!this.chatIsInitialized) {\r\n this.chatIsInitialized = true;\r\n\r\n // Send URL to agent\r\n this.sendSingleChatMessage(this.popUrl);\r\n }\r\n\r\n const request = {\r\n 'label': 'RCP Chat',\r\n 'message': message\r\n };\r\n\r\n const url = `${this.baseUri}/services/${this.chatApiVersion}/contacts/chats/${this.chatSessionId}/send-text`;\r\n\r\n return this.httpClient.post(url, JSON.stringify(request), { headers: this.chatHeaders(true) })\r\n .pipe(catchError(err => of(err.statusText)));\r\n }\r\n\r\n endChatSession() {\r\n this.isChatLive = false;\r\n this.chatIsInitialized = false;\r\n if (this.masterChatSessionId) {\r\n const url = `${this.baseUri}/services/${this.chatApiVersion}/contacts/chats/${this.masterChatSessionId}`;\r\n this.httpClient.delete(url, { headers: this.chatHeaders(false) }).subscribe();\r\n }\r\n this.masterChatSessionId = null;\r\n }\r\n\r\n redact(str: string): string {\r\n if (!str) {\r\n return str;\r\n }\r\n return str.replace(/[0-9]/g, '*').replace(/[^\\s]+\\@[^\\s]+\\.[^\\s]+/g, '*@*.*');\r\n }\r\n\r\n protected processAgentMessages(res: any): ChatResponse {\r\n // If chat has ended then exit\r\n if (!this.isChatLive || res === 'Session Ended') {\r\n this.isChatLive = false;\r\n return { messageType: 'Agent End Chat Session', messages: ['Chat Session Has Ended'] } as ChatResponse;\r\n }\r\n\r\n const noMessages = new ChatResponse();\r\n // if nothing returned in response and chat is live then exit\r\n if (!res) {\r\n return noMessages;\r\n }\r\n\r\n // update the temporary chatSessionId from response\r\n this.chatSessionId = res.chatSession;\r\n\r\n // begin parsing the message response\r\n const response = { messages: []} as ChatResponse;\r\n for (const msg of res.messages) {\r\n let partyTypeValue = 'System';\r\n let message = '';\r\n if (!msg.Text) {\r\n message = msg.Status;\r\n // this is a system response and should be ignored\r\n if (message === 'Active' && this.isChatLive) {\r\n return noMessages;\r\n }\r\n } else {\r\n // System only message. Do not show to client.\r\n if (msg.Text.indexOf(this.inContactId) > -1) {\r\n return noMessages;\r\n }\r\n\r\n message = '\\n' + msg.Text;\r\n partyTypeValue = msg.PartyTypeValue;\r\n }\r\n\r\n if (message === 'No Message' || message === 'Waiting') {\r\n continue;\r\n }\r\n\r\n if (partyTypeValue === 'System' || partyTypeValue === 'Agent') {\r\n response.messageType = 'Agent Message';\r\n\r\n if (message.indexOf('Due to inactivity, we are ending this chat') > -1) {\r\n response.messageType = 'Timeout';\r\n this.isChatLive = false;\r\n }\r\n if (message.indexOf('ChatSessionEnded') > -1) {\r\n message = 'Chat Session Has Ended';\r\n response.messageType = 'Agent End Chat Session';\r\n this.isChatLive = false;\r\n }\r\n if (message.indexOf('AgentLeftChat') > -1) {\r\n message = 'Hold while we transfer you to another agent for assistance.';\r\n response.messageType = 'Agent Transfer';\r\n }\r\n\r\n response.messages.push(message);\r\n }\r\n }\r\n\r\n return response;\r\n }\r\n\r\n protected setUserAccounts(accounts: AccountDetail[]) {\r\n this.accounts = accounts;\r\n if (!accounts || accounts.length === 0 || window.location.search.includes('chat=off')) {\r\n this.areAccountsEligible = false;\r\n return;\r\n }\r\n\r\n if (!!accounts.find(x => !x.eligibility.viewAccountDetails) && environment.name !== 'local') {\r\n this.areAccountsEligible = false;\r\n return;\r\n }\r\n\r\n const url = `${environment.apiEndpoint}api/user-accounts-chat-status`;\r\n this.httpClient.get(url, SpinnerSettings.hideSpinner()).subscribe(\r\n (res: any) => {\r\n this.areAccountsEligible = res.isChatEligible;\r\n\r\n if (res.isChatEligible) {\r\n const fieldObject: GaFieldsObject = {\r\n gaEvent: '_chat_',\r\n eventCategory: GaInfo.event.category.chat,\r\n eventAction: 'Chat Eligible'\r\n };\r\n\r\n this.activity.sendEvent(fieldObject);\r\n }\r\n },\r\n err => this.areAccountsEligible = false\r\n );\r\n }\r\n\r\n private getCurrentAcctId() {\r\n const accountContext = this.cache.get(this.cache.items.accountContext);\r\n if (accountContext && !this.router.url.includes('summary')) {\r\n return (accountContext).acctId;\r\n }\r\n\r\n return (this.accounts || []).find(x => x.isDefault)?.acctId || (this.accounts || [])[0].acctId;\r\n }\r\n\r\n private chatHeaders(isJson: boolean) {\r\n return new HttpHeaders({\r\n 'Authorization': `bearer ${this.accessToken}`,\r\n 'content-Type': isJson ? 'application/json' : 'application/x-www-form-urlencoded'\r\n });\r\n }\r\n}\r\n"], "mappings": "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", "names": ["ChatService", "constructor", "httpClient", "cache", "activity", "router", "isChatLive", "areAccountsEligible", "chatIsInitialized", "chatPollingTimeout", "subscribe", "items", "userLinkedAccounts", "res", "setUserAccounts", "canShowChat", "features", "chat", "getToken", "acctId", "getCurrentAcctId", "url", "environment", "apiEndpoint", "post", "SpinnerSettings", "hideSpinner", "pipe", "tap", "accessToken", "baseUri", "resourceServerBaseUri", "trim", "popUrl", "chatSessionId", "masterChatSessionId", "inContactId", "chatApiVersion", "lastIndexOf", "length", "slice", "catchError", "err", "throwError", "getChatText", "get", "headers", "chatHeaders", "map", "processAgentMessages", "statusText", "of", "ChatResponse", "fieldObject", "gaEvent", "eventCategory", "GaInfo", "event", "category", "eventAction", "eventLabel", "JSON", "stringify", "sendEvent", "endChatSession", "messageType", "messages", "sendSingleChatMessage", "message", "request", "delete", "redact", "str", "replace", "noMessages", "chatSession", "response", "msg", "partyTypeValue", "Text", "indexOf", "PartyTypeValue", "Status", "push", "accounts", "window", "location", "search", "includes", "find", "x", "eligibility", "viewAccountDetails", "name", "isChatEligible", "_a", "accountContext", "isDefault", "isJson", "HttpHeaders", "\u0275\u0275inject", "HttpClient", "CacheService", "ActivityService", "Router", "factory", "\u0275fac", "providedIn", "_ChatService"] }