new(kb.gbapp): #322 more user context for VM.

This commit is contained in:
rodrigorodriguez 2023-02-22 16:06:57 -03:00
parent 7268103831
commit 6168fd0c75
8 changed files with 68 additions and 74 deletions

View file

@ -804,11 +804,11 @@ export class DialogKeywords {
// await CollectionUtil.asyncForEach(args, async arg => { // await CollectionUtil.asyncForEach(args, async arg => {
// i++; // i++;
// list.sections[0].rows.push({ title: arg, id: `button${i}` }); // list.sections[0].rows.push({ title: arg, id: `button${i}` });
// await this.talk(arg); // await this.getTalk(arg);
// }); // });
// const button = new wpp.Buttons(Messages[locale].choices, choices, ' ', ' '); // const button = new wpp.Buttons(Messages[locale].choices, choices, ' ', ' ');
// await this.talk(button); // await this.getTalk(button);
GBLog.info(`BASIC: HEAR with [${args.toString()}] (Asking for input).`); GBLog.info(`BASIC: HEAR with [${args.toString()}] (Asking for input).`);
} else { } else {
@ -850,7 +850,7 @@ export class DialogKeywords {
const value = extractEntity(answer); const value = extractEntity(answer);
if (value === null) { if (value === null) {
await this.talk({ pid, text: 'Por favor, digite um e-mail válido.' }); await this.getTalk({ pid, text: 'Por favor, digite um e-mail válido.' });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
@ -863,7 +863,7 @@ export class DialogKeywords {
const value = extractEntity(answer); const value = extractEntity(answer);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk({ pid, text: 'Por favor, digite um nome válido.' }); await this.getTalk({ pid, text: 'Por favor, digite um nome válido.' });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
@ -876,7 +876,7 @@ export class DialogKeywords {
const value = extractEntity(answer); const value = extractEntity(answer);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk({ pid, text: 'Por favor, digite um número válido.' }); await this.getTalk({ pid, text: 'Por favor, digite um número válido.' });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
@ -891,7 +891,7 @@ export class DialogKeywords {
const value = extractEntity(answer); const value = extractEntity(answer);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk({ pid, text: 'Por favor, digite uma data no formato 12/12/2020.' }); await this.getTalk({ pid, text: 'Por favor, digite uma data no formato 12/12/2020.' });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
@ -904,7 +904,7 @@ export class DialogKeywords {
const value = extractEntity(answer); const value = extractEntity(answer);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk({ pid, text: 'Por favor, digite um horário no formato hh:ss.' }); await this.getTalk({ pid, text: 'Por favor, digite um horário no formato hh:ss.' });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
@ -923,7 +923,7 @@ export class DialogKeywords {
const value = extractEntity(answer); const value = extractEntity(answer);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk({ pid, text: 'Por favor, digite um valor monetário.' }); await this.getTalk({ pid, text: 'Por favor, digite um valor monetário.' });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
@ -935,12 +935,12 @@ export class DialogKeywords {
phoneNumber = phone(answer, { country: 'BRA' })[0]; phoneNumber = phone(answer, { country: 'BRA' })[0];
phoneNumber = phoneUtil.parse(phoneNumber); phoneNumber = phoneUtil.parse(phoneNumber);
} catch (error) { } catch (error) {
await this.talk({ pid, text: Messages[locale].validation_enter_valid_mobile }); await this.getTalk({ pid, text: Messages[locale].validation_enter_valid_mobile });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
if (!phoneUtil.isPossibleNumber(phoneNumber)) { if (!phoneUtil.isPossibleNumber(phoneNumber)) {
await this.talk({ pid, text: 'Por favor, digite um número de telefone válido.' }); await this.getTalk({ pid, text: 'Por favor, digite um número de telefone válido.' });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
@ -960,7 +960,7 @@ export class DialogKeywords {
const value = extractEntity(answer); const value = extractEntity(answer);
if (value === null || value.length != 1) { if (value === null || value.length != 1) {
await this.talk({ pid, text: 'Por favor, digite um CEP válido.' }); await this.getTalk({ pid, text: 'Por favor, digite um CEP válido.' });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
@ -975,7 +975,7 @@ export class DialogKeywords {
}); });
if (result === null) { if (result === null) {
await this.talk({ pid, text: `Escolha por favor um dos itens sugeridos.` }); await this.getTalk({ pid, text: `Escolha por favor um dos itens sugeridos.` });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
} else if (kind === 'language') { } else if (kind === 'language') {
@ -1007,7 +1007,7 @@ export class DialogKeywords {
}); });
if (result === null) { if (result === null) {
await this.talk({ pid, text: `Escolha por favor um dos itens sugeridos.` }); await this.getTalk({ pid, text: `Escolha por favor um dos itens sugeridos.` });
return await this.getHear({ pid, kind, arg }); return await this.getHear({ pid, kind, arg });
} }
} }
@ -1064,15 +1064,14 @@ export class DialogKeywords {
/** /**
* Talks to the user by using the specified text. * Talks to the user by using the specified text.
*/ */
public async talk(x) { public async getTalk({pid, text}) {
const text="",pid=0
GBLog.info(`BASIC: TALK '${text}'.`); GBLog.info(`BASIC: TALK '${text}'.`);
const { min, user } = await DialogKeywords.getProcessInfo(pid); const { min, user } = await DialogKeywords.getProcessInfo(pid);
await min.whatsAppDirectLine.sendButton();
if (user) { if (user) {
// TODO: const translate = this.user ? this.user.basicOptions.translatorOn : false; // TODO: const translate = this.user ? this.user.basicOptions.translatorOn : false;
// await min.conversationalService['sendOnConversation'](min, user, text); await min.conversationalService['sendOnConversation'](min, user, text);
} }
} }

View file

@ -47,10 +47,10 @@ import walkPromise from 'walk-promise';
import child_process from 'child_process'; import child_process from 'child_process';
import Path from 'path'; import Path from 'path';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js'; import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
import pkg from 'swagger-client';
import { DialogKeywords } from './DialogKeywords.js'; import { DialogKeywords } from './DialogKeywords.js';
import { KeywordsExpressions } from './KeywordsExpressions.js'; import { KeywordsExpressions } from './KeywordsExpressions.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js'; import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
import { GuaribasUser } from '../../security.gbapp/models/index.js';
/** /**
* @fileoverview Decision was to priorize security(isolation) and debugging, * @fileoverview Decision was to priorize security(isolation) and debugging,
@ -319,12 +319,11 @@ export class GBVMService extends GBService {
/** /**
* Executes the converted JavaScript from BASIC code inside execution context. * Executes the converted JavaScript from BASIC code inside execution context.
*/ */
public static async callVM(text: string, min: GBMinInstance, step, deployer: GBDeployer, debug: boolean) { public static async callVM(text: string, min: GBMinInstance, step, user:GuaribasUser, deployer: GBDeployer, debug: boolean = false) {
// Creates a class DialogKeywords which is the *this* pointer // Creates a class DialogKeywords which is the *this* pointer
// in BASIC. // in BASIC.
const user = step ? await min.userProfile.get(step.context, {}) : null; const dk = new DialogKeywords(min, deployer, null);
const dk = new DialogKeywords(min, deployer, user);
const sandbox = {}; const sandbox = {};
const contentLocale = min.core.getParam<string>( const contentLocale = min.core.getParam<string>(
min.instance, min.instance,

View file

@ -590,7 +590,7 @@ export class KeywordsExpressions {
if ($3.substr(0, 1) !== '"') { if ($3.substr(0, 1) !== '"') {
$3 = `"${$3}"`; $3 = `"${$3}"`;
} }
return `await dk.talk ({pid: pid, text: ${$3}})`; return `await dk.getTalk ({pid: pid, text: ${$3}})`;
} }
]; ];

View file

@ -139,7 +139,7 @@ export class ScheduleServices extends GBService {
let min: GBMinInstance = GBServer.globals.minInstances.filter( let min: GBMinInstance = GBServer.globals.minInstances.filter(
p => p.instance.instanceId === item.instanceId p => p.instance.instanceId === item.instanceId
)[0]; )[0];
await GBVMService.callVM(script, min, null, null, false); await GBVMService.callVM(script, min, null, null, null, false);
}; };
(async () => { (async () => {
await finalData(); await finalData();

View file

@ -91,11 +91,11 @@ export class SystemKeywords {
} }
public async callVM({ pid, text }) { public async callVM({ pid, text }) {
const min = null; const { min, user } = await DialogKeywords.getProcessInfo(pid);
const step = null; const step = null;
const deployer = null; const deployer = null;
return await GBVMService.callVM(text, min, step, deployer, false); return await GBVMService.callVM(text, min, step, user, deployer, false);
} }
public async append({ pid, args }) { public async append({ pid, args }) {

View file

@ -72,16 +72,14 @@ export class WelcomeDialog extends IGBDialog {
return step.replaceDialog(GBServer.globals.entryPointDialog); return step.replaceDialog(GBServer.globals.entryPointDialog);
} }
const user = await min.userProfile.get(step.context, {});
const locale = step.context.activity.locale; const locale = step.context.activity.locale;
if ( if (
!user.once && // TODO: https://github.com/GeneralBots/BotServer/issues/9 !user.once &&
step.context.activity.channelId === 'webchat' && step.context.activity.channelId === 'webchat' &&
min.core.getParam<boolean>(min.instance, 'HelloGoodX', true) === 'true' min.core.getParam<boolean>(min.instance, 'HelloGoodX', true) === 'true'
) { ) {
user.once = true; // user.once = true;
await min.userProfile.set(step.context, user);
const a = new Date(); const a = new Date();
const date = a.getHours(); const date = a.getHours();
const msg = const msg =

View file

@ -880,11 +880,7 @@ export class GBMinService {
}); });
} }
// Saves session user (persisted GuaribasUser is inside).
await min.userProfile.set(step.context, user);
} }
// Required for MSTEAMS handling of persisted conversations. // Required for MSTEAMS handling of persisted conversations.
if (step.context.activity.channelId === 'msteams') { if (step.context.activity.channelId === 'msteams') {
@ -922,7 +918,7 @@ export class GBMinService {
if (startDialog) { if (startDialog) {
await sec.setParam(userId, 'welcomed', 'true'); await sec.setParam(userId, 'welcomed', 'true');
GBLog.info(`Auto start (teams) dialog is now being called: ${startDialog} for ${min.instance.botId}...`); GBLog.info(`Auto start (teams) dialog is now being called: ${startDialog} for ${min.instance.botId}...`);
await GBVMService.callVM(startDialog.toLowerCase(), min, step, this.deployer, false); await GBVMService.callVM(startDialog.toLowerCase(), min, step, user, this.deployer, false);
} }
} }
} }
@ -968,7 +964,7 @@ export class GBMinService {
GBLog.info( GBLog.info(
`Auto start (web 1) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...` `Auto start (web 1) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`
); );
await GBVMService.callVM(startDialog.toLowerCase(), min, step, this.deployer, false); await GBVMService.callVM(startDialog.toLowerCase(), min, step, user, this.deployer, false);
} }
} }
} else { } else {
@ -982,11 +978,10 @@ export class GBMinService {
) { ) {
await sec.setParam(userId, 'welcomed', 'true'); await sec.setParam(userId, 'welcomed', 'true');
min['conversationWelcomed'][step.context.activity.conversation.id] = true; min['conversationWelcomed'][step.context.activity.conversation.id] = true;
await min.userProfile.set(step.context, user);
GBLog.info( GBLog.info(
`Auto start (whatsapp) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...` `Auto start (whatsapp) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`
); );
await GBVMService.callVM(startDialog.toLowerCase(), min, step, this.deployer, false); await GBVMService.callVM(startDialog.toLowerCase(), min, step, user, this.deployer, false);
} }
} }
} }
@ -1000,9 +995,6 @@ export class GBMinService {
await this.processEventActivity(min, user, context, step); await this.processEventActivity(min, user, context, step);
} }
// Saves conversation state for later use.
await conversationState.saveChanges(context, true);
} catch (error) { } catch (error) {
const msg = `ERROR: ${error.message} ${error.stack ? error.stack : ''}`; const msg = `ERROR: ${error.message} ${error.stack ? error.stack : ''}`;
GBLog.error(msg); GBLog.error(msg);
@ -1046,7 +1038,7 @@ export class GBMinService {
if (startDialog && !min['conversationWelcomed'][step.context.activity.conversation.id]) { if (startDialog && !min['conversationWelcomed'][step.context.activity.conversation.id]) {
user.welcomed = true; user.welcomed = true;
GBLog.info(`Auto start (web 2) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`); GBLog.info(`Auto start (web 2) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`);
await GBVMService.callVM(startDialog.toLowerCase(), min, step, this.deployer, false); await GBVMService.callVM(startDialog.toLowerCase(), min, step, user, this.deployer, false);
} }
} else if (context.activity.name === 'updateToken') { } else if (context.activity.name === 'updateToken') {
const token = context.activity.data; const token = context.activity.data;
@ -1128,6 +1120,7 @@ export class GBMinService {
const member = context.activity.from; const member = context.activity.from;
let user = await sec.ensureUser(min.instance.instanceId, member.id, member.name, '', 'web', member.name, null); let user = await sec.ensureUser(min.instance.instanceId, member.id, member.name, '', 'web', member.name, null);
const userId = user.userId; const userId = user.userId;
const params = user.params ? JSON.parse(user.params) : {}; const params = user.params ? JSON.parse(user.params) : {};
@ -1144,12 +1137,16 @@ export class GBMinService {
user.conversationId = conversation.Id; user.conversationId = conversation.Id;
} }
message = await analytics.createMessage( message = await analytics.createMessage(
min.instance.instanceId, min.instance.instanceId,
user.conversationId, user.conversationId,
userId, userId,
context.activity.text context.activity.text
); );
const conversationReference = JSON.stringify(TurnContext.getConversationReference(context.activity));
await sec.updateConversationReferenceById(userId, conversationReference);
} }
} }
@ -1197,7 +1194,7 @@ export class GBMinService {
const isVMCall = Object.keys(min.scriptMap).find(key => min.scriptMap[key] === context.activity.text) !== undefined; const isVMCall = Object.keys(min.scriptMap).find(key => min.scriptMap[key] === context.activity.text) !== undefined;
if (isVMCall) { if (isVMCall) {
await GBVMService.callVM(context.activity.text, min, step, this.deployer, false); await GBVMService.callVM(context.activity.text, min, step, user, this.deployer, false);
} else if (context.activity.text.charAt(0) === '/') { } else if (context.activity.text.charAt(0) === '/') {
const text = context.activity.text; const text = context.activity.text;
const parts = text.split(' '); const parts = text.split(' ');
@ -1207,16 +1204,13 @@ export class GBMinService {
if (cmdOrDialogName === '/start') { if (cmdOrDialogName === '/start') {
// Reset user. // Reset user.
const user = await min.userProfile.get(context, {});
await min.conversationalService.sendEvent(min, step, 'loadInstance', {}); await min.conversationalService.sendEvent(min, step, 'loadInstance', {});
user.loaded = false;
await min.userProfile.set(step.context, user);
} else if (cmdOrDialogName === '/call') { } else if (cmdOrDialogName === '/call') {
await GBVMService.callVM(args, min, step, this.deployer, false); await GBVMService.callVM(args, min, step, user, this.deployer, false);
} else if (cmdOrDialogName === '/callsch') { } else if (cmdOrDialogName === '/callsch') {
await GBVMService.callVM(args, min, null, null, false); await GBVMService.callVM(args, min, null, null, null, false);
} else if (cmdOrDialogName === '/calldbg') { } else if (cmdOrDialogName === '/calldbg') {
await GBVMService.callVM(args, min, step, this.deployer, true); await GBVMService.callVM(args, min, step, user, this.deployer, true);
} else { } else {
await step.beginDialog(cmdOrDialogName, { args: args }); await step.beginDialog(cmdOrDialogName, { args: args });
} }

View file

@ -169,7 +169,9 @@ export class AskDialog extends IGBDialog {
}, },
async step => { async step => {
let answer: GuaribasAnswer = null; let answer: GuaribasAnswer = null;
const user = await min.userProfile.get(step.context, {}); const member = step.context.activity.from;
const sec = new SecService();
let user = await sec.ensureUser(min.instance.instanceId, member.id, member.name, '', 'web', member.name, null);
const minBoot = GBServer.globals.minBoot as any; const minBoot = GBServer.globals.minBoot as any;
@ -182,7 +184,7 @@ export class AskDialog extends IGBDialog {
if (!text) { if (!text) {
const startDialog = min.core.getParam(min.instance, 'Start Dialog', null); const startDialog = min.core.getParam(min.instance, 'Start Dialog', null);
if (startDialog) { if (startDialog) {
await GBVMService.callVM(startDialog.toLowerCase().trim(), min, step, this.deployer, false); await GBVMService.callVM(startDialog.toLowerCase().trim(), min, step, user, this.deployer, false);
} }
return step.endDialog(); return step.endDialog();
@ -210,18 +212,19 @@ export class AskDialog extends IGBDialog {
min.instance.searchScore ? min.instance.searchScore : minBoot.instance.searchScore min.instance.searchScore ? min.instance.searchScore : minBoot.instance.searchScore
); );
user.lastQuestion = text; // TODO: https://github.com/GeneralBots/BotServer/issues/9 user.lastQuestion = text;
await min.userProfile.set(step.context, user); await min.userProfile.set(step.context, user);
const resultsA = await service.ask(min.instance, text, searchScore, user.subjects);
const resultsA = await service.ask(min.instance, text, searchScore, null /* user.subjects */ );
// If there is some result, answer immediately. // If there is some result, answer immediately.
if (resultsA !== undefined && resultsA.answer !== undefined) { if (resultsA !== undefined && resultsA.answer !== undefined) {
// Saves some context info. // Saves some context info.
user.isAsking = false; // user.isAsking = false;
user.lastQuestionId = resultsA.questionId; // user.lastQuestionId = resultsA.questionId;
await min.userProfile.set(step.context, user); await min.userProfile.set(step.context, user);
// Sends the answer to all outputs, including projector. // Sends the answer to all outputs, including projector.
@ -229,35 +232,36 @@ export class AskDialog extends IGBDialog {
answer = resultsA.answer; answer = resultsA.answer;
// If this search was restricted to some subjects... // If this search was restricted to some subjects...
} else if (user.subjects && user.subjects.length > 0) { }
// ...second time running Search, now with no filter. // TODO: https://github.com/GeneralBots/BotServer/issues/9
// else if (user.subjects && user.subjects.length > 0) {
// // ...second time running Search, now with no filter.
const resultsB = await service.ask(min.instance, text, searchScore, undefined); // const resultsB = await service.ask(min.instance, text, searchScore, undefined);
// If there is some result, answer immediately. // // If there is some result, answer immediately.
if (resultsB !== undefined && resultsB.answer !== undefined) { // if (resultsB !== undefined && resultsB.answer !== undefined) {
// Saves some context info. // // Saves some context info.
const user2 = await min.userProfile.get(step.context, {}); // // user2.isAsking = false;
user2.isAsking = false; // // user2.lastQuestionId = resultsB.questionId;
user2.lastQuestionId = resultsB.questionId;
await min.userProfile.set(step.context, user2);
// Informs user that a broader search will be used. // // Informs user that a broader search will be used.
if (user2.subjects.length > 0) { // if (user2.subjects.length > 0) {
await min.conversationalService.sendText(min, step, Messages[locale].wider_answer); // await min.conversationalService.sendText(min, step, Messages[locale].wider_answer);
} // }
answer = resultsB.answer; // answer = resultsB.answer;
} // }
} // }
// Try to answer by search. // Try to answer by search.
if (answer) { if (answer) {
return await AskDialog.handleAnswer(service, min, step, answer); return await AskDialog.handleAnswer(service, min, step, user, answer);
} }
// Tries to answer by NLP. // Tries to answer by NLP.
@ -322,11 +326,11 @@ export class AskDialog extends IGBDialog {
]; ];
} }
private static async handleAnswer(service: KBService, min: GBMinInstance, step: any, answer: GuaribasAnswer) { private static async handleAnswer(service: KBService, min: GBMinInstance, step: any, user, answer: GuaribasAnswer) {
const text = answer.content; const text = answer.content;
if (text.endsWith('.docx')) { if (text.endsWith('.docx')) {
const mainName = GBVMService.getMethodNameFromVBSFilename(text); const mainName = GBVMService.getMethodNameFromVBSFilename(text);
return await GBVMService.callVM(mainName, min, step, this.deployer, false); return await GBVMService.callVM(mainName, min, step, user, this.deployer, false);
} else { } else {
await service.sendAnswer(min, AskDialog.getChannel(step), step, answer); await service.sendAnswer(min, AskDialog.getChannel(step), step, answer);
return await step.replaceDialog('/ask', { isReturning: true }); return await step.replaceDialog('/ask', { isReturning: true });