Microsoft updated everything again, so we need to update it too.

This commit is contained in:
Rodrigo Rodriguez (pragmatismo.io) 2018-11-01 21:06:11 -03:00
parent 820d4f612e
commit 677057c282
22 changed files with 333 additions and 314 deletions

View file

@ -41,15 +41,13 @@ import { GBConfigService } from "../../core.gbapp/services/GBConfigService";
import { BotAdapter } from "botbuilder"; import { BotAdapter } from "botbuilder";
import { GBAdminService } from "../services/GBAdminService"; import { GBAdminService } from "../services/GBAdminService";
import { Messages } from "../strings"; import { Messages } from "../strings";
import { WaterfallDialog } from "botbuilder-dialogs";
/** /**
* Dialogs for administration tasks. * Dialogs for administration tasks.
*/ */
export class AdminDialog extends IGBDialog { export class AdminDialog extends IGBDialog {
static async createFarmCommand(text: any, min: GBMinInstance) {}
static async createFarmCommand(text: any, min: GBMinInstance) {
}
static async undeployPackageCommand(text: any, min: GBMinInstance) { static async undeployPackageCommand(text: any, min: GBMinInstance) {
let packageName = text.split(" ")[1]; let packageName = text.split(" ")[1];
@ -80,70 +78,75 @@ export class AdminDialog extends IGBDialog {
let importer = new GBImporter(min.core); let importer = new GBImporter(min.core);
let deployer = new GBDeployer(min.core, importer); let deployer = new GBDeployer(min.core, importer);
min.dialogs.add("/admin", [ min.dialogs.add(
async dc => { new WaterfallDialog("/admin", [
const locale = dc.context.activity.locale; async step => {
const prompt = Messages[locale].authenticate; const locale = step.context.activity.locale;
await dc.prompt("textPrompt", prompt); const prompt = Messages[locale].authenticate;
}, await step.prompt("textPrompt", prompt);
async (dc, password) => { return await step.next();
const locale = dc.context.activity.locale; },
if ( async step => {
password === GBConfigService.get("ADMIN_PASS") && const locale = step.context.activity.locale;
GBAdminService.StrongRegex.test(password) let password = step.result;
) { if (
await dc.context.sendActivity(Messages[locale].welcome); password === GBConfigService.get("ADMIN_PASS") &&
await dc.prompt("textPrompt", Messages[locale].which_task); GBAdminService.StrongRegex.test(password)
} else { ) {
await dc.prompt("textPrompt", Messages[locale].wrong_password); await step.context.sendActivity(Messages[locale].welcome);
await dc.endAll(); await step.prompt("textPrompt", Messages[locale].which_task);
} } else {
}, await step.prompt("textPrompt", Messages[locale].wrong_password);
async (dc, value) => { await step.endDialog();
const locale = dc.context.activity.locale; }
var text = value; return await step.next();
let cmdName = text.split(" ")[0]; },
async step => {
const locale = step.context.activity.locale;
var text = step.result;
let cmdName = text.split(" ")[0];
dc.context.sendActivity(Messages[locale].working(cmdName)); step.context.sendActivity(Messages[locale].working(cmdName));
let unknownCommand = false; let unknownCommand = false;
if (text === "quit") { if (text === "quit") {
await dc.replace("/"); await step.replaceDialog("/");
} else if (cmdName === "createFarm") { } else if (cmdName === "createFarm") {
await AdminDialog.createFarmCommand(text, deployer); await AdminDialog.createFarmCommand(text, deployer);
await dc.replace("/admin", { firstRun: false }); await step.replaceDialog("/admin", { firstRun: false });
} else if (cmdName === "deployPackage") { } else if (cmdName === "deployPackage") {
await AdminDialog.deployPackageCommand(text, deployer); await AdminDialog.deployPackageCommand(text, deployer);
await dc.replace("/admin", { firstRun: false }); await step.replaceDialog("/admin", { firstRun: false });
} else if (cmdName === "redeployPackage") { } else if (cmdName === "redeployPackage") {
await AdminDialog.undeployPackageCommand(text, min); await AdminDialog.undeployPackageCommand(text, min);
await AdminDialog.deployPackageCommand(text, deployer); await AdminDialog.deployPackageCommand(text, deployer);
await dc.context.sendActivity(); await step.replaceDialog("/admin", { firstRun: false });
await dc.replace("/admin", { firstRun: false }); } else if (cmdName === "undeployPackage") {
} else if (cmdName === "undeployPackage") { await AdminDialog.undeployPackageCommand(text, min);
await AdminDialog.undeployPackageCommand(text, min); await step.replaceDialog("/admin", { firstRun: false });
await dc.replace("/admin", { firstRun: false }); } else if (cmdName === "setupSecurity") {
} else if (cmdName === "setupSecurity") { await AdminDialog.setupSecurity(min, step);
await AdminDialog.setupSecurity(min, dc); } else {
} else { unknownCommand = true;
unknownCommand = true; }
}
if (unknownCommand) { if (unknownCommand) {
await dc.context.sendActivity(Messages[locale].unknown_command); await step.context.sendActivity(Messages[locale].unknown_command);
} else { } else {
await dc.context.sendActivity( await step.context.sendActivity(
Messages[locale].finshed_working(cmdName) Messages[locale].finshed_working(cmdName)
); );
}
await step.endDialog();
await step.replaceDialog("/answer", { query: text });
return await step.next();
} }
await dc.endAll(); ])
await dc.replace("/answer", { query: text }); );
}
]);
} }
private static async setupSecurity(min: any, dc: any) { private static async setupSecurity(min: any, step: any) {
const locale = dc.context.activity.locale; const locale = step.activity.locale;
let state = `${min.instance.instanceId}${Math.floor( let state = `${min.instance.instanceId}${Math.floor(
Math.random() * 1000000000 Math.random() * 1000000000
)}`; )}`;
@ -160,6 +163,6 @@ export class AdminDialog extends IGBDialog {
min.instance.botId min.instance.botId
}/token&state=${state}&response_mode=query`; }/token&state=${state}&response_mode=query`;
await dc.context.sendActivity(Messages[locale].consent(url)); await step.sendActivity(Messages[locale].consent(url));
} }
} }

View file

@ -59,6 +59,6 @@ export class GBAdminPackage implements IGBPackage {
unloadBot(min: GBMinInstance): void { unloadBot(min: GBMinInstance): void {
} }
onNewSession(min: GBMinInstance, dc: any): void { onNewSession(min: GBMinInstance, step: any): void {
} }
} }

View file

@ -56,7 +56,7 @@ export class GBAnalyticsPackage implements IGBPackage {
unloadBot(min: GBMinInstance): void { unloadBot(min: GBMinInstance): void {
} }
onNewSession(min: GBMinInstance, dc: any): void { onNewSession(min: GBMinInstance, step: any): void {
} }
} }

View file

@ -48,9 +48,9 @@ export class BotFarmDialog extends IGBDialog {
*/ */
static setup(bot: BotAdapter, min: GBMinInstance) { static setup(bot: BotAdapter, min: GBMinInstance) {
min.dialogs.add("/createBotFarm", [ min.dialogs.add("/createBotFarm", [
async dc => { async step => {
let locale = dc.context.activity.locale; let locale = step.context.activity.locale;
await dc.prompt("choicePrompt", Messages[locale].what_about_me, [ await step.prompt("choicePrompt", Messages[locale].what_about_me, [
"1", "1",
"2", "2",
"3", "3",
@ -58,9 +58,9 @@ export class BotFarmDialog extends IGBDialog {
"5" "5"
]); ]);
}, },
async (dc, value) => { async step => {
let locale = dc.context.activity.locale; let locale = step.context.activity.locale;
await dc.context.sendActivity(Messages[locale].thanks); await step.context.sendActivity(Messages[locale].thanks);
} }
]); ]);
} }

View file

@ -55,7 +55,7 @@ export class GBWhatsappPackage implements IGBPackage {
unloadBot(min: GBMinInstance): void { unloadBot(min: GBMinInstance): void {
} }
onNewSession(min: GBMinInstance, dc: any): void { onNewSession(min: GBMinInstance, step: any): void {
} }
} }

View file

@ -56,6 +56,6 @@ export class GBConsolePackage implements IGBPackage {
unloadBot(min: GBMinInstance): void { unloadBot(min: GBMinInstance): void {
} }
onNewSession(min: GBMinInstance, dc: any): void { onNewSession(min: GBMinInstance, step: any): void {
} }
} }

View file

@ -35,6 +35,7 @@
import { IGBDialog } from "botlib"; import { IGBDialog } from "botlib";
import { GBMinInstance } from "botlib"; import { GBMinInstance } from "botlib";
import { BotAdapter } from "botbuilder"; import { BotAdapter } from "botbuilder";
import {WaterfallDialog } from "botbuilder-dialogs";
import { Messages } from "../strings"; import { Messages } from "../strings";
export class WelcomeDialog extends IGBDialog { export class WelcomeDialog extends IGBDialog {
@ -45,11 +46,12 @@ export class WelcomeDialog extends IGBDialog {
* @param min The minimal bot instance data. * @param min The minimal bot instance data.
*/ */
static setup(bot: BotAdapter, min: GBMinInstance) { static setup(bot: BotAdapter, min: GBMinInstance) {
min.dialogs.add("/", [
async (dc) => { min.dialogs.add(new WaterfallDialog("/", [
const user = await min.userProfile.get(context, {}); async step => {
const locale = dc.context.activity.locale; const user = await min.userProfile.get(context, {});
const locale = step.context.activity.locale;
if (!user.once) { if (!user.once) {
user.once = true; user.once = true;
@ -63,18 +65,19 @@ export class WelcomeDialog extends IGBDialog {
? Messages[locale].good_evening ? Messages[locale].good_evening
: Messages[locale].good_night; : Messages[locale].good_night;
await dc.context.sendActivity(Messages[locale].hi(msg)); await step.context.sendActivity(Messages[locale].hi(msg));
await dc.replace("/ask", { firstTime: true }); await step.replaceDialog("/ask", { firstTime: true });
if ( if (
dc.context.activity && step.context.activity &&
dc.context.activity.type == "message" && step.context.activity.type == "message" &&
dc.context.activity.text != "" step.context.activity.text != ""
) { ) {
await dc.replace("/answer", { query: dc.context.activity.text }); await step.replaceDialog("/answer", { query: step.context.activity.text });
} }
} }
return await step.next();
} }
]); ]))
} }
} }

View file

@ -36,6 +36,7 @@ import { IGBDialog } from "botlib";
import { GBMinInstance } from "botlib"; import { GBMinInstance } from "botlib";
import { BotAdapter } from "botbuilder"; import { BotAdapter } from "botbuilder";
import { Messages } from "../strings"; import { Messages } from "../strings";
import { WaterfallDialog } from "botbuilder-dialogs";
export class WhoAmIDialog extends IGBDialog { export class WhoAmIDialog extends IGBDialog {
/** /**
@ -45,21 +46,22 @@ export class WhoAmIDialog extends IGBDialog {
* @param min The minimal bot instance data. * @param min The minimal bot instance data.
*/ */
static setup(bot: BotAdapter, min: GBMinInstance) { static setup(bot: BotAdapter, min: GBMinInstance) {
min.dialogs.add("/whoAmI", [ min.dialogs.add(new WaterfallDialog("/whoAmI", [
async dc => { async step => {
let locale = dc.context.activity.locale; let locale = step.context.activity.locale;
await dc.context.sendActivity(`${min.instance.description}`); await step.context.sendActivity(`${min.instance.description}`);
if (min.instance.whoAmIVideo) { if (min.instance.whoAmIVideo) {
await dc.context.sendActivity(Messages[locale].show_video); await step.context.sendActivity(Messages[locale].show_video);
await min.conversationalService.sendEvent(dc, "play", { await min.conversationalService.sendEvent(step, "play", {
playerType: "video", playerType: "video",
data: min.instance.whoAmIVideo.trim() data: min.instance.whoAmIVideo.trim()
}); });
} }
await dc.replace("/ask", { isReturning: true }); await step.replaceDialog("/ask", { isReturning: true });
return await step.next();
} }
]); ]));
} }
} }

View file

@ -66,7 +66,7 @@ export class GBCorePackage implements IGBPackage {
unloadBot(min: GBMinInstance): void { unloadBot(min: GBMinInstance): void {
} }
onNewSession(min: GBMinInstance, dc: any): void { onNewSession(min: GBMinInstance, step: any): void {
} }
} }

View file

@ -56,17 +56,17 @@ export class GBConversationalService implements IGBConversationalService {
this.coreService = coreService; this.coreService = coreService;
} }
getCurrentLanguage(dc: any) { getCurrentLanguage(step: any) {
return dc.context.activity.locale; return step.context.activity.locale;
} }
async sendEvent(dc: any, name: string, value: any): Promise<any> { async sendEvent(step: any, name: string, value: any): Promise<any> {
if (dc.context.activity.channelId === "webchat") { if (step.context.activity.channelId === "webchat") {
const msg = MessageFactory.text(""); const msg = MessageFactory.text("");
msg.value = value; msg.value = value;
msg.type = "event"; msg.type = "event";
msg.name = name; msg.name = name;
return dc.context.sendActivity(msg); return step.context.sendActivity(msg);
} }
} }
@ -95,7 +95,7 @@ export class GBConversationalService implements IGBConversationalService {
}); });
} }
async routeNLP(dc: any, min: GBMinInstance, text: string): Promise<boolean> { async routeNLP(step: any, min: GBMinInstance, text: string): Promise<boolean> {
// Invokes LUIS. // Invokes LUIS.
const model = new LuisRecognizer({ const model = new LuisRecognizer({
@ -106,7 +106,7 @@ export class GBConversationalService implements IGBConversationalService {
let nlp: any; let nlp: any;
try { try {
nlp = await model.recognize(dc.context); nlp = await model.recognize(step.context);
} catch (error) { } catch (error) {
let msg = `Error calling NLP server, check if you have a published model and assigned keys on the service. Error: ${ let msg = `Error calling NLP server, check if you have a published model and assigned keys on the service. Error: ${
error.statusCode ? error.statusCode : "" error.statusCode ? error.statusCode : ""
@ -131,7 +131,7 @@ export class GBConversationalService implements IGBConversationalService {
logger.info("NLP called:" + intent + ", " + entity); logger.info("NLP called:" + intent + ", " + entity);
try { try {
await dc.replace("/" + intent, nlp.entities); await step.replace("/" + intent, nlp.entities);
return Promise.resolve(true); return Promise.resolve(true);
} catch (error) { } catch (error) {
let msg = `Error finding dialog associated to NLP event: ${intent}: ${ let msg = `Error finding dialog associated to NLP event: ${intent}: ${
@ -143,24 +143,24 @@ export class GBConversationalService implements IGBConversationalService {
return Promise.resolve(false); return Promise.resolve(false);
} }
async checkLanguage(dc, min, text) { async checkLanguage(step, min, text) {
let locale = await AzureText.getLocale( let locale = await AzureText.getLocale(
min.instance.textAnalyticsKey, min.instance.textAnalyticsKey,
min.instance.textAnalyticsEndpoint, min.instance.textAnalyticsEndpoint,
text text
); );
if (locale != dc.context.activity.locale.split("-")[0]) { if (locale != step.context.activity.locale.split("-")[0]) {
switch (locale) { switch (locale) {
case "pt": case "pt":
dc.context.activity.locale = "pt-BR"; step.context.activity.locale = "pt-BR";
await dc.context.sendActivity(Messages[locale].changing_language); await step.context.sendActivity(Messages[locale].changing_language);
break; break;
case "en": case "en":
dc.context.activity.locale = "en-US"; step.context.activity.locale = "en-US";
await dc.context.sendActivity(Messages[locale].changing_language); await step.context.sendActivity(Messages[locale].changing_language);
break; break;
default: default:
await dc.context.sendActivity(`Unknown language: ${locale}`); await step.context.sendActivity(`Unknown language: ${locale}`);
break; break;
} }
} }

View file

@ -329,30 +329,31 @@ export class GBMinService {
} }
private invokeLoadBot(appPackages: any[], min: any, server: any) { private invokeLoadBot(appPackages: any[], min: any, server: any) {
let sysPackages = new Array<IGBPackage>();
// NOTE: A semicolon is necessary before this line.
[
GBCorePackage,
GBSecurityPackage,
GBAdminPackage,
GBKBPackage,
GBAnalyticsPackage,
GBCustomerSatisfactionPackage,
GBWhatsappPackage
].forEach(sysPackage => {
let p = Object.create(sysPackage.prototype) as IGBPackage;
p.loadBot(min);
sysPackages.push(p);
if (sysPackage.name === "GBWhatsappPackage") {
let url = "/instances/:botId/whatsapp";
server.post(url, (req, res) => {
p["channel"].received(req, res);
});
}
}, this);
appPackages.forEach(e => { appPackages.forEach(e => {
e.sysPackages = new Array<IGBPackage>(); e.sysPackages = sysPackages;
// NOTE: A semicolon is necessary before this line.
[
GBAdminPackage,
GBAnalyticsPackage,
GBCorePackage,
GBSecurityPackage,
GBKBPackage,
GBCustomerSatisfactionPackage,
GBWhatsappPackage
].forEach(sysPackage => {
let p = Object.create(sysPackage.prototype) as IGBPackage;
p.loadBot(min);
e.sysPackages.push(p);
if (sysPackage.name === "GBWhatsappPackage") {
let url = "/instances/:botId/whatsapp";
server.post(url, (req, res) => {
p["channel"].received(req, res);
});
}
}, this);
e.loadBot(min); e.loadBot(min);
}, this); }, this);
} }
@ -371,14 +372,14 @@ export class GBMinService {
) { ) {
return adapter.processActivity(req, res, async context => { return adapter.processActivity(req, res, async context => {
const state = conversationState.get(context); const state = conversationState.get(context);
const dc = await min.dialogs.createContext(context, state); const step = await min.dialogs.createContext(context, state);
dc.context.activity.locale = "en-US"; // TODO: Make dynamic. step.context.activity.locale = "en-US"; // TODO: Make dynamic.
try { try {
const user = await min.userProfile.get(context, {}); const user = await min.userProfile.get(context, {});
if (!user.loaded) { if (!user.loaded) {
await min.conversationalService.sendEvent(dc, "loadInstance", { await min.conversationalService.sendEvent(step, "loadInstance", {
instanceId: instance.instanceId, instanceId: instance.instanceId,
botId: instance.botId, botId: instance.botId,
theme: instance.theme, theme: instance.theme,
@ -402,11 +403,11 @@ export class GBMinService {
if (member.name === "GeneralBots") { if (member.name === "GeneralBots") {
logger.info(`Bot added to conversation, starting chat...`); logger.info(`Bot added to conversation, starting chat...`);
appPackages.forEach(e => { appPackages.forEach(e => {
e.onNewSession(min, dc); e.onNewSession(min, step);
}); });
// Processes the root dialog. // Processes the root dialog.
await dc.beginDialog("/"); await step.beginDialog("/");
} else { } else {
logger.info(`Member added to conversation: ${member.name}`); logger.info(`Member added to conversation: ${member.name}`);
} }
@ -416,20 +417,20 @@ export class GBMinService {
// Checks for /admin request. // Checks for /admin request.
if (context.activity.text === "admin") { if (context.activity.text === "admin") {
await dc.beginDialog("/admin"); await step.beginDialog("/admin");
// 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 dc.beginDialog("/menu", { await step.beginDialog("/menu", {
data: JSON.parse(context.activity.text) data: JSON.parse(context.activity.text)
}); });
// Otherwise, continue to the active dialog in the stack. // Otherwise, continue to the active dialog in the stack.
} else { } else {
if (dc.activeDialog) { if (step.activeDialog) {
await dc.continue(); await step.continue();
} else { } else {
await dc.beginDialog("/answer", { query: context.activity.text }); await step.beginDialog("/answer", { query: context.activity.text });
} }
} }
@ -437,42 +438,42 @@ export class GBMinService {
} else if (context.activity.type === "event") { } else if (context.activity.type === "event") {
// Empties dialog stack before going to the target. // Empties dialog stack before going to the target.
await dc.endAll(); await step.endAll();
if (context.activity.name === "whoAmI") { if (context.activity.name === "whoAmI") {
await dc.beginDialog("/whoAmI"); await step.beginDialog("/whoAmI");
} else if (context.activity.name === "showSubjects") { } else if (context.activity.name === "showSubjects") {
await dc.beginDialog("/menu"); await step.beginDialog("/menu");
} else if (context.activity.name === "giveFeedback") { } else if (context.activity.name === "giveFeedback") {
await dc.beginDialog("/feedback", { await step.beginDialog("/feedback", {
fromMenu: true fromMenu: true
}); });
} else if (context.activity.name === "showFAQ") { } else if (context.activity.name === "showFAQ") {
await dc.beginDialog("/faq"); await step.beginDialog("/faq");
} else if (context.activity.name === "answerEvent") { } else if (context.activity.name === "answerEvent") {
await dc.beginDialog("/answerEvent", { await step.beginDialog("/answerEvent", {
questionId: (context.activity as any).data, questionId: (context.activity as any).data,
fromFaq: true fromFaq: true
}); });
} else if (context.activity.name === "quality") { } else if (context.activity.name === "quality") {
await dc.beginDialog("/quality", { await step.beginDialog("/quality", {
score: (context.activity as any).data score: (context.activity as any).data
}); });
} else if (context.activity.name === "updateToken") { } else if (context.activity.name === "updateToken") {
let token = (context.activity as any).data; let token = (context.activity as any).data;
await dc.beginDialog("/adminUpdateToken", { token: token }); await step.beginDialog("/adminUpdateToken", { token: token });
} else { } else {
await dc.continue(); await step.continue();
} }
} }
} catch (error) { } catch (error) {
let msg = `ERROR: ${error.message} ${error.stack ? error.stack : ""}`; let msg = `ERROR: ${error.message} ${error.stack ? error.stack : ""}`;
logger.error(msg); logger.error(msg);
await dc.context.sendActivity( await step.context.sendActivity(
Messages[dc.context.activity.locale].very_sorry_about_error Messages[step.context.activity.locale].very_sorry_about_error
); );
await dc.beginDialog("/ask", { isReturning: true }); await step.beginDialog("/ask", { isReturning: true });
} }
}); });
} }

View file

@ -38,6 +38,7 @@ import { GBMinInstance } from "botlib";
import { IGBDialog } from "botlib"; import { IGBDialog } from "botlib";
import { BotAdapter } from "botbuilder"; import { BotAdapter } from "botbuilder";
import { Messages } from "../strings"; import { Messages } from "../strings";
import { WaterfallDialog } from "botbuilder-dialogs";
export class FeedbackDialog extends IGBDialog { export class FeedbackDialog extends IGBDialog {
/** /**
@ -49,53 +50,59 @@ export class FeedbackDialog extends IGBDialog {
static setup(bot: BotAdapter, min: GBMinInstance) { static setup(bot: BotAdapter, min: GBMinInstance) {
const service = new CSService(); const service = new CSService();
min.dialogs.add("/feedbackNumber", [ min.dialogs.add(
async dc => { new WaterfallDialog("/feedbackNumber", [
let locale = dc.context.activity.locale; async step => {
await dc.prompt("choicePrompt", Messages[locale].what_about_me, [ let locale = step.context.activity.locale;
"1", // TODO: Migrate to 4.*+ await step.prompt("choicePrompt", Messages[locale].what_about_me, [
"2", // "1",
"3", // "2",
"4", // "3",
"5" // "4",
]); // "5"
}, // ]);
async (dc, value) => { return await step.next();
let locale = dc.context.activity.locale; },
let rate = value.entity; async step => {
const user = await min.userProfile.get(context, {}); let locale = step.context.activity.locale;
await service.updateConversationRate(user.conversation, rate); let rate = step.result.entity;
await dc.context.sendActivity(Messages[locale].thanks); const user = await min.userProfile.get(context, {});
} await service.updateConversationRate(user.conversation, rate);
]); await step.context.sendActivity(Messages[locale].thanks);
return await step.next();
min.dialogs.add("/feedback", [ }
async (dc, args) => { ])
let locale = dc.context.activity.locale; );
if (args && args.fromMenu) {
await dc.context.sendActivity(Messages[locale].about_suggestions); min.dialogs.add(new WaterfallDialog("/feedback", [
async step => {
let locale = step.context.activity.locale;
if (step.result.fromMenu) {
await step.context.sendActivity(Messages[locale].about_suggestions);
} }
await dc.prompt("textPrompt", Messages[locale].what_about_service); await step.prompt("textPrompt", Messages[locale].what_about_service);
return await step.next();
}, },
async (dc, value) => { async step => {
let locale = dc.context.activity.locale; let locale = step.context.activity.locale;
let rate = await AzureText.getSentiment( let rate = await AzureText.getSentiment(
min.instance.textAnalyticsKey, min.instance.textAnalyticsKey,
min.instance.textAnalyticsEndpoint, min.instance.textAnalyticsEndpoint,
min.conversationalService.getCurrentLanguage(dc), min.conversationalService.getCurrentLanguage(step),
value step.result
); );
if (rate > 0.5) { if (rate > 0.5) {
await dc.context.sendActivity(Messages[locale].glad_you_liked); await step.context.sendActivity(Messages[locale].glad_you_liked);
} else { } else {
await dc.context.sendActivity(Messages[locale].we_will_improve); await step.context.sendActivity(Messages[locale].we_will_improve);
// TODO: Record. // TODO: Record.
} }
await dc.replace("/ask", { isReturning: true }); await step.replaceDialog("/ask", { isReturning: true });
return await step.next();
} }
]); ]));
} }
} }

View file

@ -38,6 +38,7 @@ import { GBMinInstance } from "botlib";
import { CSService } from "../services/CSService"; import { CSService } from "../services/CSService";
import { BotAdapter } from "botbuilder"; import { BotAdapter } from "botbuilder";
import { Messages } from "../strings"; import { Messages } from "../strings";
import { WaterfallDialog } from "botbuilder-dialogs";
const logger = require("../../../src/logger"); const logger = require("../../../src/logger");
export class QualityDialog extends IGBDialog { export class QualityDialog extends IGBDialog {
@ -50,31 +51,32 @@ export class QualityDialog extends IGBDialog {
static setup(bot: BotAdapter, min: GBMinInstance) { static setup(bot: BotAdapter, min: GBMinInstance) {
const service = new CSService(); const service = new CSService();
min.dialogs.add("/quality", [ min.dialogs.add( new WaterfallDialog("/quality", [
async (dc, args) => { async step => {
const locale = dc.context.activity.locale; const locale = step.context.activity.locale;
const user = await min.userProfile.get(context, {}); const user = await min.userProfile.get(context, {});
var score = args.score; var score = step.result;
setTimeout( setTimeout(
() => min.conversationalService.sendEvent(dc, "stop", null), () => min.conversationalService.sendEvent(step, "stop", null),
400 400
); );
if (score == 0) { if (score == 0) {
await dc.context.sendActivity(Messages[locale].im_sorry_lets_try); await step.context.sendActivity(Messages[locale].im_sorry_lets_try);
} else { } else {
await dc.context.sendActivity(Messages[locale].great_thanks); await step.context.sendActivity(Messages[locale].great_thanks);
await service.insertQuestionAlternate( await service.insertQuestionAlternate(
min.instance.instanceId, min.instance.instanceId,
user.lastQuestion, user.lastQuestion,
user.lastQuestionId user.lastQuestionId
); );
await dc.replace("/ask", { isReturning: true }); await step.replaceDialog("/ask", { isReturning: true });
} }
return await step.next();
} }
]); ]));
} }
} }

View file

@ -57,7 +57,7 @@ export class GBCustomerSatisfactionPackage implements IGBPackage {
unloadBot(min: GBMinInstance): void { unloadBot(min: GBMinInstance): void {
} }
onNewSession(min: GBMinInstance, dc: any): void { onNewSession(min: GBMinInstance, step: any): void {
} }
} }

View file

@ -38,8 +38,7 @@ import { GBMinInstance } from "botlib";
import { KBService } from "./../services/KBService"; import { KBService } from "./../services/KBService";
import { BotAdapter } from "botbuilder"; import { BotAdapter } from "botbuilder";
import { Messages } from "../strings"; import { Messages } from "../strings";
import { LuisRecognizer } from "botbuilder-ai"; import { WaterfallDialog } from "botbuilder-dialogs";
import { GuaribasQuestion } from "../models";
const logger = require("../../../src/logger"); const logger = require("../../../src/logger");
@ -53,12 +52,12 @@ export class AskDialog extends IGBDialog {
static setup(bot: BotAdapter, min: GBMinInstance) { static setup(bot: BotAdapter, min: GBMinInstance) {
const service = new KBService(min.core.sequelize); const service = new KBService(min.core.sequelize);
min.dialogs.add("/answerEvent", [ min.dialogs.add(new WaterfallDialog("/answerEvent", [
async (dc, args) => { async step => {
if (args && args.questionId) { if (step.result && step.result.questionId) {
let question = await service.getQuestionById( let question = await service.getQuestionById(
min.instance.instanceId, min.instance.instanceId,
args.questionId step.result.questionId
); );
let answer = await service.getAnswerById( let answer = await service.getAnswerById(
min.instance.instanceId, min.instance.instanceId,
@ -67,34 +66,34 @@ export class AskDialog extends IGBDialog {
// Sends the answer to all outputs, including projector. // Sends the answer to all outputs, including projector.
await service.sendAnswer(min.conversationalService, dc, answer); await service.sendAnswer(min.conversationalService, step, answer);
await dc.replace("/ask", { isReturning: true }); await step.replaceDialog("/ask", { isReturning: true });
} }
return await step.next();
} }
]); ]));
min.dialogs.add("/answer", [ min.dialogs.add(new WaterfallDialog("/answer", [
async (dc, args) => { async step => {
const user = await min.userProfile.get(context, {}); const user = await min.userProfile.get(context, {});
let text = step.result.query;
let text = args.query;
if (!text) { if (!text) {
throw new Error(`/answer being called with no args.query text.`); throw new Error(`/answer being called with no args.query text.`);
} }
let locale = dc.context.activity.locale; let locale = step.context.activity.locale;
// Stops any content on projector. // Stops any content on projector.
await min.conversationalService.sendEvent(dc, "stop", null); await min.conversationalService.sendEvent(step, "stop", null);
// Handle extra text from FAQ. // Handle extra text from FAQ.
if (args && args.query) { if (step.result && step.result.query) {
text = args.query; text = step.result.query;
} else if (args && args.fromFaq) { } else if (step.result && step.result.fromFaq) {
await dc.context.sendActivity(Messages[locale].going_answer); await step.context.sendActivity(Messages[locale].going_answer);
} }
// Spells check the input text before sending Search or NLP. // Spells check the input text before sending Search or NLP.
@ -135,13 +134,13 @@ export class AskDialog extends IGBDialog {
await service.sendAnswer( await service.sendAnswer(
min.conversationalService, min.conversationalService,
dc, step,
resultsA.answer resultsA.answer
); );
// Goes to ask loop, again. // Goes to ask loop, again.
await dc.replace("/ask", { isReturning: true }); await step.replaceDialog("/ask", { isReturning: true });
} else { } else {
// Second time running Search, now with no filter. // Second time running Search, now with no filter.
@ -169,30 +168,31 @@ export class AskDialog extends IGBDialog {
let subjectText = `${KBService.getSubjectItemsSeparatedBySpaces( let subjectText = `${KBService.getSubjectItemsSeparatedBySpaces(
user.subjects user.subjects
)}`; )}`;
await dc.context.sendActivity(Messages[locale].wider_answer); await step.context.sendActivity(Messages[locale].wider_answer);
} }
// Sends the answer to all outputs, including projector. // Sends the answer to all outputs, including projector.
await service.sendAnswer( await service.sendAnswer(
min.conversationalService, min.conversationalService,
dc, step,
resultsB.answer resultsB.answer
); );
await dc.replace("/ask", { isReturning: true }); await step.replaceDialog("/ask", { isReturning: true });
} else { } else {
if (!(await min.conversationalService.routeNLP(dc, min, text))) { if (!(await min.conversationalService.routeNLP(step, min, text))) {
await dc.context.sendActivity(Messages[locale].did_not_find); await step.context.sendActivity(Messages[locale].did_not_find);
await dc.replace("/ask", { isReturning: true }); await step.replaceDialog("/ask", { isReturning: true });
} }
} }
} }
return await step.next();
} }
]); ]));
min.dialogs.add("/ask", [ min.dialogs.add(new WaterfallDialog("/ask", [
async (dc, args) => { async step => {
const locale = dc.context.activity.locale; const locale = step.context.activity.locale;
const user = await min.userProfile.get(context, {}); const user = await min.userProfile.get(context, {});
user.isAsking = true; user.isAsking = true;
if (!user.subjects) { if (!user.subjects) {
@ -202,9 +202,9 @@ export class AskDialog extends IGBDialog {
// Three forms of asking. // Three forms of asking.
if (args && args.firstTime) { if (step.result && step.result.firstTime) {
text = Messages[locale].ask_first_time; text = Messages[locale].ask_first_time;
} else if (args && args.isReturning) { } else if (step.result && step.result.isReturning) {
text = Messages[locale].anything_else; text = Messages[locale].anything_else;
} else if (user.subjects.length > 0) { } else if (user.subjects.length > 0) {
text = Messages[locale].which_question; text = Messages[locale].which_question;
@ -213,13 +213,14 @@ export class AskDialog extends IGBDialog {
} }
if (text.length > 0) { if (text.length > 0) {
await dc.prompt("textPrompt", text); // TODO: await step.prompt("textPrompt", text:text);
} }
return await step.next();
}, },
async (dc, value) => { async step => {
await dc.endAll(); await step.replaceDialog("/answer", { query: step.result });
await dc.beginDialog("/answer", { query: value }); return await step.next();
} }
]); ]));
} }
} }

View file

@ -37,6 +37,7 @@ import { IGBDialog } from "botlib"
import { BotAdapter } from "botbuilder" import { BotAdapter } from "botbuilder"
import { Messages } from "../strings"; import { Messages } from "../strings";
import { GBMinInstance } from "botlib" import { GBMinInstance } from "botlib"
import { WaterfallDialog } from 'botbuilder-dialogs';
export class FaqDialog extends IGBDialog { export class FaqDialog extends IGBDialog {
/** /**
@ -49,20 +50,21 @@ export class FaqDialog extends IGBDialog {
const service = new KBService(min.core.sequelize) const service = new KBService(min.core.sequelize)
min.dialogs.add("/faq", [ min.dialogs.add(new WaterfallDialog("/faq", [
async (dc, args) => { async step => {
let data = await service.getFaqBySubjectArray("faq", null) let data = await service.getFaqBySubjectArray("faq", null)
const locale = dc.context.activity.locale; const locale = step.context.activity.locale;
if (data) { if (data) {
await min.conversationalService.sendEvent(dc, "play", { await min.conversationalService.sendEvent(step, "play", {
playerType: "bullet", playerType: "bullet",
data: data.slice(0, 10) data: data.slice(0, 10)
}) })
await dc.context.sendActivity(Messages[locale].see_faq) // TODO: RND messages. await step.context.sendActivity(Messages[locale].see_faq) // TODO: RND messages.
await dc.endAll() await step.endDialog()
return await step.next();
} }
} }
]) ]))
} }
} }

View file

@ -30,17 +30,18 @@
| | | |
\*****************************************************************************/ \*****************************************************************************/
"use strict" "use strict";
const UrlJoin = require("url-join") const UrlJoin = require("url-join");
import { BotAdapter, CardFactory, MessageFactory } from "botbuilder" import { BotAdapter, CardFactory, MessageFactory } from "botbuilder";
import { IGBDialog } from "botlib" import { IGBDialog } from "botlib";
import { GBMinInstance } from "botlib" import { GBMinInstance } from "botlib";
import { GuaribasSubject } from "../models" import { GuaribasSubject } from "../models";
import { KBService } from "../services/KBService" import { KBService } from "../services/KBService";
import { Messages } from "../strings" import { Messages } from "../strings";
import { AzureText } from "pragmatismo-io-framework" import { AzureText } from "pragmatismo-io-framework";
import { WaterfallDialog } from "botbuilder-dialogs";
export class MenuDialog extends IGBDialog { export class MenuDialog extends IGBDialog {
/** /**
@ -50,30 +51,30 @@ export class MenuDialog extends IGBDialog {
* @param min The minimal bot instance data. * @param min The minimal bot instance data.
*/ */
static setup(bot: BotAdapter, min: GBMinInstance) { static setup(bot: BotAdapter, min: GBMinInstance) {
var service = new KBService(min.core.sequelize) var service = new KBService(min.core.sequelize);
min.dialogs.add("/menu", [ min.dialogs.add(new WaterfallDialog("/menu", [
async (dc, args) => { async step => {
const locale = dc.context.activity.locale const locale = step.context.activity.locale;
var rootSubjectId = null var rootSubjectId = null;
if (args && args.data) { if (step.result && step.result.data) {
var subject = args.data var subject = step.result.data;
// If there is a shortcut specified as subject destination, go there. // If there is a shortcut specified as subject destination, go there.
if (subject.to) { if (subject.to) {
let dialog = subject.to.split(":")[1] let dialog = subject.to.split(":")[1];
await dc.replace("/" + dialog) await step.replaceDialog("/" + dialog);
await dc.end() await step.endDialog();
return return;
} }
// Adds to bot a perception of a new subject. // Adds to bot a perception of a new subject.
const user = await min.userProfile.get(context, {}); const user = await min.userProfile.get(context, {});
user.subjects.push(subject) user.subjects.push(subject);
rootSubjectId = subject.subjectId rootSubjectId = subject.subjectId;
// Whenever a subject is selected, shows a faq about it. // Whenever a subject is selected, shows a faq about it.
@ -81,42 +82,37 @@ export class MenuDialog extends IGBDialog {
let data = await service.getFaqBySubjectArray( let data = await service.getFaqBySubjectArray(
"menu", "menu",
user.subjects user.subjects
) );
await min.conversationalService.sendEvent(dc, "play", { await min.conversationalService.sendEvent(step, "play", {
playerType: "bullet", playerType: "bullet",
data: data.slice(0, 10) data: data.slice(0, 10)
}) });
} }
} else { } else {
const user = await min.userProfile.get(context, {}); const user = await min.userProfile.get(context, {});
user.subjects = [] user.subjects = [];
await dc.context.sendActivity(Messages[locale].here_is_subjects) // TODO: Handle rnd. await step.context.sendActivity(Messages[locale].here_is_subjects); // TODO: Handle rnd.
user.isAsking = false user.isAsking = false;
} }
const msg = MessageFactory.text("") const msg = MessageFactory.text("");
var attachments = [] var attachments = [];
let data = await service.getSubjectItems( let data = await service.getSubjectItems(
min.instance.instanceId, min.instance.instanceId,
rootSubjectId rootSubjectId
) );
msg.attachmentLayout = "carousel" msg.attachmentLayout = "carousel";
data.forEach(function(item: GuaribasSubject) { data.forEach(function(item: GuaribasSubject) {
var subject = item var subject = item;
var card = CardFactory.heroCard( var card = CardFactory.heroCard(
subject.title, subject.title,
subject.description, subject.description,
CardFactory.images([ CardFactory.images([
UrlJoin( UrlJoin("/kb", min.instance.kb, "subjects", "subject.png")
"/kb",
min.instance.kb,
"subjects",
"subject.png"
)
]), ]),
CardFactory.actions([ CardFactory.actions([
{ {
@ -131,40 +127,42 @@ export class MenuDialog extends IGBDialog {
}) })
} }
]) ])
) );
attachments.push(card) attachments.push(card);
}) });
if (attachments.length == 0) { if (attachments.length == 0) {
const user = await min.userProfile.get(context, {}); const user = await min.userProfile.get(context, {});
if (user.subjects && user.subjects.length > 0) { if (user.subjects && user.subjects.length > 0) {
await dc.context.sendActivity( await step.context.sendActivity(
Messages[locale].lets_search( Messages[locale].lets_search(
KBService.getFormattedSubjectItems(user.subjects) KBService.getFormattedSubjectItems(user.subjects)
) )
) );
} }
await dc.replace("/ask", {}) await step.replaceDialog("/ask", {});
} else { } else {
msg.attachments = attachments msg.attachments = attachments;
await dc.context.sendActivity(msg) await step.context.sendActivity(msg);
} }
const user = await min.userProfile.get(context, {}); const user = await min.userProfile.get(context, {});
user.isAsking = true user.isAsking = true;
return await step.next();
}, },
async (dc, value) => { async step => {
var text = value var text = step.result;
const locale = dc.context.activity.locale const locale = step.context.activity.locale;
if (AzureText.isIntentNo(locale, text)) { if (AzureText.isIntentNo(locale, text)) {
await dc.replace("/feedback") await step.replaceDialog("/feedback");
} else { } else {
await dc.replace("/ask") await step.replaceDialog("/ask");
} }
return await step.next();
} }
]) ]));
} }
} }

View file

@ -68,7 +68,7 @@ export class GBKBPackage implements IGBPackage {
unloadBot(min: GBMinInstance): void { unloadBot(min: GBMinInstance): void {
} }
onNewSession(min: GBMinInstance, dc: any): void { onNewSession(min: GBMinInstance, step: any): void {
} }
} }

View file

@ -342,18 +342,18 @@ export class KBService {
} }
async sendAnswer(conversationalService: IGBConversationalService, async sendAnswer(conversationalService: IGBConversationalService,
dc: any, answer: GuaribasAnswer) { step: any, answer: GuaribasAnswer) {
if (answer.content.endsWith('.mp4')) { if (answer.content.endsWith('.mp4')) {
await conversationalService.sendEvent(dc, "play", { await conversationalService.sendEvent(step, "play", {
playerType: "video", playerType: "video",
data: answer.content data: answer.content
}) })
} else if (answer.content.length > 140 && } else if (answer.content.length > 140 &&
dc.context._activity.channelId === "webchat") { step.context._activity.channelId === "webchat") {
const locale = dc.context.activity.locale; const locale = step.context.activity.locale;
await dc.context.sendActivity(Messages[locale].will_answer_projector) // TODO: Handle rnd. await step.context.sendActivity(Messages[locale].will_answer_projector) // TODO: Handle rnd.
var html = answer.content var html = answer.content
if (answer.format === ".md") { if (answer.format === ".md") {
@ -370,7 +370,7 @@ export class KBService {
}) })
html = marked(answer.content) html = marked(answer.content)
} }
await conversationalService.sendEvent(dc, "play", await conversationalService.sendEvent(step, "play",
{ {
playerType: "markdown", data: { playerType: "markdown", data: {
content: html, answer: answer, content: html, answer: answer,
@ -378,8 +378,8 @@ export class KBService {
} }
}) })
} else { } else {
await dc.context.sendActivity(answer.content) await step.context.sendActivity(answer.content)
await conversationalService.sendEvent(dc, "stop", null) await conversationalService.sendEvent(step, "stop", null)
} }
} }

View file

@ -63,7 +63,7 @@ export class GBSecurityPackage implements IGBPackage {
unloadBot(min: GBMinInstance): void { unloadBot(min: GBMinInstance): void {
} }
onNewSession(min: GBMinInstance, dc: any): void { onNewSession(min: GBMinInstance, step: any): void {
} }
} }

View file

@ -66,7 +66,7 @@ export class GBWhatsappPackage implements IGBPackage {
unloadBot(min: GBMinInstance): void { unloadBot(min: GBMinInstance): void {
} }
onNewSession(min: GBMinInstance, dc: any): void { onNewSession(min: GBMinInstance, step: any): void {
} }
} }

View file

@ -158,7 +158,7 @@ export class GBServer {
instances = await core.loadInstances(); instances = await core.loadInstances();
let instance = instances[0]; let instance = instances[0];
if (process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
logger.info(`Updating bots proxies...`); logger.info(`Updating bot endpoint to local reverse proxy (ngrok)...`);
await azureDeployer.updateBotProxy( await azureDeployer.updateBotProxy(
instance.botId, instance.botId,