Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
087f3f8
Fixed messages and added sns events for close cases after escalation.
AlexanderKanakis Sep 14, 2022
1952726
Additonal close case messages and events
AlexanderKanakis Sep 23, 2022
919cd3f
minor fix
AlexanderKanakis Sep 23, 2022
65fb208
Added close chat message for livechat user
AlexanderKanakis Sep 23, 2022
97f929f
Minor fix on 'CHAT_CLOSED_BY_UNDEFINED_REASON' event
AlexanderKanakis Sep 23, 2022
9d7adaf
Minor fix on 'CHAT_CLOSED_BY_UNDEFINED_REASON' event
AlexanderKanakis Sep 23, 2022
8bc3541
Fix syntax error in analytics event
AlexanderKanakis Sep 27, 2022
5180e92
Created more detailed event names
AlexanderKanakis Sep 29, 2022
adf04a0
Minor fix for unused parameter in function 'get' of 'AvailabilityEndp…
AlexanderKanakis Sep 29, 2022
9940213
Send events from inside 'handleEndChat function'
AlexanderKanakis Sep 29, 2022
7ca7da3
Ensure we don't send event in the case chat is closed by client
AlexanderKanakis Oct 4, 2022
007ac9c
Added event cases
AlexanderKanakis Oct 5, 2022
ed43262
Merge branch 'master' into escalation_on_close_message_fix
AlexanderKanakis Oct 5, 2022
6444101
Added event cases for Agent Status Callback Errors
AlexanderKanakis Oct 5, 2022
2a8046d
Fix Lint
AlexanderKanakis Oct 5, 2022
7db606f
Minor fixes
AlexanderKanakis Oct 6, 2022
21d26ce
Merge branch 'send_independent_close_chat_message' into escalation_on…
AlexanderKanakis Oct 10, 2022
fc1d122
Give correct message on chatEndedReason === unavailable
AlexanderKanakis Oct 10, 2022
a695f87
Fix minor issues
AlexanderKanakis Oct 10, 2022
864b6c0
Better names for events and closed chat messages
AlexanderKanakis Oct 11, 2022
5cdf3e1
Event fixes
AlexanderKanakis Oct 11, 2022
78da510
Removed client messages for chat closed room description
AlexanderKanakis Oct 13, 2022
3ac7c4a
Revert "Removed client messages for chat closed room description"
AlexanderKanakis Oct 13, 2022
4520dd8
-Untangle end chat client messages from close chat reasons for Admin UI
AlexanderKanakis Oct 13, 2022
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
48 changes: 40 additions & 8 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 @@ -192,7 +196,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 +213,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 +230,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 +247,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 +284,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 +301,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 +318,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