fix(core): Loaded dynamically a .js file containing converted VBA dialogs.
This commit is contained in:
parent
1761e06061
commit
3f32e48fad
10 changed files with 89 additions and 81 deletions
|
@ -33,16 +33,16 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { IGBInstance, IGBPackage } from 'botlib';
|
import { IGBInstance, IGBPackage ,GBMinInstance } from 'botlib';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview General Bots server core.
|
* @fileoverview General Bots server core.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export class DialogClass {
|
export class DialogClass {
|
||||||
public min: IGBInstance;
|
public min: GBMinInstance;
|
||||||
|
|
||||||
constructor(min: IGBInstance) {
|
constructor(min: GBMinInstance) {
|
||||||
this.min = min;
|
this.min = min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ export class DialogClass {
|
||||||
new WaterfallDialog('/vmSend', [
|
new WaterfallDialog('/vmSend', [
|
||||||
async step => {
|
async step => {
|
||||||
await step.context.sendActivity(text);
|
await step.context.sendActivity(text);
|
||||||
|
|
||||||
return await step.next();
|
return await step.next();
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
|
@ -184,8 +184,9 @@ export class GBCoreService implements IGBCoreService {
|
||||||
alter: alter,
|
alter: alter,
|
||||||
force: force
|
force: force
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const msg = 'Database synchronization is disabled.';
|
const msg = `Database synchronization is disabled.`;
|
||||||
logger.info(msg);
|
logger.info(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,21 +219,21 @@ export class GBCoreService implements IGBCoreService {
|
||||||
|
|
||||||
public async writeEnv(instance: IGBInstance) {
|
public async writeEnv(instance: IGBInstance) {
|
||||||
const env = `ADDITIONAL_DEPLOY_PATH=
|
const env = `ADDITIONAL_DEPLOY_PATH=
|
||||||
ADMIN_PASS=${instance.adminPass}
|
ADMIN_PASS=${instance.adminPass}
|
||||||
CLOUD_SUBSCRIPTIONID=${instance.cloudSubscriptionId}
|
CLOUD_SUBSCRIPTIONID=${instance.cloudSubscriptionId}
|
||||||
CLOUD_LOCATION=${instance.cloudLocation}
|
CLOUD_LOCATION=${instance.cloudLocation}
|
||||||
CLOUD_GROUP=${instance.botId}
|
CLOUD_GROUP=${instance.botId}
|
||||||
CLOUD_USERNAME=${instance.cloudUsername}
|
CLOUD_USERNAME=${instance.cloudUsername}
|
||||||
CLOUD_PASSWORD=${instance.cloudPassword}
|
CLOUD_PASSWORD=${instance.cloudPassword}
|
||||||
MARKETPLACE_ID=${instance.marketplaceId}
|
MARKETPLACE_ID=${instance.marketplaceId}
|
||||||
MARKETPLACE_SECRET=${instance.marketplacePassword}
|
MARKETPLACE_SECRET=${instance.marketplacePassword}
|
||||||
NLP_AUTHORING_KEY=${instance.nlpAuthoringKey}
|
NLP_AUTHORING_KEY=${instance.nlpAuthoringKey}
|
||||||
STORAGE_DIALECT=${instance.storageDialect}
|
STORAGE_DIALECT=${instance.storageDialect}
|
||||||
STORAGE_SERVER=${instance.storageServer}.database.windows.net
|
STORAGE_SERVER=${instance.storageServer}.database.windows.net
|
||||||
STORAGE_NAME=${instance.storageName}
|
STORAGE_NAME=${instance.storageName}
|
||||||
STORAGE_USERNAME=${instance.storageUsername}
|
STORAGE_USERNAME=${instance.storageUsername}
|
||||||
STORAGE_PASSWORD=${instance.storagePassword}
|
STORAGE_PASSWORD=${instance.storagePassword}
|
||||||
STORAGE_SYNC=true`;
|
STORAGE_SYNC=true`;
|
||||||
|
|
||||||
fs.writeFileSync('.env', env);
|
fs.writeFileSync('.env', env);
|
||||||
}
|
}
|
||||||
|
@ -312,6 +313,7 @@ export class GBCoreService implements IGBCoreService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadSysPackages(core: GBCoreService) {
|
public loadSysPackages(core: GBCoreService) {
|
||||||
|
|
||||||
// NOTE: if there is any code before this line a semicolon
|
// NOTE: if there is any code before this line a semicolon
|
||||||
// will be necessary before this line.
|
// will be necessary before this line.
|
||||||
// Loads all system packages.
|
// Loads all system packages.
|
||||||
|
@ -342,26 +344,21 @@ export class GBCoreService implements IGBCoreService {
|
||||||
|
|
||||||
public async createBootInstance(core: GBCoreService, azureDeployer: AzureDeployerService, proxyAddress: string) {
|
public async createBootInstance(core: GBCoreService, azureDeployer: AzureDeployerService, proxyAddress: string) {
|
||||||
let instance: IGBInstance;
|
let instance: IGBInstance;
|
||||||
try {
|
|
||||||
await core.initStorage();
|
|
||||||
} catch (error) {
|
|
||||||
logger.info(`Deploying cognitive infrastructure (on the cloud / on premises)...`);
|
logger.info(`Deploying cognitive infrastructure (on the cloud / on premises)...`);
|
||||||
try {
|
try {
|
||||||
instance = await azureDeployer.deployFarm(proxyAddress);
|
instance = await azureDeployer.deployFarm(proxyAddress);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
'In case of error, please cleanup any infrastructure objects ' +
|
`In case of error, please cleanup any infrastructure objects
|
||||||
'created during this procedure and .env before running again.'
|
created during this procedure and .env before running again.`
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
core.writeEnv(instance);
|
core.writeEnv(instance);
|
||||||
logger.info(`File .env written, starting General Bots...`);
|
logger.info(`File .env written, starting General Bots...`);
|
||||||
GBConfigService.init();
|
GBConfigService.init();
|
||||||
await core.initStorage();
|
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public openBrowserInDevelopment() {
|
public openBrowserInDevelopment() {
|
||||||
|
|
|
@ -43,7 +43,7 @@ const Fs = require('fs');
|
||||||
const WaitUntil = require('wait-until');
|
const WaitUntil = require('wait-until');
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
|
|
||||||
import { IGBCoreService, IGBInstance } from 'botlib';
|
import { GBMinInstance, IGBCoreService, IGBInstance } from 'botlib';
|
||||||
import { GBError } from 'botlib';
|
import { GBError } from 'botlib';
|
||||||
import { IGBPackage } from 'botlib';
|
import { IGBPackage } from 'botlib';
|
||||||
import { AzureSearch } from 'pragmatismo-io-framework';
|
import { AzureSearch } from 'pragmatismo-io-framework';
|
||||||
|
@ -174,9 +174,11 @@ export class GBDeployer {
|
||||||
/** Deploys all .gbot files first. */
|
/** Deploys all .gbot files first. */
|
||||||
|
|
||||||
botPackages.forEach(e => {
|
botPackages.forEach(e => {
|
||||||
|
if (e!=='packages\\boot.gbot'){
|
||||||
logger.info(`Deploying bot: ${e}...`);
|
logger.info(`Deploying bot: ${e}...`);
|
||||||
_this.deployBot(e);
|
_this.deployBot(e);
|
||||||
logger.info(`Bot: ${e} deployed...`);
|
logger.info(`Bot: ${e} deployed...`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Then all remaining generalPackages are loaded. */
|
/** Then all remaining generalPackages are loaded. */
|
||||||
|
@ -251,10 +253,11 @@ export class GBDeployer {
|
||||||
public async deployBot(localPath: string): Promise<IGBInstance> {
|
public async deployBot(localPath: string): Promise<IGBInstance> {
|
||||||
const packageType = Path.extname(localPath);
|
const packageType = Path.extname(localPath);
|
||||||
const packageName = Path.basename(localPath);
|
const packageName = Path.basename(localPath);
|
||||||
const instance = await this.importer.importIfNotExistsBotPackage(
|
const instance = await this.importer.importIfNotExistsBotPackage(null,
|
||||||
packageName,
|
packageName,
|
||||||
localPath
|
localPath
|
||||||
);
|
);
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +285,7 @@ export class GBDeployer {
|
||||||
// })
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
public async deployPackageFromLocalPath(min: IGBInstance, localPath: string) {
|
public async deployPackageFromLocalPath(min: GBMinInstance, localPath: string) {
|
||||||
const packageType = Path.extname(localPath);
|
const packageType = Path.extname(localPath);
|
||||||
|
|
||||||
switch (packageType) {
|
switch (packageType) {
|
||||||
|
|
|
@ -50,41 +50,29 @@ export class GBImporter {
|
||||||
this.core = core;
|
this.core = core;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async importIfNotExistsBotPackage(
|
public async importIfNotExistsBotPackage(botId: string, packageName: string, localPath: string) {
|
||||||
packageName: string,
|
const packageJson = JSON.parse(fs.readFileSync(UrlJoin(localPath, 'package.json'), 'utf8'));
|
||||||
localPath: string) {
|
if (!botId) {
|
||||||
|
botId = packageJson.botId;
|
||||||
const packageJson = JSON.parse(
|
}
|
||||||
fs.readFileSync(UrlJoin(localPath, 'package.json'), 'utf8')
|
|
||||||
);
|
|
||||||
const botId = packageJson.botId;
|
|
||||||
const instance = await this.core.loadInstance(botId);
|
const instance = await this.core.loadInstance(botId);
|
||||||
if (instance) {
|
if (instance) {
|
||||||
return instance;
|
return instance;
|
||||||
} else {
|
} else {
|
||||||
return await this.createInstanceInternal(packageName, localPath, packageJson);
|
return await this.createInstanceInternal(botId, packageName, localPath, packageJson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createInstanceInternal(
|
private async createInstanceInternal(botId: string, packageName: string, localPath: string, packageJson: any) {
|
||||||
packageName: string,
|
const settings = JSON.parse(fs.readFileSync(UrlJoin(localPath, 'settings.json'), 'utf8'));
|
||||||
localPath: string,
|
const servicesJson = JSON.parse(fs.readFileSync(UrlJoin(localPath, 'services.json'), 'utf8'));
|
||||||
packageJson: any
|
|
||||||
) {
|
|
||||||
const settings = JSON.parse(
|
|
||||||
fs.readFileSync(UrlJoin(localPath, 'settings.json'), 'utf8')
|
|
||||||
);
|
|
||||||
const servicesJson = JSON.parse(
|
|
||||||
fs.readFileSync(UrlJoin(localPath, 'services.json'), 'utf8')
|
|
||||||
);
|
|
||||||
|
|
||||||
packageJson = {...packageJson, ...settings, ...servicesJson};
|
packageJson = { ...packageJson, ...settings, ...servicesJson };
|
||||||
|
|
||||||
GuaribasInstance.create(packageJson).then((instance: IGBInstance) => {
|
if (botId){
|
||||||
const service = new SecService();
|
packageJson.botId = botId;
|
||||||
// TODO: service.importSecurityFile(localPath, instance)
|
}
|
||||||
|
|
||||||
Promise.resolve(instance);
|
return GuaribasInstance.create(packageJson);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,8 @@ export class GBMinService {
|
||||||
public async buildMin(
|
public async buildMin(
|
||||||
server: any,
|
server: any,
|
||||||
appPackages: IGBPackage[],
|
appPackages: IGBPackage[],
|
||||||
instances: GuaribasInstance[]
|
instances: GuaribasInstance[],
|
||||||
|
deployer: GBDeployer
|
||||||
): Promise<GBMinInstance> {
|
): Promise<GBMinInstance> {
|
||||||
// Serves default UI on root address '/'.
|
// Serves default UI on root address '/'.
|
||||||
|
|
||||||
|
@ -169,6 +170,11 @@ export class GBMinService {
|
||||||
instance
|
instance
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Install default VBA module.
|
||||||
|
|
||||||
|
deployer.deployPackageFromLocalPath(min, 'packages/default.gbdialog');
|
||||||
|
|
||||||
|
|
||||||
// Call the loadBot context.activity for all packages.
|
// Call the loadBot context.activity for all packages.
|
||||||
|
|
||||||
this.invokeLoadBot(appPackages, min, server);
|
this.invokeLoadBot(appPackages, min, server);
|
||||||
|
|
|
@ -33,8 +33,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { IGBCoreService, IGBInstance } from 'botlib';
|
import { IGBCoreService, IGBInstance } from 'botlib';
|
||||||
import { GBError } from 'botlib';
|
import { GBMinInstance } from 'botlib';
|
||||||
import { IGBPackage } from 'botlib';
|
|
||||||
const logger = require('../../../src/logger');
|
const logger = require('../../../src/logger');
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
|
@ -57,18 +56,20 @@ export class GBVMService implements IGBCoreService {
|
||||||
|
|
||||||
public async loadJS(
|
public async loadJS(
|
||||||
filename: string,
|
filename: string,
|
||||||
min: IGBInstance,
|
min: GBMinInstance,
|
||||||
core: IGBCoreService,
|
core: IGBCoreService,
|
||||||
deployer: GBDeployer,
|
deployer: GBDeployer,
|
||||||
localPath: string
|
localPath: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
localPath = UrlJoin(localPath, 'chat.dialog.js');
|
|
||||||
const code: string = fs.readFileSync(UrlJoin(localPath, filename), 'utf8');
|
localPath = UrlJoin(localPath, 'bot.vbs.js');
|
||||||
|
const code: string = fs.readFileSync(localPath, 'utf8');
|
||||||
const sandbox: DialogClass = new DialogClass(min);
|
const sandbox: DialogClass = new DialogClass(min);
|
||||||
const context = vm.createContext(sandbox);
|
const context = vm.createContext(sandbox);
|
||||||
|
|
||||||
this.script.runInContext(code, context);
|
vm.runInContext(code, context);
|
||||||
console.log(util.inspect(sandbox));
|
console.log(util.inspect(sandbox));
|
||||||
|
sandbox['chat'](sandbox);
|
||||||
|
|
||||||
await deployer.deployScriptToStorage(min.instanceId, filename);
|
await deployer.deployScriptToStorage(min.instanceId, filename);
|
||||||
logger.info(`[GBVMService] Finished loading of ${filename}`);
|
logger.info(`[GBVMService] Finished loading of ${filename}`);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
export function chat() {
|
|
||||||
|
function chat(bot) {
|
||||||
|
|
||||||
//****************************************************************************
|
//****************************************************************************
|
||||||
// ( )_ _
|
// ( )_ _
|
||||||
// _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _
|
// _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _
|
||||||
|
@ -31,11 +33,13 @@ export function chat() {
|
||||||
//
|
//
|
||||||
//****************************************************************************
|
//****************************************************************************
|
||||||
|
|
||||||
|
bot.talk('Qual seu e-mail?');
|
||||||
|
|
||||||
main = () => {
|
main = () => {
|
||||||
bot.addFunction(PegaEmail);
|
bot.addFunction(PegaEmail);
|
||||||
|
|
||||||
PegaEmail = bot => {
|
PegaEmail = bot => {
|
||||||
bot.say('Qual seu e-mail?');
|
bot.talk('Qual seu e-mail?');
|
||||||
email = bot.expectEmail;
|
email = bot.expectEmail;
|
||||||
bot.post('/restservice', email);
|
bot.post('/restservice', email);
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,10 +59,10 @@ export class AskDialog extends IGBDialog {
|
||||||
min.dialogs.add(
|
min.dialogs.add(
|
||||||
new WaterfallDialog('/answerEvent', [
|
new WaterfallDialog('/answerEvent', [
|
||||||
async step => {
|
async step => {
|
||||||
if (step.options && step.options.questionId) {
|
if (step.options && step.options['questionId']) {
|
||||||
const question = await service.getQuestionById(
|
const question = await service.getQuestionById(
|
||||||
min.instance.instanceId,
|
min.instance.instanceId,
|
||||||
step.options.questionId
|
step.options['questionId']
|
||||||
);
|
);
|
||||||
const answer = await service.getAnswerById(
|
const answer = await service.getAnswerById(
|
||||||
min.instance.instanceId,
|
min.instance.instanceId,
|
||||||
|
@ -84,7 +84,7 @@ export class AskDialog extends IGBDialog {
|
||||||
new WaterfallDialog('/answer', [
|
new WaterfallDialog('/answer', [
|
||||||
async step => {
|
async step => {
|
||||||
const user = await min.userProfile.get(step.context, {});
|
const user = await min.userProfile.get(step.context, {});
|
||||||
let text = step.options.query;
|
let text = step.options['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.`);
|
||||||
}
|
}
|
||||||
|
@ -97,9 +97,9 @@ export class AskDialog extends IGBDialog {
|
||||||
|
|
||||||
// Handle extra text from FAQ.
|
// Handle extra text from FAQ.
|
||||||
|
|
||||||
if (step.options && step.options.query) {
|
if (step.options && step.options['query']) {
|
||||||
text = step.options.query;
|
text = step.options['query'];
|
||||||
} else if (step.options && step.options.fromFaq) {
|
} else if (step.options && step.options['fromFaq']) {
|
||||||
await step.context.sendActivity(Messages[locale].going_answer);
|
await step.context.sendActivity(Messages[locale].going_answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,9 +212,9 @@ export class AskDialog extends IGBDialog {
|
||||||
|
|
||||||
// Three forms of asking.
|
// Three forms of asking.
|
||||||
|
|
||||||
if (step.options && step.options.firstTime) {
|
if (step.options && step.options['firstTime']) {
|
||||||
text = Messages[locale].ask_first_time;
|
text = Messages[locale].ask_first_time;
|
||||||
} else if (step.options && step.options.isReturning) {
|
} else if (step.options && step.options['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;
|
||||||
|
|
|
@ -63,7 +63,7 @@ export class MenuDialog extends IGBDialog {
|
||||||
const locale = step.context.activity.locale;
|
const locale = step.context.activity.locale;
|
||||||
let rootSubjectId = null;
|
let rootSubjectId = null;
|
||||||
|
|
||||||
if (step.options && step.options.data) {
|
if (step.options && step.options['data']) {
|
||||||
const subject = step.result.data;
|
const 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.
|
||||||
|
|
22
src/app.ts
22
src/app.ts
|
@ -103,24 +103,32 @@ export class GBServer {
|
||||||
const conversationalService: GBConversationalService = new GBConversationalService(core);
|
const conversationalService: GBConversationalService = new GBConversationalService(core);
|
||||||
core.ensureAdminIsSecured();
|
core.ensureAdminIsSecured();
|
||||||
|
|
||||||
const bootInstance = await core.createBootInstance(core, azureDeployer, proxyAddress);
|
let bootInstance: IGBInstance = null;
|
||||||
await core.checkStorage(azureDeployer);
|
try {
|
||||||
|
await core.initStorage();
|
||||||
|
} catch (error) {
|
||||||
|
bootInstance = await core.createBootInstance(core, azureDeployer, proxyAddress);
|
||||||
|
await core.initStorage();
|
||||||
|
}
|
||||||
|
|
||||||
await core.loadSysPackages(core);
|
await core.loadSysPackages(core);
|
||||||
|
await core.checkStorage(azureDeployer);
|
||||||
await deployer.deployPackages(core, server, appPackages);
|
await deployer.deployPackages(core, server, appPackages);
|
||||||
|
|
||||||
logger.info(`Publishing instances...`);
|
logger.info(`Publishing instances...`);
|
||||||
const packageInstance = await importer.importIfNotExistsBotPackage('boot.gbot', 'packages/boot.gbot');
|
const packageInstance = await importer.importIfNotExistsBotPackage(
|
||||||
|
GBConfigService.get('CLOUD_GROUP'),
|
||||||
|
'boot.gbot',
|
||||||
|
'packages/boot.gbot'
|
||||||
|
);
|
||||||
const fullInstance = Object.assign(packageInstance, bootInstance);
|
const fullInstance = Object.assign(packageInstance, bootInstance);
|
||||||
await core.saveInstance(fullInstance);
|
await core.saveInstance(fullInstance);
|
||||||
let instances: GuaribasInstance[] = await core.loadAllInstances(core, azureDeployer, proxyAddress);
|
let instances: GuaribasInstance[] = await core.loadAllInstances(core, azureDeployer, proxyAddress);
|
||||||
instances = await core.ensureInstances(instances, bootInstance, core);
|
instances = await core.ensureInstances(instances, bootInstance, core);
|
||||||
|
|
||||||
// Install default VBA module.
|
|
||||||
|
|
||||||
deployer.deployPackageFromLocalPath(instances[0], 'packages/default.gbdialog');
|
|
||||||
|
|
||||||
const minService: GBMinService = new GBMinService(core, conversationalService, adminService, deployer);
|
const minService: GBMinService = new GBMinService(core, conversationalService, adminService, deployer);
|
||||||
await minService.buildMin(server, appPackages, instances);
|
await minService.buildMin(server, appPackages, instances, deployer);
|
||||||
|
|
||||||
logger.info(`The Bot Server is in RUNNING mode...`);
|
logger.info(`The Bot Server is in RUNNING mode...`);
|
||||||
core.openBrowserInDevelopment();
|
core.openBrowserInDevelopment();
|
||||||
|
|
Loading…
Add table
Reference in a new issue