From 1fedba8859fb6f2bf5a660bb98b91683a4adb3d5 Mon Sep 17 00:00:00 2001 From: shubhsherl Date: Tue, 8 Sep 2020 19:56:28 +0530 Subject: [PATCH 1/4] Add welcome event on first assignment --- DialogflowApp.ts | 14 ++++++-- config/Settings.ts | 10 ++++++ handler/OnAgentAssignedHandler.ts | 58 +++++++++++++++++++++++++++++++ i18n/en.json | 4 ++- 4 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 handler/OnAgentAssignedHandler.ts diff --git a/DialogflowApp.ts b/DialogflowApp.ts index a17b4c3..2cb7c0f 100644 --- a/DialogflowApp.ts +++ b/DialogflowApp.ts @@ -10,7 +10,7 @@ import { } from '@rocket.chat/apps-engine/definition/accessors'; import { ApiSecurity, ApiVisibility } from '@rocket.chat/apps-engine/definition/api'; import { App } from '@rocket.chat/apps-engine/definition/App'; -import { ILivechatMessage } from '@rocket.chat/apps-engine/definition/livechat'; +import { ILivechatMessage, ILivechatEventContext, IPostLivechatAgentAssigned } from '@rocket.chat/apps-engine/definition/livechat'; import { IPostMessageSent } from '@rocket.chat/apps-engine/definition/messages'; import { IAppInfo } from '@rocket.chat/apps-engine/definition/metadata'; import { ISetting } from '@rocket.chat/apps-engine/definition/settings'; @@ -20,9 +20,10 @@ import { FulfillmentsEndpoint } from './endpoints/FulfillmentsEndpoint'; import { IncomingEndpoint } from './endpoints/IncomingEndpoint'; import { ExecuteLivechatBlockActionHandler } from './handler/ExecuteLivechatBlockActionHandler'; import { OnSettingUpdatedHandler } from './handler/OnSettingUpdatedHandler'; +import { OnAgentAssignedHandler } from './handler/OnAgentAssignedHandler'; import { PostMessageSentHandler } from './handler/PostMessageSentHandler'; -export class DialogflowApp extends App implements IPostMessageSent, IUIKitLivechatInteractionHandler { +export class DialogflowApp extends App implements IPostMessageSent, IPostLivechatAgentAssigned, IUIKitLivechatInteractionHandler { constructor(info: IAppInfo, logger: ILogger, accessors: IAppAccessors) { super(info, logger, accessors); } @@ -45,6 +46,15 @@ export class DialogflowApp extends App implements IPostMessageSent, IUIKitLivech await handler.run(); } + public async executePostLivechatAgentAssigned(context: ILivechatEventContext, + read: IRead, + http: IHttp, + persis: IPersistence, + modify: IModify): Promise { + const handler = new OnAgentAssignedHandler(this, context, read, http, persis, modify); + await handler.run(); + } + public async onSettingUpdated(setting: ISetting, configurationModify: IConfigurationModify, read: IRead, http: IHttp): Promise { const onSettingUpdatedHandler: OnSettingUpdatedHandler = new OnSettingUpdatedHandler(this, read, http); await onSettingUpdatedHandler.run(); diff --git a/config/Settings.ts b/config/Settings.ts index f52cb84..7e52711 100644 --- a/config/Settings.ts +++ b/config/Settings.ts @@ -11,6 +11,7 @@ export enum AppSetting { DialogflowServiceUnavailableMessage = 'dialogflow_service_unavailable_message', DialogflowCloseChatMessage = 'dialogflow_close_chat_message', DialogflowHideQuickReplies = 'dialogflow_hide_quick_replies', + DialogflowWelcomeIntentOnStart = 'dialogflow_welcome_intent_on_start' } export enum DefaultMessage { @@ -108,4 +109,13 @@ export const settings: Array = [ i18nDescription: 'dialogflow_hide_quick_replies_description', required: true, }, + { + id: AppSetting.DialogflowWelcomeIntentOnStart, + public: true, + type: SettingType.BOOLEAN, + packageValue: false, + i18nLabel: 'dialogflow_welcome_intent_on_start', + i18nDescription: 'dialogflow_welcome_intent_on_start_description', + required: true, + }, ]; diff --git a/handler/OnAgentAssignedHandler.ts b/handler/OnAgentAssignedHandler.ts new file mode 100644 index 0000000..3b75189 --- /dev/null +++ b/handler/OnAgentAssignedHandler.ts @@ -0,0 +1,58 @@ +import { IHttp, IModify, IPersistence, IRead } from '@rocket.chat/apps-engine/definition/accessors'; +import { IApp } from '@rocket.chat/apps-engine/definition/IApp'; +import { ILivechatEventContext, ILivechatRoom } from '@rocket.chat/apps-engine/definition/livechat'; +import { RoomType } from '@rocket.chat/apps-engine/definition/rooms'; +import { AppSetting, DefaultMessage } from '../config/Settings'; +import { DialogflowRequestType, IDialogflowMessage } from '../enum/Dialogflow'; +import { Logs } from '../enum/Logs'; +import { Dialogflow } from '../lib/Dialogflow'; +import { createDialogflowMessage, createMessage } from '../lib/Message'; +import { getAppSettingValue } from '../lib/Settings'; + +export class OnAgentAssignedHandler { + constructor(private readonly app: IApp, + private readonly context: ILivechatEventContext, + private readonly read: IRead, + private readonly http: IHttp, + private readonly persis: IPersistence, + private readonly modify: IModify) {} + + public async run() { + const { room } = this.context; + const livechatRoom = room as ILivechatRoom; + + const { id: rid, type, servedBy, isOpen } = livechatRoom; + + const DialogflowBotUsername: string = await getAppSettingValue(this.read, AppSetting.DialogflowBotUsername); + const { value: sendWelcomeEvent } = await this.read.getEnvironmentReader().getSettings().getById(AppSetting.DialogflowWelcomeIntentOnStart); + + if (!type || type !== RoomType.LIVE_CHAT) { + return; + } + + if (!isOpen || !sendWelcomeEvent) { + return; + } + + if (!servedBy || servedBy.username !== DialogflowBotUsername) { + return; + } + + try { + const event = { name: "Welcome", languageCode: "en" }; + const response: IDialogflowMessage = await Dialogflow.sendRequest(this.http, this.read, this.modify, rid, event, DialogflowRequestType.EVENT); + await createDialogflowMessage(rid, this.read, this.modify, response); + } catch (error) { + this.app.getLogger().error(`${Logs.DIALOGFLOW_REST_API_ERROR} ${error.message}`); + + const serviceUnavailable: string = await getAppSettingValue(this.read, AppSetting.DialogflowServiceUnavailableMessage); + + await createMessage(rid, + this.read, + this.modify, + { text: serviceUnavailable ? serviceUnavailable : DefaultMessage.DEFAULT_DialogflowServiceUnavailableMessage }); + + return; + } + } +} diff --git a/i18n/en.json b/i18n/en.json index fa36e66..916a938 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -14,5 +14,7 @@ "dialogflow_close_chat_message": "Close Chat Message", "dialogflow_close_chat_message_description": "This message will be sent automatically when a chat is closed", "dialogflow_hide_quick_replies": "Hide Quick Replies", - "dialogflow_hide_quick_replies_description": "If enabled, then all quick-replies will hide when a visitor clicks on any one of them" + "dialogflow_hide_quick_replies_description": "If enabled, then all quick-replies will hide when a visitor clicks on any one of them", + "dialogflow_welcome_intent_on_start": "Send Welcome Intent", + "dialogflow_welcome_intent_on_start_description": "If enabled, then a welcome message will be sent when bot is assigned to any visitor" } From 7c4e96e533bce2e8b46460596b0afcda2d1ca314 Mon Sep 17 00:00:00 2001 From: Shubham Singh Date: Thu, 10 Sep 2020 11:38:50 +0530 Subject: [PATCH 2/4] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 70c8731..ea09b44 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ You can find all these credentials in a JSON file, which u can get from [here](h - This message will be sent automatically when a chat is closed 10. Hide Quick Replies (required) - If enabled, then all quick-replies will hide when a visitor clicks on any one of them + 11. Send Welcome Intent (required) + - If enabled, then a welcome event will be sent to bot, when the bot is assigned to any visitor 4. (Optional Step) Lastly you can test your Dialogflow Connection by viewing App Logs. To view the logs, goto App Page (`Setting > Apps > Dialogflow`). There click on menu item (3 vertical dots icon) and then select `View Logs`. There select the **most recent** `onSettingUpdated` title. If you see `------------------ Google Credentials validation Success ----------------` message, then it means your setup is fine. If you don't see this message, then recheck your Dialogflow credentials. From 267ba0f163a73fa6e1f208dc14035328eafbc4fd Mon Sep 17 00:00:00 2001 From: shubhsherl Date: Mon, 14 Sep 2020 12:36:27 +0530 Subject: [PATCH 3/4] Fix welcome event for a session --- handler/OnAgentAssignedHandler.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/handler/OnAgentAssignedHandler.ts b/handler/OnAgentAssignedHandler.ts index 3b75189..8c954d8 100644 --- a/handler/OnAgentAssignedHandler.ts +++ b/handler/OnAgentAssignedHandler.ts @@ -7,6 +7,7 @@ import { DialogflowRequestType, IDialogflowMessage } from '../enum/Dialogflow'; import { Logs } from '../enum/Logs'; import { Dialogflow } from '../lib/Dialogflow'; import { createDialogflowMessage, createMessage } from '../lib/Message'; +import { updateRoomCustomFields } from '../lib/Room'; import { getAppSettingValue } from '../lib/Settings'; export class OnAgentAssignedHandler { @@ -21,7 +22,8 @@ export class OnAgentAssignedHandler { const { room } = this.context; const livechatRoom = room as ILivechatRoom; - const { id: rid, type, servedBy, isOpen } = livechatRoom; + const { id: rid, type, servedBy, isOpen, customFields = {} } = livechatRoom; + const { welcomeEventSent = false } = customFields; const DialogflowBotUsername: string = await getAppSettingValue(this.read, AppSetting.DialogflowBotUsername); const { value: sendWelcomeEvent } = await this.read.getEnvironmentReader().getSettings().getById(AppSetting.DialogflowWelcomeIntentOnStart); @@ -38,10 +40,16 @@ export class OnAgentAssignedHandler { return; } + if (welcomeEventSent) { + return; + } + try { const event = { name: "Welcome", languageCode: "en" }; const response: IDialogflowMessage = await Dialogflow.sendRequest(this.http, this.read, this.modify, rid, event, DialogflowRequestType.EVENT); + await createDialogflowMessage(rid, this.read, this.modify, response); + await updateRoomCustomFields(rid, { welcomeEventSent: true }, this.read, this.modify); } catch (error) { this.app.getLogger().error(`${Logs.DIALOGFLOW_REST_API_ERROR} ${error.message}`); From b76f4328f5b8c57c4643479e9d34fabb863d5884 Mon Sep 17 00:00:00 2001 From: shubhsherl Date: Thu, 24 Sep 2020 18:20:06 +0530 Subject: [PATCH 4/4] Add custom welcome message --- config/Settings.ts | 23 ++++++++++++++++++++++- handler/OnAgentAssignedHandler.ts | 9 ++++++++- i18n/en.json | 6 +++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/config/Settings.ts b/config/Settings.ts index 7e52711..392ba32 100644 --- a/config/Settings.ts +++ b/config/Settings.ts @@ -11,13 +11,16 @@ export enum AppSetting { DialogflowServiceUnavailableMessage = 'dialogflow_service_unavailable_message', DialogflowCloseChatMessage = 'dialogflow_close_chat_message', DialogflowHideQuickReplies = 'dialogflow_hide_quick_replies', - DialogflowWelcomeIntentOnStart = 'dialogflow_welcome_intent_on_start' + DialogflowEnableWelcomeMessage = 'dialogflow_enable_welcome_message', + DialogflowWelcomeMessage = 'dialogflow_welcome_message', + DialogflowWelcomeIntentOnStart = 'dialogflow_welcome_intent_on_start', } export enum DefaultMessage { DEFAULT_DialogflowServiceUnavailableMessage = 'Sorry, I\'m having trouble answering your question.', DEFAULT_DialogflowHandoverMessage = 'Transferring to an online agent', DEFAULT_DialogflowCloseChatMessage = 'Closing the chat, Goodbye', + DEFAULT_DialogflowWelcomeMessage = 'Thanks for connecting', } export const settings: Array = [ @@ -109,6 +112,24 @@ export const settings: Array = [ i18nDescription: 'dialogflow_hide_quick_replies_description', required: true, }, + { + id: AppSetting.DialogflowEnableWelcomeMessage, + public: true, + type: SettingType.BOOLEAN, + packageValue: false, + i18nLabel: 'dialogflow_enable_welcome_message', + i18nDescription: 'dialogflow_enable_welcome_message_description', + required: false, + }, + { + id: AppSetting.DialogflowWelcomeMessage, + public: true, + type: SettingType.STRING, + packageValue: DefaultMessage.DEFAULT_DialogflowWelcomeMessage, + i18nLabel: 'dialogflow_welcome_message', + i18nDescription: 'dialogflow_welcome_message_description', + required: false, + }, { id: AppSetting.DialogflowWelcomeIntentOnStart, public: true, diff --git a/handler/OnAgentAssignedHandler.ts b/handler/OnAgentAssignedHandler.ts index 8c954d8..a3c64d0 100644 --- a/handler/OnAgentAssignedHandler.ts +++ b/handler/OnAgentAssignedHandler.ts @@ -27,6 +27,7 @@ export class OnAgentAssignedHandler { const DialogflowBotUsername: string = await getAppSettingValue(this.read, AppSetting.DialogflowBotUsername); const { value: sendWelcomeEvent } = await this.read.getEnvironmentReader().getSettings().getById(AppSetting.DialogflowWelcomeIntentOnStart); + const { value: sendWelcomeMessage } = await this.read.getEnvironmentReader().getSettings().getById(AppSetting.DialogflowEnableWelcomeMessage); if (!type || type !== RoomType.LIVE_CHAT) { return; @@ -44,12 +45,18 @@ export class OnAgentAssignedHandler { return; } + if (sendWelcomeMessage) { + const welcomeMessage: string = await getAppSettingValue(this.read, AppSetting.DialogflowWelcomeMessage); + await createMessage(rid, this.read, this.modify, { text: welcomeMessage || DefaultMessage.DEFAULT_DialogflowWelcomeMessage }); + } + + await updateRoomCustomFields(rid, { welcomeEventSent: true }, this.read, this.modify); + try { const event = { name: "Welcome", languageCode: "en" }; const response: IDialogflowMessage = await Dialogflow.sendRequest(this.http, this.read, this.modify, rid, event, DialogflowRequestType.EVENT); await createDialogflowMessage(rid, this.read, this.modify, response); - await updateRoomCustomFields(rid, { welcomeEventSent: true }, this.read, this.modify); } catch (error) { this.app.getLogger().error(`${Logs.DIALOGFLOW_REST_API_ERROR} ${error.message}`); diff --git a/i18n/en.json b/i18n/en.json index 916a938..458b497 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -15,6 +15,10 @@ "dialogflow_close_chat_message_description": "This message will be sent automatically when a chat is closed", "dialogflow_hide_quick_replies": "Hide Quick Replies", "dialogflow_hide_quick_replies_description": "If enabled, then all quick-replies will hide when a visitor clicks on any one of them", + "dialogflow_enable_welcome_message": "Enable Custom Welcome Message", + "dialogflow_enable_welcome_message_description": "If enabled, then a custom welcome message will be sent when bot is assigned to any visitor", + "dialogflow_welcome_message": "Dialogflow Message to send on start", + "dialogflow_welcome_message_description": "Custom welcome message to send to visitor", "dialogflow_welcome_intent_on_start": "Send Welcome Intent", - "dialogflow_welcome_intent_on_start_description": "If enabled, then a welcome message will be sent when bot is assigned to any visitor" + "dialogflow_welcome_intent_on_start_description": "If enabled, then a welcome event will be sent when bot is assigned to any visitor" }