new(all): TRUE multicloud.
|
@ -313,7 +313,7 @@ export class AdminDialog extends IGBDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packageName.indexOf('.') !== -1) {
|
if (packageName.indexOf('.') !== -1) {
|
||||||
cmd1 = `deployPackage ${process.env.STORAGE_SITE} /${process.env.STORAGE_LIBRARY}/${botId}.gbai/${packageName}`;
|
cmd1 = `deployPackage ${process.env.STORAGE_SITE} /${GBConfigService.get('STORAGE_LIBRARY')}/${botId}.gbai/${packageName}`;
|
||||||
} else {
|
} else {
|
||||||
cmd1 = `deployPackage ${packageName}`;
|
cmd1 = `deployPackage ${packageName}`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,8 +187,8 @@ export class GBAdminService implements IGBAdminService {
|
||||||
await deployer['cleanupPackage'](min.instance, packageName);
|
await deployer['cleanupPackage'](min.instance, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.STORAGE_FILE) {
|
if (GBConfigService.get('STORAGE_FILE')) {
|
||||||
const path = Path.join(process.env.STORAGE_LIBRARY, gbaiPath);
|
const path = Path.join(GBConfigService.get('STORAGE_LIBRARY'), gbaiPath);
|
||||||
Fs.cpSync(path, localFolder, { errorOnExist: false, force: true, recursive: true});
|
Fs.cpSync(path, localFolder, { errorOnExist: false, force: true, recursive: true});
|
||||||
} else {
|
} else {
|
||||||
await deployer['downloadFolder'](min, Path.join('work', `${gbai}`), Path.basename(localFolder));
|
await deployer['downloadFolder'](min, Path.join('work', `${gbai}`), Path.basename(localFolder));
|
||||||
|
|
|
@ -36,11 +36,11 @@
|
||||||
|
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GBConversationalService } from '../services/GBConversationalService.js';
|
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { GBLogEx } from '../services/GBLogEx.js';
|
import { GBLogEx } from '../services/GBLogEx.js';
|
||||||
|
import { GBConfigService } from '../services/GBConfigService.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog for Welcoming people.
|
* Dialog for Welcoming people.
|
||||||
|
@ -65,7 +65,7 @@ export class WelcomeDialog extends IGBDialog {
|
||||||
async step => {
|
async step => {
|
||||||
if (
|
if (
|
||||||
GBServer.globals.entryPointDialog !== null &&
|
GBServer.globals.entryPointDialog !== null &&
|
||||||
min.instance.botId === process.env.BOT_ID &&
|
min.instance.botId === GBConfigService.get('BOT_ID') &&
|
||||||
step.context.activity.channelId === 'webchat'
|
step.context.activity.channelId === 'webchat'
|
||||||
) {
|
) {
|
||||||
return step.replaceDialog(GBServer.globals.entryPointDialog);
|
return step.replaceDialog(GBServer.globals.entryPointDialog);
|
||||||
|
|
|
@ -42,7 +42,7 @@ import * as en from 'dotenv-extended';
|
||||||
*/
|
*/
|
||||||
export class GBConfigService {
|
export class GBConfigService {
|
||||||
public static getBoolean(value: string): boolean {
|
public static getBoolean(value: string): boolean {
|
||||||
return (this.get(value) as unknown) as boolean;
|
return this.get(value) as unknown as boolean;
|
||||||
}
|
}
|
||||||
public static getServerPort(): string {
|
public static getServerPort(): string {
|
||||||
if (process.env.PORT) {
|
if (process.env.PORT) {
|
||||||
|
@ -84,8 +84,11 @@ export class GBConfigService {
|
||||||
case 'CLOUD_USERNAME':
|
case 'CLOUD_USERNAME':
|
||||||
value = undefined;
|
value = undefined;
|
||||||
break;
|
break;
|
||||||
|
case 'STORAGE_LIBRARY':
|
||||||
|
value = `${process.env.HOME}/gbpackages`;
|
||||||
|
break;
|
||||||
case 'BOT_ID':
|
case 'BOT_ID':
|
||||||
value = undefined;
|
value = 'default';
|
||||||
break;
|
break;
|
||||||
case 'CLOUD_PASSWORD':
|
case 'CLOUD_PASSWORD':
|
||||||
value = undefined;
|
value = undefined;
|
||||||
|
@ -103,7 +106,7 @@ export class GBConfigService {
|
||||||
value = undefined;
|
value = undefined;
|
||||||
break;
|
break;
|
||||||
case 'STORAGE_DIALECT':
|
case 'STORAGE_DIALECT':
|
||||||
value = undefined;
|
value = 'sqlite';
|
||||||
break;
|
break;
|
||||||
case 'STORAGE_FILE':
|
case 'STORAGE_FILE':
|
||||||
value = './data.db';
|
value = './data.db';
|
||||||
|
@ -160,7 +163,7 @@ export class GBConfigService {
|
||||||
value = true;
|
value = true;
|
||||||
break;
|
break;
|
||||||
case 'BOT_URL':
|
case 'BOT_URL':
|
||||||
value = undefined;
|
value = 'http://localhost:4242';
|
||||||
break;
|
break;
|
||||||
case 'STORAGE_SERVER':
|
case 'STORAGE_SERVER':
|
||||||
value = undefined;
|
value = undefined;
|
||||||
|
|
|
@ -50,6 +50,7 @@ import { GBSecurityPackage } from '../../security.gbapp/index.js';
|
||||||
import { GBWhatsappPackage } from '../../whatsapp.gblib/index.js';
|
import { GBWhatsappPackage } from '../../whatsapp.gblib/index.js';
|
||||||
import { GuaribasApplications, GuaribasInstance, GuaribasLog } from '../models/GBModel.js';
|
import { GuaribasApplications, GuaribasInstance, GuaribasLog } from '../models/GBModel.js';
|
||||||
import { GBConfigService } from './GBConfigService.js';
|
import { GBConfigService } from './GBConfigService.js';
|
||||||
|
import mkdirp from 'mkdirp';
|
||||||
import { GBAzureDeployerPackage } from '../../azuredeployer.gbapp/index.js';
|
import { GBAzureDeployerPackage } from '../../azuredeployer.gbapp/index.js';
|
||||||
import { GBSharePointPackage } from '../../sharepoint.gblib/index.js';
|
import { GBSharePointPackage } from '../../sharepoint.gblib/index.js';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||||
|
@ -109,7 +110,7 @@ export class GBCoreService implements IGBCoreService {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.adminService = new GBAdminService(this);
|
this.adminService = new GBAdminService(this);
|
||||||
}
|
}
|
||||||
public async ensureInstances(instances: IGBInstance[], bootInstance: any, core: IGBCoreService) { }
|
public async ensureInstances(instances: IGBInstance[], bootInstance: any, core: IGBCoreService) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets database config and connect to storage. Currently two databases
|
* Gets database config and connect to storage. Currently two databases
|
||||||
|
@ -138,8 +139,8 @@ export class GBCoreService implements IGBCoreService {
|
||||||
const logging: boolean | Function =
|
const logging: boolean | Function =
|
||||||
GBConfigService.get('STORAGE_LOGGING') === 'true'
|
GBConfigService.get('STORAGE_LOGGING') === 'true'
|
||||||
? (str: string): void => {
|
? (str: string): void => {
|
||||||
GBLogEx.info(0, str);
|
GBLogEx.info(0, str);
|
||||||
}
|
}
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
const encrypt: boolean = GBConfigService.get('STORAGE_ENCRYPT') === 'true';
|
const encrypt: boolean = GBConfigService.get('STORAGE_ENCRYPT') === 'true';
|
||||||
|
@ -231,7 +232,6 @@ export class GBCoreService implements IGBCoreService {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all items to start several listeners.
|
* Loads all items to start several listeners.
|
||||||
*/
|
*/
|
||||||
|
@ -426,12 +426,11 @@ ENDPOINT_UPDATE=true
|
||||||
let instances: IGBInstance[];
|
let instances: IGBInstance[];
|
||||||
try {
|
try {
|
||||||
instances = await core.loadInstances();
|
instances = await core.loadInstances();
|
||||||
const group = GBConfigService.get('CLOUD_GROUP')??GBConfigService.get('BOT_ID');
|
const group = GBConfigService.get('CLOUD_GROUP') ?? GBConfigService.get('BOT_ID');
|
||||||
if (process.env.ENDPOINT_UPDATE === 'true') {
|
if (process.env.ENDPOINT_UPDATE === 'true') {
|
||||||
await CollectionUtil.asyncForEach(instances, async instance => {
|
await CollectionUtil.asyncForEach(instances, async instance => {
|
||||||
GBLogEx.info(instance.instanceId, `Updating bot endpoint for ${instance.botId}...`);
|
GBLogEx.info(instance.instanceId, `Updating bot endpoint for ${instance.botId}...`);
|
||||||
try {
|
try {
|
||||||
|
|
||||||
await installationDeployer.updateBotProxy(
|
await installationDeployer.updateBotProxy(
|
||||||
instance.botId,
|
instance.botId,
|
||||||
group,
|
group,
|
||||||
|
@ -459,7 +458,10 @@ ENDPOINT_UPDATE=true
|
||||||
Try setting STORAGE_SYNC to true in .env file. Error: ${error.message}.`
|
Try setting STORAGE_SYNC to true in .env file. Error: ${error.message}.`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
GBLogEx.info(0, `Storage is empty. After collecting storage structure from all .gbapps it will get synced.`);
|
GBLogEx.info(
|
||||||
|
0,
|
||||||
|
`Storage is empty. After collecting storage structure from all .gbapps it will get synced.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Cannot connect to operating storage: ${error.message}.`);
|
throw new Error(`Cannot connect to operating storage: ${error.message}.`);
|
||||||
|
@ -520,7 +522,6 @@ ENDPOINT_UPDATE=true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async createBootInstance(
|
public async createBootInstance(
|
||||||
core: GBCoreService,
|
core: GBCoreService,
|
||||||
installationDeployer: IGBInstallationDeployer,
|
installationDeployer: IGBInstallationDeployer,
|
||||||
|
@ -529,9 +530,10 @@ ENDPOINT_UPDATE=true
|
||||||
return await this.createBootInstanceEx(
|
return await this.createBootInstanceEx(
|
||||||
core,
|
core,
|
||||||
installationDeployer,
|
installationDeployer,
|
||||||
proxyAddress, null,
|
proxyAddress,
|
||||||
GBConfigService.get('FREE_TIER'));
|
null,
|
||||||
|
GBConfigService.get('FREE_TIER')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Creates the first bot instance (boot instance) used to "boot" the server.
|
* Creates the first bot instance (boot instance) used to "boot" the server.
|
||||||
|
@ -548,8 +550,10 @@ ENDPOINT_UPDATE=true
|
||||||
) {
|
) {
|
||||||
GBLogEx.info(0, `Deploying cognitive infrastructure (on the cloud / on premises)...`);
|
GBLogEx.info(0, `Deploying cognitive infrastructure (on the cloud / on premises)...`);
|
||||||
try {
|
try {
|
||||||
const { instance, credentials, subscriptionId, installationDeployer }
|
const { instance, credentials, subscriptionId, installationDeployer } = await StartDialog.createBaseInstance(
|
||||||
= await StartDialog.createBaseInstance(deployer, freeTier);
|
deployer,
|
||||||
|
freeTier
|
||||||
|
);
|
||||||
installationDeployer['core'] = this;
|
installationDeployer['core'] = this;
|
||||||
const changedInstance = await installationDeployer['deployFarm2'](
|
const changedInstance = await installationDeployer['deployFarm2'](
|
||||||
proxyAddress,
|
proxyAddress,
|
||||||
|
@ -668,27 +672,26 @@ ENDPOINT_UPDATE=true
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setConfig(min, name: string, value: any): Promise<any> {
|
public async setConfig(min, name: string, value: any): Promise<any> {
|
||||||
|
|
||||||
// Handles calls for BASIC persistence on sheet files.
|
// Handles calls for BASIC persistence on sheet files.
|
||||||
|
|
||||||
GBLog.info( `Defining Config.xlsx variable ${name}= '${value}'...`);
|
GBLog.info(`Defining Config.xlsx variable ${name}= '${value}'...`);
|
||||||
|
|
||||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||||
|
|
||||||
const maxLines = 512;
|
const maxLines = 512;
|
||||||
const file = "Config.xlsx";
|
const file = 'Config.xlsx';
|
||||||
const path = DialogKeywords.getGBAIPath(min.botId, `gbot`);;
|
const path = DialogKeywords.getGBAIPath(min.botId, `gbot`);
|
||||||
|
|
||||||
let document = await (new SystemKeywords()).internalGetDocument(client, baseUrl, path, file);
|
let document = await new SystemKeywords().internalGetDocument(client, baseUrl, path, file);
|
||||||
|
|
||||||
// Creates workbook session that will be discarded.
|
// Creates book session that will be discarded.
|
||||||
|
|
||||||
let sheets = await client
|
let sheets = await client.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets`).get();
|
||||||
.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets`)
|
|
||||||
.get();
|
|
||||||
|
|
||||||
let results = await client
|
let results = await client
|
||||||
.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='A1:A${maxLines}')`)
|
.api(
|
||||||
|
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='A1:A${maxLines}')`
|
||||||
|
)
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
const rows = results.text;
|
const rows = results.text;
|
||||||
|
@ -708,12 +711,12 @@ ENDPOINT_UPDATE=true
|
||||||
body.values[0][0] = value;
|
body.values[0][0] = value;
|
||||||
|
|
||||||
await client
|
await client
|
||||||
.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${address}')`)
|
.api(
|
||||||
|
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${address}')`
|
||||||
|
)
|
||||||
.patch(body);
|
.patch(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a dynamic param from instance. Dynamic params are defined in Config.xlsx
|
* Get a dynamic param from instance. Dynamic params are defined in Config.xlsx
|
||||||
* and loaded into the work folder from comida command.
|
* and loaded into the work folder from comida command.
|
||||||
|
@ -729,8 +732,7 @@ ENDPOINT_UPDATE=true
|
||||||
// Gets .gbot Params from specified bot.
|
// Gets .gbot Params from specified bot.
|
||||||
|
|
||||||
if (instance.params) {
|
if (instance.params) {
|
||||||
|
params = typeof instance.params === 'object' ? instance.params : JSON.parse(instance.params);
|
||||||
params = typeof (instance.params) === 'object' ? instance.params : JSON.parse(instance.params);
|
|
||||||
params = GBUtil.caseInsensitive(params);
|
params = GBUtil.caseInsensitive(params);
|
||||||
value = params ? params[name] : defaultValue;
|
value = params ? params[name] : defaultValue;
|
||||||
}
|
}
|
||||||
|
@ -740,7 +742,6 @@ ENDPOINT_UPDATE=true
|
||||||
params = GBUtil.caseInsensitive(instance['dataValues']);
|
params = GBUtil.caseInsensitive(instance['dataValues']);
|
||||||
|
|
||||||
if (params && !value) {
|
if (params && !value) {
|
||||||
|
|
||||||
// Retrieves the value from specified bot instance (no params collection).
|
// Retrieves the value from specified bot instance (no params collection).
|
||||||
|
|
||||||
value = instance['dataValues'][name];
|
value = instance['dataValues'][name];
|
||||||
|
@ -749,27 +750,23 @@ ENDPOINT_UPDATE=true
|
||||||
|
|
||||||
const minBoot = GBServer.globals.minBoot as any;
|
const minBoot = GBServer.globals.minBoot as any;
|
||||||
|
|
||||||
if (
|
if (minBoot.instance && !value && instance.botId != minBoot.instance.botId) {
|
||||||
minBoot.instance &&
|
|
||||||
!value && instance.botId != minBoot.instance.botId) {
|
|
||||||
|
|
||||||
instance = minBoot.instance;
|
instance = minBoot.instance;
|
||||||
|
|
||||||
if(instance.params){
|
if (instance.params) {
|
||||||
params = typeof (instance.params) === 'object' ? instance.params : JSON.parse(instance.params);
|
params = typeof instance.params === 'object' ? instance.params : JSON.parse(instance.params);
|
||||||
params = GBUtil.caseInsensitive(params);
|
params = GBUtil.caseInsensitive(params);
|
||||||
value = params ? params[name] : defaultValue;
|
value = params ? params[name] : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If still did not found in boot bot params, try instance fields.
|
// If still did not found in boot bot params, try instance fields.
|
||||||
|
|
||||||
if (!value){
|
if (!value) {
|
||||||
value = instance['dataValues'][name];
|
value = instance['dataValues'][name];
|
||||||
}
|
}
|
||||||
if (!value){
|
if (!value) {
|
||||||
value = instance[name];
|
value = instance[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -787,7 +784,7 @@ ENDPOINT_UPDATE=true
|
||||||
return new Number(value ? value : defaultValue ? defaultValue : 0).valueOf();
|
return new Number(value ? value : defaultValue ? defaultValue : 0).valueOf();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ret = value ?? defaultValue;
|
const ret = value ?? defaultValue;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,7 +795,7 @@ ENDPOINT_UPDATE=true
|
||||||
let params = null;
|
let params = null;
|
||||||
const list = [];
|
const list = [];
|
||||||
if (instance.params) {
|
if (instance.params) {
|
||||||
params = typeof (instance.params) === 'object' ? instance.params : JSON.parse(instance.params);
|
params = typeof instance.params === 'object' ? instance.params : JSON.parse(instance.params);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(params).forEach(e => {
|
Object.keys(params).forEach(e => {
|
||||||
|
@ -810,5 +807,83 @@ ENDPOINT_UPDATE=true
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async ensureFolders(instances, deployer: GBDeployer) {
|
||||||
|
let libraryPath = GBConfigService.get('STORAGE_LIBRARY');
|
||||||
|
|
||||||
|
if (!Fs.existsSync(libraryPath)) {
|
||||||
|
mkdirp.sync(libraryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
await this.syncBotStorage(instances, 'default', deployer, libraryPath);
|
||||||
|
|
||||||
|
const files = Fs.readdirSync(libraryPath);
|
||||||
|
await CollectionUtil.asyncForEach(files, async file => {
|
||||||
|
|
||||||
|
if (file.trim().toLowerCase() !== 'default.gbai'){
|
||||||
|
|
||||||
|
let botId = file.replace(/\.gbai/, '');
|
||||||
|
|
||||||
|
await this.syncBotStorage(instances, botId, deployer, libraryPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async syncBotStorage(instances: any, botId: any, deployer: GBDeployer, libraryPath: string) {
|
||||||
|
let instance = instances.find(p => p.botId.toLowerCase().trim() === botId.toLowerCase().trim());
|
||||||
|
|
||||||
|
if (!instance) {
|
||||||
|
|
||||||
|
GBLog.info(`Importing package ${botId}...`);
|
||||||
|
|
||||||
|
// Creates a bot.
|
||||||
|
|
||||||
|
let mobile = null,
|
||||||
|
email = null;
|
||||||
|
|
||||||
|
instance = await deployer.deployBlankBot(botId, mobile, email);
|
||||||
|
const gbaiPath = Path.join(libraryPath, `${botId}.gbai`);
|
||||||
|
|
||||||
|
if (!Fs.existsSync(gbaiPath)) {
|
||||||
|
|
||||||
|
Fs.mkdirSync(gbaiPath, { recursive: true });
|
||||||
|
|
||||||
|
const base = Path.join(process.env.PWD, 'templates', 'default.gbai');
|
||||||
|
|
||||||
|
Fs.cpSync(Path.join(base, `default.gbkb`), gbaiPath, {
|
||||||
|
errorOnExist: false,
|
||||||
|
force: true,
|
||||||
|
recursive: true
|
||||||
|
});
|
||||||
|
Fs.cpSync(Path.join(base, `default.gbot`), gbaiPath, {
|
||||||
|
errorOnExist: false,
|
||||||
|
force: true,
|
||||||
|
recursive: true
|
||||||
|
});
|
||||||
|
Fs.cpSync(Path.join(base, `default.gbtheme`), gbaiPath, {
|
||||||
|
errorOnExist: false,
|
||||||
|
force: true,
|
||||||
|
recursive: true
|
||||||
|
});
|
||||||
|
Fs.cpSync(Path.join(base, `default.gbdata`), gbaiPath, {
|
||||||
|
errorOnExist: false,
|
||||||
|
force: true,
|
||||||
|
recursive: true
|
||||||
|
});
|
||||||
|
Fs.cpSync(Path.join(base, `default.gbdialog`), gbaiPath, {
|
||||||
|
errorOnExist: false,
|
||||||
|
force: true,
|
||||||
|
recursive: true
|
||||||
|
});
|
||||||
|
Fs.cpSync(Path.join(base, `default.gbdrive`), gbaiPath, {
|
||||||
|
errorOnExist: false,
|
||||||
|
force: true,
|
||||||
|
recursive: true
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
);
|
);
|
||||||
|
|
||||||
const siteId = process.env.STORAGE_SITE_ID;
|
const siteId = process.env.STORAGE_SITE_ID;
|
||||||
const libraryId = process.env.STORAGE_LIBRARY;
|
const libraryId = GBConfigService.get('STORAGE_LIBRARY');
|
||||||
|
|
||||||
const client = MicrosoftGraph.Client.init({
|
const client = MicrosoftGraph.Client.init({
|
||||||
authProvider: done => {
|
authProvider: done => {
|
||||||
|
@ -222,22 +222,24 @@ export class GBDeployer implements IGBDeployer {
|
||||||
const instance = await this.importer.createBotInstance(botId);
|
const instance = await this.importer.createBotInstance(botId);
|
||||||
const bootInstance = GBServer.globals.bootInstance;
|
const bootInstance = GBServer.globals.bootInstance;
|
||||||
|
|
||||||
// Gets the access token to perform service operations.
|
if (!GBConfigService.get('STORAGE_FILE')) {
|
||||||
|
// Gets the access token to perform service operations.
|
||||||
|
|
||||||
const accessToken = await (GBServer.globals.minBoot.adminService as any)['acquireElevatedToken'](
|
const accessToken = await (GBServer.globals.minBoot.adminService as any)['acquireElevatedToken'](
|
||||||
bootInstance.instanceId,
|
bootInstance.instanceId,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
// Creates the MSFT application that will be associated to the bot.
|
// Creates the MSFT application that will be associated to the bot.
|
||||||
|
|
||||||
const service = await AzureDeployerService.createInstance(this);
|
const service = await AzureDeployerService.createInstance(this);
|
||||||
const application = await service.createApplication(accessToken, botId);
|
const application = await service.createApplication(accessToken, botId);
|
||||||
|
// Fills new instance base information and get App secret.
|
||||||
|
|
||||||
// Fills new instance base information and get App secret.
|
instance.marketplaceId = (application as any).appId;
|
||||||
|
instance.marketplacePassword = await service.createApplicationSecret(accessToken, (application as any).id);
|
||||||
|
}
|
||||||
|
|
||||||
instance.marketplaceId = (application as any).appId;
|
|
||||||
instance.marketplacePassword = await service.createApplicationSecret(accessToken, (application as any).id);
|
|
||||||
instance.adminPass = GBAdminService.getRndPassword();
|
instance.adminPass = GBAdminService.getRndPassword();
|
||||||
instance.title = botId;
|
instance.title = botId;
|
||||||
instance.activationCode = instance.botId.substring(0, 15);
|
instance.activationCode = instance.botId.substring(0, 15);
|
||||||
|
@ -249,10 +251,12 @@ export class GBDeployer implements IGBDeployer {
|
||||||
// Saves bot information to the store.
|
// Saves bot information to the store.
|
||||||
|
|
||||||
await this.core.saveInstance(instance);
|
await this.core.saveInstance(instance);
|
||||||
|
if (!GBConfigService.get('STORAGE_FILE')) {
|
||||||
|
await this.deployBotOnAzure(instance, GBServer.globals.publicAddress);
|
||||||
|
}
|
||||||
// Creates remaining objects on the cloud and updates instance information.
|
// Creates remaining objects on the cloud and updates instance information.
|
||||||
|
|
||||||
return await this.deployBotFull(instance, GBServer.globals.publicAddress);
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -267,7 +271,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
/**
|
/**
|
||||||
* Performs all tasks of deploying a new bot on the cloud.
|
* Performs all tasks of deploying a new bot on the cloud.
|
||||||
*/
|
*/
|
||||||
public async deployBotFull(instance: IGBInstance, publicAddress: string): Promise<IGBInstance> {
|
public async deployBotOnAzure(instance: IGBInstance, publicAddress: string): Promise<IGBInstance> {
|
||||||
// Reads base configuration from environent file.
|
// Reads base configuration from environent file.
|
||||||
|
|
||||||
const service = await AzureDeployerService.createInstance(this);
|
const service = await AzureDeployerService.createInstance(this);
|
||||||
|
@ -411,7 +415,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
public async deployBotFromLocalPath(localPath: string, publicAddress: string): Promise<void> {
|
public async deployBotFromLocalPath(localPath: string, publicAddress: string): Promise<void> {
|
||||||
const packageName = Path.basename(localPath);
|
const packageName = Path.basename(localPath);
|
||||||
const instance = await this.importer.importIfNotExistsBotPackage(undefined, packageName, localPath);
|
const instance = await this.importer.importIfNotExistsBotPackage(undefined, packageName, localPath);
|
||||||
await this.deployBotFull(instance, publicAddress);
|
await this.deployBotOnAzure(instance, publicAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,10 +42,11 @@ import { FacebookAdapter } from 'botbuilder-adapter-facebook';
|
||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
import Fs from 'fs';
|
import Fs from 'fs';
|
||||||
import arrayBufferToBuffer from 'arraybuffer-to-buffer';
|
import arrayBufferToBuffer from 'arraybuffer-to-buffer';
|
||||||
import { v2 as webdav } from 'webdav-server';
|
|
||||||
import { NlpManager } from 'node-nlp';
|
import { NlpManager } from 'node-nlp';
|
||||||
import Koa from 'koa';
|
import Koa from 'koa';
|
||||||
|
import { v2 as webdav } from 'webdav-server';
|
||||||
import { createRpcServer } from '@push-rpc/core';
|
import { createRpcServer } from '@push-rpc/core';
|
||||||
|
import { start as startRouter } from '../../../packages/core.gbapp/services/router/bridge.js';
|
||||||
import wash from 'washyourmouthoutwithsoap';
|
import wash from 'washyourmouthoutwithsoap';
|
||||||
import {
|
import {
|
||||||
AutoSaveStateMiddleware,
|
AutoSaveStateMiddleware,
|
||||||
|
@ -172,6 +173,9 @@ export class GBMinService {
|
||||||
await CollectionUtil.asyncForEach(
|
await CollectionUtil.asyncForEach(
|
||||||
instances,
|
instances,
|
||||||
(async instance => {
|
(async instance => {
|
||||||
|
|
||||||
|
startRouter(GBServer.globals.server, instance.botId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
GBLog.info(`Mounting ${instance.botId}...`);
|
GBLog.info(`Mounting ${instance.botId}...`);
|
||||||
await this['mountBot'](instance);
|
await this['mountBot'](instance);
|
||||||
|
@ -256,7 +260,7 @@ export class GBMinService {
|
||||||
|
|
||||||
// Serves individual URL for each bot conversational interface.
|
// Serves individual URL for each bot conversational interface.
|
||||||
|
|
||||||
await this.deployer['deployPackage2'](min, user, 'packages/default.gbtheme');
|
await this.deployer['deployPackage2'](min, user, 'templates/default.gbai/default.gbtheme');
|
||||||
|
|
||||||
// Install per bot deployed packages.
|
// Install per bot deployed packages.
|
||||||
|
|
||||||
|
@ -317,12 +321,12 @@ export class GBMinService {
|
||||||
mkdirp.sync(dir);
|
mkdirp.sync(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.STORAGE_FILE) {
|
if (GBConfigService.get('STORAGE_FILE')) {
|
||||||
dir = Path.join(process.env.STORAGE_LIBRARY, 'work', gbai);
|
dir = Path.join(GBConfigService.get('STORAGE_LIBRARY'), 'work', gbai);
|
||||||
|
|
||||||
const server = new webdav.WebDAVServer();
|
const server = GBServer.globals.webDavServer;
|
||||||
server.setFileSystem(`/${botId}`, new webdav.PhysicalFileSystem(dir), success => {
|
server.setFileSystem(`/${botId}`, new webdav.PhysicalFileSystem(dir), success => {
|
||||||
server.start(() => console.log('WEBDAV READY'));
|
GBLogEx.info(1, `WebDav for ${botId} loaded.`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Loads Named Entity data for this bot.
|
// Loads Named Entity data for this bot.
|
||||||
|
@ -691,8 +695,8 @@ export class GBMinService {
|
||||||
color2: this.core.getParam(instance, 'Color2', null)
|
color2: this.core.getParam(instance, 'Color2', null)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (process.env.STORAGE_FILE) {
|
if (GBConfigService.get('STORAGE_FILE')) {
|
||||||
config['domain'] = `http://localhost:${process.env.PORT}/directline`;
|
config['domain'] = `http://localhost:${process.env.PORT}/directline/${botId}`;
|
||||||
} else {
|
} else {
|
||||||
const webchatTokenContainer = await this.getWebchatToken(instance);
|
const webchatTokenContainer = await this.getWebchatToken(instance);
|
||||||
config['conversationId']= webchatTokenContainer.conversationId,
|
config['conversationId']= webchatTokenContainer.conversationId,
|
||||||
|
@ -763,7 +767,7 @@ export class GBMinService {
|
||||||
? instance.marketplacePassword
|
? instance.marketplacePassword
|
||||||
: GBConfigService.get('MARKETPLACE_SECRET')
|
: GBConfigService.get('MARKETPLACE_SECRET')
|
||||||
};
|
};
|
||||||
if (process.env.STORAGE_FILE) {
|
if (GBConfigService.get('STORAGE_FILE')) {
|
||||||
config['clientOptions'] = { baseUri: `http://localhost:${process.env.PORT}` };
|
config['clientOptions'] = { baseUri: `http://localhost:${process.env.PORT}` };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,8 +834,6 @@ export class GBMinService {
|
||||||
|
|
||||||
let url = `/api/messages/${instance.botId}`;
|
let url = `/api/messages/${instance.botId}`;
|
||||||
GBServer.globals.server.post(url, receiver);
|
GBServer.globals.server.post(url, receiver);
|
||||||
url = `/api/messages`;
|
|
||||||
GBServer.globals.server.post(url, receiver);
|
|
||||||
|
|
||||||
// NLP Manager.
|
// NLP Manager.
|
||||||
|
|
||||||
|
@ -843,6 +845,10 @@ export class GBMinService {
|
||||||
GBServer.globals.minBoot.instance.marketplaceId = GBConfigService.get('MARKETPLACE_ID');
|
GBServer.globals.minBoot.instance.marketplaceId = GBConfigService.get('MARKETPLACE_ID');
|
||||||
GBServer.globals.minBoot.instance.marketplacePassword = GBConfigService.get('MARKETPLACE_SECRET');
|
GBServer.globals.minBoot.instance.marketplacePassword = GBConfigService.get('MARKETPLACE_SECRET');
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
url = `/api/messages`;
|
||||||
|
GBServer.globals.server.post(url, receiver);
|
||||||
|
}
|
||||||
|
|
||||||
if (min.instance.facebookWorkplaceVerifyToken) {
|
if (min.instance.facebookWorkplaceVerifyToken) {
|
||||||
min['fbAdapter'] = new FacebookAdapter({
|
min['fbAdapter'] = new FacebookAdapter({
|
||||||
|
@ -1192,7 +1198,7 @@ export class GBMinService {
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (process.env.STORAGE_FILE) {
|
if (GBConfigService.get('STORAGE_FILE')) {
|
||||||
const context = adapter['createContext'](req);
|
const context = adapter['createContext'](req);
|
||||||
context['_activity'] = context.activity.body;
|
context['_activity'] = context.activity.body;
|
||||||
await handler(context);
|
await handler(context);
|
||||||
|
|
|
@ -11,7 +11,7 @@ const conversationsCleanupInterval = 10000;
|
||||||
const conversations: { [key: string]: IConversation } = {};
|
const conversations: { [key: string]: IConversation } = {};
|
||||||
const botDataStore: { [key: string]: IBotData } = {};
|
const botDataStore: { [key: string]: IBotData } = {};
|
||||||
|
|
||||||
export const getRouter = (serviceUrl: string, botUrl: string, conversationInitRequired = true): express.Router => {
|
export const getRouter = (serviceUrl: string, botUrl: string, conversationInitRequired = true, botId): express.Router => {
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.use(bodyParser.json()); // for parsing application/json
|
router.use(bodyParser.json()); // for parsing application/json
|
||||||
|
@ -22,8 +22,9 @@ export const getRouter = (serviceUrl: string, botUrl: string, conversationInitRe
|
||||||
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, x-ms-bot-agent');
|
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, x-ms-bot-agent');
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
// CLIENT ENDPOINT
|
// CLIENT ENDPOINT
|
||||||
router.options('/directline', (req, res) => {
|
router.options(`/directline/${botId}/`, (req, res) => {
|
||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ export const getRouter = (serviceUrl: string, botUrl: string, conversationInitRe
|
||||||
};
|
};
|
||||||
|
|
||||||
router.post('/v3/directline/conversations',reqs );
|
router.post('/v3/directline/conversations',reqs );
|
||||||
router.post('/directline/conversations',reqs );
|
router.post(`/directline/${botId}/conversations`,reqs );
|
||||||
|
|
||||||
// Reconnect API
|
// Reconnect API
|
||||||
router.get('/v3/directline/conversations/:conversationId', (req, res) => {
|
router.get('/v3/directline/conversations/:conversationId', (req, res) => {
|
||||||
|
@ -69,7 +70,7 @@ export const getRouter = (serviceUrl: string, botUrl: string, conversationInitRe
|
||||||
});
|
});
|
||||||
|
|
||||||
// Gets activities from store (local history array for now)
|
// Gets activities from store (local history array for now)
|
||||||
router.get('/directline/conversations/:conversationId/activities', (req, res) => {
|
router.get(`/directline/${botId}/conversations/:conversationId/activities`, (req, res) => {
|
||||||
const watermark = req.query.watermark && req.query.watermark !== 'null' ? Number(req.query.watermark) : 0;
|
const watermark = req.query.watermark && req.query.watermark !== 'null' ? Number(req.query.watermark) : 0;
|
||||||
|
|
||||||
const conversation = getConversation(req.params.conversationId, conversationInitRequired);
|
const conversation = getConversation(req.params.conversationId, conversationInitRequired);
|
||||||
|
@ -95,7 +96,7 @@ export const getRouter = (serviceUrl: string, botUrl: string, conversationInitRe
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sends message to bot. Assumes message activities
|
// Sends message to bot. Assumes message activities
|
||||||
router.post('/directline/conversations/:conversationId/activities', (req, res) => {
|
router.post(`/directline/${botId}/conversations/:conversationId/activities`, (req, res) => {
|
||||||
const incomingActivity = req.body;
|
const incomingActivity = req.body;
|
||||||
// Make copy of activity. Add required fields
|
// Make copy of activity. Add required fields
|
||||||
const activity = createMessageActivity(incomingActivity, serviceUrl, req.params.conversationId);
|
const activity = createMessageActivity(incomingActivity, serviceUrl, req.params.conversationId);
|
||||||
|
@ -209,11 +210,11 @@ export const getRouter = (serviceUrl: string, botUrl: string, conversationInitRe
|
||||||
* @param conversationInitRequired Requires that a conversation is initialized before it is accessed, returning a 400
|
* @param conversationInitRequired Requires that a conversation is initialized before it is accessed, returning a 400
|
||||||
* when not the case. If set to false, a new conversation reference is created on the fly. This is true by default.
|
* when not the case. If set to false, a new conversation reference is created on the fly. This is true by default.
|
||||||
*/
|
*/
|
||||||
export const initializeRoutes = (app: express.Express, port: number, botUrl: string, conversationInitRequired = true) => {
|
export const initializeRoutes = (app: express.Express, port: number, botUrl: string, conversationInitRequired = true, botId) => {
|
||||||
conversationsCleanup();
|
conversationsCleanup();
|
||||||
|
|
||||||
const directLineEndpoint = `http://127.0.0.1:${port}`;
|
const directLineEndpoint = `http://127.0.0.1:${port}`;
|
||||||
const router = getRouter(directLineEndpoint, botUrl, conversationInitRequired);
|
const router = getRouter(directLineEndpoint, botUrl, conversationInitRequired, botId);
|
||||||
|
|
||||||
app.use(router);
|
app.use(router);
|
||||||
console.log(`Routing messages to bot on ${botUrl}`);
|
console.log(`Routing messages to bot on ${botUrl}`);
|
||||||
|
@ -272,9 +273,9 @@ const setPrivateConversationData = (req: express.Request, res: express.Response)
|
||||||
res.status(200).send(setBotData(req.params.channelId, req.params.conversationId, req.params.userId, req.body));
|
res.status(200).send(setBotData(req.params.channelId, req.params.conversationId, req.params.userId, req.body));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const start = (server)=>{
|
export const start = (server, botId)=>{
|
||||||
|
|
||||||
initializeRoutes(server, Number(process.env.PORT), `http://127.0.0.1:${process.env.PORT}/api/messages`);
|
initializeRoutes(server, Number(process.env.PORT), `http://127.0.0.1:${process.env.PORT}/api/messages/${botId}`, null, botId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteStateForUser = (req: express.Request, res: express.Response) => {
|
const deleteStateForUser = (req: express.Request, res: express.Response) => {
|
||||||
|
|
|
@ -1370,7 +1370,7 @@ export class KBService implements IGBKBService {
|
||||||
await this.importKbPackage(min, localPath, p, instance);
|
await this.importKbPackage(min, localPath, p, instance);
|
||||||
GBDeployer.mountGBKBAssets(packageName, min.botId, localPath);
|
GBDeployer.mountGBKBAssets(packageName, min.botId, localPath);
|
||||||
|
|
||||||
if (!process.env.STORAGE_FILE) {
|
if (!GBConfigService.get('STORAGE_FILE')) {
|
||||||
const service = await AzureDeployerService.createInstance(deployer);
|
const service = await AzureDeployerService.createInstance(deployer);
|
||||||
const searchIndex = instance.searchIndex ? instance.searchIndex : GBServer.globals.minBoot.instance.searchIndex;
|
const searchIndex = instance.searchIndex ? instance.searchIndex : GBServer.globals.minBoot.instance.searchIndex;
|
||||||
await deployer.rebuildIndex(instance, service.getKBSearchSchema(searchIndex));
|
await deployer.rebuildIndex(instance, service.getKBSearchSchema(searchIndex));
|
||||||
|
|
|
@ -65,4 +65,5 @@ export class RootData {
|
||||||
public dbg;
|
public dbg;
|
||||||
public img;
|
public img;
|
||||||
indexSemaphore: any;
|
indexSemaphore: any;
|
||||||
|
public webDavServer;
|
||||||
}
|
}
|
||||||
|
|
53
src/app.ts
|
@ -40,8 +40,7 @@ import bodyParser from 'body-parser';
|
||||||
import { GBLog, GBMinInstance, IGBCoreService, IGBInstance } from 'botlib';
|
import { GBLog, GBMinInstance, IGBCoreService, IGBInstance } from 'botlib';
|
||||||
import child_process from 'child_process';
|
import child_process from 'child_process';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import {start as startRouter} from '../packages/core.gbapp/services/router/bridge.js'
|
import { v2 as webdav } from 'webdav-server';
|
||||||
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import httpProxy from 'http-proxy';
|
import httpProxy from 'http-proxy';
|
||||||
|
@ -89,7 +88,7 @@ export class GBServer {
|
||||||
|
|
||||||
const server = express();
|
const server = express();
|
||||||
this.initEndpointsDocs(server);
|
this.initEndpointsDocs(server);
|
||||||
startRouter(server);
|
|
||||||
GBServer.globals.server = server;
|
GBServer.globals.server = server;
|
||||||
|
|
||||||
GBServer.globals.httpsServer = null;
|
GBServer.globals.httpsServer = null;
|
||||||
|
@ -105,6 +104,8 @@ export class GBServer {
|
||||||
GBServer.globals.debuggers = [];
|
GBServer.globals.debuggers = [];
|
||||||
GBServer.globals.users = [];
|
GBServer.globals.users = [];
|
||||||
GBServer.globals.indexSemaphore = new Mutex();
|
GBServer.globals.indexSemaphore = new Mutex();
|
||||||
|
GBServer.globals.webDavServer = new webdav.WebDAVServer();
|
||||||
|
GBServer.globals.webDavServer.start();
|
||||||
|
|
||||||
server.use(bodyParser.json());
|
server.use(bodyParser.json());
|
||||||
server.use(bodyParser.json({ limit: '1mb' }));
|
server.use(bodyParser.json({ limit: '1mb' }));
|
||||||
|
@ -121,7 +122,10 @@ export class GBServer {
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on('uncaughtException', (err, p) => {
|
process.on('uncaughtException', (err, p) => {
|
||||||
GBLogEx.error(0, `GBEXCEPTION: ${GBUtil.toYAML(JSON.parse(JSON.stringify(err, Object.getOwnPropertyNames(err))))}`);
|
GBLogEx.error(
|
||||||
|
0,
|
||||||
|
`GBEXCEPTION: ${GBUtil.toYAML(JSON.parse(JSON.stringify(err, Object.getOwnPropertyNames(err))))}`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on('unhandledRejection', (err, p) => {
|
process.on('unhandledRejection', (err, p) => {
|
||||||
|
@ -134,7 +138,10 @@ export class GBServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bypass) {
|
if (!bypass) {
|
||||||
GBLogEx.error(0,`GBREJECTION: ${GBUtil.toYAML(JSON.parse(JSON.stringify(err, Object.getOwnPropertyNames(err))))}`);
|
GBLogEx.error(
|
||||||
|
0,
|
||||||
|
`GBREJECTION: ${GBUtil.toYAML(JSON.parse(JSON.stringify(err, Object.getOwnPropertyNames(err))))}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -186,7 +193,6 @@ export class GBServer {
|
||||||
} else if (GBConfigService.get('STORAGE_FILE')) {
|
} else if (GBConfigService.get('STORAGE_FILE')) {
|
||||||
await core.initStorage();
|
await core.initStorage();
|
||||||
} else {
|
} else {
|
||||||
runOnce = true;
|
|
||||||
[GBServer.globals.bootInstance, azureDeployer] = await core['createBootInstanceEx'](
|
[GBServer.globals.bootInstance, azureDeployer] = await core['createBootInstanceEx'](
|
||||||
core,
|
core,
|
||||||
null,
|
null,
|
||||||
|
@ -194,6 +200,7 @@ export class GBServer {
|
||||||
deployer,
|
deployer,
|
||||||
GBConfigService.get('FREE_TIER')
|
GBConfigService.get('FREE_TIER')
|
||||||
);
|
);
|
||||||
|
await core.saveInstance(GBServer.globals.bootInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
core.ensureAdminIsSecured();
|
core.ensureAdminIsSecured();
|
||||||
|
@ -207,10 +214,6 @@ export class GBServer {
|
||||||
await deployer.deployPackages(core, server, GBServer.globals.appPackages);
|
await deployer.deployPackages(core, server, GBServer.globals.appPackages);
|
||||||
await core.syncDatabaseStructure();
|
await core.syncDatabaseStructure();
|
||||||
|
|
||||||
if (runOnce) {
|
|
||||||
await core.saveInstance(GBServer.globals.bootInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deployment of local applications for the first time.
|
// Deployment of local applications for the first time.
|
||||||
|
|
||||||
if (GBConfigService.get('DISABLE_WEB') !== 'true') {
|
if (GBConfigService.get('DISABLE_WEB') !== 'true') {
|
||||||
|
@ -224,24 +227,28 @@ export class GBServer {
|
||||||
GBServer.globals.publicAddress
|
GBServer.globals.publicAddress
|
||||||
);
|
);
|
||||||
|
|
||||||
if (instances.length === 0) {
|
if (instances. length === 0) {
|
||||||
const instance = await importer.importIfNotExistsBotPackage(
|
if (!GBConfigService.get('STORAGE_FILE')) {
|
||||||
GBConfigService.get('BOT_ID'),
|
const instance = await importer.importIfNotExistsBotPackage(
|
||||||
'boot.gbot',
|
GBConfigService.get('BOT_ID'),
|
||||||
'packages/boot.gbot',
|
'boot.gbot',
|
||||||
GBServer.globals.bootInstance
|
'packages/boot.gbot',
|
||||||
);
|
GBServer.globals.bootInstance
|
||||||
|
);
|
||||||
|
|
||||||
instances.push(instance);
|
instances.push(instance);
|
||||||
GBServer.globals.minBoot.instance = instances[0];
|
GBServer.globals.minBoot.instance = instances[0];
|
||||||
GBServer.globals.bootInstance = instances[0];
|
GBServer.globals.bootInstance = instances[0];
|
||||||
await deployer.deployBotFull(instance, GBServer.globals.publicAddress);
|
await deployer.deployBotOnAzure(instance, GBServer.globals.publicAddress);
|
||||||
|
|
||||||
// Runs the search even with empty content to create structure.
|
// Runs the search even with empty content to create structure.
|
||||||
|
|
||||||
await azureDeployer['runSearch'](instance);
|
await azureDeployer['runSearch'](instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await core['ensureFolders'](instances, deployer);
|
||||||
|
|
||||||
GBServer.globals.bootInstance = instances[0];
|
GBServer.globals.bootInstance = instances[0];
|
||||||
|
|
||||||
// Builds minimal service infrastructure.
|
// Builds minimal service infrastructure.
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
import * as YAML from 'yaml';
|
import * as YAML from 'yaml';
|
||||||
import SwaggerClient from 'swagger-client';
|
import SwaggerClient from 'swagger-client';
|
||||||
import Fs from 'fs';
|
import Fs from 'fs';
|
||||||
|
import { GBConfigService } from '../packages/core.gbapp/services/GBConfigService.js';
|
||||||
|
|
||||||
export class GBUtil {
|
export class GBUtil {
|
||||||
public static repeat(chr, count) {
|
public static repeat(chr, count) {
|
||||||
|
@ -69,14 +70,14 @@ export class GBUtil {
|
||||||
public static async getDirectLineClient(min) {
|
public static async getDirectLineClient(min) {
|
||||||
|
|
||||||
let config = {
|
let config = {
|
||||||
url: `http://127.0.0.1:${process.env.port}/api/messages`,
|
url: `http://127.0.0.1:${GBConfigService.get('PORT')}/api/messages`,
|
||||||
spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')),
|
spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')),
|
||||||
requestInterceptor: req => {
|
requestInterceptor: req => {
|
||||||
req.headers['Authorization'] = `Bearer ${min.instance.webchatKey}`;
|
req.headers['Authorization'] = `Bearer ${min.instance.webchatKey}`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (process.env.STORAGE_FILE) {
|
if (GBConfigService.get('STORAGE_FILE')) {
|
||||||
config['spec'].servers = [{ url: `http://127.0.0.1:${process.env.PORT}/api/messages` }];
|
config['spec'].servers = [{ url: `http://127.0.0.1:${GBConfigService.get('PORT')}/api/messages` }];
|
||||||
config['openapi'] = '3.0.0';
|
config['openapi'] = '3.0.0';
|
||||||
}
|
}
|
||||||
return await new SwaggerClient(config);
|
return await new SwaggerClient(config);
|
||||||
|
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 958 B After Width: | Height: | Size: 958 B |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 247 KiB After Width: | Height: | Size: 247 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |