From d5ca7afe2f6b0bac78cfa75db8c0ab6478293d04 Mon Sep 17 00:00:00 2001 From: Alan Date: Tue, 14 Feb 2023 14:11:52 -0300 Subject: [PATCH] Merge branch 'main' of https://github.com/GeneralBots/BotServer --- package.json | 1 + packages/admin.gbapp/dialogs/AdminDialog.ts | 18 +++ packages/basic.gblib/services/GBVMService.ts | 28 ++-- .../services/ImageProcessingServices.ts | 32 +++++ .../services/KeywordsExpressions.ts | 7 + .../basic.gblib/services/SystemKeywords.ts | 1 + packages/core.gbapp/index.ts | 4 +- packages/core.gbapp/models/GBModel.ts | 9 +- packages/core.gbapp/services/GBCoreService.ts | 129 ++++++++++-------- packages/core.gbapp/services/GBLogEx.ts | 85 ++++++++++++ packages/kb.gbapp/dialogs/AskDialog.ts | 2 +- src/RootData.ts | 1 + 12 files changed, 238 insertions(+), 79 deletions(-) create mode 100644 packages/core.gbapp/services/GBLogEx.ts diff --git a/package.json b/package.json index 9501e49e..3e5e3dcb 100644 --- a/package.json +++ b/package.json @@ -105,6 +105,7 @@ "google-libphonenumber": "3.2.31", "googleapis": "109.0.1", "ibm-watson": "7.1.2", + "join-images-updated": "1.1.4", "keyv": "4.5.2", "koa": "2.13.4", "koa-body": "6.0.1", diff --git a/packages/admin.gbapp/dialogs/AdminDialog.ts b/packages/admin.gbapp/dialogs/AdminDialog.ts index 66761df1..24d95a58 100644 --- a/packages/admin.gbapp/dialogs/AdminDialog.ts +++ b/packages/admin.gbapp/dialogs/AdminDialog.ts @@ -238,6 +238,24 @@ export class AdminDialog extends IGBDialog { ]) ); + + min.dialogs.add( + new WaterfallDialog('/logs', [ + async step => { + if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) { + return await step.beginDialog('/auth'); + } else { + return await step.next(step.options); + } + }, + async step => { + const logs = await min.core['getLatestLogs'](); + await min.conversationalService.sendText(min, step, logs); + return await step.replaceDialog('/ask', { isReturning: true }); + } + ])); + + min.dialogs.add( new WaterfallDialog('/publish', [ async step => { diff --git a/packages/basic.gblib/services/GBVMService.ts b/packages/basic.gblib/services/GBVMService.ts index d0bbfa90..1b19cbba 100644 --- a/packages/basic.gblib/services/GBVMService.ts +++ b/packages/basic.gblib/services/GBVMService.ts @@ -32,7 +32,7 @@ 'use strict'; -import { GBLog, GBMinInstance, GBService, IGBCoreService, GBDialogStep } from 'botlib'; +import { GBMinInstance, GBService, IGBCoreService, GBDialogStep } from 'botlib'; import * as Fs from 'fs'; import { GBServer } from '../../../src/app.js'; import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js'; @@ -50,9 +50,7 @@ import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js'; import pkg from 'swagger-client'; import { DialogKeywords } from './DialogKeywords.js'; import { KeywordsExpressions } from './KeywordsExpressions.js'; -const { Swagger } = pkg; - - +import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js'; /** * @fileoverview Decision was to priorize security(isolation) and debugging, @@ -129,7 +127,7 @@ export class GBVMService extends GBService { }`; Fs.writeFileSync(urlJoin(folder, 'package.json'), packageJson); - GBLog.info(`BASIC: Installing .gbdialog node_modules for ${min.botId}...`); + GBLogEx.info(min, `BASIC: Installing .gbdialog node_modules for ${min.botId}...`); const npmPath = urlJoin(process.env.PWD, 'node_modules', '.bin', 'npm'); child_process.execSync(`${npmPath} install`, { cwd: folder }); } @@ -139,7 +137,7 @@ export class GBVMService extends GBService { const fullFilename = urlJoin(folder, filename); if (process.env.GBDIALOG_HOTSWAP) { Fs.watchFile(fullFilename, async () => { - await this.translateBASIC(fullFilename, mainName, min.botId); + await this.translateBASIC(fullFilename, mainName, min); const parsedCode: string = Fs.readFileSync(jsfile, 'utf8'); min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode; }); @@ -152,10 +150,10 @@ export class GBVMService extends GBService { const jsStat = Fs.statSync(jsfile); const interval = 30000; // If compiled is older 30 seconds, then recompile. if (compiledAt.isFile() && compiledAt['mtimeMs'] > jsStat['mtimeMs'] + interval) { - await this.translateBASIC(fullFilename, mainName, min.botId); + await this.translateBASIC(fullFilename, mainName, min); } } else { - await this.translateBASIC(fullFilename, mainName, min.botId); + await this.translateBASIC(fullFilename, mainName, min); } const parsedCode: string = Fs.readFileSync(jsfile, 'utf8'); min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode; @@ -163,7 +161,7 @@ export class GBVMService extends GBService { }); } - public async translateBASIC(filename: any, mainName: string, botId: string) { + public async translateBASIC(filename: any, mainName: string, min:GBMinInstance) { // Converts General Bots BASIC into regular VBS let basicCode: string = Fs.readFileSync(filename, 'utf8'); @@ -204,10 +202,10 @@ export class GBVMService extends GBService { // Interprocess communication from local HTTP to the BotServer. - const dk = rest.createClient('http://localhost:1111/api/v2/${botId}/dialog'); - const sys = rest.createClient('http://localhost:1111/api/v2/${botId}/system'); - const wa = rest.createClient('http://localhost:1111/api/v2/${botId}/webautomation'); - const img = rest.createClient('http://localhost:1111/api/v2/${botId}/imagprocessing'); + const dk = rest.createClient('http://localhost:1111/api/v2/${min.botId}/dialog'); + const sys = rest.createClient('http://localhost:1111/api/v2/${min.botId}/system'); + const wa = rest.createClient('http://localhost:1111/api/v2/${min.botId}/webautomation'); + const img = rest.createClient('http://localhost:1111/api/v2/${min.botId}/imagprocessing'); // Local variables. @@ -245,7 +243,7 @@ export class GBVMService extends GBService { `; Fs.writeFileSync(jsfile, code); - GBLog.info(`[GBVMService] Finished loading of ${filename}, JavaScript from Word: \n ${code}`); + GBLogEx.info(min, `[GBVMService] Finished loading of ${filename}, JavaScript from Word: \n ${code}`); } public static getMethodNameFromVBSFilename(filename: string) { @@ -288,7 +286,7 @@ export class GBVMService extends GBService { public async convert(code: string) { // Start and End of VB2TS tags of processing. - code = process.env.ENABLE_AUTH ? `hear gbLogin as login\n${code}` : code; + code = process.env.ENABLE_AUTH ? `hear GBLogExin as login\n${code}` : code; var lines = code.split('\n'); const keywords = KeywordsExpressions.getKeywords(); let current = 41; diff --git a/packages/basic.gblib/services/ImageProcessingServices.ts b/packages/basic.gblib/services/ImageProcessingServices.ts index 63dc84c8..9bd96ba0 100644 --- a/packages/basic.gblib/services/ImageProcessingServices.ts +++ b/packages/basic.gblib/services/ImageProcessingServices.ts @@ -32,9 +32,15 @@ 'use strict'; +import Path from 'path'; import { GBLog, GBMinInstance } from 'botlib'; import { DialogKeywords } from './DialogKeywords.js'; import sharp from 'sharp'; +import joinImages from 'join-images-updated'; +import { CollectionUtil } from 'pragmatismo-io-framework'; +import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js'; +import urlJoin from 'url-join'; +import { GBServer } from '../../../src/app.js'; /** * Image processing services of conversation to be called by BASIC. @@ -95,6 +101,32 @@ export class ImageProcessingServices { return; } + /** + * SET ORIENTATION VERTICAL + * + * file = MERGE file1, file2, file3 + */ + public async mergeImage({pid, files}) + { + const { min, user } = await DialogKeywords.getProcessInfo(pid); + + let paths = []; + await CollectionUtil.asyncForEach(files, async file => { + const gbfile = DialogKeywords.getFileByHandle(file); + paths.push(gbfile.path); + }); + + const botId = this.min.instance.botId; + const gbaiName = `${botId}.gbai`; + const img = await joinImages(paths); + const localName = Path.join('work', gbaiName, 'cache', `img-mrg${GBAdminService.getRndReadableIdentifier()}.png`); + const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName)); + img.toFile(localName); + + return { localName: localName, url: url, data: null }; + + } + /** * Sharpen the image. * diff --git a/packages/basic.gblib/services/KeywordsExpressions.ts b/packages/basic.gblib/services/KeywordsExpressions.ts index 26bf4f65..8df1cd92 100644 --- a/packages/basic.gblib/services/KeywordsExpressions.ts +++ b/packages/basic.gblib/services/KeywordsExpressions.ts @@ -677,6 +677,13 @@ export class KeywordsExpressions { } ]; + keywords[i++] = [ + /^\s*(MERGE)(\s*)(.*)/gim, + ($0, $1, $2, $3) => { + return `await img.mergeImage({pid: pid, files: [${$3}]})`; + } + ]; + keywords[i++] = [ /^\s*PRESS\s*(.*)/gim, ($0, $1, $2) => { diff --git a/packages/basic.gblib/services/SystemKeywords.ts b/packages/basic.gblib/services/SystemKeywords.ts index c8642775..786f4d42 100644 --- a/packages/basic.gblib/services/SystemKeywords.ts +++ b/packages/basic.gblib/services/SystemKeywords.ts @@ -1412,6 +1412,7 @@ export class SystemKeywords { const images = []; let index = 0; path = Path.join(gbaiName, 'cache', `tmp${GBAdminService.getRndReadableIdentifier()}.docx`); + url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName)); const traverseDataToInjectImageUrl = async o => { for (var i in o) { diff --git a/packages/core.gbapp/index.ts b/packages/core.gbapp/index.ts index f1a0a007..190a65fe 100644 --- a/packages/core.gbapp/index.ts +++ b/packages/core.gbapp/index.ts @@ -43,7 +43,7 @@ import { LanguageDialog } from './dialogs/LanguageDialog.js'; import { SwitchBotDialog } from './dialogs/SwitchBot.js'; import { WelcomeDialog } from './dialogs/WelcomeDialog.js'; import { WhoAmIDialog } from './dialogs/WhoAmIDialog.js'; -import { GuaribasChannel, GuaribasException, GuaribasInstance, GuaribasPackage } from './models/GBModel.js'; +import { GuaribasChannel, GuaribasInstance, GuaribasLog, GuaribasPackage } from './models/GBModel.js'; /** * Package for core.gbapp. @@ -53,7 +53,7 @@ export class GBCorePackage implements IGBPackage { public CurrentEngineName = 'guaribas-1.0.0'; public async loadPackage (core: IGBCoreService, sequelize: Sequelize): Promise { - core.sequelize.addModels([GuaribasInstance, GuaribasPackage, GuaribasChannel, GuaribasException]); + core.sequelize.addModels([GuaribasInstance, GuaribasPackage, GuaribasChannel, GuaribasLog]); } public async getDialogs (min: GBMinInstance) { diff --git a/packages/core.gbapp/models/GBModel.ts b/packages/core.gbapp/models/GBModel.ts index 203654db..76e3b17c 100644 --- a/packages/core.gbapp/models/GBModel.ts +++ b/packages/core.gbapp/models/GBModel.ts @@ -326,15 +326,18 @@ export class GuaribasChannel extends Model { */ @Table //tslint:disable-next-line:max-classes-per-file -export class GuaribasException extends Model { +export class GuaribasLog extends Model { @PrimaryKey @AutoIncrement @Column(DataType.INTEGER) - declare exceptionId: number; + declare logId: number; - @Column(DataType.STRING(255)) + @Column(DataType.STRING(1024)) declare message: string; + @Column(DataType.STRING(1)) + declare kind: string; + @ForeignKey(() => GuaribasInstance) @Column(DataType.INTEGER) declare instanceId: number; diff --git a/packages/core.gbapp/services/GBCoreService.ts b/packages/core.gbapp/services/GBCoreService.ts index 2e52de62..9f387925 100644 --- a/packages/core.gbapp/services/GBCoreService.ts +++ b/packages/core.gbapp/services/GBCoreService.ts @@ -50,7 +50,7 @@ import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp import { GBKBPackage } from '../../kb.gbapp/index.js'; import { GBSecurityPackage } from '../../security.gbapp/index.js'; import { GBWhatsappPackage } from '../../whatsapp.gblib/index.js'; -import { GuaribasInstance } from '../models/GBModel.js'; +import { GuaribasInstance, GuaribasLog} from '../models/GBModel.js'; import { GBConfigService } from './GBConfigService.js'; import { GBAzureDeployerPackage } from '../../azuredeployer.gbapp/index.js'; import { GBSharePointPackage } from '../../sharepoint.gblib/index.js'; @@ -102,16 +102,16 @@ export class GBCoreService implements IGBCoreService { /** * */ - constructor () { + constructor() { this.adminService = new GBAdminService(this); } - public async ensureInstances (instances: IGBInstance[], bootInstance: any, core: IGBCoreService) {} + public async ensureInstances(instances: IGBInstance[], bootInstance: any, core: IGBCoreService) {} /** * Gets database config and connect to storage. Currently two databases * are available: SQL Server and SQLite. */ - public async initStorage (): Promise { + public async initStorage(): Promise { this.dialect = GBConfigService.get('STORAGE_DIALECT'); let host: string | undefined; @@ -177,7 +177,7 @@ export class GBCoreService implements IGBCoreService { * Checks wheather storage is acessible or not and opens firewall * in case of any connection block. */ - public async checkStorage (installationDeployer: IGBInstallationDeployer) { + public async checkStorage(installationDeployer: IGBInstallationDeployer) { try { await this.sequelize.authenticate(); } catch (error) { @@ -195,7 +195,7 @@ export class GBCoreService implements IGBCoreService { /** * Syncronizes structure between model and tables in storage. */ - public async syncDatabaseStructure () { + public async syncDatabaseStructure() { if (GBConfigService.get('STORAGE_SYNC') === 'true') { const alter = GBConfigService.get('STORAGE_SYNC_ALTER') === 'true'; GBLog.info('Syncing database...'); @@ -213,7 +213,29 @@ export class GBCoreService implements IGBCoreService { /** * Loads all items to start several listeners. */ - public async loadInstances (): Promise { + public async getLatestLogs(instanceId: number): Promise { + const options = { + where: { + instanceId: instanceId, + state: 'active', + created: { + [Op.gt]: new Date(Date.now() - 60 * 60 * 1000 * 48) // Latest 48 hours. + } + } + }; + const list = await GuaribasLog.findAll(options); + let out = 'General Bots Log\n'; + await CollectionUtil.asyncForEach(list, async e => { + out = `${out}\n${e.createdAt} - ${e.message}`; + }); + return out; + } + + + /** + * Loads all items to start several listeners. + */ + public async loadInstances(): Promise { if (process.env.LOAD_ONLY !== undefined) { const bots = process.env.LOAD_ONLY.split(`;`); const and = []; @@ -236,7 +258,7 @@ export class GBCoreService implements IGBCoreService { /** * Loads just one Bot instance by its internal Id. */ - public async loadInstanceById (instanceId: number): Promise { + public async loadInstanceById(instanceId: number): Promise { const options = { where: { instanceId: instanceId, state: 'active' } }; return await GuaribasInstance.findOne(options); @@ -244,7 +266,7 @@ export class GBCoreService implements IGBCoreService { /** * Loads just one Bot instance. */ - public async loadInstanceByActivationCode (code: string): Promise { + public async loadInstanceByActivationCode(code: string): Promise { let options = { where: { activationCode: code, state: 'active' } }; return await GuaribasInstance.findOne(options); @@ -252,7 +274,7 @@ export class GBCoreService implements IGBCoreService { /** * Loads just one Bot instance. */ - public async loadInstanceByBotId (botId: string): Promise { + public async loadInstanceByBotId(botId: string): Promise { const options = { where: {} }; options.where = { botId: botId, state: 'active' }; @@ -264,7 +286,7 @@ export class GBCoreService implements IGBCoreService { * first startup, when user is asked some questions to create the * full base environment. */ - public async writeEnv (instance: IGBInstance) { + public async writeEnv(instance: IGBInstance) { const env = ` ADDITIONAL_DEPLOY_PATH= ADMIN_PASS=${instance.adminPass} @@ -294,7 +316,7 @@ ENDPOINT_UPDATE=true * when calling back from web services. This ensures that reverse proxy is * established. */ - public async ensureProxy (port): Promise { + public async ensureProxy(port): Promise { try { if (Fs.existsSync('node_modules/ngrok/bin/ngrok.exe') || Fs.existsSync('node_modules/ngrok/bin/ngrok')) { return await ngrok.connect({ port: port }); @@ -315,7 +337,7 @@ ENDPOINT_UPDATE=true * Setup generic web hooks so .gbapps can expose application logic * and get called on demand. */ - public installWebHook (isGet: boolean, url: string, callback: any) { + public installWebHook(isGet: boolean, url: string, callback: any) { if (isGet) { GBServer.globals.server.get(url, (req, res) => { callback(req, res); @@ -331,7 +353,7 @@ ENDPOINT_UPDATE=true * Defines the entry point dialog to be called whenever a user * starts talking to the bot. */ - public setEntryPointDialog (dialogName: string) { + public setEntryPointDialog(dialogName: string) { GBServer.globals.entryPointDialog = dialogName; } @@ -339,14 +361,14 @@ ENDPOINT_UPDATE=true * Replaces the default web application root path used to start the GB * with a custom home page. */ - public setWWWRoot (localPath: string) { + public setWWWRoot(localPath: string) { GBServer.globals.wwwroot = localPath; } /** * Removes a bot instance from storage. */ - public async deleteInstance (botId: string) { + public async deleteInstance(botId: string) { const options = { where: {} }; options.where = { botId: botId }; await GuaribasInstance.destroy(options); @@ -356,7 +378,7 @@ ENDPOINT_UPDATE=true * Saves a bot instance object to the storage handling * multi-column JSON based store 'params' field. */ - public async saveInstance (fullInstance: any) { + public async saveInstance(fullInstance: any) { const options = { where: {} }; options.where = { botId: fullInstance.botId }; let instance = await GuaribasInstance.findOne(options); @@ -377,7 +399,7 @@ ENDPOINT_UPDATE=true /** * Loads all bot instances from object storage, if it's formatted. */ - public async loadAllInstances ( + public async loadAllInstances( core: IGBCoreService, installationDeployer: IGBInstallationDeployer, proxyAddress: string @@ -431,7 +453,7 @@ ENDPOINT_UPDATE=true /** * Loads all system packages from 'packages' folder. */ - public async loadSysPackages (core: GBCoreService): Promise { + public async loadSysPackages(core: GBCoreService): Promise { // NOTE: if there is any code before this line a semicolon // will be necessary before this line. // Loads all system packages. @@ -469,7 +491,7 @@ ENDPOINT_UPDATE=true * Verifies that an complex global password has been specified * before starting the server. */ - public ensureAdminIsSecured () { + public ensureAdminIsSecured() { const password = GBConfigService.get('ADMIN_PASS'); if (!GBAdminService.StrongRegex.test(password)) { throw new Error( @@ -484,7 +506,7 @@ ENDPOINT_UPDATE=true * So a base main bot is always deployed and will act as root bot for * configuration tree with three levels: .env > root bot > all other bots. */ - public async createBootInstance ( + public async createBootInstance( core: GBCoreService, installationDeployer: IGBInstallationDeployer, proxyAddress: string @@ -519,7 +541,7 @@ ENDPOINT_UPDATE=true /** * Helper to get the web browser onpened in UI interfaces. */ - public openBrowserInDevelopment () { + public openBrowserInDevelopment() { if (process.env.NODE_ENV === 'development') { open('http://localhost:4242'); } @@ -540,35 +562,29 @@ ENDPOINT_UPDATE=true * // ' FOREIGN KEY ([groupId1], [groupId2]) REFERENCES [Group] ([groupId1], [groupId1]) ON DELETE NO ACTION,' + * // ' FOREIGN KEY ([instanceId]) REFERENCES [Instance] ([instanceId]) ON DELETE NO ACTION)' */ - private createTableQueryOverride (tableName, attributes, options): string { + private createTableQueryOverride(tableName, attributes, options): string { let sql: string = this.createTableQuery.apply(this.queryGenerator, [tableName, attributes, options]); const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/; const matches = re1.exec(sql); if (matches !== null) { const table = matches[1]; const re2 = /PRIMARY\s+KEY\s+\(\[[^\]]*\](?:,\s*\[[^\]]*\])*\)/; - sql = sql.replace( - re2, - (match: string, ...args: any[]): string => { - return `CONSTRAINT [${table}_pk] ${match}`; - } - ); + sql = sql.replace(re2, (match: string, ...args: any[]): string => { + return `CONSTRAINT [${table}_pk] ${match}`; + }); const re3 = /FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g; const re4 = /\[([^\]]*)\]/g; - sql = sql.replace( - re3, - (match: string, ...args: any[]): string => { - const fkcols = args[0]; - let fkname = table; - let matches2 = re4.exec(fkcols); - while (matches2 !== null) { - fkname += `_${matches2[1]}`; - matches2 = re4.exec(fkcols); - } - - return `CONSTRAINT [${fkname}_fk] FOREIGN KEY (${fkcols})`; + sql = sql.replace(re3, (match: string, ...args: any[]): string => { + const fkcols = args[0]; + let fkname = table; + let matches2 = re4.exec(fkcols); + while (matches2 !== null) { + fkname += `_${matches2[1]}`; + matches2 = re4.exec(fkcols); } - ); + + return `CONSTRAINT [${fkname}_fk] FOREIGN KEY (${fkcols})`; + }); } return sql; @@ -582,7 +598,7 @@ ENDPOINT_UPDATE=true * ' CONSTRAINT [invalid2] FOREIGN KEY ([groupId1], [groupId2]) REFERENCES [Group] ([groupId1], [groupId2]) ON DELETE NO ACTION, ' + * ' CONSTRAINT [invalid3] FOREIGN KEY ([instanceId1]) REFERENCES [Instance] ([instanceId1]) ON DELETE NO ACTION' */ - private changeColumnQueryOverride (tableName, attributes): string { + private changeColumnQueryOverride(tableName, attributes): string { let sql: string = this.changeColumnQuery.apply(this.queryGenerator, [tableName, attributes]); const re1 = /ALTER\s+TABLE\s+\[([^\]]*)\]/; const matches = re1.exec(sql); @@ -590,20 +606,17 @@ ENDPOINT_UPDATE=true const table = matches[1]; const re2 = /(ADD\s+)?CONSTRAINT\s+\[([^\]]*)\]\s+FOREIGN\s+KEY\s+\((\[[^\]]*\](?:,\s*\[[^\]]*\])*)\)/g; const re3 = /\[([^\]]*)\]/g; - sql = sql.replace( - re2, - (match: string, ...args: any[]): string => { - const fkcols = args[2]; - let fkname = table; - let matches2 = re3.exec(fkcols); - while (matches2 !== null) { - fkname += `_${matches2[1]}`; - matches2 = re3.exec(fkcols); - } - - return `${args[0] ? args[0] : ''}CONSTRAINT [${fkname}_fk] FOREIGN KEY (${fkcols})`; + sql = sql.replace(re2, (match: string, ...args: any[]): string => { + const fkcols = args[2]; + let fkname = table; + let matches2 = re3.exec(fkcols); + while (matches2 !== null) { + fkname += `_${matches2[1]}`; + matches2 = re3.exec(fkcols); } - ); + + return `${args[0] ? args[0] : ''}CONSTRAINT [${fkname}_fk] FOREIGN KEY (${fkcols})`; + }); } return sql; @@ -612,7 +625,7 @@ ENDPOINT_UPDATE=true /** * Opens storage firewall used by the server when starting to get root bot instance. */ - private async openStorageFrontier (installationDeployer: IGBInstallationDeployer) { + private async openStorageFrontier(installationDeployer: IGBInstallationDeployer) { const group = GBConfigService.get('CLOUD_GROUP'); const serverName = GBConfigService.get('STORAGE_SERVER').split('.database.windows.net')[0]; await installationDeployer.openStorageFirewall(group, serverName); @@ -625,7 +638,7 @@ ENDPOINT_UPDATE=true * @param name Name of param to get from instance. * @param defaultValue Value returned when no param is defined in Config.xlsx. */ - public getParam (instance: IGBInstance, name: string, defaultValue?: T): any { + public getParam(instance: IGBInstance, name: string, defaultValue?: T): any { let value = null; if (instance.params) { const params = JSON.parse(instance.params); diff --git a/packages/core.gbapp/services/GBLogEx.ts b/packages/core.gbapp/services/GBLogEx.ts new file mode 100644 index 00000000..37f5a03b --- /dev/null +++ b/packages/core.gbapp/services/GBLogEx.ts @@ -0,0 +1,85 @@ +/*****************************************************************************\ +| ( )_ _ | +| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ _ _ _ | +| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/ \ /`\ /'_`\ | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| |*| |( (_) ) | +| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | +| | | ( )_) | | +| (_) \___/' | +| | +| 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. | +| | +\*****************************************************************************/ + +/** + * @fileoverview General Bots server core. + */ + +'use strict'; + +import { GBLog, IGBInstance } from "botlib"; +import { GuaribasLog } from "../models/GBModel"; + +export class GBLogEx { + public static async error(minOrInstanceId: any, message: string) { + GBLog.error(message); + if (typeof minOrInstanceId === 'object') { + minOrInstanceId = minOrInstanceId.instance.instanceId; + } + await this.log(minOrInstanceId, 'e', message); + } + + public static async debug(minOrInstanceId: any, message: string) { + GBLog.debug(message); + if (typeof minOrInstanceId === 'object') { + minOrInstanceId = minOrInstanceId.instance.instanceId; + } + await this.log(minOrInstanceId, 'd', message); + } + + public static async info(minOrInstanceId: any, message: string) { + GBLog.info(message); + if (typeof minOrInstanceId === 'object') { + minOrInstanceId = minOrInstanceId.instance.instanceId; + } + await this.log(minOrInstanceId, 'i', message); + } + + public static async verbose(minOrInstanceId: any, message: string) { + GBLog.verbose(message); + if (typeof minOrInstanceId === 'object') { + minOrInstanceId = minOrInstanceId.instance.instanceId; + } + await this.log(minOrInstanceId, 'v', message); + } + + /** + * Finds and update user agent information to a next available person. + */ + public static async log(instance: IGBInstance, kind: string, message: string): Promise { + return await GuaribasLog.create({ + instanceId: instance.instanceId, + message: message, + kind: kind + }); + } +} diff --git a/packages/kb.gbapp/dialogs/AskDialog.ts b/packages/kb.gbapp/dialogs/AskDialog.ts index 35d956d3..feaf1169 100644 --- a/packages/kb.gbapp/dialogs/AskDialog.ts +++ b/packages/kb.gbapp/dialogs/AskDialog.ts @@ -101,7 +101,7 @@ export class AskDialog extends IGBDialog { if (step.options && step.options.firstTime) { text = Messages[locale].ask_first_time; } else if (step.options && step.options.isReturning) { - text = ''; // REMOVED: Messages[locale].anything_else; + text = Messages[locale].anything_else; } else if (step.options && step.options.emptyPrompt) { text = ''; } else if (user.subjects.length > 0) { diff --git a/src/RootData.ts b/src/RootData.ts index 01ec0a32..2cc40292 100644 --- a/src/RootData.ts +++ b/src/RootData.ts @@ -29,6 +29,7 @@ | our trademarks remain entirely with us. | | | \*****************************************************************************/ + /** * @fileoverview General Bots server core. */