fix(core.gbapp): New HEAR possibilities coded.
This commit is contained in:
parent
ae31e4f9aa
commit
797af37b81
6 changed files with 129 additions and 27 deletions
|
@ -59,4 +59,11 @@ ALTER TABLE dbo.GuaribasPackage ADD
|
||||||
params custom(512) NULL
|
params custom(512) NULL
|
||||||
GO
|
GO
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# 2.0.56
|
||||||
|
|
||||||
|
ALTER TABLE dbo.GuaribasUser ADD
|
||||||
|
hearOnDialog nvarchar(64) NULL
|
||||||
|
GO
|
|
@ -43,7 +43,7 @@ import { GBDeployer } from './GBDeployer';
|
||||||
const MicrosoftGraph = require('@microsoft/microsoft-graph-client');
|
const MicrosoftGraph = require('@microsoft/microsoft-graph-client');
|
||||||
import { Messages } from '../strings';
|
import { Messages } from '../strings';
|
||||||
import { GBServer } from '../../../src/app';
|
import { GBServer } from '../../../src/app';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
import { SecService } from '../../security.gbapp/services/SecService';
|
||||||
const request = require('request-promise-native');
|
const request = require('request-promise-native');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,6 +90,15 @@ class SysClass {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async gotoDialog(from: string, dialogName: string) {
|
||||||
|
let sec = new SecService();
|
||||||
|
let user = await sec.getUserFromSystemId(from);
|
||||||
|
if (!user) {
|
||||||
|
user = await sec.ensureUser(this.min.instance.instanceId, from, from, null, 'whatsapp', 'from');
|
||||||
|
}
|
||||||
|
await sec.updateUserHearOnDialog(user.userId, dialogName);
|
||||||
|
}
|
||||||
|
|
||||||
public async wait(seconds: number) {
|
public async wait(seconds: number) {
|
||||||
// tslint:disable-next-line no-string-based-set-timeout
|
// tslint:disable-next-line no-string-based-set-timeout
|
||||||
GBLog.info(`BASIC: Talking to a specific user (TALK TO).`);
|
GBLog.info(`BASIC: Talking to a specific user (TALK TO).`);
|
||||||
|
@ -246,6 +255,7 @@ class SysClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async find(file: string, ...args): Promise<any> {
|
public async find(file: string, ...args): Promise<any> {
|
||||||
let token = await this.min.adminService.acquireElevatedToken(this.min.instance.instanceId);
|
let token = await this.min.adminService.acquireElevatedToken(this.min.instance.instanceId);
|
||||||
|
|
||||||
|
@ -358,6 +368,7 @@ class SysClass {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic function to call any REST API.
|
* Generic function to call any REST API.
|
||||||
*/
|
*/
|
||||||
|
@ -469,14 +480,14 @@ export class DialogClass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async isAffirmative(step, text) {
|
public async isAffirmative(step, text) {
|
||||||
return text.toLowerCase().match(Messages[step.context.activity.locale].affirmative_sentences);
|
return text.toLowerCase().match(Messages[step.context.activity.locale].affirmative_sentences);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getNow(step) {
|
public async getNow(step) {
|
||||||
const nowUTC = new Date();
|
const nowUTC = new Date();
|
||||||
const now = new Date((typeof nowUTC === "string" ?
|
const now = new Date((typeof nowUTC === "string" ?
|
||||||
new Date(nowUTC) :
|
new Date(nowUTC) :
|
||||||
nowUTC).toLocaleString("en-US", {timeZone: process.env.DEFAULT_TIMEZONE}));
|
nowUTC).toLocaleString("en-US", { timeZone: process.env.DEFAULT_TIMEZONE }));
|
||||||
|
|
||||||
return now.getHours() + ':' + now.getMinutes();
|
return now.getHours() + ':' + now.getMinutes();
|
||||||
}
|
}
|
||||||
|
@ -533,7 +544,7 @@ export class DialogClass {
|
||||||
return await step.beginDialog('/t');
|
return await step.beginDialog('/t');
|
||||||
}
|
}
|
||||||
|
|
||||||
public async hear(step, promise, previousResolve) {
|
public async hear(step, promise, previousResolve, kind) {
|
||||||
function random(low, high) {
|
function random(low, high) {
|
||||||
return Math.random() * (high - low) + low;
|
return Math.random() * (high - low) + low;
|
||||||
}
|
}
|
||||||
|
@ -541,7 +552,7 @@ export class DialogClass {
|
||||||
this.min.cbMap[idPromise] = {};
|
this.min.cbMap[idPromise] = {};
|
||||||
this.min.cbMap[idPromise].promise = promise;
|
this.min.cbMap[idPromise].promise = promise;
|
||||||
|
|
||||||
const opts = { id: idPromise, previousResolve: previousResolve };
|
const opts = { id: idPromise, previousResolve: previousResolve, kind: kind };
|
||||||
if (previousResolve !== undefined) {
|
if (previousResolve !== undefined) {
|
||||||
previousResolve(opts);
|
previousResolve(opts);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -163,13 +163,21 @@ export class GBMinService {
|
||||||
let sec = new SecService();
|
let sec = new SecService();
|
||||||
let user = await sec.getUserFromSystemId(id);
|
let user = await sec.getUserFromSystemId(id);
|
||||||
|
|
||||||
if (user === null) {
|
if (user === null || user.hearOnDialog) {
|
||||||
user = await sec.ensureUser(activeMin.instance.instanceId, id, senderName, '', 'whatsapp', senderName);
|
user = await sec.ensureUser(activeMin.instance.instanceId, id, senderName, '', 'whatsapp', senderName);
|
||||||
|
|
||||||
let startDialog = activeMin.core.getParam(activeMin.instance, 'Start Dialog', null);
|
let startDialog = user.hearOnDialog ?
|
||||||
|
user.hearOnDialog :
|
||||||
|
activeMin.core.getParam(activeMin.instance, 'Start Dialog', null);
|
||||||
|
|
||||||
GBLog.info(`Auto start dialog is now being called: ${startDialog}...`);
|
GBLog.info(`Auto start dialog is now being called: ${startDialog}...`);
|
||||||
if (startDialog) {
|
if (startDialog) {
|
||||||
req.body.messages[0].body = `${startDialog}`;
|
req.body.messages[0].body = `${startDialog}`;
|
||||||
|
|
||||||
|
// Resets HEAR ON DIALOG value to none and passes
|
||||||
|
// current dialog to the direct line.
|
||||||
|
|
||||||
|
await sec.updateUserHearOnDialog(user.userId, null);
|
||||||
await (activeMin as any).whatsAppDirectLine.received(req, res);
|
await (activeMin as any).whatsAppDirectLine.received(req, res);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -759,6 +767,7 @@ export class GBMinService {
|
||||||
await step.beginDialog(cmdOrDialogName, { args: args });
|
await step.beginDialog(cmdOrDialogName, { args: args });
|
||||||
}
|
}
|
||||||
} else if (globalQuit(step.context.activity.locale, context.activity.text)) {
|
} else if (globalQuit(step.context.activity.locale, context.activity.text)) {
|
||||||
|
|
||||||
// TODO: Hard-code additional languages.
|
// TODO: Hard-code additional languages.
|
||||||
await step.cancelAllDialogs();
|
await step.cancelAllDialogs();
|
||||||
await min.conversationalService.sendText(min, step, Messages[step.context.activity.locale].canceled);
|
await min.conversationalService.sendText(min, step, Messages[step.context.activity.locale].canceled);
|
||||||
|
@ -768,6 +777,7 @@ export class GBMinService {
|
||||||
// Checks for /menu JSON signature.
|
// Checks for /menu JSON signature.
|
||||||
} else if (context.activity.text.startsWith('{"title"')) {
|
} else if (context.activity.text.startsWith('{"title"')) {
|
||||||
await step.beginDialog('/menu', JSON.parse(context.activity.text));
|
await step.beginDialog('/menu', JSON.parse(context.activity.text));
|
||||||
|
|
||||||
// Otherwise, continue to the active dialog in the stack.
|
// Otherwise, continue to the active dialog in the stack.
|
||||||
} else if (
|
} else if (
|
||||||
!(await this.deployer.getStoragePackageByName(min.instance.instanceId, `${min.instance.botId}.gbkb`)) &&
|
!(await this.deployer.getStoragePackageByName(min.instance.instanceId, `${min.instance.botId}.gbkb`)) &&
|
||||||
|
@ -782,14 +792,14 @@ export class GBMinService {
|
||||||
const originalText = text;
|
const originalText = text;
|
||||||
text = text.replace(/<([^>]+?)([^>]*?)>(.*?)<\/\1>/gi, '');
|
text = text.replace(/<([^>]+?)([^>]*?)>(.*?)<\/\1>/gi, '');
|
||||||
|
|
||||||
// Spells check the input text before translating.
|
// Spells check the input text before translating,
|
||||||
|
// keeping fixed tokens as specified in Config.
|
||||||
|
|
||||||
const keepText: string = min.core.getParam<string>(
|
const keepText: string = min.core.getParam<string>(
|
||||||
min.instance,
|
min.instance,
|
||||||
'Keep Text',
|
'Keep Text',
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
if (keepText) {
|
if (keepText) {
|
||||||
const list = keepText.split(';');
|
const list = keepText.split(';');
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
@ -807,6 +817,7 @@ export class GBMinService {
|
||||||
text = text.replace(`KEEPTEXT${i}`, item.trim());
|
text = text.replace(`KEEPTEXT${i}`, item.trim());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detects user typed language and updates their locale profile if applies.
|
// Detects user typed language and updates their locale profile if applies.
|
||||||
|
|
||||||
let locale = min.core.getParam<string>(
|
let locale = min.core.getParam<string>(
|
||||||
|
@ -830,13 +841,15 @@ export class GBMinService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasBadWord = wash.check(locale, context.activity.text);
|
// Checks for bad words on input text.
|
||||||
|
|
||||||
|
const hasBadWord = wash.check(locale, context.activity.text);
|
||||||
if (hasBadWord) {
|
if (hasBadWord) {
|
||||||
return await step.beginDialog('/pleaseNoBadWords');
|
return await step.beginDialog('/pleaseNoBadWords');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translates the input text if is turned on instance params.
|
// Translates text into content language, keeping
|
||||||
|
// reserved tokens specified in Config.
|
||||||
|
|
||||||
if (keepText) {
|
if (keepText) {
|
||||||
const list = keepText.split(';');
|
const list = keepText.split(';');
|
||||||
|
@ -860,7 +873,6 @@ export class GBMinService {
|
||||||
text = text.replace(new RegExp(item.trim(), 'gi'), `KEEPTEXT${i}`);
|
text = text.replace(new RegExp(item.trim(), 'gi'), `KEEPTEXT${i}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
text = await min.conversationalService.translate(min, text, contentLocale);
|
text = await min.conversationalService.translate(min, text, contentLocale);
|
||||||
if (keepText) {
|
if (keepText) {
|
||||||
const list = keepText.split(';');
|
const list = keepText.split(';');
|
||||||
|
|
|
@ -168,6 +168,10 @@ export class GBVMService extends GBService {
|
||||||
|
|
||||||
code = code.replace(/(hear email)/gi, `email = askEmail()`);
|
code = code.replace(/(hear email)/gi, `email = askEmail()`);
|
||||||
|
|
||||||
|
code = code.replace(/(hear on)(\s)(.*)/gi, ($0, $1, $2, $3) => {
|
||||||
|
return `sys().gotoDialog(${$3})\n`;
|
||||||
|
});
|
||||||
|
|
||||||
code = code.replace(/(hear)\s*(\w+)/gi, ($0, $1, $2) => {
|
code = code.replace(/(hear)\s*(\w+)/gi, ($0, $1, $2) => {
|
||||||
return `${$2} = hear()`;
|
return `${$2} = hear()`;
|
||||||
});
|
});
|
||||||
|
@ -316,7 +320,15 @@ export class GBVMService extends GBService {
|
||||||
parsedCode += code.substring(start + match1[0].length + 1, pos + match1[0].length);
|
parsedCode += code.substring(start + match1[0].length + 1, pos + match1[0].length);
|
||||||
parsedCode += '});\n';
|
parsedCode += '});\n';
|
||||||
parsedCode += '}\n';
|
parsedCode += '}\n';
|
||||||
parsedCode += `hear (step, ${promiseName}, resolve);\n`;
|
|
||||||
|
|
||||||
|
let kind = 'general';
|
||||||
|
if (variable === "YES OR NO") {
|
||||||
|
kind = 'yesOrNo';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
parsedCode += `hear (step, ${promiseName}, resolve, '${kind}');\n`;
|
||||||
parsedCode += code.substring(pos + match1[0].length);
|
parsedCode += code.substring(pos + match1[0].length);
|
||||||
|
|
||||||
// A interaction will be made for each hear.
|
// A interaction will be made for each hear.
|
||||||
|
@ -324,8 +336,6 @@ export class GBVMService extends GBService {
|
||||||
code = parsedCode;
|
code = parsedCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
parsedCode = this.handleThisAndAwait(parsedCode);
|
parsedCode = this.handleThisAndAwait(parsedCode);
|
||||||
|
|
||||||
parsedCode = parsedCode.replace(/(now)(?=(?:[^"]|"[^"]*")*$)/gi, 'await this.getNow(step)');
|
parsedCode = parsedCode.replace(/(now)(?=(?:[^"]|"[^"]*")*$)/gi, 'await this.getNow(step)');
|
||||||
|
@ -335,7 +345,7 @@ export class GBVMService extends GBService {
|
||||||
fs.writeFileSync(jsfile, parsedCode);
|
fs.writeFileSync(jsfile, parsedCode);
|
||||||
|
|
||||||
this.executeJS(min, deployer, parsedCode, mainName);
|
this.executeJS(min, deployer, parsedCode, mainName);
|
||||||
GBLog.info(`[GBVMService] Finished loading of ${filename}, JavaScript from Word: ${parsedCode}`);
|
GBLog.info(`[GBVMService] Finished loading of ${filename}, JavaScript from Word: \n ${parsedCode}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,20 +396,69 @@ export class GBVMService extends GBService {
|
||||||
min.dialogs.add(
|
min.dialogs.add(
|
||||||
new WaterfallDialog('/hear', [
|
new WaterfallDialog('/hear', [
|
||||||
async step => {
|
async step => {
|
||||||
step.activeDialog.state.options = {};
|
step.activeDialog.state.options = step.options;
|
||||||
step.activeDialog.state.options.cbId = (step.options as any).id;
|
step.activeDialog.state.options.id = (step.options as any).id;
|
||||||
step.activeDialog.state.options.previousResolve = (step.options as any).previousResolve;
|
step.activeDialog.state.options.previousResolve = (step.options as any).previousResolve;
|
||||||
GBLog.info('BASIC: Asking for input (HEAR).');
|
|
||||||
|
if (step.options['kind'] === "yesOrNo") {
|
||||||
|
|
||||||
|
GBLog.info('BASIC: Asking for input (HEAR YES OR NO).');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
GBLog.info('BASIC: Asking for input (HEAR).');
|
||||||
|
}
|
||||||
|
|
||||||
return await min.conversationalService.prompt(min, step, null);
|
return await min.conversationalService.prompt(min, step, null);
|
||||||
},
|
},
|
||||||
async step => {
|
async step => {
|
||||||
const cbId = step.activeDialog.state.options.cbId;
|
|
||||||
|
|
||||||
if (min.cbMap[cbId]) {
|
const isIntentYes = (locale, utterance) => {
|
||||||
const promise = min.cbMap[cbId].promise;
|
return utterance.toLowerCase().match(Messages[locale].affirmative_sentences);
|
||||||
delete min.cbMap[cbId];
|
}
|
||||||
|
|
||||||
|
let result = step.result;
|
||||||
|
if (step.activeDialog.state.options['boolean']) {
|
||||||
|
|
||||||
|
if (isIntentYes(step.context.locale, step.result)) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return await step.replaceDialog('/hear', step.activeDialog.state.options);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (step.activeDialog.state.options['email']) {
|
||||||
|
// e@e.com
|
||||||
|
}
|
||||||
|
else if (step.activeDialog.state.options['number']) {
|
||||||
|
// MAX and MIN.
|
||||||
|
}
|
||||||
|
else if (step.activeDialog.state.options['date']) {
|
||||||
|
// 12/12/2020 OK
|
||||||
|
}
|
||||||
|
else if (step.activeDialog.state.options['hour']) {
|
||||||
|
// 12:12
|
||||||
|
}
|
||||||
|
else if (step.activeDialog.state.options['money']) {
|
||||||
|
// 23,12
|
||||||
|
}
|
||||||
|
else if (step.activeDialog.state.options['phone']) {
|
||||||
|
// +55 21
|
||||||
|
}
|
||||||
|
else if (step.activeDialog.state.options['zipcode']) {
|
||||||
|
// 12333-222
|
||||||
|
}
|
||||||
|
else if (step.activeDialog.state.options['menu']){
|
||||||
|
// ['drums', 'guitar', 'bass']; kpmSearch
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = step.activeDialog.state.options.id;
|
||||||
|
if (min.cbMap[id]) {
|
||||||
|
const promise = min.cbMap[id].promise;
|
||||||
|
delete min.cbMap[id];
|
||||||
try {
|
try {
|
||||||
const opts = await promise(step, step.result);
|
const opts = await promise(step, result);
|
||||||
return await step.replaceDialog('/hear', opts);
|
return await step.replaceDialog('/hear', opts);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
GBLog.error(`Error in BASIC code: ${error}`);
|
GBLog.error(`Error in BASIC code: ${error}`);
|
||||||
|
|
|
@ -91,6 +91,9 @@ export class GuaribasUser extends Model<GuaribasUser> {
|
||||||
@Column(DataType.TEXT)
|
@Column(DataType.TEXT)
|
||||||
@Column
|
@Column
|
||||||
conversationReference: string
|
conversationReference: string
|
||||||
|
|
||||||
|
@Column(DataType.STRING(64))
|
||||||
|
hearOnDialog: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -91,6 +91,16 @@ export class SecService extends GBService {
|
||||||
return await user.save();
|
return await user.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async updateUserHearOnDialog(userId: number, dialogName: string): Promise<GuaribasUser> {
|
||||||
|
let user = await GuaribasUser.findOne({
|
||||||
|
where: {
|
||||||
|
userId: userId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
user.hearOnDialog = dialogName;
|
||||||
|
return await user.save();
|
||||||
|
}
|
||||||
|
|
||||||
public async updateUserInstance(userSystemId: string, instanceId: number): Promise<GuaribasUser> {
|
public async updateUserInstance(userSystemId: string, instanceId: number): Promise<GuaribasUser> {
|
||||||
let user = await GuaribasUser.findOne({
|
let user = await GuaribasUser.findOne({
|
||||||
where: {
|
where: {
|
||||||
|
|
Loading…
Add table
Reference in a new issue