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/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. diff --git a/config/Settings.ts b/config/Settings.ts index f52cb84..392ba32 100644 --- a/config/Settings.ts +++ b/config/Settings.ts @@ -11,12 +11,16 @@ export enum AppSetting { DialogflowServiceUnavailableMessage = 'dialogflow_service_unavailable_message', DialogflowCloseChatMessage = 'dialogflow_close_chat_message', DialogflowHideQuickReplies = 'dialogflow_hide_quick_replies', + 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 = [ @@ -108,4 +112,31 @@ 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, + 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..a3c64d0 --- /dev/null +++ b/handler/OnAgentAssignedHandler.ts @@ -0,0 +1,73 @@ +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 { updateRoomCustomFields } from '../lib/Room'; +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, 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); + const { value: sendWelcomeMessage } = await this.read.getEnvironmentReader().getSettings().getById(AppSetting.DialogflowEnableWelcomeMessage); + + if (!type || type !== RoomType.LIVE_CHAT) { + return; + } + + if (!isOpen || !sendWelcomeEvent) { + return; + } + + if (!servedBy || servedBy.username !== DialogflowBotUsername) { + return; + } + + if (welcomeEventSent) { + 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); + } 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..458b497 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -14,5 +14,11 @@ "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_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 event will be sent when bot is assigned to any visitor" }