New tasks on Azure Deployer and start of Bot Farm deployer.
This commit is contained in:
parent
7991dced80
commit
7ef4e22764
12 changed files with 717 additions and 423 deletions
|
@ -33,21 +33,24 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const UrlJoin = require("url-join");
|
const UrlJoin = require("url-join");
|
||||||
import { AzureSearch } from "pragmatismo-io-framework";
|
|
||||||
import { GBMinInstance } from "botlib";
|
import { GBMinInstance } from "botlib";
|
||||||
import { IGBDialog } from "botlib";
|
import { IGBDialog } from "botlib";
|
||||||
import { GBDeployer } from "../../core.gbapp/services/GBDeployer";
|
import { GBDeployer } from "../../core.gbapp/services/GBDeployer";
|
||||||
import { GBImporter } from "../../core.gbapp/services/GBImporter";
|
import { GBImporter } from "../../core.gbapp/services/GBImporter";
|
||||||
import { GBConfigService } from "../../core.gbapp/services/GBConfigService";
|
import { GBConfigService } from "../../core.gbapp/services/GBConfigService";
|
||||||
import { KBService } from "./../../kb.gbapp/services/KBService";
|
|
||||||
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";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 undeployPackageCommand(text: any, min: GBMinInstance) {
|
static async undeployPackageCommand(text: any, min: GBMinInstance) {
|
||||||
let packageName = text.split(" ")[1];
|
let packageName = text.split(" ")[1];
|
||||||
let importer = new GBImporter(min.core);
|
let importer = new GBImporter(min.core);
|
||||||
|
@ -106,6 +109,9 @@ export class AdminDialog extends IGBDialog {
|
||||||
|
|
||||||
if (text === "quit") {
|
if (text === "quit") {
|
||||||
await dc.replace("/");
|
await dc.replace("/");
|
||||||
|
} else if (cmdName === "createFarm") {
|
||||||
|
await AdminDialog.createFarmCommand(text, deployer);
|
||||||
|
await dc.replace("/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 dc.replace("/admin", { firstRun: false });
|
||||||
|
|
65
deploy/azuredeployer.gbapp/dialogs/BotFarmDialog.ts
Normal file
65
deploy/azuredeployer.gbapp/dialogs/BotFarmDialog.ts
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*****************************************************************************\
|
||||||
|
| ( )_ _ |
|
||||||
|
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||||
|
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||||
|
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||||
|
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||||
|
| | | ( )_) | |
|
||||||
|
| (_) \___/' |
|
||||||
|
| |
|
||||||
|
| General Bots Copyright (c) Pragmatismo.io. All rights reserved. |
|
||||||
|
| Licensed under the AGPL-3.0. |
|
||||||
|
| |
|
||||||
|
| According to our dual licensing model, this program can be used either |
|
||||||
|
| under the terms of the GNU Affero General Public License, version 3, |
|
||||||
|
| or under a proprietary license. |
|
||||||
|
| |
|
||||||
|
| The texts of the GNU Affero General Public License with an additional |
|
||||||
|
| permission and of our proprietary license can be found at and |
|
||||||
|
| in the LICENSE file you have received along with this program. |
|
||||||
|
| |
|
||||||
|
| This program is distributed in the hope that it will be useful, |
|
||||||
|
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||||
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
|
| GNU Affero General Public License for more details. |
|
||||||
|
| |
|
||||||
|
| "General Bots" is a registered trademark of Pragmatismo.io. |
|
||||||
|
| The licensing of the program under the AGPLv3 does not imply a |
|
||||||
|
| trademark license. Therefore any rights, title and interest in |
|
||||||
|
| our trademarks remain entirely with us. |
|
||||||
|
| |
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import { GBMinInstance } from "botlib";
|
||||||
|
import { IGBDialog } from "botlib";
|
||||||
|
import { BotAdapter } from "botbuilder";
|
||||||
|
import { Messages } from "../strings";
|
||||||
|
|
||||||
|
export class BotFarmDialog extends IGBDialog {
|
||||||
|
/**
|
||||||
|
* Setup dialogs flows and define services call.
|
||||||
|
*
|
||||||
|
* @param bot The bot adapter.
|
||||||
|
* @param min The minimal bot instance data.
|
||||||
|
*/
|
||||||
|
static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||||
|
min.dialogs.add("/createBotFarm", [
|
||||||
|
async dc => {
|
||||||
|
let locale = dc.context.activity.locale;
|
||||||
|
await dc.prompt("choicePrompt", Messages[locale].what_about_me, [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
"4",
|
||||||
|
"5"
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
async (dc, value) => {
|
||||||
|
let locale = dc.context.activity.locale;
|
||||||
|
await dc.context.sendActivity(Messages[locale].thanks);
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,12 +33,8 @@
|
||||||
"use strict"
|
"use strict"
|
||||||
|
|
||||||
const UrlJoin = require("url-join")
|
const UrlJoin = require("url-join")
|
||||||
|
|
||||||
|
|
||||||
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
|
import { GBMinInstance, IGBPackage, IGBCoreService } from "botlib"
|
||||||
|
|
||||||
import { Sequelize } from "sequelize-typescript"
|
import { Sequelize } from "sequelize-typescript"
|
||||||
import { AzureDeployerService } from "./services/AzureDeployerService"
|
|
||||||
|
|
||||||
|
|
||||||
export class GBWhatsappPackage implements IGBPackage {
|
export class GBWhatsappPackage implements IGBPackage {
|
457
deploy/azuredeployer.gbapp/services/AzureDeployerService.ts
Normal file
457
deploy/azuredeployer.gbapp/services/AzureDeployerService.ts
Normal file
|
@ -0,0 +1,457 @@
|
||||||
|
/*****************************************************************************\
|
||||||
|
| ( )_ _ |
|
||||||
|
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||||
|
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||||
|
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||||
|
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||||
|
| | | ( )_) | |
|
||||||
|
| (_) \___/' |
|
||||||
|
| |
|
||||||
|
| General Bots Copyright (c) Pragmatismo.io. All rights reserved. |
|
||||||
|
| Licensed under the AGPL-3.0. |
|
||||||
|
| |
|
||||||
|
| According to our dual licensing model, this program can be used either |
|
||||||
|
| under the terms of the GNU Affero General Public License, version 3, |
|
||||||
|
| or under a proprietary license. |
|
||||||
|
| |
|
||||||
|
| The texts of the GNU Affero General Public License with an additional |
|
||||||
|
| permission and of our proprietary license can be found at and |
|
||||||
|
| in the LICENSE file you have received along with this program. |
|
||||||
|
| |
|
||||||
|
| This program is distributed in the hope that it will be useful, |
|
||||||
|
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||||
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
|
| GNU Affero General Public License for more details. |
|
||||||
|
| |
|
||||||
|
| "General Bots" is a registered trademark of Pragmatismo.io. |
|
||||||
|
| The licensing of the program under the AGPLv3 does not imply a |
|
||||||
|
| trademark license. Therefore any rights, title and interest in |
|
||||||
|
| our trademarks remain entirely with us. |
|
||||||
|
| |
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
import { GBService, IGBInstance } from "botlib";
|
||||||
|
const msRestAzure = require("ms-rest-azure");
|
||||||
|
import {
|
||||||
|
ResourceManagementClient,
|
||||||
|
SubscriptionClient
|
||||||
|
} from "azure-arm-resource";
|
||||||
|
import { WebSiteManagementClient } from "azure-arm-website";
|
||||||
|
import { SqlManagementClient } from "azure-arm-sql";
|
||||||
|
import { CognitiveServicesManagementClient } from "azure-arm-cognitiveservices";
|
||||||
|
import { CognitiveServicesAccount } from "azure-arm-cognitiveservices/lib/models";
|
||||||
|
import { SearchManagementClient } from "azure-arm-search";
|
||||||
|
import { WebResource, ServiceClient } from "ms-rest-js";
|
||||||
|
import * as simplegit from "simple-git/promise";
|
||||||
|
import { AppServicePlan } from "azure-arm-website/lib/models";
|
||||||
|
const git = simplegit();
|
||||||
|
const logger = require("../../../src/logger");
|
||||||
|
const UrlJoin = require("url-join");
|
||||||
|
const PasswordGenerator = require("strict-password-generator").default;
|
||||||
|
|
||||||
|
export class AzureDeployerService extends GBService {
|
||||||
|
instance: IGBInstance;
|
||||||
|
resourceClient: ResourceManagementClient.ResourceManagementClient;
|
||||||
|
webSiteClient: WebSiteManagementClient;
|
||||||
|
storageClient: SqlManagementClient;
|
||||||
|
cognitiveClient: CognitiveServicesManagementClient;
|
||||||
|
searchClient: SearchManagementClient;
|
||||||
|
provider = "Microsoft.BotService";
|
||||||
|
subscriptionClient: SubscriptionClient.SubscriptionClient;
|
||||||
|
|
||||||
|
constructor(credentials, subscriptionId) {
|
||||||
|
super();
|
||||||
|
this.resourceClient = new ResourceManagementClient.default(
|
||||||
|
credentials,
|
||||||
|
subscriptionId
|
||||||
|
);
|
||||||
|
this.webSiteClient = new WebSiteManagementClient(
|
||||||
|
credentials,
|
||||||
|
subscriptionId
|
||||||
|
);
|
||||||
|
this.storageClient = new SqlManagementClient(credentials, subscriptionId);
|
||||||
|
this.cognitiveClient = new CognitiveServicesManagementClient(
|
||||||
|
credentials,
|
||||||
|
subscriptionId
|
||||||
|
);
|
||||||
|
this.searchClient = new SearchManagementClient(credentials, subscriptionId);
|
||||||
|
this.subscriptionClient = new SubscriptionClient.default(credentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getSubscriptions() {
|
||||||
|
this.subscriptionClient.subscriptions.list();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async deploy(
|
||||||
|
instance: IGBInstance,
|
||||||
|
location: string
|
||||||
|
): Promise<IGBInstance> {
|
||||||
|
|
||||||
|
logger.info(`Creating Deploy...`);
|
||||||
|
await this.createDeploy(name, location);
|
||||||
|
|
||||||
|
logger.info(`Creating Server...`);
|
||||||
|
let serverFarm = await this.createHostingPlan(
|
||||||
|
name,
|
||||||
|
`${name}-server-plan`,
|
||||||
|
location
|
||||||
|
);
|
||||||
|
await this.createServer(serverFarm.id, name, `${name}-server`, location);
|
||||||
|
|
||||||
|
let administratorLogin = AzureDeployerService.getRndAdminAccount();
|
||||||
|
let administratorPassword = AzureDeployerService.getRndPassword();
|
||||||
|
|
||||||
|
logger.info(`Creating Storage...`);
|
||||||
|
let storageServerName = `${name}-storage`;
|
||||||
|
await this.createStorageServer(
|
||||||
|
name,
|
||||||
|
`${storageServerName}-server`,
|
||||||
|
administratorLogin,
|
||||||
|
administratorPassword,
|
||||||
|
storageServerName,
|
||||||
|
location
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.createStorage(
|
||||||
|
name,
|
||||||
|
storageServerName,
|
||||||
|
`${name}-storage`,
|
||||||
|
location
|
||||||
|
);
|
||||||
|
instance.storageUsername = administratorLogin;
|
||||||
|
instance.storagePassword = administratorPassword;
|
||||||
|
instance.storageName = storageServerName;
|
||||||
|
instance.storageDialect = "mssql";
|
||||||
|
instance.storageServerName = storageServerName;
|
||||||
|
|
||||||
|
logger.info(`Creating Search...`);
|
||||||
|
let search = await this.createSearch(name, `${name}-search`, location);
|
||||||
|
|
||||||
|
logger.info(`Creating Bot...`);
|
||||||
|
//await this.createBot(credentials.tokenCache._entries[0].accessToken,
|
||||||
|
// name, name, name, 'global', subscriptionId, tenantId);
|
||||||
|
|
||||||
|
logger.info(`Creating NLP...`);
|
||||||
|
let nlp = await this.createNLP(name, `${name}-nlp`, location);
|
||||||
|
let keys = await this.cognitiveClient.accounts.listKeys(name, nlp.name);
|
||||||
|
instance.nlpEndpoint = nlp.endpoint;
|
||||||
|
instance.nlpKey = keys.key1;
|
||||||
|
|
||||||
|
logger.info(`Creating Speech...`);
|
||||||
|
let speech = await this.createSpeech(name, `${name}-speech`, location);
|
||||||
|
keys = await this.cognitiveClient.accounts.listKeys(name, speech.name);
|
||||||
|
instance.speechKeyEndpoint = speech.endpoint;
|
||||||
|
instance.speechKey = keys.key1;
|
||||||
|
|
||||||
|
logger.info(`Creating SpellChecker...`);
|
||||||
|
let spellChecker = await this.createSpellChecker(
|
||||||
|
name,
|
||||||
|
`${name}-spellchecker`,
|
||||||
|
location
|
||||||
|
);
|
||||||
|
keys = await this.cognitiveClient.accounts.listKeys(
|
||||||
|
name,
|
||||||
|
spellChecker.name
|
||||||
|
);
|
||||||
|
instance.spellCheckerKey = keys.key1;
|
||||||
|
instance.spellCheckerEndpoint = spellChecker.endpoint;
|
||||||
|
|
||||||
|
logger.info(`Creating Text Analytics...`);
|
||||||
|
let textAnalytics = await this.createTextAnalytics(
|
||||||
|
name,
|
||||||
|
`${name}-textanalytics`,
|
||||||
|
location
|
||||||
|
);
|
||||||
|
keys = await this.cognitiveClient.accounts.listKeys(
|
||||||
|
name,
|
||||||
|
textAnalytics.name
|
||||||
|
);
|
||||||
|
instance.textAnalyticsServerUrl = textAnalytics.endpoint;
|
||||||
|
instance.textAnalyticsKey = keys.key1;
|
||||||
|
|
||||||
|
logger.info(`Cleaning Deploy it can take a while...`);
|
||||||
|
// DISABLED: await this.dangerouslyDeleteDeploy(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async dangerouslyDeleteDeploy(name) {
|
||||||
|
return this.resourceClient.resourceGroups.deleteMethod(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createStorageServer(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
administratorLogin,
|
||||||
|
administratorPassword,
|
||||||
|
serverName,
|
||||||
|
location
|
||||||
|
) {
|
||||||
|
var params = {
|
||||||
|
location: location,
|
||||||
|
administratorLogin: administratorLogin,
|
||||||
|
administratorLoginPassword: administratorPassword,
|
||||||
|
fullyQualifiedDomainName: `${serverName}.database.windows.net`
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.storageClient.servers.createOrUpdate(group, name, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async registerProviders(subscriptionId, baseUrl, accessToken) {
|
||||||
|
let query = `subscriptions/${subscriptionId}/providers/${
|
||||||
|
this.provider
|
||||||
|
}/register?api-version=2018-02-01`;
|
||||||
|
let requestUrl = UrlJoin(baseUrl, query);
|
||||||
|
|
||||||
|
let req = new WebResource();
|
||||||
|
req.method = "POST";
|
||||||
|
req.url = requestUrl;
|
||||||
|
req.headers = {};
|
||||||
|
req.headers["Content-Type"] = "application/json; charset=utf-8";
|
||||||
|
req.headers["accept-language"] = "*";
|
||||||
|
req.headers["x-ms-client-request-id"] = msRestAzure.generateUuid();
|
||||||
|
req.headers["Authorization"] = "Bearer " + accessToken;
|
||||||
|
|
||||||
|
let httpClient = new ServiceClient();
|
||||||
|
let res = await httpClient.sendRequest(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createBot(
|
||||||
|
accessToken,
|
||||||
|
botId,
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
subscriptionId,
|
||||||
|
tenantId
|
||||||
|
) {
|
||||||
|
let baseUrl = `https://management.azure.com/`;
|
||||||
|
let appId = "";
|
||||||
|
let description = "";
|
||||||
|
let endpoint = "";
|
||||||
|
let nlpKey = "";
|
||||||
|
let nlpAppId = "3";
|
||||||
|
|
||||||
|
let parameters = {
|
||||||
|
parameters: {
|
||||||
|
location: location,
|
||||||
|
sku: {
|
||||||
|
name: "F0"
|
||||||
|
},
|
||||||
|
name: name,
|
||||||
|
//"type": "sampletype",
|
||||||
|
id: botId,
|
||||||
|
kind: "sdk",
|
||||||
|
properties: {
|
||||||
|
description: description,
|
||||||
|
displayName: name,
|
||||||
|
endpoint: endpoint,
|
||||||
|
iconUrl: "http://myicon",
|
||||||
|
luisAppIds: [nlpAppId],
|
||||||
|
luisKey: nlpKey,
|
||||||
|
msaAppId: appId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${
|
||||||
|
this.provider
|
||||||
|
}/botServices/${botId}?api-version=2017-12-01`;
|
||||||
|
let requestUrl = UrlJoin(baseUrl, query);
|
||||||
|
|
||||||
|
let req = new WebResource();
|
||||||
|
req.method = "PUT";
|
||||||
|
req.url = requestUrl;
|
||||||
|
req.headers = {};
|
||||||
|
req.headers["Content-Type"] = "application/json";
|
||||||
|
req.headers["accept-language"] = "*";
|
||||||
|
//req.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
|
||||||
|
req.headers["Authorization"] = "Bearer " + accessToken;
|
||||||
|
|
||||||
|
let requestContent = JSON.stringify(parameters);
|
||||||
|
req.body = requestContent;
|
||||||
|
|
||||||
|
let httpClient = new ServiceClient();
|
||||||
|
let res = await httpClient.sendRequest(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createSearch(group, name, location) {
|
||||||
|
var params = {
|
||||||
|
sku: { name: "free" },
|
||||||
|
location: location
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.searchClient.services.createOrUpdate(group, name, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createStorage(group, serverName, name, location) {
|
||||||
|
var params = {
|
||||||
|
sku: { name: "Free" },
|
||||||
|
createMode: "Default",
|
||||||
|
location: location
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.storageClient.databases.createOrUpdate(
|
||||||
|
group,
|
||||||
|
serverName,
|
||||||
|
name,
|
||||||
|
params
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createCognitiveServices(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
kind
|
||||||
|
): Promise<CognitiveServicesAccount> {
|
||||||
|
// * 'Bing.Autosuggest.v7', 'Bing.CustomSearch',
|
||||||
|
// * 'Bing.Search.v7', 'Bing.Speech', 'Bing.SpellCheck.v7', 'ComputerVision',
|
||||||
|
// * 'ContentModerator', 'CustomSpeech', 'CustomVision.Prediction',
|
||||||
|
// * 'CustomVision.Training', 'Emotion', 'Face', 'LUIS', 'QnAMaker',
|
||||||
|
// * 'SpeakerRecognition', 'SpeechTranslation', 'TextAnalytics',
|
||||||
|
// * 'TextTranslation', 'WebLM'
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
sku: { name: "F0" },
|
||||||
|
createMode: "Default",
|
||||||
|
location: location,
|
||||||
|
kind: kind,
|
||||||
|
properties: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
return await this.cognitiveClient.accounts.create(group, name, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createSpeech(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
location
|
||||||
|
): Promise<CognitiveServicesAccount> {
|
||||||
|
return await this.createCognitiveServices(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
"SpeechServices"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createNLP(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
location
|
||||||
|
): Promise<CognitiveServicesAccount> {
|
||||||
|
return await this.createCognitiveServices(group, name, location, "LUIS");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createSpellChecker(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
location
|
||||||
|
): Promise<CognitiveServicesAccount> {
|
||||||
|
return await this.createCognitiveServices(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
"global",
|
||||||
|
"Bing.SpellCheck.v7"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createTextAnalytics(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
location
|
||||||
|
): Promise<CognitiveServicesAccount> {
|
||||||
|
return await this.createCognitiveServices(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
location,
|
||||||
|
"TextAnalytics"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createDeploy(name, location) {
|
||||||
|
var params = { location: location };
|
||||||
|
return this.resourceClient.resourceGroups.createOrUpdate(name, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createHostingPlan(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
location
|
||||||
|
): Promise<AppServicePlan> {
|
||||||
|
let params = {
|
||||||
|
serverFarmWithRichSkuName: name,
|
||||||
|
location: location,
|
||||||
|
sku: {
|
||||||
|
name: "F1",
|
||||||
|
capacity: 1,
|
||||||
|
tier: "Free"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.webSiteClient.appServicePlans.createOrUpdate(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
params
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createServer(farmId, group, name, location) {
|
||||||
|
var parameters = {
|
||||||
|
location: location,
|
||||||
|
serverFarmId: farmId
|
||||||
|
};
|
||||||
|
return this.webSiteClient.webApps.createOrUpdate(group, name, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async updateWebisteConfig(group, serverFarmId, name, location) {
|
||||||
|
var siteConfig = {
|
||||||
|
location: location,
|
||||||
|
serverFarmId: serverFarmId,
|
||||||
|
numberOfWorkers: 1,
|
||||||
|
phpVersion: "5.5"
|
||||||
|
};
|
||||||
|
return this.webSiteClient.webApps.createOrUpdateConfiguration(
|
||||||
|
group,
|
||||||
|
name,
|
||||||
|
siteConfig
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private deleteDeploy(name) {
|
||||||
|
return this.resourceClient.resourceGroups.deleteMethod(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
async deployGeneralBotsToAzure() {
|
||||||
|
let status = await git.status();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static getRndAdminAccount() {
|
||||||
|
const passwordGenerator = new PasswordGenerator();
|
||||||
|
const options = {
|
||||||
|
upperCaseAlpha: true,
|
||||||
|
lowerCaseAlpha: true,
|
||||||
|
number: true,
|
||||||
|
specialCharacter: true,
|
||||||
|
minimumLength: 8,
|
||||||
|
maximumLength: 8
|
||||||
|
};
|
||||||
|
let password = passwordGenerator.generatePassword(options);
|
||||||
|
return `sa${password}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static getRndPassword() {
|
||||||
|
const passwordGenerator = new PasswordGenerator();
|
||||||
|
const options = {
|
||||||
|
upperCaseAlpha: true,
|
||||||
|
lowerCaseAlpha: true,
|
||||||
|
number: true,
|
||||||
|
specialCharacter: true,
|
||||||
|
minimumLength: 8,
|
||||||
|
maximumLength: 8
|
||||||
|
};
|
||||||
|
let password = passwordGenerator.generatePassword(options);
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
}
|
22
deploy/azuredeployer.gbapp/strings.ts
Normal file
22
deploy/azuredeployer.gbapp/strings.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
export const Messages = {
|
||||||
|
"en-US": {
|
||||||
|
about_suggestions: "Suggestions are welcomed and improve my quality...",
|
||||||
|
what_about_service: "What about my service?",
|
||||||
|
glad_you_liked: "I'm glad you liked. I'm here for you.",
|
||||||
|
we_will_improve: "Let's take note of that, thanks for sharing.",
|
||||||
|
what_about_me: "What about the service, please rate between 1 and 5.",
|
||||||
|
thanks: "Thanks!",
|
||||||
|
im_sorry_lets_try: "I'm sorry. Let's try again...",
|
||||||
|
great_thanks: "Great, thanks for sharing your thoughts."
|
||||||
|
},
|
||||||
|
"pt-BR": {
|
||||||
|
about_suggestions: "Sugestões melhoram muito minha qualidade...",
|
||||||
|
what_about_service:"O que achou do meu atendimento?",
|
||||||
|
glad_you_liked: "Bom saber que você gostou. Conte comigo.",
|
||||||
|
we_will_improve: "Vamos registrar sua questão, obrigado pela sinceridade.",
|
||||||
|
what_about_me: "O que achou do meu atendimento, de 1 a 5?",
|
||||||
|
thanks: "Obrigado!",
|
||||||
|
im_sorry_lets_try: "Desculpe-me, vamos tentar novamente.",
|
||||||
|
great_thanks: "Ótimo, obrigado por contribuir com sua resposta."
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,304 +0,0 @@
|
||||||
/*****************************************************************************\
|
|
||||||
| ( )_ _ |
|
|
||||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
|
||||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
|
||||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
|
||||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
|
||||||
| | | ( )_) | |
|
|
||||||
| (_) \___/' |
|
|
||||||
| |
|
|
||||||
| General Bots Copyright (c) Pragmatismo.io. All rights reserved. |
|
|
||||||
| Licensed under the AGPL-3.0. |
|
|
||||||
| |
|
|
||||||
| According to our dual licensing model, this program can be used either |
|
|
||||||
| under the terms of the GNU Affero General Public License, version 3, |
|
|
||||||
| or under a proprietary license. |
|
|
||||||
| |
|
|
||||||
| The texts of the GNU Affero General Public License with an additional |
|
|
||||||
| permission and of our proprietary license can be found at and |
|
|
||||||
| in the LICENSE file you have received along with this program. |
|
|
||||||
| |
|
|
||||||
| This program is distributed in the hope that it will be useful, |
|
|
||||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
|
||||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
||||||
| GNU Affero General Public License for more details. |
|
|
||||||
| |
|
|
||||||
| "General Bots" is a registered trademark of Pragmatismo.io. |
|
|
||||||
| The licensing of the program under the AGPLv3 does not imply a |
|
|
||||||
| trademark license. Therefore any rights, title and interest in |
|
|
||||||
| our trademarks remain entirely with us. |
|
|
||||||
| |
|
|
||||||
\*****************************************************************************/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { GBService, IGBInstance } from "botlib"
|
|
||||||
const msRestAzure = require('ms-rest-azure');
|
|
||||||
import { ResourceManagementClient } from 'azure-arm-resource'
|
|
||||||
import { WebSiteManagementClient } from 'azure-arm-website';
|
|
||||||
import { SqlManagementClient } from "azure-arm-sql";
|
|
||||||
import { CognitiveServicesManagementClient } from "azure-arm-cognitiveservices";
|
|
||||||
import { CognitiveServicesAccount } from "azure-arm-cognitiveservices/lib/models";
|
|
||||||
import { SearchManagementClient } from "azure-arm-search";
|
|
||||||
import { BotConfiguration, BotService, EndpointService, IBotService, IConnectedService, ServiceTypes } from 'botframework-config';
|
|
||||||
import { WebResource, ServiceClient } from "ms-rest-js";
|
|
||||||
import * as simplegit from 'simple-git/promise';
|
|
||||||
import { AppServicePlan } from "azure-arm-website/lib/models";
|
|
||||||
|
|
||||||
const git = simplegit();
|
|
||||||
const logger = require("../../../src/logger");
|
|
||||||
const UrlJoin = require("url-join")
|
|
||||||
|
|
||||||
export class AzureDeployerService extends GBService {
|
|
||||||
|
|
||||||
instance: IGBInstance
|
|
||||||
resourceClient: ResourceManagementClient.ResourceManagementClient;
|
|
||||||
webSiteClient: WebSiteManagementClient;
|
|
||||||
storageClient: SqlManagementClient;
|
|
||||||
cognitiveClient: CognitiveServicesManagementClient;
|
|
||||||
searchClient: SearchManagementClient;
|
|
||||||
provider = 'Microsoft.BotService';
|
|
||||||
|
|
||||||
|
|
||||||
public async process(username: any, password: any, instance: IGBInstance,
|
|
||||||
subscriptionId: string, location: string) {
|
|
||||||
let _this = this;
|
|
||||||
msRestAzure.loginWithUsernamePassword(username, password, async (err, credentials) => {
|
|
||||||
|
|
||||||
_this.resourceClient = new ResourceManagementClient.default(credentials, subscriptionId);
|
|
||||||
_this.webSiteClient = new WebSiteManagementClient(credentials, subscriptionId);
|
|
||||||
_this.storageClient = new SqlManagementClient(credentials, subscriptionId);
|
|
||||||
_this.cognitiveClient = new CognitiveServicesManagementClient(credentials, subscriptionId);
|
|
||||||
_this.searchClient = new SearchManagementClient(credentials, subscriptionId);
|
|
||||||
|
|
||||||
let name = "generalbots";
|
|
||||||
let administratorLogin = ""
|
|
||||||
let administratorPassword = ""
|
|
||||||
let serverName = name + "";
|
|
||||||
let tenantId = '';
|
|
||||||
|
|
||||||
logger.info(`Creating Deploy...`);
|
|
||||||
let deploymentName = await this.createDeploy(name, location);
|
|
||||||
|
|
||||||
logger.info(`Creating Server...`);
|
|
||||||
let serverFarm = await this.createHostingPlan(name, `${name}-server-plan`, location);
|
|
||||||
await this.createServer(serverFarm.id, name, `${name}-server`, location);
|
|
||||||
|
|
||||||
logger.info(`Creating Storage...`);
|
|
||||||
//await this.createStorageServer(name, `${name}-storage-server`, administratorLogin, administratorPassword, serverName, location);
|
|
||||||
//await this.createStorage(name, name, `${name}-storage`, location);
|
|
||||||
|
|
||||||
logger.info(`Creating NLP...`);
|
|
||||||
//await this.createNLP(name, `${name}-nlp`, location);
|
|
||||||
|
|
||||||
logger.info(`Creating Speech...`);
|
|
||||||
//await this.createSpeech(name, `${name}-speech`, location);
|
|
||||||
|
|
||||||
logger.info(`Creating SpellChecker...`);
|
|
||||||
//await this.createSpellChecker(name, `${name}-spellchecker`, location);
|
|
||||||
|
|
||||||
logger.info(`Creating Text Analytics...`);
|
|
||||||
//await this.createTextAnalytics(name, `${name}-textanalytics`, location);
|
|
||||||
|
|
||||||
logger.info(`Creating Search...`);
|
|
||||||
//await this.createSearch(name, `${name}-search`, location);
|
|
||||||
|
|
||||||
logger.info(`Creating Bot...`);
|
|
||||||
//await this.createBot(credentials.tokenCache._entries[0].accessToken,
|
|
||||||
// name, name, name, 'global', subscriptionId, tenantId);
|
|
||||||
|
|
||||||
|
|
||||||
logger.info(`Cleaning Deploy it can take a while...`);
|
|
||||||
// DISABLED: await this.dangerouslyDeleteDeploy(name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async dangerouslyDeleteDeploy(name) {
|
|
||||||
|
|
||||||
return this.resourceClient.resourceGroups.deleteMethod(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createStorageServer(group, name, administratorLogin,
|
|
||||||
administratorPassword, serverName, location) {
|
|
||||||
|
|
||||||
var params = {
|
|
||||||
location: location,
|
|
||||||
administratorLogin: administratorLogin,
|
|
||||||
administratorLoginPassword: administratorPassword,
|
|
||||||
fullyQualifiedDomainName: `${serverName}.database.windows.net`
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.storageClient.servers.createOrUpdate(group, name, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async registerProviders(subscriptionId, baseUrl, accessToken, ){
|
|
||||||
|
|
||||||
let query = `subscriptions/${subscriptionId}/providers/${this.provider}/register?api-version=2018-02-01`
|
|
||||||
let requestUrl = UrlJoin(baseUrl, query);
|
|
||||||
|
|
||||||
let req = new WebResource();
|
|
||||||
req.method = 'POST';
|
|
||||||
req.url = requestUrl;
|
|
||||||
req.headers = {};
|
|
||||||
req.headers['Content-Type'] = 'application/json; charset=utf-8';
|
|
||||||
req.headers["accept-language"] = '*'
|
|
||||||
req.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
|
|
||||||
req.headers['Authorization'] = 'Bearer ' + accessToken;
|
|
||||||
|
|
||||||
let httpClient = new ServiceClient();
|
|
||||||
let res = await httpClient.sendRequest(req);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createBot(accessToken, botId, group, name, location, subscriptionId, tenantId) {
|
|
||||||
|
|
||||||
let baseUrl = `https://management.azure.com/`;
|
|
||||||
let appId = '2cac4573-0aea-442a-a222-dcc340000000';
|
|
||||||
let description = 'description';
|
|
||||||
let endpoint = 'http://localhost:4242/';
|
|
||||||
let nlpKey = 'c5869c6c13854434a3f228aad2d6dfb6';
|
|
||||||
let nlpAppId = "3e431b4f-96a4-4bdb-b2d5-3ea462ddb773";
|
|
||||||
|
|
||||||
let parameters = { parameters:{
|
|
||||||
"location": location,
|
|
||||||
"sku": {
|
|
||||||
"name": "F0"
|
|
||||||
},
|
|
||||||
"name": name,
|
|
||||||
//"type": "sampletype",
|
|
||||||
"id": botId,
|
|
||||||
"kind": "sdk",
|
|
||||||
"properties": {
|
|
||||||
"description": description,
|
|
||||||
"displayName": name,
|
|
||||||
"endpoint": endpoint,
|
|
||||||
"iconUrl": "http://myicon",
|
|
||||||
"luisAppIds": [
|
|
||||||
nlpAppId,
|
|
||||||
],
|
|
||||||
"luisKey": nlpKey,
|
|
||||||
"msaAppId": appId
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
let query = `subscriptions/${subscriptionId}/resourceGroups/${group}/providers/${this.provider}/botServices/${botId}?api-version=2017-12-01`;
|
|
||||||
let requestUrl = UrlJoin(baseUrl, query);
|
|
||||||
|
|
||||||
let req = new WebResource();
|
|
||||||
req.method = 'PUT';
|
|
||||||
req.url = requestUrl;
|
|
||||||
req.headers = {};
|
|
||||||
req.headers['Content-Type'] = 'application/json';
|
|
||||||
req.headers["accept-language"] = '*'
|
|
||||||
//req.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
|
|
||||||
req.headers['Authorization'] = 'Bearer ' + accessToken;
|
|
||||||
|
|
||||||
let requestContent = JSON.stringify(parameters);
|
|
||||||
req.body = requestContent;
|
|
||||||
|
|
||||||
let httpClient = new ServiceClient();
|
|
||||||
let res = await httpClient.sendRequest(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createSearch(group, name, location) {
|
|
||||||
var params = {
|
|
||||||
sku: { name: 'free' },
|
|
||||||
location: location
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.searchClient.services.createOrUpdate(group, name, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createStorage(group, serverName, name, location) {
|
|
||||||
|
|
||||||
var params = {
|
|
||||||
sku: { name: 'Free' },
|
|
||||||
createMode: 'Default',
|
|
||||||
location: location
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.storageClient.databases.createOrUpdate(group,
|
|
||||||
serverName, name, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createCognitiveServices(group, name, location, kind): Promise<CognitiveServicesAccount> {
|
|
||||||
|
|
||||||
// * 'Bing.Autosuggest.v7', 'Bing.CustomSearch',
|
|
||||||
// * 'Bing.Search.v7', 'Bing.Speech', 'Bing.SpellCheck.v7', 'ComputerVision',
|
|
||||||
// * 'ContentModerator', 'CustomSpeech', 'CustomVision.Prediction',
|
|
||||||
// * 'CustomVision.Training', 'Emotion', 'Face', 'LUIS', 'QnAMaker',
|
|
||||||
// * 'SpeakerRecognition', 'SpeechTranslation', 'TextAnalytics',
|
|
||||||
// * 'TextTranslation', 'WebLM'
|
|
||||||
|
|
||||||
let params = {
|
|
||||||
sku: { name: 'F0' },
|
|
||||||
createMode: 'Default',
|
|
||||||
location: location,
|
|
||||||
kind: kind,
|
|
||||||
properties: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
return await this.cognitiveClient.accounts.create(group, name, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createSpeech(group, name, location): Promise<CognitiveServicesAccount> {
|
|
||||||
return await this.createCognitiveServices(group, name, location, 'SpeechServices');
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createNLP(group, name, location): Promise<CognitiveServicesAccount> {
|
|
||||||
return await this.createCognitiveServices(group, name, location, 'LUIS');
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createSpellChecker(group, name, location): Promise<CognitiveServicesAccount> {
|
|
||||||
return await this.createCognitiveServices(group, name, 'global', 'Bing.SpellCheck.v7');
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createTextAnalytics(group, name, location): Promise<CognitiveServicesAccount> {
|
|
||||||
return await this.createCognitiveServices(group, name, location, 'TextAnalytics');
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createDeploy(name, location) {
|
|
||||||
var params = { location: location };
|
|
||||||
return this.resourceClient.resourceGroups.createOrUpdate(name, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createHostingPlan(group, name, location):Promise<AppServicePlan> {
|
|
||||||
let params = {
|
|
||||||
serverFarmWithRichSkuName: name,
|
|
||||||
location: location,
|
|
||||||
sku: {
|
|
||||||
name: 'F1',
|
|
||||||
capacity: 1,
|
|
||||||
tier: 'Free'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.webSiteClient.appServicePlans.createOrUpdate(group, name, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async createServer(farmId, group, name, location) {
|
|
||||||
var parameters = {
|
|
||||||
location: location,
|
|
||||||
serverFarmId: farmId
|
|
||||||
};
|
|
||||||
return this.webSiteClient.webApps.createOrUpdate(group, name, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async updateWebisteConfig(group, serverFarmId, name, location) {
|
|
||||||
var siteConfig = {
|
|
||||||
location: location,
|
|
||||||
serverFarmId: serverFarmId,
|
|
||||||
numberOfWorkers: 1,
|
|
||||||
phpVersion: '5.5'
|
|
||||||
};
|
|
||||||
return this.webSiteClient.webApps.createOrUpdateConfiguration(group, name, siteConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
private deleteDeploy(name) {
|
|
||||||
return this.resourceClient.resourceGroups.deleteMethod(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
async deployGeneralBotsToAzure(){
|
|
||||||
let status = await git.status();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -65,9 +65,9 @@ export class GuaribasInstance extends Model<GuaribasInstance>
|
||||||
@AutoIncrement
|
@AutoIncrement
|
||||||
@Column
|
@Column
|
||||||
instanceId: number;
|
instanceId: number;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
botServerUrl:string;
|
botServerUrl: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
whoAmIVideo: string;
|
whoAmIVideo: string;
|
||||||
|
@ -109,10 +109,10 @@ export class GuaribasInstance extends Model<GuaribasInstance>
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
authenticatorTenant: string;
|
authenticatorTenant: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
authenticatorAuthorityHostUrl: string;
|
authenticatorAuthorityHostUrl: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
authenticatorClientId: string;
|
authenticatorClientId: string;
|
||||||
|
|
||||||
|
@ -148,13 +148,19 @@ export class GuaribasInstance extends Model<GuaribasInstance>
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
smsServiceNumber: string;
|
smsServiceNumber: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
speechKey: string;
|
speechKey: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
speechKeyEndpoint: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
spellcheckerKey: string;
|
spellcheckerKey: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
spellcheckerEndpoint: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
theme: string;
|
theme: string;
|
||||||
|
|
||||||
|
@ -168,11 +174,11 @@ export class GuaribasInstance extends Model<GuaribasInstance>
|
||||||
nlpAppId: string;
|
nlpAppId: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
nlpSubscriptionKey: string;
|
nlpKey: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Column({ type: DataType.STRING(512) })
|
@Column({ type: DataType.STRING(512) })
|
||||||
nlpServerUrl: string;
|
nlpEndpoint: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
searchHost: string;
|
searchHost: string;
|
||||||
|
@ -186,6 +192,24 @@ export class GuaribasInstance extends Model<GuaribasInstance>
|
||||||
@Column
|
@Column
|
||||||
searchIndexer: string;
|
searchIndexer: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
storageUsername: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
storagePassword: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
storageName: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
storageServer: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
storageDialect: string;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
storagePath: string;
|
||||||
|
|
||||||
/* Settings section of bot.json */
|
/* Settings section of bot.json */
|
||||||
|
|
||||||
@Column(DataType.FLOAT)
|
@Column(DataType.FLOAT)
|
||||||
|
|
|
@ -100,8 +100,8 @@ export class GBConversationalService implements IGBConversationalService {
|
||||||
|
|
||||||
const model = new LuisRecognizer({
|
const model = new LuisRecognizer({
|
||||||
applicationId: min.instance.nlpAppId,
|
applicationId: min.instance.nlpAppId,
|
||||||
endpointKey: min.instance.nlpSubscriptionKey,
|
endpointKey: min.instance.nlpKey,
|
||||||
endpoint: min.instance.nlpServerUrl
|
endpoint: min.instance.nlpEndpoint
|
||||||
});
|
});
|
||||||
|
|
||||||
let nlp: any;
|
let nlp: any;
|
||||||
|
|
|
@ -30,55 +30,83 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict"
|
"use strict";
|
||||||
|
|
||||||
const logger = require("../../../src/logger")
|
const logger = require("../../../src/logger");
|
||||||
import { Sequelize } from "sequelize-typescript"
|
import { Sequelize } from "sequelize-typescript";
|
||||||
import { GBConfigService } from "./GBConfigService"
|
import { GBConfigService } from "./GBConfigService";
|
||||||
import { IGBInstance, IGBCoreService } from "botlib"
|
import { IGBInstance, IGBCoreService } from "botlib";
|
||||||
import { GuaribasInstance } from "../models/GBModel"
|
import { GuaribasInstance } from "../models/GBModel";
|
||||||
import { GBAdminService } from "../../admin.gbapp/services/GBAdminService";
|
import { GBAdminService } from "../../admin.gbapp/services/GBAdminService";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { AzureDeployerService } from "../../azuredeployer.gbapp/services/AzureDeployerService";
|
||||||
|
const msRestAzure = require("ms-rest-azure");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core service layer.
|
* Core service layer.
|
||||||
*/
|
*/
|
||||||
export class GBCoreService implements IGBCoreService {
|
export class GBCoreService implements IGBCoreService {
|
||||||
|
async ensureCloud() {
|
||||||
|
if (!fs.existsSync(".env")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.warn(
|
||||||
|
"This mechanism will only work for organizational ids and ids that are not 2FA enabled."
|
||||||
|
);
|
||||||
|
|
||||||
|
let credentials = await msRestAzure.loginWithUsernamePassword(
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
);
|
||||||
|
let subscriptionId = "";
|
||||||
|
|
||||||
|
let s = new AzureDeployerService(credentials, subscriptionId);
|
||||||
|
let instance = new GuaribasInstance();
|
||||||
|
await s.deploy(instance, "westus");
|
||||||
|
instance.save();
|
||||||
|
|
||||||
|
let content = `STORAGE_HOST = ${instance.storageServer}\n
|
||||||
|
STORAGE_NAME, STORAGE_USERNAME, STORAGE_PASSWORD, STORAGE_DIALECT`;
|
||||||
|
|
||||||
|
fs.writeFileSync(".env", content);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Data access layer instance.
|
* Data access layer instance.
|
||||||
*/
|
*/
|
||||||
public sequelize: Sequelize
|
public sequelize: Sequelize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Administrative services.
|
* Administrative services.
|
||||||
*/
|
*/
|
||||||
public adminService: GBAdminService
|
public adminService: GBAdminService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows filtering on SQL generated before send to the database.
|
* Allows filtering on SQL generated before send to the database.
|
||||||
*/
|
*/
|
||||||
private queryGenerator: any
|
private queryGenerator: any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom create table query.
|
* Custom create table query.
|
||||||
*/
|
*/
|
||||||
private createTableQuery: (tableName, attributes, options) => string
|
private createTableQuery: (tableName, attributes, options) => string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom change column query.
|
* Custom change column query.
|
||||||
*/
|
*/
|
||||||
private changeColumnQuery: (tableName, attributes) => string
|
private changeColumnQuery: (tableName, attributes) => string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialect used. Tested: mssql and sqlite.
|
* Dialect used. Tested: mssql and sqlite.
|
||||||
*/
|
*/
|
||||||
private dialect: string
|
private dialect: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor retrieves default values.
|
* Constructor retrieves default values.
|
||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
this.dialect = GBConfigService.get("STORAGE_DIALECT")
|
this.dialect = GBConfigService.get("STORAGE_DIALECT");
|
||||||
this.adminService = new GBAdminService(this)
|
this.adminService = new GBAdminService(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,29 +115,29 @@ export class GBCoreService implements IGBCoreService {
|
||||||
async initDatabase() {
|
async initDatabase() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
let host: string | undefined
|
let host: string | undefined;
|
||||||
let database: string | undefined
|
let database: string | undefined;
|
||||||
let username: string | undefined
|
let username: string | undefined;
|
||||||
let password: string | undefined
|
let password: string | undefined;
|
||||||
let storage: string | undefined
|
let storage: string | undefined;
|
||||||
|
|
||||||
if (this.dialect === "mssql") {
|
if (this.dialect === "mssql") {
|
||||||
host = GBConfigService.get("STORAGE_HOST")
|
host = GBConfigService.get("STORAGE_HOST");
|
||||||
database = GBConfigService.get("STORAGE_NAME")
|
database = GBConfigService.get("STORAGE_NAME");
|
||||||
username = GBConfigService.get("STORAGE_USERNAME")
|
username = GBConfigService.get("STORAGE_USERNAME");
|
||||||
password = GBConfigService.get("STORAGE_PASSWORD")
|
password = GBConfigService.get("STORAGE_PASSWORD");
|
||||||
} else if (this.dialect === "sqlite") {
|
} else if (this.dialect === "sqlite") {
|
||||||
storage = GBConfigService.get("STORAGE_STORAGE")
|
storage = GBConfigService.get("STORAGE_STORAGE");
|
||||||
}
|
}
|
||||||
|
|
||||||
let logging =
|
let logging =
|
||||||
GBConfigService.get("STORAGE_LOGGING") === "true"
|
GBConfigService.get("STORAGE_LOGGING") === "true"
|
||||||
? (str: string) => {
|
? (str: string) => {
|
||||||
logger.info(str)
|
logger.info(str);
|
||||||
}
|
}
|
||||||
: false
|
: false;
|
||||||
|
|
||||||
let encrypt = GBConfigService.get("STORAGE_ENCRYPT") === "true"
|
let encrypt = GBConfigService.get("STORAGE_ENCRYPT") === "true";
|
||||||
|
|
||||||
this.sequelize = new Sequelize({
|
this.sequelize = new Sequelize({
|
||||||
host: host,
|
host: host,
|
||||||
|
@ -130,30 +158,30 @@ export class GBCoreService implements IGBCoreService {
|
||||||
evict: 40000,
|
evict: 40000,
|
||||||
acquire: 40000
|
acquire: 40000
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
if (this.dialect === "mssql") {
|
if (this.dialect === "mssql") {
|
||||||
this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator
|
this.queryGenerator = this.sequelize.getQueryInterface().QueryGenerator;
|
||||||
this.createTableQuery = this.queryGenerator.createTableQuery
|
this.createTableQuery = this.queryGenerator.createTableQuery;
|
||||||
this.queryGenerator.createTableQuery = (
|
this.queryGenerator.createTableQuery = (
|
||||||
tableName,
|
tableName,
|
||||||
attributes,
|
attributes,
|
||||||
options
|
options
|
||||||
) => this.createTableQueryOverride(tableName, attributes, options)
|
) => this.createTableQueryOverride(tableName, attributes, options);
|
||||||
this.changeColumnQuery = this.queryGenerator.changeColumnQuery
|
this.changeColumnQuery = this.queryGenerator.changeColumnQuery;
|
||||||
this.queryGenerator.changeColumnQuery = (tableName, attributes) =>
|
this.queryGenerator.changeColumnQuery = (tableName, attributes) =>
|
||||||
this.changeColumnQueryOverride(tableName, attributes)
|
this.changeColumnQueryOverride(tableName, attributes);
|
||||||
}
|
}
|
||||||
resolve()
|
resolve();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(error)
|
reject(error);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL:
|
* SQL:
|
||||||
*
|
*
|
||||||
* // let sql: string = '' +
|
* // let sql: string = '' +
|
||||||
* // 'IF OBJECT_ID(\'[UserGroup]\', \'U\') IS NULL\n' +
|
* // 'IF OBJECT_ID(\'[UserGroup]\', \'U\') IS NULL\n' +
|
||||||
* // 'CREATE TABLE [UserGroup] (\n' +
|
* // 'CREATE TABLE [UserGroup] (\n' +
|
||||||
|
@ -171,38 +199,37 @@ export class GBCoreService implements IGBCoreService {
|
||||||
tableName,
|
tableName,
|
||||||
attributes,
|
attributes,
|
||||||
options
|
options
|
||||||
])
|
]);
|
||||||
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/
|
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/;
|
||||||
const matches = re1.exec(sql)
|
const matches = re1.exec(sql);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
const table = matches[1]
|
const table = matches[1];
|
||||||
const re2 = /PRIMARY\s+KEY\s+\(\[[^\]]*\](?:,\s*\[[^\]]*\])*\)/
|
const re2 = /PRIMARY\s+KEY\s+\(\[[^\]]*\](?:,\s*\[[^\]]*\])*\)/;
|
||||||
sql = sql.replace(
|
sql = sql.replace(
|
||||||
re2,
|
re2,
|
||||||
(match: string, ...args: any[]): string => {
|
(match: string, ...args: any[]): string => {
|
||||||
return "CONSTRAINT [" + table + "_pk] " + match
|
return "CONSTRAINT [" + table + "_pk] " + match;
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
const re3 = /FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g
|
const re3 = /FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g;
|
||||||
const re4 = /\[([^\]]*)\]/g
|
const re4 = /\[([^\]]*)\]/g;
|
||||||
sql = sql.replace(
|
sql = sql.replace(
|
||||||
re3,
|
re3,
|
||||||
(match: string, ...args: any[]): string => {
|
(match: string, ...args: any[]): string => {
|
||||||
const fkcols = args[0]
|
const fkcols = args[0];
|
||||||
let fkname = table
|
let fkname = table;
|
||||||
let matches = re4.exec(fkcols)
|
let matches = re4.exec(fkcols);
|
||||||
while (matches != null) {
|
while (matches != null) {
|
||||||
fkname += "_" + matches[1]
|
fkname += "_" + matches[1];
|
||||||
matches = re4.exec(fkcols)
|
matches = re4.exec(fkcols);
|
||||||
}
|
}
|
||||||
return "CONSTRAINT [" + fkname + "_fk] FOREIGN KEY (" + fkcols + ")"
|
return "CONSTRAINT [" + fkname + "_fk] FOREIGN KEY (" + fkcols + ")";
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
return sql
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL:
|
* SQL:
|
||||||
* let sql = '' +
|
* let sql = '' +
|
||||||
|
@ -215,22 +242,22 @@ export class GBCoreService implements IGBCoreService {
|
||||||
let sql: string = this.changeColumnQuery.apply(this.queryGenerator, [
|
let sql: string = this.changeColumnQuery.apply(this.queryGenerator, [
|
||||||
tableName,
|
tableName,
|
||||||
attributes
|
attributes
|
||||||
])
|
]);
|
||||||
const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/
|
const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/;
|
||||||
const matches = re1.exec(sql)
|
const matches = re1.exec(sql);
|
||||||
if (matches) {
|
if (matches) {
|
||||||
const table = matches[1]
|
const table = matches[1];
|
||||||
const re2 = /(ADD\s+)?CONSTRAINT\s+\[([^\]]*)\]\s+FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g
|
const re2 = /(ADD\s+)?CONSTRAINT\s+\[([^\]]*)\]\s+FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g;
|
||||||
const re3 = /\[([^\]]*)\]/g
|
const re3 = /\[([^\]]*)\]/g;
|
||||||
sql = sql.replace(
|
sql = sql.replace(
|
||||||
re2,
|
re2,
|
||||||
(match: string, ...args: any[]): string => {
|
(match: string, ...args: any[]): string => {
|
||||||
const fkcols = args[2]
|
const fkcols = args[2];
|
||||||
let fkname = table
|
let fkname = table;
|
||||||
let matches = re3.exec(fkcols)
|
let matches = re3.exec(fkcols);
|
||||||
while (matches != null) {
|
while (matches != null) {
|
||||||
fkname += "_" + matches[1]
|
fkname += "_" + matches[1];
|
||||||
matches = re3.exec(fkcols)
|
matches = re3.exec(fkcols);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
(args[0] ? args[0] : "") +
|
(args[0] ? args[0] : "") +
|
||||||
|
@ -239,25 +266,25 @@ export class GBCoreService implements IGBCoreService {
|
||||||
"_fk] FOREIGN KEY (" +
|
"_fk] FOREIGN KEY (" +
|
||||||
fkcols +
|
fkcols +
|
||||||
")"
|
")"
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
return sql
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
async syncDatabaseStructure() {
|
async syncDatabaseStructure() {
|
||||||
if (GBConfigService.get("STORAGE_SYNC") === "true") {
|
if (GBConfigService.get("STORAGE_SYNC") === "true") {
|
||||||
const alter = GBConfigService.get("STORAGE_SYNC_ALTER") === "true"
|
const alter = GBConfigService.get("STORAGE_SYNC_ALTER") === "true";
|
||||||
const force = GBConfigService.get("STORAGE_SYNC_FORCE") === "true"
|
const force = GBConfigService.get("STORAGE_SYNC_FORCE") === "true";
|
||||||
logger.info("Syncing database...")
|
logger.info("Syncing database...");
|
||||||
return this.sequelize.sync({
|
return this.sequelize.sync({
|
||||||
alter: alter,
|
alter: alter,
|
||||||
force: force
|
force: force
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let msg = "Database synchronization is disabled.";
|
let msg = "Database synchronization is disabled.";
|
||||||
logger.info(msg)
|
logger.info(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,12 +295,11 @@ export class GBCoreService implements IGBCoreService {
|
||||||
return GuaribasInstance.findAll({});
|
return GuaribasInstance.findAll({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads just one Bot instance by its internal Id.
|
* Loads just one Bot instance by its internal Id.
|
||||||
*/
|
*/
|
||||||
async loadInstanceById(instanceId: string): Promise<IGBInstance> {
|
async loadInstanceById(instanceId: string): Promise<IGBInstance> {
|
||||||
let options = { where: {instanceId: instanceId} }
|
let options = { where: { instanceId: instanceId } };
|
||||||
return GuaribasInstance.findOne(options);
|
return GuaribasInstance.findOne(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,10 +307,10 @@ export class GBCoreService implements IGBCoreService {
|
||||||
* Loads just one Bot instance.
|
* Loads just one Bot instance.
|
||||||
*/
|
*/
|
||||||
async loadInstance(botId: string): Promise<IGBInstance> {
|
async loadInstance(botId: string): Promise<IGBInstance> {
|
||||||
let options = { where: {} }
|
let options = { where: {} };
|
||||||
|
|
||||||
if (botId != "[default]") {
|
if (botId != "[default]") {
|
||||||
options.where = { botId: botId }
|
options.where = { botId: botId };
|
||||||
}
|
}
|
||||||
|
|
||||||
return GuaribasInstance.findOne(options);
|
return GuaribasInstance.findOne(options);
|
||||||
|
|
|
@ -37,7 +37,7 @@ const UrlJoin = require("url-join");
|
||||||
const express = require("express");
|
const express = require("express");
|
||||||
const logger = require("../../../src/logger");
|
const logger = require("../../../src/logger");
|
||||||
const request = require("request-promise-native");
|
const request = require("request-promise-native");
|
||||||
const ngrok = require('ngrok');
|
const ngrok = require("ngrok");
|
||||||
var crypto = require("crypto");
|
var crypto = require("crypto");
|
||||||
var AuthenticationContext = require("adal-node").AuthenticationContext;
|
var AuthenticationContext = require("adal-node").AuthenticationContext;
|
||||||
|
|
||||||
|
@ -67,16 +67,18 @@ import {
|
||||||
import { GuaribasInstance } from "../models/GBModel";
|
import { GuaribasInstance } from "../models/GBModel";
|
||||||
import { Messages } from "../strings";
|
import { Messages } from "../strings";
|
||||||
|
|
||||||
|
|
||||||
/** Minimal service layer for a bot. */
|
/** Minimal service layer for a bot. */
|
||||||
|
|
||||||
export class GBMinService {
|
export class GBMinService {
|
||||||
|
|
||||||
core: IGBCoreService;
|
core: IGBCoreService;
|
||||||
conversationalService: IGBConversationalService;
|
conversationalService: IGBConversationalService;
|
||||||
adminService: IGBAdminService;
|
adminService: IGBAdminService;
|
||||||
deployer: GBDeployer;
|
deployer: GBDeployer;
|
||||||
|
|
||||||
corePackage = "core.gbai";
|
corePackage = "core.gbai";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static initialization of minimal instance.
|
* Static initialization of minimal instance.
|
||||||
*
|
*
|
||||||
|
@ -108,7 +110,7 @@ export class GBMinService {
|
||||||
async buildMin(
|
async buildMin(
|
||||||
server: any,
|
server: any,
|
||||||
appPackages: Array<IGBPackage>,
|
appPackages: Array<IGBPackage>,
|
||||||
instances:GuaribasInstance[]
|
instances: GuaribasInstance[]
|
||||||
): Promise<GBMinInstance> {
|
): Promise<GBMinInstance> {
|
||||||
// Serves default UI on root address '/'.
|
// Serves default UI on root address '/'.
|
||||||
|
|
||||||
|
@ -117,7 +119,7 @@ export class GBMinService {
|
||||||
"/",
|
"/",
|
||||||
express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, "build"))
|
express.static(UrlJoin(GBDeployer.deployFolder, uiPackage, "build"))
|
||||||
);
|
);
|
||||||
|
|
||||||
Promise.all(
|
Promise.all(
|
||||||
instances.map(async instance => {
|
instances.map(async instance => {
|
||||||
// Gets the authorization key for each instance from Bot Service.
|
// Gets the authorization key for each instance from Bot Service.
|
||||||
|
@ -298,11 +300,11 @@ export class GBMinService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async ngrokRefresh(){
|
private async ngrokRefresh() {
|
||||||
const url = await ngrok.connect(9090); // https://757c1652.ngrok.io -> http://localhost:9090
|
const url = await ngrok.connect(9090); // https://757c1652.ngrok.io -> http://localhost:9090
|
||||||
// TODO: Persist to storage and refresh each 8h.
|
// TODO: Persist to storage and refresh each 8h.
|
||||||
// TODO: Update all bots definition in azure.
|
// TODO: Update all bots definition in azure.
|
||||||
}
|
}
|
||||||
|
|
||||||
private async buildBotAdapter(instance: any) {
|
private async buildBotAdapter(instance: any) {
|
||||||
let adapter = new BotFrameworkAdapter({
|
let adapter = new BotFrameworkAdapter({
|
||||||
|
@ -372,15 +374,12 @@ private async ngrokRefresh(){
|
||||||
instance: any,
|
instance: any,
|
||||||
appPackages: any[]
|
appPackages: any[]
|
||||||
) {
|
) {
|
||||||
|
|
||||||
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 = min.dialogs.createContext(context, state);
|
const dc = min.dialogs.createContext(context, state);
|
||||||
dc.context.activity.locale = "en-US"; // TODO: Make dynamic.
|
dc.context.activity.locale = "en-US"; // TODO: Make dynamic.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const user = min.userState.get(dc.context);
|
const user = min.userState.get(dc.context);
|
||||||
|
|
||||||
if (!user.loaded) {
|
if (!user.loaded) {
|
||||||
|
@ -472,14 +471,13 @@ private async ngrokRefresh(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
let msg = `ERROR: ${error.message} ${
|
let msg = `ERROR: ${error.message} ${error.stack ? error.stack : ""}`;
|
||||||
error.stack ? error.stack : ""
|
logger.error(msg);
|
||||||
}`;
|
|
||||||
logger.error(msg);
|
await dc.context.sendActivity(
|
||||||
|
Messages[dc.context.activity.locale].very_sorry_about_error
|
||||||
await dc.context.sendActivity(Messages[dc.context.activity.locale].very_sorry_about_error)
|
);
|
||||||
await dc.begin("/ask", { isReturning: true });
|
await dc.begin("/ask", { isReturning: true });
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -506,7 +504,7 @@ private async ngrokRefresh(){
|
||||||
let msg = `Error calling Direct Line client, verify Bot endpoint on the cloud. Error is: ${error}.`;
|
let msg = `Error calling Direct Line client, verify Bot endpoint on the cloud. Error is: ${error}.`;
|
||||||
return Promise.reject(new Error(msg));
|
return Promise.reject(new Error(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a Speech to Text / Text to Speech token from the provider.
|
* Gets a Speech to Text / Text to Speech token from the provider.
|
||||||
|
|
|
@ -71,10 +71,12 @@
|
||||||
"pragmatismo-io-framework": "1.0.17",
|
"pragmatismo-io-framework": "1.0.17",
|
||||||
"reflect-metadata": "0.1.12",
|
"reflect-metadata": "0.1.12",
|
||||||
"request-promise-native": "1.0.5",
|
"request-promise-native": "1.0.5",
|
||||||
|
"scanf": "^1.0.2",
|
||||||
"sequelize": "4.39.0",
|
"sequelize": "4.39.0",
|
||||||
"sequelize-typescript": "0.6.6",
|
"sequelize-typescript": "0.6.6",
|
||||||
"simple-git": "^1.105.0",
|
"simple-git": "^1.105.0",
|
||||||
"sqlite3": "4.0.2",
|
"sqlite3": "4.0.2",
|
||||||
|
"strict-password-generator": "^1.1.1",
|
||||||
"swagger-client": "3.8.21",
|
"swagger-client": "3.8.21",
|
||||||
"tedious": "2.6.4",
|
"tedious": "2.6.4",
|
||||||
"ts-node": "7.0.1",
|
"ts-node": "7.0.1",
|
||||||
|
|
10
src/app.ts
10
src/app.ts
|
@ -33,13 +33,11 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const UrlJoin = require("url-join");
|
|
||||||
const logger = require("./logger");
|
const logger = require("./logger");
|
||||||
const express = require("express");
|
const express = require("express");
|
||||||
const bodyParser = require("body-parser");
|
const bodyParser = require("body-parser");
|
||||||
const MicrosoftGraph = require("@microsoft/microsoft-graph-client");
|
const scanf = require('scanf');
|
||||||
|
|
||||||
import { Sequelize } from "sequelize-typescript";
|
|
||||||
import { GBConfigService } from "../deploy/core.gbapp/services/GBConfigService";
|
import { GBConfigService } from "../deploy/core.gbapp/services/GBConfigService";
|
||||||
import { GBConversationalService } from "../deploy/core.gbapp/services/GBConversationalService";
|
import { GBConversationalService } from "../deploy/core.gbapp/services/GBConversationalService";
|
||||||
import { GBMinService } from "../deploy/core.gbapp/services/GBMinService";
|
import { GBMinService } from "../deploy/core.gbapp/services/GBMinService";
|
||||||
|
@ -56,7 +54,8 @@ import { GBCustomerSatisfactionPackage } from "../deploy/customer-satisfaction.g
|
||||||
import { IGBPackage } from "botlib";
|
import { IGBPackage } from "botlib";
|
||||||
import { GBAdminService } from "../deploy/admin.gbapp/services/GBAdminService";
|
import { GBAdminService } from "../deploy/admin.gbapp/services/GBAdminService";
|
||||||
import { GuaribasInstance } from "../deploy/core.gbapp/models/GBModel";
|
import { GuaribasInstance } from "../deploy/core.gbapp/models/GBModel";
|
||||||
import { AzureDeployerService } from "../deploy/azuredeployer.gblib/services/AzureDeployerService";
|
import { AzureDeployerService } from "deploy/azuredeployer.gbapp/services/AzureDeployerService";
|
||||||
|
|
||||||
|
|
||||||
let appPackages = new Array<IGBPackage>();
|
let appPackages = new Array<IGBPackage>();
|
||||||
|
|
||||||
|
@ -94,7 +93,10 @@ export class GBServer {
|
||||||
|
|
||||||
GBConfigService.init();
|
GBConfigService.init();
|
||||||
let core = new GBCoreService();
|
let core = new GBCoreService();
|
||||||
|
let instance = await core.ensureCloud();
|
||||||
|
|
||||||
await core.initDatabase();
|
await core.initDatabase();
|
||||||
|
|
||||||
|
|
||||||
// Boot a bot package if any.
|
// Boot a bot package if any.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue