Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/AppSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ export const AppSettings: Array<ISetting> = [
public: true,
type: SettingType.STRING,
packageValue: '',
i18nLabel: '',
i18nLabel: 'Liveagent Chat Ended Message',
i18nDescription: 'Enter message to show to the user when liveagent ends chat session.',
required: true,
},
Expand Down
108 changes: 108 additions & 0 deletions enum/Analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,22 @@ export enum EventName {
ESCALATION_FAILED_DUE_TO_NO_LIVEAGENT_AVAILABLE = 'escalation_failed_due_to_no_liveagent_available',
ESCALATION_FAILED_DUE_TO_SALESFORCE_ERROR = 'escalation_failed_due_to_salesforce_error',
ESCALATION_FAILED_DUE_TO_NETWORK_OR_APP_ERROR = 'escalation_failed_due_to_network_or_app_error',
ESCALATION_FAILED_DUE_TO_LIVEAGENT_SESSION_ID_GENERATION_ERROR = 'escalation_failed_due_to_liveagent_session_id_generation_error',
ESCALATION_FAILED_DUE_TO_LIVEAGENT_CHAT_REQUEST_ERROR = 'escalation_failed_due_to_livechat_agent_response_error',
ESCALATION_FAILED_DUE_TO_LIVEAGENT_RESPONSE_CHECKING_ERROR = 'escalation_failed_due_to_liveagent_response_checking_error',
ESCALATION_FAILED_DUE_TO_LIVEAGENT_RESPONSE_ERROR = 'escalation_failed_due_to_liveagent_response_error',
ESCALATION_FAILED_DUE_TO_SALESFORCE_INTERNAL_FAILURE = 'escalation_due_to_salesforce_internal_failure',
ESCALATION_FAILED_DUE_TO_INVALID_APP_CONFIGURATION = 'escalation_failed_due_to_invalid_app_configuration',
ESCALATION_SUCCESSFUL = 'escalation_successful',
AGENT_TRANSFER_SUCCESSFUL = 'agent_transfer_successful',
CHAT_CLOSED_BY_AGENT = 'chat_closed_by_agent',
CHAT_CLOSED_BY_TIMEOUT = 'chat_closed_by_timeout',
CHAT_CLOSED_LIVEAGENT_SESSION_EXPIRED = 'chat_closed_live_agent_session_expired',
CHAT_CLOSED_LIVEAGENT_DISCONNECTED = 'chat_closed_live_agent_disconnected',
CHAT_CLOSED_UNKNOWN_ERROR_IN_CHECKING_AGENT_RESPONSE = 'chat_closed_unknown_error_in_checking_agent_response',
ESCALATION_FAILED_DUE_TO_ERROR_GETTING_SF_MESSAGES = 'escalation_failed_due_to_error_getting_sf_messages',
ESCALATION_FAILED_DUE_TO_SALESFORCE_CHAT_API_NOT_FOUND = 'escalation_failed_due_to_salesforce_chat_api_not_found',
CHAT_CLOSED_DUE_TO_EMPTY_MESSAGE_FROM_LIVEAGENT = 'chat_closed_due_to_empty_message_from_liveagent',
}

export enum EventCatagory {
Expand Down Expand Up @@ -46,6 +58,14 @@ export const Events: Record<string, IAnalyticsEvent> = {
failure_reason: 'network/app error in SF app',
},
},
[EventName.ESCALATION_FAILED_DUE_TO_SALESFORCE_CHAT_API_NOT_FOUND]: {
category: EventCatagory.ESCALATION,
eventType: EventType.SESSION,
action: 'failed',
properties: {
failure_reason: 'salesforce chat API not found',
},
},
[EventName.ESCALATION_SUCCESSFUL]: {
category: EventCatagory.ESCALATION,
eventType: EventType.SESSION,
Expand All @@ -55,6 +75,62 @@ export const Events: Record<string, IAnalyticsEvent> = {
sf_chat_key: '',
},
},
[EventName.ESCALATION_FAILED_DUE_TO_ERROR_GETTING_SF_MESSAGES]: {
category: EventCatagory.ESCALATION,
eventType: EventType.SESSION,
action: 'failed',
properties: {
failure_reason: 'unable to pull SF messages',
},
},
[EventName.ESCALATION_FAILED_DUE_TO_LIVEAGENT_SESSION_ID_GENERATION_ERROR]: {
category: EventCatagory.ESCALATION,
eventType: EventType.SESSION,
action: 'failed',
properties: {
failure_reason: 'liveagent session id error',
},
},
[EventName.ESCALATION_FAILED_DUE_TO_LIVEAGENT_CHAT_REQUEST_ERROR]: {
category: EventCatagory.ESCALATION,
eventType: EventType.SESSION,
action: 'failed',
properties: {
failure_reason: 'error in liveagent request',
},
},
[EventName.ESCALATION_FAILED_DUE_TO_LIVEAGENT_RESPONSE_CHECKING_ERROR]: {
category: EventCatagory.ESCALATION,
eventType: EventType.SESSION,
action: 'failed',
properties: {
failure_reason: 'error in checking liveagent response',
},
},
[EventName.ESCALATION_FAILED_DUE_TO_LIVEAGENT_RESPONSE_ERROR]: {
category: EventCatagory.ESCALATION,
eventType: EventType.SESSION,
action: 'failed',
properties: {
failure_reason: 'error in liveagent response',
},
},
[EventName.ESCALATION_FAILED_DUE_TO_SALESFORCE_INTERNAL_FAILURE]: {
category: EventCatagory.ESCALATION,
eventType: EventType.SESSION,
action: 'failed',
properties: {
failure_reason: 'salesforce internal failure',
},
},
[EventName.ESCALATION_FAILED_DUE_TO_INVALID_APP_CONFIGURATION]: {
category: EventCatagory.ESCALATION,
eventType: EventType.SESSION,
action: 'failed',
properties: {
failure_reason: 'invalid app configuration',
},
},
[EventName.AGENT_TRANSFER_SUCCESSFUL]: {
category: EventCatagory.AGENT_TRANSFER,
eventType: EventType.SESSION,
Expand All @@ -77,4 +153,36 @@ export const Events: Record<string, IAnalyticsEvent> = {
close_method: 'timeout',
},
},
[EventName.CHAT_CLOSED_LIVEAGENT_SESSION_EXPIRED]: {
category: EventCatagory.CHAT_SESSION,
eventType: EventType.SESSION,
action: 'closed',
properties: {
close_method: 'expired_session',
},
},
[EventName.CHAT_CLOSED_LIVEAGENT_DISCONNECTED]: {
category: EventCatagory.CHAT_SESSION,
eventType: EventType.SESSION,
action: 'closed',
properties: {
close_method: 'liveagent_disconnected',
},
},
[EventName.CHAT_CLOSED_UNKNOWN_ERROR_IN_CHECKING_AGENT_RESPONSE]: {
category: EventCatagory.CHAT_SESSION,
eventType: EventType.SESSION,
action: 'closed',
properties: {
close_method: 'unknown_error',
},
},
[EventName.CHAT_CLOSED_DUE_TO_EMPTY_MESSAGE_FROM_LIVEAGENT]: {
category: EventCatagory.CHAT_SESSION,
eventType: EventType.SESSION,
action: 'closed',
properties: {
close_method: 'empty message from liveagent',
},
},
};
10 changes: 10 additions & 0 deletions enum/CloseMessages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export enum CloseMessages {
CLOSED_BY_AGENT = 'Chat closed by livechat agent',
CLOSED_BY_VISITOR = 'Chat closed by visitor',
CLOSED_DUE_TO_TIMEOUT = 'Chat closed due to timeout',
LIVEAGENT_SESSION_EXPIRED = 'Liveagent session expired',
UNKNOWN_ERROR_IN_CHECKING_AGENT_RESPONSE = 'Unknown error occurred while checking for Liveagent chat request',
LIVEAGENT_DISCONNECTED = 'Liveagent disconnected',
CHAT_CLOSED_DUE_TO_ERROR_GETTING_SF_MESSAGES = 'Chat closed due to error getting SF messages',
NO_AGENT_AVAILABLE = 'No agent available',
}
2 changes: 2 additions & 0 deletions enum/ErrorLogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ export enum ErrorLogs {
DIALOGFLOW_ERROR_SESSION = 'Error encountered in session. Triggering DIALOGFLOW_SESSION_ERROR_EVENT',
CHASITOR_TYPING_API_CALL_FAIL = 'Cannot successfully call ChasitorTyping/ChasitorNotTyping api.',
CHASITOR_SNEAKPEEK_API_CALL_FAIL = 'Cannot successfully call ChasitorSneakPeek api.',
ESCALATION_FAILED_DUE_TO_ERROR_GETTING_SF_MESSAGES = 'Failure getting Salesforce Messages',
QUEUE_TIME_NOT_SET = 'Start time for escalation queue has not been set',
LIVEAGENT_EMPTY_RESPONSE = 'Empty response from liveagent',
}
1 change: 1 addition & 0 deletions enum/InfoLogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export enum InfoLogs {
MESSAGE_SENT_TO_LIVEAGENT = 'Message sent to Liveagent.',
LIVEAGENT_CURRENTLY_TYPING = 'Liveagent currently typing.',
LIVEAGENT_ACCEPTED_CHAT_REQUEST = 'Chat request accepted by Liveagent.',
LIVEAGENT_DISCONNECTED = 'Liveagent Disconnected.',
SUCCESSFULLY_RECEIVED_LIVEAGENT_RESPONSE = 'Successfully received Liveagent Response.',
HANDOVER_ENDPOINT_REQUEST_RECEIVED = 'Handover endpoint request received',
AVAILABILITY_ENDPOINT_REQUEST_RECEIVED = 'Availability endpoint request received',
Expand Down
62 changes: 40 additions & 22 deletions handlers/InitiateSalesforceSessionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ export class InitiateSalesforceSession {
} catch (error) {
await sendDebugLCMessage(this.read, this.modify, this.data.room, ErrorLogs.SALESFORCE_CHAT_API_NOT_FOUND, this.data.agent);
console.error(ErrorLogs.SALESFORCE_CHAT_API_NOT_FOUND, error);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(technicalDifficultyMessage);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(
technicalDifficultyMessage,
ErrorLogs.SALESFORCE_CHAT_API_NOT_FOUND,
EventName.ESCALATION_FAILED_DUE_TO_SALESFORCE_CHAT_API_NOT_FOUND,
);
return;
}

Expand Down Expand Up @@ -105,20 +109,6 @@ export class InitiateSalesforceSession {
};
Object.keys(handoverFailure).forEach((prop) => handoverFailure[prop] === undefined && delete handoverFailure[prop]);
console.error('Failed to handover', JSON.stringify(handoverFailure));

let errorEventName: EventName;
switch (errorMessage) {
case ErrorLogs.ALL_LIVEAGENTS_UNAVAILABLE:
errorEventName = EventName.ESCALATION_FAILED_DUE_TO_NO_LIVEAGENT_AVAILABLE;
break;
case ErrorLogs.APP_CONFIGURATION_INVALID:
case ErrorLogs.SALESFORCE_INTERNAL_FAILURE:
errorEventName = EventName.ESCALATION_FAILED_DUE_TO_SALESFORCE_ERROR;
break;
default:
errorEventName = EventName.ESCALATION_FAILED_DUE_TO_NETWORK_OR_APP_ERROR;
}
this.modify.getAnalytics().sendEvent(getEventData(roomId, errorEventName));
};

await sendChatRequest(
Expand Down Expand Up @@ -192,7 +182,11 @@ export class InitiateSalesforceSession {
this.read,
AppSettingId.NO_LIVEAGENT_AGENT_AVAILABLE_MESSAGE,
);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(NoLiveagentAvailableMessage);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(
NoLiveagentAvailableMessage,
ErrorLogs.ALL_LIVEAGENTS_UNAVAILABLE,
EventName.ESCALATION_FAILED_DUE_TO_NO_LIVEAGENT_AVAILABLE,
);
break;

case 'NoPost':
Expand All @@ -205,7 +199,11 @@ export class InitiateSalesforceSession {
ErrorLogs.APP_CONFIGURATION_INVALID,
this.data.agent,
);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(technicalDifficultyMessage);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(
technicalDifficultyMessage,
ErrorLogs.APP_CONFIGURATION_INVALID,
EventName.ESCALATION_FAILED_DUE_TO_INVALID_APP_CONFIGURATION,
);
break;

case 'InternalFailure':
Expand All @@ -218,7 +216,11 @@ export class InitiateSalesforceSession {
ErrorLogs.SALESFORCE_INTERNAL_FAILURE,
this.data.agent,
);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(technicalDifficultyMessage);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(
technicalDifficultyMessage,
ErrorLogs.SALESFORCE_INTERNAL_FAILURE,
EventName.ESCALATION_FAILED_DUE_TO_SALESFORCE_INTERNAL_FAILURE,
);
break;

default:
Expand All @@ -231,7 +233,11 @@ export class InitiateSalesforceSession {
ErrorLogs.UNKNOWN_ERROR_IN_CHECKING_AGENT_RESPONSE,
this.data.agent,
);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(technicalDifficultyMessage);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(
technicalDifficultyMessage,
ErrorLogs.UNKNOWN_ERROR_IN_CHECKING_AGENT_RESPONSE,
EventName.ESCALATION_FAILED_DUE_TO_LIVEAGENT_RESPONSE_CHECKING_ERROR,
);
break;
}
} else {
Expand Down Expand Up @@ -264,7 +270,11 @@ export class InitiateSalesforceSession {
`${ErrorLogs.GETTING_LIVEAGENT_RESPONSE_ERROR}: ${error}`,
this.data.agent,
);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(technicalDifficultyMessage);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(
technicalDifficultyMessage,
ErrorLogs.GETTING_LIVEAGENT_RESPONSE_ERROR,
EventName.ESCALATION_FAILED_DUE_TO_LIVEAGENT_RESPONSE_ERROR,
);
});
})
.catch(async (error) => {
Expand All @@ -277,7 +287,11 @@ export class InitiateSalesforceSession {
`${ErrorLogs.SENDING_LIVEAGENT_CHAT_REQUEST_ERROR}: ${error}`,
this.data.agent,
);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(technicalDifficultyMessage);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(
technicalDifficultyMessage,
ErrorLogs.SENDING_LIVEAGENT_CHAT_REQUEST_ERROR,
EventName.ESCALATION_FAILED_DUE_TO_LIVEAGENT_CHAT_REQUEST_ERROR,
);
});
})
.catch(async (error) => {
Expand All @@ -290,7 +304,11 @@ export class InitiateSalesforceSession {
`${ErrorLogs.GENERATING_LIVEAGENT_SESSION_ID_ERROR}: ${error}`,
this.data.agent,
);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(technicalDifficultyMessage);
await checkAgentStatusDirectCallback.checkAgentStatusCallbackError(
technicalDifficultyMessage,
ErrorLogs.GENERATING_LIVEAGENT_SESSION_ID_ERROR,
EventName.ESCALATION_FAILED_DUE_TO_LIVEAGENT_SESSION_ID_GENERATION_ERROR,
);
});
}

Expand Down
6 changes: 5 additions & 1 deletion handlers/LiveAgentSessionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import { ILivechatEventContext } from '@rocket.chat/apps-engine/definition/livec
import { ILivechatRoom } from '@rocket.chat/apps-engine/definition/livechat/ILivechatRoom';
import { IMessage } from '@rocket.chat/apps-engine/definition/messages';
import { IUser } from '@rocket.chat/apps-engine/definition/users';
import { EventName } from '../enum/Analytics';
import { AppSettingId } from '../enum/AppSettingId';
import { CloseMessages } from '../enum/CloseMessages';
import { ErrorLogs } from '../enum/ErrorLogs';
import { InfoLogs } from '../enum/InfoLogs';
import { getError } from '../helperFunctions/Log';
import { getRoomAssoc, retrievePersistentTokens } from '../helperFunctions/PersistenceHelpers';
import { getSalesforceChatAPIEndpoint, sendMessages } from '../helperFunctions/SalesforceAPIHelpers';
import { HandleEndChatCallback } from '../helperFunctions/subscribeHelpers/SalesforceAgentAssignedHelpers/HandleEndChatCallback';
import { getEventData } from '../lib/Analytics';
import { getAppSettingValue } from '../lib/Settings';

export class LiveAgentSession {
Expand Down Expand Up @@ -65,7 +68,8 @@ export class LiveAgentSession {
assoc,
'',
);
handleEndChatCallback.handleEndChat();
this.modify.getAnalytics().sendEvent(getEventData(this.message.room.id, EventName.CHAT_CLOSED_LIVEAGENT_SESSION_EXPIRED));
handleEndChatCallback.handleEndChat(CloseMessages.LIVEAGENT_SESSION_EXPIRED);
return;
}
console.log(InfoLogs.MESSAGE_SENT_TO_LIVEAGENT);
Expand Down
1 change: 0 additions & 1 deletion handlers/SalesforceAgentAssignedHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export class SalesforceAgentAssigned {
return;
}
const LAChatEndedMessage: string = await getAppSettingValue(this.read, AppSettingId.LIVEAGENT_CHAT_ENDED_MESSAGE);

const connectedToAgentMessage = `${InfoLogs.CONNECTING_TO_SALESFORCE_LIVEAGENT} ${salesforceAgentName}.`;
await sendLCMessage(this.read, this.modify, this.data.room, connectedToAgentMessage, this.data.agent);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { IHttp, IModify, IPersistence, IRead } from '@rocket.chat/apps-engine/definition/accessors';
import { IApp } from '@rocket.chat/apps-engine/definition/IApp';
import { ILivechatEventContext } from '@rocket.chat/apps-engine/definition/livechat';
import { EventName } from '../../../enum/Analytics';
import { AppSettingId } from '../../../enum/AppSettingId';
import { getRoomAssoc } from '../../../helperFunctions/PersistenceHelpers';
import { getEventData } from '../../../lib/Analytics';
import { getAppSettingValue } from '../../../lib/Settings';
import { updateRoomCustomFields } from '../../RoomCustomFieldsHelper';
import { HandleEndChatCallback } from '../SalesforceAgentAssignedHelpers/HandleEndChatCallback';
Expand All @@ -18,7 +20,7 @@ export class CheckAgentStatusCallback {
private technicalDifficultyMessage: string,
) {}

public async checkAgentStatusCallbackError(error: string) {
public async checkAgentStatusCallbackError(error: string, closeMessage: string, eventName?: EventName) {
const assoc = getRoomAssoc(this.data.room.id);

const NoLiveagentAvailableMessage: string = await getAppSettingValue(this.read, AppSettingId.NO_LIVEAGENT_AGENT_AVAILABLE_MESSAGE);
Expand All @@ -39,8 +41,10 @@ export class CheckAgentStatusCallback {
assoc,
this.technicalDifficultyMessage,
);

await handleEndChatCallback.handleEndChat();
if (eventName) {
this.modify.getAnalytics().sendEvent(getEventData(this.data.room.id, eventName));
}
await handleEndChatCallback.handleEndChat(closeMessage);
return;
}
}
Loading