From d6f8574ecbf921a2cf63443dea0ceeeb0a520c73 Mon Sep 17 00:00:00 2001 From: Rodrigo Rodriguez Date: Tue, 26 Apr 2022 15:13:19 -0300 Subject: [PATCH] fix(all): MSTeams fixes. --- .../services/GBConversationalService.ts | 3 +- packages/core.gbapp/services/GBMinService.ts | 9 +- .../dialogs/FeedbackDialog.ts | 445 +++++++++--------- packages/kb.gbapp/dialogs/AskDialog.ts | 6 +- .../security.gbapp/services/SecService.ts | 22 +- 5 files changed, 250 insertions(+), 235 deletions(-) diff --git a/packages/core.gbapp/services/GBConversationalService.ts b/packages/core.gbapp/services/GBConversationalService.ts index b859cfc0..35ccf1a8 100644 --- a/packages/core.gbapp/services/GBConversationalService.ts +++ b/packages/core.gbapp/services/GBConversationalService.ts @@ -255,7 +255,8 @@ export class GBConversationalService { } public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise { - if (!this.userMobile(step)) { + if (!this.userMobile(step) && + step.context.activity.channelId !== 'msteams') { GBLog.info(`Sending event ${name}:${typeof value === 'object' ? JSON.stringify(value) : value ? value : ''} to client...`); const msg = MessageFactory.text(''); diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index 2f0bfec9..6cd7d09f 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -163,7 +163,7 @@ export class GBMinService { setTimeout(resolve, ms); }); }; - await sleep(10000); + await sleep(20000); res.status(200); res.end(); }); @@ -889,8 +889,9 @@ export class GBMinService { const sec = new SecService(); if (!user.loaded) { - - await min.conversationalService.sendEvent(min, step, 'loadInstance', {}); + if (step.context.activity.channelId !== 'msteams') { + await min.conversationalService.sendEvent(min, step, 'loadInstance', {}); + } user.loaded = true; user.subjects = []; @@ -925,12 +926,14 @@ export class GBMinService { } + if (step.context.activity.channelId !== 'msteams') { const service = new KBService(min.core.sequelize); const data = await service.getFaqBySubjectArray(instance.instanceId, 'faq', undefined); await min.conversationalService.sendEvent(min, step, 'play', { playerType: 'bullet', data: data.slice(0, 10) }); + } // Saves session user (persisted GuaribasUser is inside). diff --git a/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts b/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts index 47425d08..171b6f82 100644 --- a/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts +++ b/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts @@ -34,227 +34,228 @@ * @fileoverview General Bots server core. */ -'use strict'; + 'use strict'; -import { BotAdapter } from 'botbuilder'; -import { WaterfallDialog } from 'botbuilder-dialogs'; -import { GBMinInstance, IGBDialog } from 'botlib'; -import { GBMinService } from '../../core.gbapp/services/GBMinService'; -import { AnalyticsService } from '../../analytics.gblib/services/AnalyticsService'; -import { SecService } from '../../security.gbapp/services/SecService'; -import { CSService } from '../services/CSService'; -import { Messages } from '../strings'; - -/** - * Dialog for feedback collecting. - */ -export class FeedbackDialog extends IGBDialog { - /** - * Setup dialogs flows and define services call. - * - * @param bot The bot adapter. - * @param min The minimal bot instance data. - */ - public static setup(bot: BotAdapter, min: GBMinInstance) { - const service = new CSService(); - - min.dialogs.add( - new WaterfallDialog('/pleaseNoBadWords', [ - async step => { - const locale = step.context.activity.locale; - await min.conversationalService.sendText(min, step, Messages[locale].please_no_bad_words); - - return await step.next(); - } - ]) - ); - - min.dialogs.add( - new WaterfallDialog('/t', [ - async step => { - if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { - return await step.beginDialog('/auth'); - } - else{ - return await step.next(step.options); - } - }, - async step => { - - const locale = step.context.activity.locale; - - const sec = new SecService(); - let from = GBMinService.userMobile(step); - - await min.conversationalService.sendText(min, step, Messages[locale].please_wait_transfering); - const agentSystemId = await sec.assignHumanAgent(from, min.instance.instanceId); - - const user = await min.userProfile.get(step.context, {}); - user.systemUser = await sec.getUserFromAgentSystemId(agentSystemId); - await min.userProfile.set(step.context, user); - - if (agentSystemId.charAt(2) === ":" || agentSystemId.indexOf("@") > -1) { // Agent is from Teams or Google Chat. - const agent = await sec.getUserFromSystemId(agentSystemId); - await min.conversationalService['sendOnConversation'](min, agent, - Messages[locale].notify_agent(step.context.activity.from.name)); - - } - else { - await min.whatsAppDirectLine.sendToDevice(agentSystemId, Messages[locale].notify_agent(step.context.activity.from.name)); - - } - return await step.next(); - } - ]) - ); - - min.dialogs.add( - new WaterfallDialog('/qt', [ - async step => { - if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { - return await step.beginDialog('/auth'); - } - else{ - return await step.next(step.options); - } - }, - async step => { - - const locale = step.context.activity.locale; - - const sec = new SecService(); - const userSystemId = GBMinService.userMobile(step); - const user = await min.userProfile.get(step.context, {}); - - if (user.systemUser.agentMode === 'self') { - const manualUser = await sec.getUserFromAgentSystemId(userSystemId); - - await min.whatsAppDirectLine.sendToDeviceEx(manualUser.userSystemId, - Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id); - - if (userSystemId.charAt(2) === ":" || userSystemId.indexOf('@') > -1) { // Agent is from Teams or Google Chat. - await min.conversationalService.sendText(min, step, Messages[locale].notify_end_transfer(min.instance.botId)); - } - else { - await min.whatsAppDirectLine.sendToDeviceEx(userSystemId, - Messages[locale].notify_end_transfer(min.instance.botId), locale - , step.context.activity.conversation.id); - } - - await sec.updateHumanAgent(userSystemId, min.instance.instanceId, null); - await sec.updateHumanAgent(manualUser.userSystemId, min.instance.instanceId, null); - - user.systemUser = await sec.getUserFromSystemId(userSystemId); - await min.userProfile.set(step.context, user); + import { BotAdapter } from 'botbuilder'; + import { WaterfallDialog } from 'botbuilder-dialogs'; + import { GBMinInstance, IGBDialog } from 'botlib'; + import { GBMinService } from '../../core.gbapp/services/GBMinService'; + import { AnalyticsService } from '../../analytics.gblib/services/AnalyticsService'; + import { SecService } from '../../security.gbapp/services/SecService'; + import { CSService } from '../services/CSService'; + import { Messages } from '../strings'; - } - - else if (user.systemUser.agentMode === 'human') { - const agent = await sec.getUserFromSystemId(user.systemUser.agentSystemId); - - await min.whatsAppDirectLine.sendToDeviceEx(user.systemUser.userSystemId, - Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id); - - - if (user.systemUser.agentSystemId.charAt(2) === ":" || userSystemId.indexOf('@') > -1) { // Agent is from Teams or Google Chat. - await min.conversationalService.sendText(min, step, Messages[locale].notify_end_transfer(min.instance.botId)); - } - else { - await min.whatsAppDirectLine.sendToDeviceEx(user.systemUser.agentSystemId, - Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id); - } - - await sec.updateHumanAgent(user.systemUser.userSystemId, min.instance.instanceId, null); - await sec.updateHumanAgent(agent.userSystemId, min.instance.instanceId, null); - - user.systemUser = await sec.getUserFromSystemId(userSystemId); - await min.userProfile.set(step.context, user); - - } - else - { - if (user.systemUser.userSystemId.charAt(2) === ":" || userSystemId.indexOf('@') > -1) { // Agent is from Teams or Google Chat. - await min.conversationalService.sendText(min, step, 'Nenhum atendimento em andamento.'); - } - else { - await min.whatsAppDirectLine.sendToDeviceEx(user.systemUser.userSystemId, - 'Nenhum atendimento em andamento.', locale, step.context.activity.conversation.id); - } - } - - return await step.next(); - } - ]) - ); - - min.dialogs.add( - new WaterfallDialog('/feedbackNumber', [ - async step => { - if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { - return await step.beginDialog('/auth'); - } - else{ - return await step.next(step.options); - } - }, - async step => { - const locale = step.context.activity.locale; - - return await step.next(); - }, - async step => { - const locale = step.context.activity.locale; - const rate = step.result.entity; - const user = await min.userProfile.get(step.context, {}); - await service.updateConversationRate(user.conversation, rate); - await min.conversationalService.sendText(min, step, Messages[locale].thanks); - - return await step.next(); - } - ]) - ); - - min.dialogs.add( - new WaterfallDialog('/feedback', [ - async step => { - if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { - return await step.beginDialog('/auth'); - } - else{ - return await step.next(step.options); - } - }, - async step => { - const locale = step.context.activity.locale; - - await min.conversationalService.sendText(min, step, Messages[locale].about_suggestions); - step.activeDialog.state.cbId = (step.options as any).id; - - return await min.conversationalService.prompt(min, step, Messages[locale].what_about_service); - }, - async step => { - const fixedLocale = 'en-US'; - const user = await min.userProfile.get(step.context, {}); - - // Updates values to perform Bot Analytics. - - const analytics = new AnalyticsService(); - const rate = await analytics.updateConversationSuggestion( - min.instance.instanceId, user.conversation.conversationId, step.result, user.systemUser.locale); - - if (rate > 0.5) { - await min.conversationalService.sendText(min, step, Messages[fixedLocale].glad_you_liked); - } else { - - const message = min.core.getParam(min.instance, 'Feedback Improve Message', - Messages[fixedLocale].we_will_improve); // TODO: Improve to be multi-language. - - await min.conversationalService.sendText(min, step, message); - } - - return await step.replaceDialog('/ask', { isReturning: true }); - } - ]) - ); - } -} + /** + * Dialog for feedback collecting. + */ + export class FeedbackDialog extends IGBDialog { + /** + * Setup dialogs flows and define services call. + * + * @param bot The bot adapter. + * @param min The minimal bot instance data. + */ + public static setup(bot: BotAdapter, min: GBMinInstance) { + const service = new CSService(); + + min.dialogs.add( + new WaterfallDialog('/pleaseNoBadWords', [ + async step => { + const locale = step.context.activity.locale; + await min.conversationalService.sendText(min, step, Messages[locale].please_no_bad_words); + + return await step.next(); + } + ]) + ); + + min.dialogs.add( + new WaterfallDialog('/t', [ + async step => { + if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { + return await step.beginDialog('/auth'); + } + else{ + return await step.next(step.options); + } + }, + async step => { + + const locale = step.context.activity.locale; + + const sec = new SecService(); + let from = GBMinService.userMobile(step); + + await min.conversationalService.sendText(min, step, Messages[locale].please_wait_transfering); + const agentSystemId = await sec.assignHumanAgent(min, from); + + const user = await min.userProfile.get(step.context, {}); + user.systemUser = await sec.getUserFromAgentSystemId(agentSystemId); + await min.userProfile.set(step.context, user); + + if (agentSystemId.charAt(2) === ":" || agentSystemId.indexOf("@") > -1) { // Agent is from Teams or Google Chat. + const agent = await sec.getUserFromSystemId(agentSystemId); + await min.conversationalService['sendOnConversation'](min, agent, + Messages[locale].notify_agent(step.context.activity.from.name)); + + } + else { + await min.whatsAppDirectLine.sendToDevice(agentSystemId, Messages[locale].notify_agent(step.context.activity.from.name)); + + } + return await step.next(); + } + ]) + ); + + min.dialogs.add( + new WaterfallDialog('/qt', [ + async step => { + if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { + return await step.beginDialog('/auth'); + } + else{ + return await step.next(step.options); + } + }, + async step => { + + const locale = step.context.activity.locale; + + const sec = new SecService(); + const userSystemId = GBMinService.userMobile(step); + const user = await min.userProfile.get(step.context, {}); + + if (user.systemUser.agentMode === 'self') { + const manualUser = await sec.getUserFromAgentSystemId(userSystemId); + + await min.whatsAppDirectLine.sendToDeviceEx(manualUser.userSystemId, + Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id); + + if (userSystemId.charAt(2) === ":" || userSystemId.indexOf('@') > -1) { // Agent is from Teams or Google Chat. + await min.conversationalService.sendText(min, step, Messages[locale].notify_end_transfer(min.instance.botId)); + } + else { + await min.whatsAppDirectLine.sendToDeviceEx(userSystemId, + Messages[locale].notify_end_transfer(min.instance.botId), locale + , step.context.activity.conversation.id); + } + + await sec.updateHumanAgent(userSystemId, min.instance.instanceId, null); + await sec.updateHumanAgent(manualUser.userSystemId, min.instance.instanceId, null); + + user.systemUser = await sec.getUserFromSystemId(userSystemId); + await min.userProfile.set(step.context, user); + + } + + else if (user.systemUser.agentMode === 'human') { + const agent = await sec.getUserFromSystemId(user.systemUser.agentSystemId); + + await min.whatsAppDirectLine.sendToDeviceEx(user.systemUser.userSystemId, + Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id); + + + if (user.systemUser.agentSystemId.charAt(2) === ":" || userSystemId.indexOf('@') > -1) { // Agent is from Teams or Google Chat. + await min.conversationalService.sendText(min, step, Messages[locale].notify_end_transfer(min.instance.botId)); + } + else { + await min.whatsAppDirectLine.sendToDeviceEx(user.systemUser.agentSystemId, + Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id); + } + + await sec.updateHumanAgent(user.systemUser.userSystemId, min.instance.instanceId, null); + await sec.updateHumanAgent(agent.userSystemId, min.instance.instanceId, null); + + user.systemUser = await sec.getUserFromSystemId(userSystemId); + await min.userProfile.set(step.context, user); + + } + else + { + if (user.systemUser.userSystemId.charAt(2) === ":" || userSystemId.indexOf('@') > -1) { // Agent is from Teams or Google Chat. + await min.conversationalService.sendText(min, step, 'Nenhum atendimento em andamento.'); + } + else { + await min.whatsAppDirectLine.sendToDeviceEx(user.systemUser.userSystemId, + 'Nenhum atendimento em andamento.', locale, step.context.activity.conversation.id); + } + } + + return await step.next(); + } + ]) + ); + + min.dialogs.add( + new WaterfallDialog('/feedbackNumber', [ + async step => { + if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { + return await step.beginDialog('/auth'); + } + else{ + return await step.next(step.options); + } + }, + async step => { + const locale = step.context.activity.locale; + + return await step.next(); + }, + async step => { + const locale = step.context.activity.locale; + const rate = step.result.entity; + const user = await min.userProfile.get(step.context, {}); + await service.updateConversationRate(user.conversation, rate); + await min.conversationalService.sendText(min, step, Messages[locale].thanks); + + return await step.next(); + } + ]) + ); + + min.dialogs.add( + new WaterfallDialog('/feedback', [ + async step => { + if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { + return await step.beginDialog('/auth'); + } + else{ + return await step.next(step.options); + } + }, + async step => { + const locale = step.context.activity.locale; + + await min.conversationalService.sendText(min, step, Messages[locale].about_suggestions); + step.activeDialog.state.cbId = (step.options as any).id; + + return await min.conversationalService.prompt(min, step, Messages[locale].what_about_service); + }, + async step => { + const fixedLocale = 'en-US'; + const user = await min.userProfile.get(step.context, {}); + + // Updates values to perform Bot Analytics. + + const analytics = new AnalyticsService(); + const rate = await analytics.updateConversationSuggestion( + min.instance.instanceId, user.conversation.conversationId, step.result, user.systemUser.locale); + + if (rate > 0.5) { + await min.conversationalService.sendText(min, step, Messages[fixedLocale].glad_you_liked); + } else { + + const message = min.core.getParam(min.instance, 'Feedback Improve Message', + Messages[fixedLocale].we_will_improve); // TODO: Improve to be multi-language. + + await min.conversationalService.sendText(min, step, message); + } + + return await step.replaceDialog('/ask', { isReturning: true }); + } + ]) + ); + } + } + \ No newline at end of file diff --git a/packages/kb.gbapp/dialogs/AskDialog.ts b/packages/kb.gbapp/dialogs/AskDialog.ts index e114facd..c353a6c4 100644 --- a/packages/kb.gbapp/dialogs/AskDialog.ts +++ b/packages/kb.gbapp/dialogs/AskDialog.ts @@ -188,9 +188,9 @@ export class AskDialog extends IGBDialog { const locale = step.context.activity.locale; // Stops any content on projector. - - await min.conversationalService.sendEvent(min, step, 'stop', undefined); - + if (step.context.activity.channelId !== 'msteams') { + await min.conversationalService.sendEvent(min, step, 'stop', undefined); + } // Handle extra text from FAQ. if (step.options && step.options.query) { diff --git a/packages/security.gbapp/services/SecService.ts b/packages/security.gbapp/services/SecService.ts index 435d2c72..1dc47568 100644 --- a/packages/security.gbapp/services/SecService.ts +++ b/packages/security.gbapp/services/SecService.ts @@ -2,7 +2,7 @@ const Fs = require('fs'); const urlJoin = require('url-join'); import { ConversationReference } from 'botbuilder'; -import { GBLog, GBService, IGBInstance } from 'botlib'; +import { GBLog, GBMinInstance, GBService, IGBInstance } from 'botlib'; import { CollectionUtil } from 'pragmatismo-io-framework'; import { GuaribasGroup, GuaribasUser, GuaribasUserGroup } from '../models'; import {FindOptions} from 'sequelize'; @@ -167,21 +167,31 @@ export class SecService extends GBService { return user.agentMode === 'self'; } - public async assignHumanAgent(userSystemId: string, instanceId: number): Promise { + public async assignHumanAgent(min: GBMinInstance, userSystemId: string): Promise { let agentSystemId; - const list = process.env.TRANSFER_TO.split(';'); + + let list = min.core.getParam( + min.instance, + 'Transfer To', + process.env.TRANSFER_TO + ); + + if (list){ + list = list.split(';') + } + await CollectionUtil.asyncForEach(list, async item => { if ( - !(item !== undefined && + item !== undefined && agentSystemId === undefined && - item !== userSystemId && await this.isAgentSystemId(item)) + item !== userSystemId && !await this.isAgentSystemId(item) ) { // TODO: Optimize loop. agentSystemId = item; } }); GBLog.info(`Selected agentId: ${agentSystemId}`); - await this.updateHumanAgent(userSystemId, instanceId, agentSystemId); + await this.updateHumanAgent(userSystemId, min.instance.instanceId, agentSystemId); GBLog.info(`Updated agentId to: ${agentSystemId}`); return agentSystemId;