Added Azure AD administration routines.
This commit is contained in:
parent
e7a7fcedbf
commit
c03228dbbe
18 changed files with 617 additions and 374 deletions
|
@ -30,33 +30,33 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict"
|
||||
"use strict";
|
||||
|
||||
const UrlJoin = require("url-join")
|
||||
import { AzureSearch } from "pragmatismo-io-framework"
|
||||
import { GBMinInstance } from "botlib"
|
||||
import { IGBDialog } from "botlib"
|
||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer'
|
||||
import { GBImporter } from '../../core.gbapp/services/GBImporter'
|
||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService'
|
||||
import { KBService } from './../../kb.gbapp/services/KBService'
|
||||
import { BotAdapter } from "botbuilder"
|
||||
const UrlJoin = require("url-join");
|
||||
import { AzureSearch } from "pragmatismo-io-framework";
|
||||
import { GBMinInstance } from "botlib";
|
||||
import { IGBDialog } from "botlib";
|
||||
import { GBDeployer } from "../../core.gbapp/services/GBDeployer";
|
||||
import { GBImporter } from "../../core.gbapp/services/GBImporter";
|
||||
import { GBConfigService } from "../../core.gbapp/services/GBConfigService";
|
||||
import { KBService } from "./../../kb.gbapp/services/KBService";
|
||||
import { BotAdapter } from "botbuilder";
|
||||
import { GBAdminService } from "../services/GBAdminService";
|
||||
|
||||
/**
|
||||
* Dialogs for administration tasks.
|
||||
*/
|
||||
export class AdminDialog extends IGBDialog {
|
||||
|
||||
|
||||
static async undeployPackageCommand(text: any, min: GBMinInstance, dc) {
|
||||
let packageName = text.split(" ")[1]
|
||||
let importer = new GBImporter(min.core)
|
||||
let deployer = new GBDeployer(min.core, importer)
|
||||
dc.context.sendActivity(`Undeploying package ${packageName}...`)
|
||||
let packageName = text.split(" ")[1];
|
||||
let importer = new GBImporter(min.core);
|
||||
let deployer = new GBDeployer(min.core, importer);
|
||||
dc.context.sendActivity(`Undeploying package ${packageName}...`);
|
||||
await deployer.undeployPackageFromLocalPath(
|
||||
min.instance,
|
||||
UrlJoin("deploy", packageName))
|
||||
dc.context.sendActivity(`Package ${packageName} undeployed...`)
|
||||
UrlJoin("deploy", packageName)
|
||||
);
|
||||
dc.context.sendActivity(`Package ${packageName} undeployed...`);
|
||||
}
|
||||
|
||||
static async deployPackageCommand(
|
||||
|
@ -65,11 +65,17 @@ export class AdminDialog extends IGBDialog {
|
|||
deployer: GBDeployer,
|
||||
min: GBMinInstance
|
||||
) {
|
||||
let packageName = text.split(" ")[1]
|
||||
await dc.context.sendActivity(`Deploying package ${packageName}... (It may take a few seconds)`)
|
||||
let additionalPath = GBConfigService.get("ADDITIONAL_DEPLOY_PATH")
|
||||
await deployer.deployPackageFromLocalPath(UrlJoin(additionalPath, packageName))
|
||||
await dc.context.sendActivity(`Package ${packageName} deployed... Please run rebuildIndex command.`)
|
||||
let packageName = text.split(" ")[1];
|
||||
await dc.context.sendActivity(
|
||||
`Deploying package ${packageName}... (It may take a few seconds)`
|
||||
);
|
||||
let additionalPath = GBConfigService.get("ADDITIONAL_DEPLOY_PATH");
|
||||
await deployer.deployPackageFromLocalPath(
|
||||
UrlJoin(additionalPath, packageName)
|
||||
);
|
||||
await dc.context.sendActivity(
|
||||
`Package ${packageName} deployed... Please run rebuildIndex command.`
|
||||
);
|
||||
}
|
||||
|
||||
static async rebuildIndexCommand(min: GBMinInstance, dc) {
|
||||
|
@ -78,95 +84,120 @@ export class AdminDialog extends IGBDialog {
|
|||
min.instance.searchHost,
|
||||
min.instance.searchIndex,
|
||||
min.instance.searchIndexer
|
||||
)
|
||||
dc.context.sendActivity("Rebuilding index...")
|
||||
await search.deleteIndex()
|
||||
let kbService = new KBService(min.core.sequelize)
|
||||
await search.createIndex(kbService.getSearchSchema(min.instance.searchIndex), "gb")
|
||||
await dc.context.sendActivity("Index rebuilt.")
|
||||
);
|
||||
dc.context.sendActivity("Rebuilding index...");
|
||||
await search.deleteIndex();
|
||||
let kbService = new KBService(min.core.sequelize);
|
||||
await search.createIndex(
|
||||
kbService.getSearchSchema(min.instance.searchIndex),
|
||||
"gb"
|
||||
);
|
||||
await dc.context.sendActivity("Index rebuilt.");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
|
||||
// Setup services.
|
||||
|
||||
let importer = new GBImporter(min.core)
|
||||
let deployer = new GBDeployer(min.core, importer)
|
||||
let importer = new GBImporter(min.core);
|
||||
let deployer = new GBDeployer(min.core, importer);
|
||||
|
||||
min.dialogs.add("/admin", [
|
||||
async dc => {
|
||||
await AdminDialog.refreshAdminToken(min, dc);
|
||||
// await dc.context.sendActivity(
|
||||
// `Deploying package ... (It may take a few seconds)`
|
||||
// );
|
||||
// await AdminDialog.deployPackageCommand(
|
||||
// "deployPackage ProjectOnline.gbkb",
|
||||
// dc,
|
||||
// deployer,
|
||||
// min
|
||||
// );
|
||||
await dc.endAll();
|
||||
}
|
||||
]);
|
||||
|
||||
async (dc) => {
|
||||
|
||||
await dc.context.sendActivity(`Deploying package ... (It may take a few seconds)`)
|
||||
await AdminDialog.deployPackageCommand("deployPackage ProjectOnline.gbkb", dc, deployer, min)
|
||||
await dc.endAll()
|
||||
|
||||
}])
|
||||
min.dialogs.add("/adminUpdateToken", [
|
||||
async (dc, args, next) => {
|
||||
await dc.endAll();
|
||||
let service = new GBAdminService();
|
||||
await service.saveValue("authenticatorToken", args.token)
|
||||
await dc.context.sendActivity("Token has been updated.");
|
||||
await dc.replace("/ask")
|
||||
}
|
||||
]);
|
||||
|
||||
min.dialogs.add("/admin1", [
|
||||
|
||||
async (dc, args) => {
|
||||
const prompt = "Please, authenticate:"
|
||||
await dc.prompt('textPrompt', prompt)
|
||||
const prompt = "Please, authenticate:";
|
||||
await dc.prompt("textPrompt", prompt);
|
||||
},
|
||||
async (dc, value) => {
|
||||
let text = value
|
||||
const user = min.userState.get(dc.context)
|
||||
let text = value;
|
||||
const user = min.userState.get(dc.context);
|
||||
|
||||
if (
|
||||
!user.authenticated ||
|
||||
text === GBConfigService.get("ADMIN_PASS")
|
||||
) {
|
||||
user.authenticated = true
|
||||
if (!user.authenticated || text === GBConfigService.get("ADMIN_PASS")) {
|
||||
user.authenticated = true;
|
||||
await dc.context.sendActivity(
|
||||
"Welcome to Pragmatismo.io GeneralBots Administration."
|
||||
)
|
||||
await dc.prompt('textPrompt', "Which task do you wanna run now?")
|
||||
);
|
||||
await dc.prompt("textPrompt", "Which task do you wanna run now?");
|
||||
} else {
|
||||
await dc.endAll()
|
||||
await dc.endAll();
|
||||
}
|
||||
},
|
||||
async (dc, value) => {
|
||||
var text = value
|
||||
const user = min.userState.get(dc.context)
|
||||
var text = value;
|
||||
const user = min.userState.get(dc.context);
|
||||
|
||||
if (text === "quit") {
|
||||
user.authenticated = false
|
||||
await dc.replace("/")
|
||||
user.authenticated = false;
|
||||
await dc.replace("/");
|
||||
} else if (text === "sync") {
|
||||
await min.core.syncDatabaseStructure()
|
||||
await dc.context.sendActivity("Sync started...")
|
||||
await dc.replace("/admin", { firstRun: false })
|
||||
await min.core.syncDatabaseStructure();
|
||||
await dc.context.sendActivity("Sync started...");
|
||||
await dc.replace("/admin", { firstRun: false });
|
||||
} else if (text.split(" ")[0] === "rebuildIndex") {
|
||||
await AdminDialog.rebuildIndexCommand(min, dc)
|
||||
await dc.replace("/admin", { firstRun: false })
|
||||
await AdminDialog.rebuildIndexCommand(min, dc);
|
||||
await dc.replace("/admin", { firstRun: false });
|
||||
} else if (text.split(" ")[0] === "deployPackage") {
|
||||
await AdminDialog.deployPackageCommand(text, dc, deployer, min)
|
||||
await dc.replace("/admin", { firstRun: false })
|
||||
await AdminDialog.deployPackageCommand(text, dc, deployer, min);
|
||||
await dc.replace("/admin", { firstRun: false });
|
||||
} else if (text.split(" ")[0] === "redeployPackage") {
|
||||
await AdminDialog.undeployPackageCommand(text, min, dc)
|
||||
await AdminDialog.deployPackageCommand(text, dc, deployer, min)
|
||||
await dc.context.sendActivity("Redeploy done.")
|
||||
await dc.replace("/admin", { firstRun: false })
|
||||
await AdminDialog.undeployPackageCommand(text, min, dc);
|
||||
await AdminDialog.deployPackageCommand(text, dc, deployer, min);
|
||||
await dc.context.sendActivity("Redeploy done.");
|
||||
await dc.replace("/admin", { firstRun: false });
|
||||
} else if (text.split(" ")[0] === "undeployPackage") {
|
||||
await AdminDialog.undeployPackageCommand(text, min, dc)
|
||||
await dc.replace("/admin", { firstRun: false })
|
||||
await AdminDialog.undeployPackageCommand(text, min, dc);
|
||||
await dc.replace("/admin", { firstRun: false });
|
||||
} else if (text.split(" ")[0] === "applyPackage") {
|
||||
await dc.context.sendActivity("Applying in progress...")
|
||||
await min.core.loadInstance(text.split(" ")[1])
|
||||
await dc.context.sendActivity("Applying done...")
|
||||
await dc.replace("/admin", { firstRun: false })
|
||||
await dc.context.sendActivity("Applying in progress...");
|
||||
await min.core.loadInstance(text.split(" ")[1]);
|
||||
await dc.context.sendActivity("Applying done...");
|
||||
await dc.replace("/admin", { firstRun: false });
|
||||
} else if (text.split(" ")[0] === "rat") {
|
||||
await min.conversationalService.sendEvent(dc, "play", { playerType: "login", data: null })
|
||||
await dc.context.sendActivity("Realize login clicando no botão de login, por favor...")
|
||||
await AdminDialog.refreshAdminToken(min, dc);
|
||||
}
|
||||
}
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
private static async refreshAdminToken(min: any, dc: any) {
|
||||
let config = {
|
||||
authenticatorTenant: min.instance.authenticatorTenant,
|
||||
authenticatorClientID: min.instance.authenticatorClientID
|
||||
};
|
||||
await min.conversationalService.sendEvent(dc, "play", {
|
||||
playerType: "login",
|
||||
data: config
|
||||
});
|
||||
await dc.context.sendActivity("Update your Administrative token by Login...");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,11 +38,15 @@ import { AdminDialog } from './dialogs/AdminDialog'
|
|||
import { GBMinInstance, IGBPackage, IGBCoreService } from 'botlib'
|
||||
|
||||
import { Sequelize } from 'sequelize-typescript'
|
||||
import { GuaribasAdmin } from './models/AdminModel';
|
||||
|
||||
export class GBAdminPackage implements IGBPackage {
|
||||
sysPackages: IGBPackage[] = null
|
||||
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): void {
|
||||
core.sequelize.addModels([
|
||||
GuaribasAdmin
|
||||
])
|
||||
}
|
||||
|
||||
unloadPackage(core: IGBCoreService): void {
|
||||
|
|
61
deploy/admin.gbapp/models/AdminModel.ts
Normal file
61
deploy/admin.gbapp/models/AdminModel.ts
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 {
|
||||
Table,
|
||||
Column,
|
||||
Model,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
} from "sequelize-typescript";
|
||||
|
||||
|
||||
@Table
|
||||
export class GuaribasAdmin extends Model<GuaribasAdmin>
|
||||
{
|
||||
|
||||
@Column
|
||||
key: string;
|
||||
|
||||
@Column
|
||||
value: string;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
updatedAt: Date;
|
||||
}
|
57
deploy/admin.gbapp/services/GBAdminService.ts
Normal file
57
deploy/admin.gbapp/services/GBAdminService.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
|
||||
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
|
||||
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
|
||||
| | | ( )_) | |
|
||||
| (_) \___/' |
|
||||
| |
|
||||
| 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 { GuaribasAdmin } from "../models/AdminModel";
|
||||
|
||||
export class GBAdminService {
|
||||
|
||||
async saveValue(key: string, value: string): Promise<GuaribasAdmin> {
|
||||
let options = { where: {} }
|
||||
options.where = { key: key }
|
||||
let admin = await GuaribasAdmin.findOne(options);
|
||||
if (admin == null) {
|
||||
admin = new GuaribasAdmin();
|
||||
admin.key = key;
|
||||
}
|
||||
admin.value = value;
|
||||
return admin.save()
|
||||
}
|
||||
|
||||
async getValue(key: string) {
|
||||
let options = { where: {} }
|
||||
options.where = { key: key }
|
||||
let obj = await GuaribasAdmin.findOne(options);
|
||||
return Promise.resolve(obj.value);
|
||||
}
|
||||
}
|
|
@ -54,14 +54,15 @@ export class WelcomeDialog extends IGBDialog {
|
|||
user.once = true;
|
||||
var a = new Date();
|
||||
const date = a.getHours();
|
||||
var msg = 4;
|
||||
date < 12
|
||||
? Messages[locale].good_morning
|
||||
: date < 18
|
||||
? Messages[locale].good_evening
|
||||
: Messages[locale].good_night;
|
||||
var msg =
|
||||
date < 12
|
||||
? Messages[locale].good_morning
|
||||
: date < 18
|
||||
? Messages[locale].good_evening
|
||||
: Messages[locale].good_night;
|
||||
|
||||
await dc.context.sendActivity(Messages[locale].hi(msg));
|
||||
await dc.replace("/ask", { firstTime: true });
|
||||
|
||||
if (
|
||||
dc.context.activity &&
|
||||
|
|
|
@ -30,14 +30,14 @@
|
|||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict"
|
||||
"use strict";
|
||||
|
||||
import {
|
||||
DataTypes,
|
||||
DataTypeUUIDv4,
|
||||
DataTypeDate,
|
||||
DataTypeDecimal
|
||||
} from "sequelize"
|
||||
} from "sequelize";
|
||||
|
||||
import {
|
||||
Sequelize,
|
||||
|
@ -54,170 +54,214 @@ import {
|
|||
DataType,
|
||||
PrimaryKey,
|
||||
AutoIncrement
|
||||
} from "sequelize-typescript"
|
||||
} from "sequelize-typescript";
|
||||
|
||||
import { IGBInstance } from "botlib"
|
||||
import { IGBInstance } from "botlib";
|
||||
|
||||
@Table
|
||||
export class GuaribasInstance extends Model<GuaribasInstance> implements IGBInstance {
|
||||
|
||||
export class GuaribasInstance extends Model<GuaribasInstance>
|
||||
implements IGBInstance {
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
instanceId: number
|
||||
|
||||
@Column applicationPrincipal: string
|
||||
instanceId: number;
|
||||
|
||||
@Column
|
||||
whoAmIVideo: string
|
||||
applicationPrincipal: string;
|
||||
|
||||
@Column botId: string
|
||||
@Column
|
||||
whoAmIVideo: string;
|
||||
|
||||
@Column title: string
|
||||
@Column
|
||||
botId: string;
|
||||
|
||||
@Column description: string
|
||||
@Column
|
||||
title: string;
|
||||
|
||||
@Column version: string
|
||||
@Column
|
||||
description: string;
|
||||
|
||||
@Column enabledAdmin: boolean
|
||||
@Column
|
||||
version: string;
|
||||
|
||||
@Column
|
||||
enabledAdmin: boolean;
|
||||
|
||||
/* Services section on bot.json */
|
||||
|
||||
@Column engineName: string
|
||||
@Column
|
||||
engineName: string;
|
||||
|
||||
@Column marketplaceId: string
|
||||
@Column
|
||||
marketplaceId: string;
|
||||
|
||||
@Column textAnalyticsKey: string
|
||||
@Column
|
||||
textAnalyticsKey: string;
|
||||
|
||||
@Column textAnalyticsServerUrl: string
|
||||
@Column
|
||||
textAnalyticsServerUrl: string;
|
||||
|
||||
@Column marketplacePassword: string
|
||||
@Column
|
||||
marketplacePassword: string;
|
||||
|
||||
@Column webchatKey: string
|
||||
@Column
|
||||
webchatKey: string;
|
||||
|
||||
@Column whatsappBotKey: string
|
||||
@Column
|
||||
authenticatorTenant: string;
|
||||
@Column
|
||||
authenticatorSignUpSignInPolicy: string;
|
||||
@Column
|
||||
authenticatorClientID: string;
|
||||
|
||||
@Column whatsappServiceKey: string
|
||||
@Column
|
||||
whatsappBotKey: string;
|
||||
|
||||
@Column whatsappServiceNumber: string
|
||||
@Column
|
||||
whatsappServiceKey: string;
|
||||
|
||||
@Column whatsappServiceUrl: string
|
||||
@Column
|
||||
whatsappServiceNumber: string;
|
||||
|
||||
@Column whatsappServiceWebhookUrl: string
|
||||
@Column
|
||||
whatsappServiceUrl: string;
|
||||
|
||||
@Column speechKey: string
|
||||
@Column
|
||||
whatsappServiceWebhookUrl: string;
|
||||
|
||||
@Column spellcheckerKey: string
|
||||
@Column
|
||||
smsKey: string;
|
||||
|
||||
@Column theme: string
|
||||
@Column
|
||||
smsSecret: string;
|
||||
|
||||
@Column ui: string
|
||||
|
||||
@Column kb: string
|
||||
@Column
|
||||
smsServiceNumber: string;
|
||||
|
||||
@Column
|
||||
nlpAppId: string
|
||||
|
||||
speechKey: string;
|
||||
|
||||
@Column
|
||||
nlpSubscriptionKey: string
|
||||
|
||||
spellcheckerKey: string;
|
||||
|
||||
@Column
|
||||
theme: string;
|
||||
|
||||
@Column
|
||||
ui: string;
|
||||
|
||||
@Column
|
||||
kb: string;
|
||||
|
||||
@Column
|
||||
nlpAppId: string;
|
||||
|
||||
@Column
|
||||
nlpSubscriptionKey: string;
|
||||
|
||||
@Column
|
||||
@Column({ type: DataType.STRING(512) })
|
||||
nlpServerUrl: string
|
||||
nlpServerUrl: string;
|
||||
|
||||
@Column searchHost: string
|
||||
@Column
|
||||
searchHost: string;
|
||||
|
||||
@Column searchKey: string
|
||||
@Column
|
||||
searchKey: string;
|
||||
|
||||
@Column searchIndex: string
|
||||
@Column
|
||||
searchIndex: string;
|
||||
|
||||
@Column searchIndexer: string
|
||||
@Column
|
||||
searchIndexer: string;
|
||||
|
||||
/* Settings section of bot.json */
|
||||
|
||||
@Column(DataType.FLOAT) nlpVsSearch: number
|
||||
@Column(DataType.FLOAT)
|
||||
nlpVsSearch: number;
|
||||
|
||||
@Column(DataType.FLOAT) searchScore: number
|
||||
@Column(DataType.FLOAT)
|
||||
searchScore: number;
|
||||
|
||||
@Column(DataType.FLOAT) nlpScore: number
|
||||
@Column(DataType.FLOAT)
|
||||
nlpScore: number;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
createdAt: Date
|
||||
createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
updatedAt: Date
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasPackage extends Model<GuaribasPackage> {
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
packageId: number
|
||||
packageId: number;
|
||||
|
||||
@Column
|
||||
packageName: string
|
||||
packageName: string;
|
||||
|
||||
@ForeignKey(() => GuaribasInstance)
|
||||
@Column
|
||||
instanceId: number
|
||||
instanceId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasInstance)
|
||||
instance: GuaribasInstance
|
||||
instance: GuaribasInstance;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
createdAt: Date
|
||||
createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
updatedAt: Date
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasChannel extends Model<GuaribasChannel> {
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
channelId: number
|
||||
channelId: number;
|
||||
|
||||
@Column title: string
|
||||
@Column
|
||||
title: string;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
createdAt: Date
|
||||
createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
updatedAt: Date
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
@Table
|
||||
export class GuaribasException extends Model<GuaribasException> {
|
||||
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
@Column
|
||||
exceptionId: number
|
||||
exceptionId: number;
|
||||
|
||||
@Column message: string
|
||||
@Column
|
||||
message: string;
|
||||
|
||||
@ForeignKey(() => GuaribasInstance)
|
||||
@Column
|
||||
instanceId: number
|
||||
instanceId: number;
|
||||
|
||||
@BelongsTo(() => GuaribasInstance)
|
||||
instance: GuaribasInstance
|
||||
instance: GuaribasInstance;
|
||||
|
||||
@Column
|
||||
@CreatedAt
|
||||
createdAt: Date
|
||||
createdAt: Date;
|
||||
|
||||
@Column
|
||||
@UpdatedAt
|
||||
updatedAt: Date
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { IGBInstance } from 'botlib';
|
||||
/*****************************************************************************\
|
||||
| ( )_ _ |
|
||||
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
|
||||
|
@ -41,6 +42,8 @@ import { LuisRecognizer } from "botbuilder-ai";
|
|||
import { MessageFactory } from "botbuilder";
|
||||
import { Messages } from "../strings";
|
||||
import { AzureText } from "pragmatismo-io-framework";
|
||||
const Nexmo = require("nexmo");
|
||||
|
||||
|
||||
export interface LanguagePickerSettings {
|
||||
defaultLocale?: string;
|
||||
|
@ -66,6 +69,19 @@ export class GBConversationalService implements IGBConversationalService {
|
|||
return dc.context.sendActivity(msg);
|
||||
}
|
||||
|
||||
async sendSms(min: GBMinInstance, mobile: string, text: string) : Promise<any> {
|
||||
const nexmo = new Nexmo({
|
||||
apiKey: min.instance.smsKey,
|
||||
apiSecret: min.instance.smsSecret,
|
||||
});
|
||||
nexmo.message.sendSms(
|
||||
min.instance.smsServiceNumber,
|
||||
mobile,
|
||||
text,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
async routeNLP(dc: any, min: GBMinInstance, text: string): Promise<boolean> {
|
||||
// Invokes LUIS.
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import { Sequelize } from "sequelize-typescript"
|
|||
import { GBConfigService } from "./GBConfigService"
|
||||
import { IGBInstance, IGBCoreService } from "botlib"
|
||||
import { GuaribasInstance } from "../models/GBModel"
|
||||
import { GBAdminService } from "../../admin.gbapp/services/GBAdminService";
|
||||
|
||||
/**
|
||||
* Core service layer.
|
||||
|
@ -47,6 +48,11 @@ export class GBCoreService implements IGBCoreService {
|
|||
*/
|
||||
public sequelize: Sequelize
|
||||
|
||||
/**
|
||||
* Administrative services.
|
||||
*/
|
||||
public adminService: GBAdminService
|
||||
|
||||
/**
|
||||
* Allows filtering on SQL generated before send to the database.
|
||||
*/
|
||||
|
@ -72,6 +78,7 @@ export class GBCoreService implements IGBCoreService {
|
|||
*/
|
||||
constructor() {
|
||||
this.dialect = GBConfigService.get("DATABASE_DIALECT")
|
||||
this.adminService = new GBAdminService();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,8 +105,8 @@ export class GBCoreService implements IGBCoreService {
|
|||
let logging =
|
||||
GBConfigService.get("DATABASE_LOGGING") === "true"
|
||||
? (str: string) => {
|
||||
logger.info(str)
|
||||
}
|
||||
logger.info(str)
|
||||
}
|
||||
: false
|
||||
|
||||
let encrypt = GBConfigService.get("DATABASE_ENCRYPT") === "true"
|
||||
|
@ -240,79 +247,38 @@ export class GBCoreService implements IGBCoreService {
|
|||
}
|
||||
|
||||
async syncDatabaseStructure() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (GBConfigService.get("DATABASE_SYNC") === "true") {
|
||||
const alter = GBConfigService.get("DATABASE_SYNC_ALTER") === "true"
|
||||
const force = GBConfigService.get("DATABASE_SYNC_FORCE") === "true"
|
||||
logger.info("Syncing database...")
|
||||
this.sequelize
|
||||
.sync({
|
||||
alter: alter,
|
||||
force: force
|
||||
})
|
||||
.then(
|
||||
value => {
|
||||
logger.info("Database synced.")
|
||||
resolve(value)
|
||||
},
|
||||
err => reject(err)
|
||||
)
|
||||
} else {
|
||||
logger.info("Database synchronization is disabled.")
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
if (GBConfigService.get("DATABASE_SYNC") === "true") {
|
||||
const alter = GBConfigService.get("DATABASE_SYNC_ALTER") === "true"
|
||||
const force = GBConfigService.get("DATABASE_SYNC_FORCE") === "true"
|
||||
logger.info("Syncing database...")
|
||||
return this.sequelize.sync({
|
||||
alter: alter,
|
||||
force: force
|
||||
});
|
||||
} else {
|
||||
let msg = "Database synchronization is disabled.";
|
||||
logger.info(msg)
|
||||
return Promise.reject(msg)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all items to start several listeners.
|
||||
*/
|
||||
async loadInstances(): Promise<IGBInstance> {
|
||||
return new Promise((resolve, reject) => {
|
||||
GuaribasInstance.findAll({})
|
||||
.then((items: IGBInstance[]) => {
|
||||
if (!items) items = []
|
||||
|
||||
if (items.length == 0) {
|
||||
resolve([])
|
||||
} else {
|
||||
resolve(items)
|
||||
}
|
||||
})
|
||||
.catch(reason => {
|
||||
if (reason.message.indexOf("no such table: GuaribasInstance") != -1) {
|
||||
resolve([])
|
||||
} else {
|
||||
logger.info(`GuaribasServiceError: ${reason}`)
|
||||
reject(reason)
|
||||
}
|
||||
})
|
||||
})
|
||||
return GuaribasInstance.findAll({});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads just one Bot instance.
|
||||
*/
|
||||
async loadInstance(botId: string): Promise<IGBInstance> {
|
||||
return new Promise<IGBInstance>((resolve, reject) => {
|
||||
let options = { where: {} }
|
||||
let options = { where: {} }
|
||||
|
||||
if (botId != "[default]") {
|
||||
options.where = { botId: botId }
|
||||
}
|
||||
if (botId != "[default]") {
|
||||
options.where = { botId: botId }
|
||||
}
|
||||
|
||||
GuaribasInstance.findOne(options)
|
||||
.then((instance: IGBInstance) => {
|
||||
if (instance) {
|
||||
resolve(instance)
|
||||
} else {
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
logger.info(`GuaribasServiceError: ${err}`)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
return GuaribasInstance.findOne(options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ export class GBDeployer {
|
|||
appPackagesProcessed++
|
||||
})
|
||||
.catch(err => {
|
||||
logger.info(`Error deploying App (.gbapp): ${e}: ${err}`)
|
||||
logger.error(`Error deploying App (.gbapp): ${e}: ${err}`)
|
||||
appPackagesProcessed++
|
||||
})
|
||||
} else {
|
||||
|
@ -145,14 +145,16 @@ export class GBDeployer {
|
|||
WaitUntil()
|
||||
.interval(1000)
|
||||
.times(10)
|
||||
.condition(function(cb) {
|
||||
.condition(function (cb) {
|
||||
logger.info(`Waiting for app package deployment...`)
|
||||
cb(appPackagesProcessed == gbappPackages.length)
|
||||
})
|
||||
.done(function(result) {
|
||||
logger.info(`App Package deployment done.`)
|
||||
.done(function (result) {
|
||||
logger.info(`App Package deployment done.`);
|
||||
|
||||
core.syncDatabaseStructure()
|
||||
(async () => {
|
||||
await core.syncDatabaseStructure()
|
||||
})()
|
||||
|
||||
/** Deploys all .gbot files first. */
|
||||
|
||||
|
@ -179,7 +181,7 @@ export class GBDeployer {
|
|||
server.use("/themes/" + filenameOnly, express.static(filename))
|
||||
logger.info(
|
||||
`Theme (.gbtheme) assets accessible at: ${"/themes/" +
|
||||
filenameOnly}.`
|
||||
filenameOnly}.`
|
||||
)
|
||||
|
||||
/** Knowledge base for bots. */
|
||||
|
@ -205,13 +207,13 @@ export class GBDeployer {
|
|||
})
|
||||
|
||||
WaitUntil()
|
||||
.interval(1000)
|
||||
.interval(100)
|
||||
.times(5)
|
||||
.condition(function(cb) {
|
||||
.condition(function (cb) {
|
||||
logger.info(`Waiting for package deployment...`)
|
||||
cb(totalPackages == generalPackages.length)
|
||||
})
|
||||
.done(function(result) {
|
||||
.done(function (result) {
|
||||
if (botPackages.length === 0) {
|
||||
logger.info(
|
||||
"The server is running with no bot instances, at least one .gbot file must be deployed."
|
||||
|
|
|
@ -121,7 +121,7 @@ export class GBMinService {
|
|||
|
||||
server.get("/instances/:botId", (req, res) => {
|
||||
(async () => {
|
||||
|
||||
|
||||
// Returns the instance object to clients requesting bot info.
|
||||
|
||||
let botId = req.params.botId
|
||||
|
@ -136,7 +136,9 @@ export class GBMinService {
|
|||
theme: instance.theme,
|
||||
secret: instance.webchatKey, // TODO: Use token.
|
||||
speechToken: speechToken,
|
||||
conversationId: webchatToken.conversationId
|
||||
conversationId: webchatToken.conversationId,
|
||||
authenticatorTenant: instance.authenticatorTenant,
|
||||
authenticatorClientID: instance.authenticatorClientID
|
||||
})
|
||||
)
|
||||
} else {
|
||||
|
@ -270,97 +272,105 @@ export class GBMinService {
|
|||
appPackages: any[]
|
||||
) {
|
||||
return adapter.processActivity(req, res, async context => {
|
||||
const state = conversationState.get(context)
|
||||
const dc = min.dialogs.createContext(context, state)
|
||||
dc.context.activity.locale = "en-US"
|
||||
const user = min.userState.get(dc.context)
|
||||
|
||||
if (!user.loaded) {
|
||||
await min.conversationalService.sendEvent(dc, "loadInstance", {
|
||||
instanceId: instance.instanceId,
|
||||
botId: instance.botId,
|
||||
theme: instance.theme,
|
||||
secret: instance.webchatKey
|
||||
})
|
||||
user.loaded = true
|
||||
user.subjects = []
|
||||
}
|
||||
try {
|
||||
const state = conversationState.get(context)
|
||||
const dc = min.dialogs.createContext(context, state)
|
||||
dc.context.activity.locale = "en-US"
|
||||
const user = min.userState.get(dc.context)
|
||||
|
||||
logger.info(
|
||||
`[RCV]: ${context.activity.type}, ChannelID: ${
|
||||
if (!user.loaded) {
|
||||
await min.conversationalService.sendEvent(dc, "loadInstance", {
|
||||
instanceId: instance.instanceId,
|
||||
botId: instance.botId,
|
||||
theme: instance.theme,
|
||||
secret: instance.webchatKey
|
||||
})
|
||||
user.loaded = true
|
||||
user.subjects = []
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`[RCV]: ${context.activity.type}, ChannelID: ${
|
||||
context.activity.channelId
|
||||
}, Name: ${context.activity.name}, Text: ${context.activity.text}.`
|
||||
)
|
||||
if (
|
||||
context.activity.type === "conversationUpdate" &&
|
||||
context.activity.membersAdded.length > 0
|
||||
) {
|
||||
|
||||
let member = context.activity.membersAdded[0]
|
||||
if (member.name === "GeneralBots") {
|
||||
logger.info(`Bot added to conversation, starting chat...`)
|
||||
appPackages.forEach(e => {
|
||||
e.onNewSession(min, dc)
|
||||
})
|
||||
}, Name: ${context.activity.name}, Text: ${context.activity.text}.`
|
||||
)
|
||||
if (
|
||||
context.activity.type === "conversationUpdate" &&
|
||||
context.activity.membersAdded.length > 0
|
||||
) {
|
||||
|
||||
// Starts root dialog.
|
||||
let member = context.activity.membersAdded[0]
|
||||
if (member.name === "GeneralBots") {
|
||||
logger.info(`Bot added to conversation, starting chat...`)
|
||||
appPackages.forEach(e => {
|
||||
e.onNewSession(min, dc)
|
||||
})
|
||||
|
||||
await dc.begin("/")
|
||||
// Processes the root dialog.
|
||||
|
||||
} else {
|
||||
logger.info(`Member added to conversation: ${member.name}`)
|
||||
}
|
||||
|
||||
// Processes messages.
|
||||
|
||||
} else if (context.activity.type === "message") {
|
||||
|
||||
// Checks for /admin request.
|
||||
|
||||
if (context.activity.text === "admin") {
|
||||
await dc.begin("/admin")
|
||||
|
||||
// Checks for /menu JSON signature.
|
||||
|
||||
} else if (context.activity.text.startsWith("{\"title\"")) {
|
||||
await dc.begin("/menu", {data:JSON.parse(context.activity.text)})
|
||||
|
||||
// Otherwise, continue to the active dialog in the stack.
|
||||
|
||||
} else {
|
||||
await dc.continue()
|
||||
}
|
||||
|
||||
// Processes events.
|
||||
|
||||
} else if (context.activity.type === "event") {
|
||||
|
||||
// Empties dialog stack before going to the target.
|
||||
|
||||
await dc.endAll()
|
||||
|
||||
if (context.activity.name === "whoAmI") {
|
||||
await dc.begin("/whoAmI")
|
||||
} else if (context.activity.name === "showSubjects") {
|
||||
await dc.begin("/menu")
|
||||
} else if (context.activity.name === "giveFeedback") {
|
||||
await dc.begin("/feedback", {
|
||||
fromMenu: true
|
||||
})
|
||||
} else if (context.activity.name === "showFAQ") {
|
||||
await dc.begin("/faq")
|
||||
} else if (context.activity.name === "ask") {
|
||||
await dc.begin("/answer", {
|
||||
query: (context.activity as any).data,
|
||||
fromFaq: true
|
||||
})
|
||||
} else if (context.activity.name === "quality") {
|
||||
await dc.begin("/quality", {
|
||||
// TODO: score: context.activity.data
|
||||
})
|
||||
} else {
|
||||
await dc.continue()
|
||||
await dc.begin("/")
|
||||
|
||||
} else {
|
||||
logger.info(`Member added to conversation: ${member.name}`)
|
||||
}
|
||||
|
||||
// Processes messages.
|
||||
|
||||
} else if (context.activity.type === "message") {
|
||||
|
||||
// Checks for /admin request.
|
||||
|
||||
if (context.activity.text === "admin") {
|
||||
await dc.begin("/admin")
|
||||
|
||||
// Checks for /menu JSON signature.
|
||||
|
||||
} else if (context.activity.text.startsWith("{\"title\"")) {
|
||||
await dc.begin("/menu", { data: JSON.parse(context.activity.text) })
|
||||
|
||||
// Otherwise, continue to the active dialog in the stack.
|
||||
|
||||
} else {
|
||||
await dc.continue()
|
||||
}
|
||||
|
||||
// Processes events.
|
||||
|
||||
} else if (context.activity.type === "event") {
|
||||
|
||||
// Empties dialog stack before going to the target.
|
||||
|
||||
await dc.endAll()
|
||||
|
||||
if (context.activity.name === "whoAmI") {
|
||||
await dc.begin("/whoAmI")
|
||||
} else if (context.activity.name === "showSubjects") {
|
||||
await dc.begin("/menu")
|
||||
} else if (context.activity.name === "giveFeedback") {
|
||||
await dc.begin("/feedback", {
|
||||
fromMenu: true
|
||||
})
|
||||
} else if (context.activity.name === "showFAQ") {
|
||||
await dc.begin("/faq")
|
||||
} else if (context.activity.name === "ask") {
|
||||
await dc.begin("/answer", {
|
||||
query: (context.activity as any).data,
|
||||
fromFaq: true
|
||||
})
|
||||
|
||||
} else if (context.activity.name === "quality") {
|
||||
await dc.begin("/quality", { score: (context.activity as any).data })
|
||||
} else if (context.activity.name === "updateToken") {
|
||||
let token = (context.activity as any).data
|
||||
await dc.begin("/adminUpdateToken", { token: token })
|
||||
} else {
|
||||
await dc.continue()
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
let msg = `Error in main activity: ${error}.`
|
||||
logger.error(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -55,4 +55,6 @@
|
|||
<div id="root"></div>
|
||||
</body>
|
||||
|
||||
|
||||
|
||||
</html>
|
|
@ -45,6 +45,7 @@ import { SpeechSynthesizer } from "botframework-webchat/CognitiveServices";
|
|||
import { SynthesisGender } from "botframework-webchat/CognitiveServices";
|
||||
import { Chat } from "botframework-webchat";
|
||||
import GBPowerBIPlayer from "./players/GBPowerBIPlayer.js";
|
||||
import { UserAgentApplication } from "msal";
|
||||
|
||||
class GBUIApp extends React.Component {
|
||||
constructor() {
|
||||
|
@ -58,6 +59,22 @@ class GBUIApp extends React.Component {
|
|||
};
|
||||
}
|
||||
|
||||
sendToken(token) {
|
||||
setTimeout(() => {
|
||||
window.botConnection
|
||||
.postActivity({
|
||||
type: "event",
|
||||
name: "updateToken",
|
||||
data: token,
|
||||
locale: "en-us",
|
||||
textFormat: "plain",
|
||||
timestamp: new Date().toISOString(),
|
||||
from: { id: "webUser", name: "You" }
|
||||
})
|
||||
.subscribe(this.send("success"));
|
||||
}, 400);
|
||||
}
|
||||
|
||||
send(command) {
|
||||
window.botConnection
|
||||
.postActivity({
|
||||
|
@ -93,8 +110,11 @@ class GBUIApp extends React.Component {
|
|||
|
||||
configureChat() {
|
||||
var botId = window.location.href.split("/")[3];
|
||||
if (botId.indexOf('#') != -1) {
|
||||
botId = botId.split("#")[0];
|
||||
}
|
||||
|
||||
if (!botId) {
|
||||
if (!botId || botId == "") {
|
||||
botId = "[default]";
|
||||
}
|
||||
|
||||
|
@ -102,7 +122,7 @@ class GBUIApp extends React.Component {
|
|||
.then(res => res.json())
|
||||
.then(
|
||||
result => {
|
||||
this.setState({instanceClient:result});
|
||||
this.setState({ instanceClient: result });
|
||||
this.setupBotConnection();
|
||||
},
|
||||
error => {
|
||||
|
@ -114,6 +134,38 @@ class GBUIApp extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
authenticate() {
|
||||
let _this_ = this;
|
||||
let authority =
|
||||
"https://login.microsoftonline.com/" +
|
||||
this.state.instanceClient.authenticatorTenant;
|
||||
|
||||
let graphScopes = ["Directory.AccessAsUser.All"];
|
||||
|
||||
let userAgentApplication = new UserAgentApplication(
|
||||
this.state.instanceClient.authenticatorClientID,
|
||||
authority,
|
||||
function (errorDesc, token, error, tokenType) {
|
||||
userAgentApplication.acquireTokenSilent(graphScopes).then(function (accessToken) {
|
||||
_this_.sendToken(accessToken);
|
||||
}, function (error) {
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
if (!userAgentApplication.isCallback(window.location.hash) && window.parent === window && !window.opener) {
|
||||
var user = userAgentApplication.getUser();
|
||||
if (user) {
|
||||
userAgentApplication.acquireTokenSilent(graphScopes).then(function (accessToken) {
|
||||
_this_.sendToken(accessToken);
|
||||
}, function (error) {
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupBotConnection() {
|
||||
let _this_ = this;
|
||||
window["botchatDebug"] = true;
|
||||
|
@ -124,14 +176,13 @@ class GBUIApp extends React.Component {
|
|||
|
||||
botConnection.connectionStatus$.subscribe(connectionStatus => {
|
||||
if (connectionStatus === ConnectionStatus.Online) {
|
||||
_this_.setState({ botConnection: botConnection });
|
||||
botConnection.postActivity({
|
||||
type: "event",
|
||||
value: "startGB",
|
||||
from: this.getUser(),
|
||||
name: "startGB"
|
||||
});
|
||||
|
||||
_this_.setState({ botConnection: botConnection });
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -145,8 +196,9 @@ class GBUIApp extends React.Component {
|
|||
)
|
||||
.subscribe(activity => {
|
||||
_this_.setState({ instance: activity.value });
|
||||
_this_.authenticate()
|
||||
});
|
||||
|
||||
|
||||
botConnection.activity$
|
||||
.filter(activity => activity.type === "event" && activity.name === "stop")
|
||||
.subscribe(activity => {
|
||||
|
@ -168,7 +220,7 @@ class GBUIApp extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
|
||||
let playerComponent = "";
|
||||
|
||||
|
@ -224,7 +276,7 @@ class GBUIApp extends React.Component {
|
|||
/>
|
||||
);
|
||||
break;
|
||||
case "login":
|
||||
case "login":
|
||||
playerComponent = (
|
||||
<GBLoginPlayer
|
||||
app={this}
|
||||
|
@ -246,7 +298,7 @@ class GBUIApp extends React.Component {
|
|||
|
||||
let speechOptions;
|
||||
let chat = <div />;
|
||||
let gbCss =<div />;
|
||||
let gbCss = <div />;
|
||||
|
||||
|
||||
let sideBar = (
|
||||
|
@ -254,7 +306,7 @@ class GBUIApp extends React.Component {
|
|||
<SidebarMenu chat={this.chat} instance={this.state.instance} />
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
if (this.state.botConnection && this.state.instance) {
|
||||
let token = this.state.instanceClient.speechToken;
|
||||
gbCss = <GBCss instance={this.state.instance} />;
|
||||
|
@ -264,7 +316,7 @@ class GBUIApp extends React.Component {
|
|||
resolve(token);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
speechOptions = {
|
||||
speechRecognizer: new SpeechRecognizer({
|
||||
locale: "pt-br",
|
||||
|
@ -301,7 +353,7 @@ class GBUIApp extends React.Component {
|
|||
|
||||
return (
|
||||
<div>
|
||||
{gbCss}
|
||||
{gbCss}
|
||||
{sideBar}
|
||||
<div className="player">{playerComponent}</div>
|
||||
{chat}
|
||||
|
|
|
@ -39,3 +39,4 @@ ReactDOM.render(
|
|||
<GBUIApp head={document.getElementsByTagName("head")[0]} />,
|
||||
document.getElementById("root")
|
||||
);
|
||||
|
||||
|
|
|
@ -31,68 +31,54 @@
|
|||
\*****************************************************************************/
|
||||
|
||||
import React from "react";
|
||||
import { Logger, LogLevel } from "msal";
|
||||
import { UserAgentApplication } from "msal";
|
||||
|
||||
class GBLoginPlayer extends React.Component {
|
||||
|
||||
constructor(tenant) {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
token: "",
|
||||
login: {}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
login() {
|
||||
|
||||
let config = {
|
||||
tenant: "pragmatismo.onmicrosoft.com", //"6ecb2a67-15af-4582-ab85-cc65096ce471",
|
||||
signUpSignInPolicy: "b2c_1_susi",
|
||||
clientID: '47cbaa05-dbb4-46f8-8608-da386c5131f1'}
|
||||
|
||||
|
||||
let authority = "https://login.microsoftonline.com/tfp/" +
|
||||
config.tenant + "/" +
|
||||
config.signUpSignInPolicy;
|
||||
|
||||
let userAgentApplication = new UserAgentApplication(
|
||||
config.clientID, authority,
|
||||
function (errorDesc, token, error, tokenType) {
|
||||
console.log(token);
|
||||
}
|
||||
doLogin(info) {
|
||||
let logger = new Logger(
|
||||
(logLevel, message, piiEnabled) => {
|
||||
console.log(message);
|
||||
},
|
||||
{ level: LogLevel.Verbose }
|
||||
);
|
||||
|
||||
|
||||
let authority =
|
||||
"https://login.microsoftonline.com/" +
|
||||
this.state.login.authenticatorTenant;
|
||||
|
||||
let graphScopes = ["Directory.AccessAsUser.All"];
|
||||
|
||||
userAgentApplication.loginPopup(graphScopes).then(function (idToken) {
|
||||
userAgentApplication.acquireTokenSilent(graphScopes).then(function (accessToken) {
|
||||
console.log(accessToken);
|
||||
|
||||
}, function (error) {
|
||||
userAgentApplication.acquireTokenPopup(graphScopes).then(function (accessToken) {
|
||||
console.log(accessToken);
|
||||
|
||||
}, function (error) {
|
||||
let userAgentApplication = new UserAgentApplication(
|
||||
this.state.login.authenticatorClientID,
|
||||
authority,
|
||||
function (errorDesc, token, error, tokenType) {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
})
|
||||
}, function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
|
||||
userAgentApplication.loginRedirect(graphScopes);
|
||||
}
|
||||
|
||||
play() {
|
||||
play(data) {
|
||||
this.setState({ login: data });
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.setState({ login: [] });
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<button
|
||||
value="Login"
|
||||
onClick={this.login}
|
||||
/>
|
||||
);
|
||||
return <button onClick={() => this.doLogin(this.state.login)}>Login</button>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ import { BotAdapter } from "botbuilder";
|
|||
import { Messages } from "../strings";
|
||||
import { LuisRecognizer } from "botbuilder-ai";
|
||||
|
||||
|
||||
const logger = require("../../../src/logger");
|
||||
|
||||
export class AskDialog extends IGBDialog {
|
||||
|
@ -69,7 +68,7 @@ export class AskDialog extends IGBDialog {
|
|||
throw new Error(`/answer being called with no args.query text.`);
|
||||
}
|
||||
|
||||
let locale = dc.context.activity.locale
|
||||
let locale = dc.context.activity.locale;
|
||||
|
||||
// Stops any content on projector.
|
||||
|
||||
|
@ -163,7 +162,7 @@ export class AskDialog extends IGBDialog {
|
|||
);
|
||||
await dc.replace("/ask", { isReturning: true });
|
||||
} else {
|
||||
if (!(await min.conversationalService.runNLP(dc, min, text))) {
|
||||
if (!(await min.conversationalService.routeNLP(dc, min, text))) {
|
||||
await dc.context.sendActivity(Messages[locale].did_not_find);
|
||||
await dc.replace("/ask", { isReturning: true });
|
||||
}
|
||||
|
@ -181,16 +180,21 @@ export class AskDialog extends IGBDialog {
|
|||
user.subjects = [];
|
||||
}
|
||||
let text = [];
|
||||
if (user.subjects.length > 0) {
|
||||
text = Messages[locale].which_question;
|
||||
}
|
||||
|
||||
if (args && args.isReturning) {
|
||||
// Three forms of asking.
|
||||
|
||||
if (args.firstTime) {
|
||||
text = Messages[locale].ask_first_time;
|
||||
} else if (args && args.isReturning) {
|
||||
text = Messages[locale].anything_else;
|
||||
} else if (user.subjects.length > 0) {
|
||||
text = Messages[locale].which_question;
|
||||
} else {
|
||||
throw new Error("Invalid use of /ask");
|
||||
}
|
||||
|
||||
if (text.length > 0) {
|
||||
await dc.prompt("textPrompt", text[0]);
|
||||
await dc.prompt("textPrompt", text);
|
||||
}
|
||||
},
|
||||
async (dc, value) => {
|
||||
|
|
|
@ -13,7 +13,9 @@ export const Messages = {
|
|||
`Vamos pesquisar sobre ${query}... O que deseja saber?`,
|
||||
see_faq:
|
||||
"Please take a look at the FAQ I've prepared for you. You can click on them to get the answer.",
|
||||
will_answer_projector:"I'll answer on the projector to a better experience..."
|
||||
will_answer_projector:
|
||||
"I'll answer on the projector to a better experience...",
|
||||
ask_first_time: "What are you looking for?"
|
||||
},
|
||||
"pt-BR": {
|
||||
did_not_find: "Desculpe-me, não encontrei nada a respeito.",
|
||||
|
@ -29,6 +31,8 @@ export const Messages = {
|
|||
`Let's search about ${query}... What do you want to know?`,
|
||||
see_faq:
|
||||
"Veja algumas perguntas mais frequentes logo na tela. Clique numa delas para eu responder.",
|
||||
will_answer_projector:"Vou te responder na tela para melhor visualização..."
|
||||
will_answer_projector:
|
||||
"Vou te responder na tela para melhor visualização...",
|
||||
ask_first_time: "Sobre como eu poderia ajudar?"
|
||||
}
|
||||
};
|
||||
|
|
|
@ -42,20 +42,22 @@
|
|||
"botlib": "^0.0.33",
|
||||
"chokidar": "^2.0.4",
|
||||
"csv-parse": "^3.0.0",
|
||||
"dotenv-extended": "^2.2.0",
|
||||
"dotenv-extended": "^2.3.0",
|
||||
"express": "^4.16.3",
|
||||
"express-promise-router": "^3.0.3",
|
||||
"fs-extra": "^7.0.0",
|
||||
"fs-walk": "^0.0.2",
|
||||
"localize": "^0.4.7",
|
||||
"marked": "^0.5.0",
|
||||
"ms": "^2.1.1",
|
||||
"nexmo": "^2.3.2",
|
||||
"pragmatismo-io-framework": "^1.0.15",
|
||||
"reflect-metadata": "^0.1.12",
|
||||
"request-promise-native": "^1.0.5",
|
||||
"sequelize": "^4.38.0",
|
||||
"sequelize": "^4.38.1",
|
||||
"sequelize-typescript": "^0.6.6",
|
||||
"sqlite3": "^4.0.2",
|
||||
"swagger-client": "^3.8.19",
|
||||
"swagger-client": "^3.8.21",
|
||||
"tedious": "^2.6.4",
|
||||
"url-join": "^4.0.0",
|
||||
"wait-until": "^0.0.2",
|
||||
|
|
|
@ -83,7 +83,6 @@ export class GBServer {
|
|||
try {
|
||||
|
||||
logger.info(`Accepting connections on ${port}...`)
|
||||
logger.info(`Starting instances...`)
|
||||
|
||||
// Reads basic configuration, initialize minimal services.
|
||||
|
||||
|
@ -93,10 +92,11 @@ export class GBServer {
|
|||
|
||||
// Boot a bot package if any.
|
||||
|
||||
logger.info(`Starting instances...`)
|
||||
let deployer = new GBDeployer(core, new GBImporter(core))
|
||||
|
||||
// Build a minimal bot instance for each .gbot deployment.
|
||||
|
||||
|
||||
let conversationalService = new GBConversationalService(core)
|
||||
let minService = new GBMinService(core, conversationalService, deployer);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue