diff --git a/packages/admin.gbapp/dialogs/AdminDialog.ts b/packages/admin.gbapp/dialogs/AdminDialog.ts index 24d95a58..f405d611 100644 --- a/packages/admin.gbapp/dialogs/AdminDialog.ts +++ b/packages/admin.gbapp/dialogs/AdminDialog.ts @@ -19,7 +19,7 @@ | 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 | +| 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. | | | @@ -39,12 +39,13 @@ import crypto from 'crypto'; import urlJoin from 'url-join'; import { WaterfallDialog } from 'botbuilder-dialogs'; -import { GBMinInstance, IGBDialog, GBLog, IGBPackage } from 'botlib'; +import { GBMinInstance, IGBDialog } from 'botlib'; import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js'; import { GBImporter } from '../../core.gbapp/services/GBImporterService.js'; import { Messages } from '../strings.js'; import { GBAdminService } from '../services/GBAdminService.js'; import { CollectionUtil } from 'pragmatismo-io-framework'; +import { SecService } from '../../security.gbapp/services/SecService.js'; /** * Dialogs for administration tasks. @@ -143,37 +144,7 @@ export class AdminDialog extends IGBDialog { try { if (text === 'quit') { - return await step.replaceDialog('/'); - } else if (cmdName === 'deployPackage' || cmdName === 'dp') { - await GBAdminService.deployPackageCommand(min, text, deployer); - - return await step.replaceDialog('/admin', { firstRun: false }); - } else if (cmdName === 'redeployPackage' || cmdName === 'rp') { - await min.conversationalService.sendText(min, step, 'The package is being *unloaded*...'); - await GBAdminService.undeployPackageCommand(text, min); - await min.conversationalService.sendText(min, step, 'Now, *deploying* package...'); - await GBAdminService.deployPackageCommand(min, text, deployer); - await min.conversationalService.sendText( - min, - step, - 'Package deployed. Just need to rebuild the index... Doing it right now.' - ); - await GBAdminService.rebuildIndexPackageCommand(min, deployer); - await min.conversationalService.sendText(min, step, 'Finished importing of that .gbkb package. Thanks.'); - return await step.replaceDialog('/admin', { firstRun: false }); - } else if (cmdName === 'undeployPackage' || cmdName === 'up') { - await min.conversationalService.sendText(min, step, 'The package is being *undeployed*...'); - await GBAdminService.undeployPackageCommand(text, min); - await min.conversationalService.sendText(min, step, 'Package *undeployed*.'); - return await step.replaceDialog('/admin', { firstRun: false }); - } else if (cmdName === 'rebuildIndex' || cmdName === 'ri' || cmdName === 'Ri') { - await GBAdminService.rebuildIndexPackageCommand(min, deployer); - - return await step.replaceDialog('/admin', { firstRun: false }); - } else if (cmdName === 'syncBotServer') { - await GBAdminService.syncBotServerCommand(min, deployer); - - return await step.replaceDialog('/admin', { firstRun: false }); + return await step.replaceDialog('/'); } else if (cmdName === 'setupSecurity') { return await step.beginDialog('/setupSecurity'); } else { @@ -325,18 +296,18 @@ export class AdminDialog extends IGBDialog { packages.push(`${botId}.gbot`); skipError = true; } else { - await min.conversationalService.sendText(min, step, `Starting publishing for ${filename}...`); packages.push(filename); } + await CollectionUtil.asyncForEach(packages, async packageName => { let cmd1; if ( - packageName.indexOf('gbdialog') !== -1 || - packageName.indexOf('gbkb') !== -1 || - packageName.indexOf('gbot') !== -1 || - packageName.indexOf('gbtheme') !== -1 + packageName.toLowerCase() === 'gbdialog' || + packageName.toLowerCase() === 'gbkb' || + packageName.toLowerCase() === 'gbot' || + packageName.toLowerCase() === 'gbtheme' ) { packageName = `${min.botId}.${packageName}`; } @@ -353,10 +324,23 @@ export class AdminDialog extends IGBDialog { const cmd2 = `undeployPackage ${packageName}`; await GBAdminService.undeployPackageCommand(cmd2, min); } - await GBAdminService.deployPackageCommand(min, cmd1, deployer); - await min.conversationalService.sendText(min, step, `Finished publishing ${packageName}.`); + let sec = new SecService(); + const member = step.context.activity.from; + const user = await sec.ensureUser( + min.instance.instanceId, + member.id, + member.name, + '', + 'web', + member.name, + null + ); + + await GBAdminService.deployPackageCommand(min, user, cmd1, deployer); + }); - await min.conversationalService.sendText(min, step, Messages[locale].publish_success); + await min.conversationalService.sendText(min, step, `Training is finished.`); + if (!step.activeDialog.state.options.confirm) { return await step.replaceDialog('/ask', { isReturning: true }); } else { diff --git a/packages/admin.gbapp/services/GBAdminService.ts b/packages/admin.gbapp/services/GBAdminService.ts index 6a8d54b8..1b3eeab8 100644 --- a/packages/admin.gbapp/services/GBAdminService.ts +++ b/packages/admin.gbapp/services/GBAdminService.ts @@ -53,6 +53,7 @@ import { caseSensitive_Numbs_SpecialCharacters_PW, lowercase_PW } from 'super-st import crypto from 'crypto'; import Fs from 'fs'; import { GBServer } from '../../../src/app.js'; +import { GuaribasUser } from '../../security.gbapp/models/index.js'; /** * Services for server administration. @@ -138,7 +139,7 @@ export class GBAdminService implements IGBAdminService { public static isSharePointPath(path: string) { return path.indexOf('sharepoint.com') !== -1; } - public static async deployPackageCommand(min: GBMinInstance, text: string, deployer: IGBDeployer) { + public static async deployPackageCommand(min: GBMinInstance, user: GuaribasUser, text: string, deployer: IGBDeployer) { const packageName = text.split(' ')[1]; if (!this.isSharePointPath(packageName)) { @@ -146,7 +147,7 @@ export class GBAdminService implements IGBAdminService { if (additionalPath === undefined) { throw new Error('ADDITIONAL_DEPLOY_PATH is not set and deployPackage was called.'); } - await deployer.deployPackage(min, urlJoin(additionalPath, packageName)); + await deployer['deployPackage2'](min, user, urlJoin(additionalPath, packageName)); } else { const siteName = text.split(' ')[1]; const folderName = text.split(' ')[2]; @@ -157,7 +158,7 @@ export class GBAdminService implements IGBAdminService { // of local resources is required. await deployer['downloadFolder'](min, Path.join('work', `${min.instance.botId}.gbai`), Path.basename(folderName)); - await deployer.deployPackage(min, localFolder); + await deployer['deployPackage2'](min, user, localFolder); } } public static async rebuildIndexPackageCommand(min: GBMinInstance, deployer: GBDeployer) { diff --git a/packages/core.gbapp/services/GBConversationalService.ts b/packages/core.gbapp/services/GBConversationalService.ts index a1f37005..a1592ce4 100644 --- a/packages/core.gbapp/services/GBConversationalService.ts +++ b/packages/core.gbapp/services/GBConversationalService.ts @@ -78,7 +78,7 @@ export class GBConversationalService { * * @param coreService */ - constructor (coreService: IGBCoreService) { + constructor(coreService: IGBCoreService) { this.coreService = coreService; } @@ -263,11 +263,11 @@ export class GBConversationalService { ]; // "what?" version ... http://jsperf.com/diacritics/12 - public static removeDiacriticsAndPunctuation (str) { + public static removeDiacriticsAndPunctuation(str) { str = GBConversationalService.removeDiacritics(str); return str.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, ''); } - public static removeDiacritics (str) { + public static removeDiacritics(str) { var diacriticsMap = {}; for (var i = 0; i < GBConversationalService.defaultDiacriticsRemovalMap.length; i++) { var letters = GBConversationalService.defaultDiacriticsRemovalMap[i].letters; @@ -281,7 +281,7 @@ export class GBConversationalService { return str; } - public getNewMobileCode () { + public getNewMobileCode() { const passwordGenerator = new PasswordGenerator(); const options = { upperCaseAlpha: false, @@ -295,15 +295,15 @@ export class GBConversationalService { return code; } - public getCurrentLanguage (step: GBDialogStep) { + public getCurrentLanguage(step: GBDialogStep) { return step.context.activity.locale; } - public userMobile (step) { + public userMobile(step) { return GBMinService.userMobile(step); } - public async sendFile ( + public async sendFile( min: GBMinInstance, step: GBDialogStep, mobile: string, @@ -330,13 +330,13 @@ export class GBConversationalService { } } - public async sendAudio (min: GBMinInstance, step: GBDialogStep, url: string): Promise { + public async sendAudio(min: GBMinInstance, step: GBDialogStep, url: string): Promise { const mobile = step.context.activity['mobile']; GBLog.info(`Sending audio to ${mobile} in URL: ${url}.`); await min.whatsAppDirectLine.sendAudioToDevice(mobile, url); } - public async sendEvent (min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise { + public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise { if (!this.userMobile(step) && step.context.activity.channelId !== 'msteams') { GBLog.info( `Sending event ${name}:${typeof value === 'object' ? JSON.stringify(value) : value ? value : ''} to client...` @@ -351,7 +351,7 @@ export class GBConversationalService { } // tslint:disable:no-unsafe-any due to Nexmo. - public async sendSms (min: GBMinInstance, mobile: string, text: string): Promise { + public async sendSms(min: GBMinInstance, mobile: string, text: string): Promise { GBLog.info(`Sending SMS to ${mobile} with text: '${text}'.`); if (!min.instance.smsKey && min.instance.smsSecret) { @@ -362,15 +362,13 @@ export class GBConversationalService { 'content-type': 'application/json', authorization: `Bearer ${min.instance.smsSecret}` }, - body: - JSON.stringify({ - numero: `${mobile}`, - servico: 'short', - mensagem: text, - parceiro_id: '', - codificacao: '0' - }) - + body: JSON.stringify({ + numero: `${mobile}`, + servico: 'short', + mensagem: text, + parceiro_id: '', + codificacao: '0' + }) }; try { @@ -383,33 +381,31 @@ export class GBConversationalService { return Promise.reject(new Error(msg)); } } else { - return new Promise( - (resolve: any, reject: any): any => { - const nexmo = new Nexmo({ - apiKey: min.instance.smsKey, - apiSecret: min.instance.smsSecret - }); - // tslint:disable-next-line:no-unsafe-any - nexmo.message.sendSms(min.instance.smsServiceNumber, mobile, text, {}, (err, data) => { - const message = data.messages ? data.messages[0] : {}; - if (err || message['error-text']) { - GBLog.error(`BASIC: error sending SMS to ${mobile}: ${message['error-text']}`); - reject(message['error-text']); - } else { - resolve(data); - } - }); - } - ); + return new Promise((resolve: any, reject: any): any => { + const nexmo = new Nexmo({ + apiKey: min.instance.smsKey, + apiSecret: min.instance.smsSecret + }); + // tslint:disable-next-line:no-unsafe-any + nexmo.message.sendSms(min.instance.smsServiceNumber, mobile, text, {}, (err, data) => { + const message = data.messages ? data.messages[0] : {}; + if (err || message['error-text']) { + GBLog.error(`BASIC: error sending SMS to ${mobile}: ${message['error-text']}`); + reject(message['error-text']); + } else { + resolve(data); + } + }); + }); } } - public async sendToMobile (min: GBMinInstance, mobile: string, message: string, conversationId) { + public async sendToMobile(min: GBMinInstance, mobile: string, message: string, conversationId) { GBLog.info(`Sending message ${message} to ${mobile}...`); await min.whatsAppDirectLine.sendToDevice(mobile, message, conversationId); } - public static async getAudioBufferFromText (text): Promise { + public static async getAudioBufferFromText(text): Promise { return new Promise(async (resolve, reject) => { const name = GBAdminService.getRndReadableIdentifier(); @@ -439,9 +435,7 @@ export class GBConversationalService { const transcoder = new prism.FFmpeg({ args: ['-analyzeduration', '0', '-loglevel', '0', '-f', 'opus', '-ar', '16000', '-ac', '1'] }); - Fs.createReadStream(waveFilename) - .pipe(transcoder) - .pipe(output); + Fs.createReadStream(waveFilename).pipe(transcoder).pipe(output); let url = urlJoin(GBServer.globals.publicAddress, 'audios', oggFilenameOnly); resolve(url); @@ -451,7 +445,7 @@ export class GBConversationalService { }); } - public static async getTextFromAudioBuffer (speechKey, cloudRegion, buffer, locale): Promise { + public static async getTextFromAudioBuffer(speechKey, cloudRegion, buffer, locale): Promise { return new Promise(async (resolve, reject) => { try { const oggFile = new Readable(); @@ -519,7 +513,7 @@ export class GBConversationalService { }); } - public async playMarkdown (min: GBMinInstance, answer: string, channel: string, step: GBDialogStep, mobile: string) { + public async playMarkdown(min: GBMinInstance, answer: string, channel: string, step: GBDialogStep, mobile: string) { const user = step ? await min.userProfile.get(step.context, {}) : null; let text = answer; @@ -528,9 +522,7 @@ export class GBConversationalService { text = await min.conversationalService.translate( min, answer, - user.locale - ? user.locale - : min.core.getParam(min.instance, 'Locale', GBConfigService.get('LOCALE')) + user.locale ? user.locale : min.core.getParam(min.instance, 'Locale', GBConfigService.get('LOCALE')) ); GBLog.verbose(`Translated text(playMarkdown): ${text}.`); } @@ -575,7 +567,7 @@ export class GBConversationalService { text = text.replace('! [', '![').replace('] (', ']('); text = text.replace(`[[embed url=`, process.env.BOT_URL + '/').replace(']]', ''); - text = text.replace(`](kb`, '](' + process.env.BOT_URL + '/kb'); + text = text.replace(`](kb`, '](' + process.env.BOT_URL + '/kb'); if (mobile) { await this.sendMarkdownToMobile(min, step, mobile, text); @@ -588,7 +580,7 @@ export class GBConversationalService { } } - private async sendHTMLToWeb (min, step: GBDialogStep, html: string, answer: string) { + private async sendHTMLToWeb(min, step: GBDialogStep, html: string, answer: string) { const locale = step.context.activity.locale; html = html.replace(/src\=\"kb\//gi, `src=\"../kb/`); @@ -598,14 +590,14 @@ export class GBConversationalService { content: html, answer: answer, prevId: 0, // https://github.com/GeneralBots/BotServer/issues/312 - nextId: 0 + nextId: 0 } }); } // tslint:enable:no-unsafe-any - public async sendMarkdownToMobile (min: GBMinInstance, step: GBDialogStep, mobile: string, text: string) { + public async sendMarkdownToMobile(min: GBMinInstance, step: GBDialogStep, mobile: string, text: string) { let sleep = ms => { return new Promise(resolve => { setTimeout(resolve, ms); @@ -775,7 +767,7 @@ export class GBConversationalService { } } - public async routeNLP (step: GBDialogStep, min: GBMinInstance, text: string) { + public async routeNLP(step: GBDialogStep, min: GBMinInstance, text: string) { if (min.instance.nlpAppId === null || min.instance.nlpAppId === undefined) { return false; } @@ -851,9 +843,7 @@ export class GBConversationalService { } GBLog.info( - `NLP called: ${intent}, entities: ${ - nlp.entities.length - }, score: ${score} > required (nlpScore): ${instanceScore}` + `NLP called: ${intent}, entities: ${nlp.entities.length}, score: ${score} > required (nlpScore): ${instanceScore}` ); step.activeDialog.state.options.entities = nlp.entities; @@ -879,7 +869,7 @@ export class GBConversationalService { return null; } - public async getLanguage (min: GBMinInstance, text: string): Promise { + public async getLanguage(min: GBMinInstance, text: string): Promise { const key = min.core.getParam(min.instance, 'textAnalyticsKey', null); if (!key) { return process.env.DEFAULT_USER_LANGUAGE; @@ -893,7 +883,7 @@ export class GBConversationalService { return language === '(Unknown)' ? 'en' : language; } - public async spellCheck (min: GBMinInstance, text: string): Promise { + public async spellCheck(min: GBMinInstance, text: string): Promise { const key = min.core.getParam(min.instance, 'spellcheckerKey', null); if (key) { @@ -908,7 +898,7 @@ export class GBConversationalService { return text; } - public async translate (min: GBMinInstance, text: string, language: string): Promise { + public async translate(min: GBMinInstance, text: string, language: string): Promise { const translatorEnabled = () => { if (min.instance.params) { const params = JSON.parse(min.instance.params); @@ -956,10 +946,14 @@ export class GBConversationalService { return Promise.reject(new Error(msg)); } } else { - const url = urlJoin(endPoint, 'translate', new URLSearchParams({ + const url = urlJoin( + endPoint, + 'translate', + new URLSearchParams({ 'api-version': '3.0', to: language - }).toString()); + }).toString() + ); let options = { method: 'POST', headers: { @@ -968,7 +962,7 @@ export class GBConversationalService { 'Content-type': 'application/json', 'X-ClientTraceId': GBAdminService.generateUuid() }, - body:text, + body: text, json: true }; @@ -984,17 +978,15 @@ export class GBConversationalService { } } - public async prompt (min: GBMinInstance, step: GBDialogStep, text: string) { + public async prompt(min: GBMinInstance, step: GBDialogStep, text: string) { let sec = new SecService(); - let user = await sec.getUserFromSystemId(step.context.activity.from.id); + let user = await sec.getUserFromSystemId(step.context.activity.from.id); if (text && text !== '') { text = await min.conversationalService.translate( min, text, - user.locale - ? user.locale - : min.core.getParam(min.instance, 'Locale', GBConfigService.get('LOCALE')) + user.locale ? user.locale : min.core.getParam(min.instance, 'Locale', GBConfigService.get('LOCALE')) ); GBLog.verbose(`Translated text(prompt): ${text}.`); } @@ -1005,18 +997,23 @@ export class GBConversationalService { } } - public async sendText (min: GBMinInstance, step, text) { + public async sendText(min: GBMinInstance, step, text) { await this['sendTextWithOptions'](min, step, text, true, null); } - public async sendTextWithOptions (min: GBMinInstance, step, text, translate, keepTextList) { + public async sendTextWithOptions(min: GBMinInstance, step, text, translate, keepTextList) { const member = step.context.activity.from; let sec = new SecService(); - let user = await sec.getUserFromSystemId(step.context.activity.from.id); + let user = await sec.getUserFromSystemId(step.context.activity.from.id); + await this['sendTextWithOptionsAndUser'](min, user, step, text, true, null); + } + + public async sendTextWithOptionsAndUser(min: GBMinInstance, user, step, text, translate, keepTextList) { + const member = step ? step.context.activity.from : null; + + let replacements = []; if (translate) { - let replacements = []; - // To fix MSFT bug. if (keepTextList) { @@ -1054,11 +1051,11 @@ export class GBConversationalService { const conversation = null; if (!user.conversationId) { const conversation = await analytics.createConversation(user); - user.conversationId = conversation.conversationId; + user.conversationId = conversation.conversationId; } analytics.createMessage(min.instance.instanceId, conversation, null, text); - if (!isNaN(member.id) && !member.id.startsWith('1000')) { + if (member && !isNaN(member.id) && !member.id.startsWith('1000')) { const to = step.context.activity.group ? step.context.activity.group : member.id; await min.whatsAppDirectLine.sendToDevice(to, text, step.context.activity.conversation.id); @@ -1066,8 +1063,7 @@ export class GBConversationalService { await step.context.sendActivity(text); } } - - public async broadcast (min: GBMinInstance, message: string) { + public async broadcast(min: GBMinInstance, message: string) { GBLog.info(`Sending broadcast notifications...`); let sleep = ms => { @@ -1091,7 +1087,7 @@ export class GBConversationalService { * * Sends a message in a user with an already started conversation (got ConversationReference set) */ - public async sendOnConversation (min: GBMinInstance, user: GuaribasUser, message: string) { + public async sendOnConversation(min: GBMinInstance, user: GuaribasUser, message: string) { if (user.conversationReference.startsWith('spaces')) { await min['googleDirectLine'].sendToDevice(user.userSystemId, null, user.conversationReference, message); } else { @@ -1110,7 +1106,7 @@ export class GBConversationalService { } } - public static kmpSearch (pattern, text) { + public static kmpSearch(pattern, text) { pattern = pattern.toLowerCase(); text = text.toLowerCase(); if (pattern.length == 0) return 0; // Immediate match diff --git a/packages/core.gbapp/services/GBDeployer.ts b/packages/core.gbapp/services/GBDeployer.ts index 18ace5a6..46ec4235 100644 --- a/packages/core.gbapp/services/GBDeployer.ts +++ b/packages/core.gbapp/services/GBDeployer.ts @@ -559,11 +559,13 @@ export class GBDeployer implements IGBDeployer { instanceId: instanceId }); } - + public async deployPackage(min: GBMinInstance, localPath: string) { + // TODO: @alanperdomo: Adjust interface mismatch. + } /** * Deploys a folder into the bot storage. */ - public async deployPackage(min: GBMinInstance, localPath: string) { + public async deployPackage2(min: GBMinInstance, user, localPath: string) { const packageType = Path.extname(localPath); let handled = false; let pck = null; @@ -717,7 +719,7 @@ export class GBDeployer implements IGBDeployer { try { GBLogEx.info(instance.instanceId, `Acquiring rebuildIndex mutex...`); release = await GBServer.globals.indexSemaphore.acquire(); - + GBLogEx.info(instance.instanceId, `Acquire rebuildIndex done.`); const search = new AzureSearch( instance.searchKey, instance.searchHost, @@ -729,7 +731,11 @@ export class GBDeployer implements IGBDeployer { try { await search.createDataSource(dsName, dsName, 'GuaribasQuestion', 'azuresql', connectionString); } catch (err) { - GBLog.error(err); + // If it is a 404 there is nothing to delete as it is the first creation. + + if (err.code !== 400 && err.message.indexOf('already exists') !==-1) { + throw err; + } } // Removes the index. @@ -739,11 +745,11 @@ export class GBDeployer implements IGBDeployer { } catch (err) { // If it is a 404 there is nothing to delete as it is the first creation. - if (err.code !== 404 && err.code !== 'OperationNotAllowed') { + if (err.code !== 'ResourceNameAlreadyInUse') { + throw err; } } - GBLogEx.info(instance.instanceId, `Acquire rebuildIndex done.`); await search.rebuildIndex(instance.searchIndexer); release(); GBLogEx.info(instance.instanceId, `Released rebuildIndex mutex.`); diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index 87b2074f..3d628148 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -282,26 +282,27 @@ export class GBMinService { // min['groupCache'] = await KBService.getGroupReplies(instance.instanceId); GBServer.globals.minInstances.push(min); + const user = null; // No user context. - await this.deployer.deployPackage(min, 'packages/default.gbtheme'); + await this.deployer['deployPackage2'](min, user, 'packages/default.gbtheme'); // Install per bot deployed packages. let packagePath = `work/${min.botId}.gbai/${min.botId}.gbdialog`; if (Fs.existsSync(packagePath)) { - await this.deployer.deployPackage(min, packagePath); + await this.deployer['deployPackage2'](min, user, packagePath); } packagePath = `work/${min.botId}.gbai/${min.botId}.gbapp`; if (Fs.existsSync(packagePath)) { - await this.deployer.deployPackage(min, packagePath); + await this.deployer['deployPackage2'](min, user, packagePath); } packagePath = `work/${min.botId}.gbai/${min.botId}.gbtheme`; if (Fs.existsSync(packagePath)) { - await this.deployer.deployPackage(min, packagePath); + await this.deployer['deployPackage2'](min, user, packagePath); } packagePath = `work/${min.botId}.gbai/${min.botId}.gblib`; if (Fs.existsSync(packagePath)) { - await this.deployer.deployPackage(min, packagePath); + await this.deployer['deployPackage2'](min, user, packagePath); } let dir = `work/${min.botId}.gbai/cache`; @@ -375,6 +376,7 @@ export class GBMinService { }; await CollectionUtil.asyncForEach(steps, async step => { + client.apis.Conversations.Conversations_PostActivity({ conversationId: conversationId, activity: { @@ -388,7 +390,7 @@ export class GBMinService { } }); - await sleep(5000); + await sleep(3000); }); } diff --git a/packages/kb.gbapp/models/index.ts b/packages/kb.gbapp/models/index.ts index d6d91a3f..363fc9a7 100644 --- a/packages/kb.gbapp/models/index.ts +++ b/packages/kb.gbapp/models/index.ts @@ -65,53 +65,52 @@ export class GuaribasSubject extends Model { @PrimaryKey @AutoIncrement @Column(DataType.INTEGER) - subjectId: number; - - @Column(DataType.INTEGER) - internalId: string; + declare subjectId: number; @Column(DataType.STRING(255)) - title: string; + declare internalId: string; + + declare title: string; @Column(DataType.STRING(512)) - description: string; + declare description: string; @Column(DataType.STRING(255)) - from: string; + declare from: string; @Column(DataType.STRING(255)) - to: string; + declare to: string; @ForeignKey(() => GuaribasSubject) @Column(DataType.INTEGER) - parentSubjectId: number; + declare parentSubjectId: number; @BelongsTo(() => GuaribasSubject, 'parentSubjectId') parentSubject: GuaribasSubject; @HasMany(() => GuaribasSubject, { foreignKey: 'parentSubjectId' }) - childrenSubjects: GuaribasSubject[]; + declare childrenSubjects: GuaribasSubject[]; @ForeignKey(() => GuaribasInstance) @Column(DataType.INTEGER) - instanceId: number; + declare instanceId: number; @BelongsTo(() => GuaribasInstance) - instance: GuaribasInstance; + declare instance: GuaribasInstance; @ForeignKey(() => GuaribasUser) @Column(DataType.INTEGER) - responsibleUserId: number; + declare responsibleUserId: number; @BelongsTo(() => GuaribasUser) - responsibleUser: GuaribasUser; + declare responsibleUser: GuaribasUser; @ForeignKey(() => GuaribasPackage) @Column(DataType.INTEGER) - packageId: number; + declare packageId: number; @BelongsTo(() => GuaribasPackage) - package: GuaribasPackage; + declare package: GuaribasPackage; } /** diff --git a/packages/kb.gbapp/services/KBService.ts b/packages/kb.gbapp/services/KBService.ts index 60e2f219..c7eb01d1 100644 --- a/packages/kb.gbapp/services/KBService.ts +++ b/packages/kb.gbapp/services/KBService.ts @@ -869,8 +869,9 @@ export class KBService implements IGBKBService { let level; for (level = 0; level < MAX_LEVEL; level++) { - menu = row._cells[level]; - if (menu && menu.text) { + const cell = row._cells[level]; + if (cell && cell.text) { + menu = cell.text; break; } } @@ -890,10 +891,10 @@ export class KBService implements IGBKBService { activeChildrenGivenLevel[level] = childrenNode; // Insert the object into JSON. - + const description = row._cells[level + 1]?row._cells[level + 1].text: null; activeObj = { title: menu, - description: row._cells[level + 1], + description: description, id: menu, children: [] }; @@ -984,7 +985,7 @@ export class KBService implements IGBKBService { min['groupCache'] = await KBService.getGroupReplies(instance.instanceId); await KBService.RefreshNER(min); - GBLog.info(`[GBDeployer] Opening package: ${localPath}`); + GBLog.info(`[GBDeployer] Start Bot Server Side Rendering... ${localPath}`); const html = await GBSSR.getHTML(min); const path = Path.join( process.env.PWD, @@ -993,7 +994,7 @@ export class KBService implements IGBKBService { `${min.instance.botId}.gbui`, 'index.html' ); - GBLogEx.info(min, `[GBDeployer] Generating SSR HTML in ${path}.`); + GBLogEx.info(min, `[GBDeployer] Saving SSR HTML in ${path}.`); Fs.writeFileSync(path, html, 'utf8'); GBLog.info(`[GBDeployer] Finished import of ${localPath}`); diff --git a/src/app.ts b/src/app.ts index 89b716fb..295dd91d 100644 --- a/src/app.ts +++ b/src/app.ts @@ -103,13 +103,13 @@ export class GBServer { server.use(bodyParser.urlencoded({ extended: true })); process.on('unhandledRejection', (err, p) => { - GBLog.error(`UNHANDLED_REJECTION(promises): ${p} ${err.toString()}`); + GBLog.error(`UNHANDLED_REJECTION(promises): ${err.toString()} ${err['stack']?'\n'+err['stack']:''}`); }); - process.on('uncaughtException', (err, origin) => { - GBLog.error(`UNCAUGHT_EXCEPTION: ${err.toString()}`); + process.on('uncaughtException', (err, p) => { + GBLog.error(`UNCAUGHT_EXCEPTION: ${err.toString()} ${err['stack']?'\n'+err['stack']:''}`); }); - + // Creates working directory. process.env.PWD = process.cwd();