From 80b91c437001a890131e509d67604e42c27cea2e Mon Sep 17 00:00:00 2001 From: Rodrigo Rodriguez Date: Tue, 1 Jun 2021 10:05:52 -0300 Subject: [PATCH] fix(basic.gbapp): Call to SEND FILE with .md files working OK. --- .../basic.gblib/services/DialogKeywords.ts | 25 +++- .../services/GBConversationalService.ts | 110 +++++++++++++++++- packages/kb.gbapp/services/KBService.ts | 96 +-------------- 3 files changed, 130 insertions(+), 101 deletions(-) diff --git a/packages/basic.gblib/services/DialogKeywords.ts b/packages/basic.gblib/services/DialogKeywords.ts index 27c560c4..9ba13e32 100644 --- a/packages/basic.gblib/services/DialogKeywords.ts +++ b/packages/basic.gblib/services/DialogKeywords.ts @@ -57,7 +57,7 @@ export class DialogKeywords { * Reference to the base system keywords functions to be called. */ public internalSys: SystemKeywords; - + /** * Current user object to get BASIC properties read. */ @@ -166,7 +166,7 @@ export class DialogKeywords { user.systemUser = await sec.updateUserLocale(user.systemUser.userId, language); await this.min.userProfile.set(step.context, user); - this.user = user; + this.user = user; } /** @@ -181,7 +181,7 @@ export class DialogKeywords { await this.min.userProfile.set(step.context, user); this.user = user; } - + /** * Defines translator behaviour. * @@ -218,6 +218,9 @@ export class DialogKeywords { */ public async userMobile(step) { if (isNaN(step.context.activity['mobile'])) { + if (step.context.activity.from && !isNaN(step.context.activity.from.id)) { + return step.context.activity.from.id; + } return 'No mobile available.'; } else { return step.context.activity['mobile']; @@ -274,6 +277,18 @@ export class DialogKeywords { this.user.basicOptions.translatorOn, null); } + private static getChannel(step): string { + if (!isNaN(step.context.activity['mobile'])) { + return 'webchat'; + } else { + if (step.context.activity.from && !isNaN(step.context.activity.from.id)) { + return 'whatsapp'; + } + return 'webchat'; + } + } + + /** * Processes the sending of the file. */ @@ -281,7 +296,9 @@ export class DialogKeywords { if (filename.indexOf('.md') > -1) { GBLog.info(`BASIC: Sending the contents of ${filename} markdown to mobile ${mobile}.`); const md = await this.min.kbService.getAnswerTextByMediaName(this.min.instance.instanceId, filename); - await this.min.conversationalService.sendMarkdownToMobile(this.min, step, mobile, md); + + await this.min.conversationalService['playMarkdown'](this.min, md, + DialogKeywords.getChannel(step), step); } else { GBLog.info(`BASIC: Sending the file ${filename} to mobile ${mobile}.`); const url = urlJoin( diff --git a/packages/core.gbapp/services/GBConversationalService.ts b/packages/core.gbapp/services/GBConversationalService.ts index 62691479..d65f4efd 100644 --- a/packages/core.gbapp/services/GBConversationalService.ts +++ b/packages/core.gbapp/services/GBConversationalService.ts @@ -46,6 +46,7 @@ import { SecService } from '../../security.gbapp/services/SecService'; import { AnalyticsService } from '../../analytics.gblib/services/AnalyticsService'; import { MicrosoftAppCredentials } from 'botframework-connector'; import { GBConfigService } from './GBConfigService'; +import { Messages } from '../strings'; import { CollectionUtil, AzureText } from 'pragmatismo-io-framework'; import { GuaribasUser } from '../../security.gbapp/models'; const urlJoin = require('url-join'); @@ -60,6 +61,7 @@ const request = require('request-promise-native'); const fs = require('fs'); const SpeechToTextV1 = require('ibm-watson/speech-to-text/v1'); const { IamAuthenticator } = require('ibm-watson/auth'); +const marked = require('marked'); /** * Provides basic services for handling messages and dispatching to back-end @@ -212,6 +214,18 @@ export class GBConversationalService { return step.context.activity.locale; } + public userMobile(step) { + if (isNaN(step.context.activity['mobile'])) { + if (step.context.activity.from && !isNaN(step.context.activity.from.id)) { + return step.context.activity.from.id; + } + return null; + } else { + return step.context.activity['mobile']; + } + } + + public async sendFile( min: GBMinInstance, step: GBDialogStep, @@ -220,8 +234,10 @@ export class GBConversationalService { caption: string ): Promise { if (step !== null) { - if (!isNaN(step.context.activity['mobile'] as any)) { - mobile = step.context.activity['mobile']; + + mobile = this.userMobile(step); + + if (mobile) { GBLog.info(`Sending file ${url} to ${mobile}...`); const filename = url.substring(url.lastIndexOf('/') + 1); await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption); @@ -397,6 +413,96 @@ export class GBConversationalService { }); } + public async playMarkdown( + min: GBMinInstance, + answer: string, + channel: string, + step: GBDialogStep + ) { + const user = await min.userProfile.get(step.context, {}); + + // Calls language translator. + + let text = await min.conversationalService.translate( + min, + answer, + user.systemUser.locale + ? user.systemUser.locale + : min.core.getParam(min.instance, 'Locale', GBConfigService.get('LOCALE')) + ); + GBLog.info(`Translated text(playMarkdown): ${text}.`); + + + var renderer = new marked.Renderer(); + renderer.oldImage = renderer.image; + renderer.image = function (href, title, text) { + var videos = ['webm', 'mp4', 'mov']; + var filetype = href.split('.').pop(); + if (videos.indexOf(filetype) > -1) { + var out = '' + return out; + } else { + return renderer.oldImage(href, title, text); + } + }; + + // Converts from Markdown to HTML. + + marked.setOptions({ + renderer: renderer, + gfm: true, + tables: true, + breaks: false, + pedantic: false, + sanitize: false, + smartLists: true, + smartypants: false, + xhtml: false + }); + + // MSFT Translator breaks markdown, so we need to fix it: + + text = text.replace('! [', '![').replace('] (', ']('); + + text = text.replace(`[[embed url=`, process.env.BOT_URL + '/').replace(']]', ''); // TODO: Improve it. + text = text.replace(`](kb`, "]("+ process.env.BOT_URL + '/kb'); // TODO: Improve it. + + // According to the channel, formats the output optimized to it. + + if (channel === 'webchat' && GBConfigService.get('DISABLE_WEB') !== 'true') { + const html = marked(text); + await this.sendMarkdownToWeb(min, step, html, answer); + } else if (channel === 'whatsapp') { + await this.sendMarkdownToMobile(min, step, user.userSystemId, text); + } else { + const html = marked(text); + await min.conversationalService.sendText(min, step, html); + } + } + + private async sendMarkdownToWeb( + min, + step: GBDialogStep, + html: string, + answer: string + ) { + const locale = step.context.activity.locale; + await this.sendText(min, step, Messages[locale].will_answer_projector); + html = html.replace(/src\=\"kb\//gi, `src=\"../kb/`); + await this.sendEvent(min, step, 'play', { + playerType: 'markdown', + data: { + content: html, + answer: answer, + prevId: 0, // TODO: answer.prevId, + nextId: 0, // TODO: answer.nextId + } + }); + } + + // tslint:enable:no-unsafe-any public async sendMarkdownToMobile(min: GBMinInstance, step: GBDialogStep, mobile: string, text: string) { diff --git a/packages/kb.gbapp/services/KBService.ts b/packages/kb.gbapp/services/KBService.ts index 412347c6..d54938e5 100644 --- a/packages/kb.gbapp/services/KBService.ts +++ b/packages/kb.gbapp/services/KBService.ts @@ -37,7 +37,6 @@ const Path = require('path'); const Fs = require('fs'); const urlJoin = require('url-join'); -const marked = require('marked'); const path = require('path'); const asyncPromise = require('async-promises'); const walkPromise = require('walk-promise'); @@ -55,7 +54,6 @@ import { IGBInstance, IGBKBService } from 'botlib'; -import { GBAdminService } from '../../admin.gbapp/services/GBAdminService'; import { CollectionUtil } from 'pragmatismo-io-framework'; import { Op } from 'sequelize'; import { Sequelize } from 'sequelize-typescript'; @@ -64,7 +62,6 @@ import { GuaribasPackage } from '../../core.gbapp/models/GBModel'; import { GBDeployer } from '../../core.gbapp/services/GBDeployer'; import { CSService } from '../../customer-satisfaction.gbapp/services/CSService'; import { GuaribasAnswer, GuaribasQuestion, GuaribasSubject } from '../models'; -import { Messages } from '../strings'; import { GBConfigService } from './../../core.gbapp/services/GBConfigService'; /** @@ -533,7 +530,7 @@ export class KBService implements IGBKBService { `${min.instance.botId}.gbkb`, 'assets', answer.content); await this.playUrl(min, min.conversationalService, step, url, channel); } else if (answer.format === '.md') { - await this.playMarkdown(min, answer, channel, step, min.conversationalService); + await min.conversationalService['playMarkdown'](min, answer, channel, step, min.conversationalService); } else if (answer.content.endsWith('.ogg') && process.env.AUDIO_DISABLED !== 'true') { await this.playAudio(min, answer, channel, step, min.conversationalService); } else { @@ -670,97 +667,6 @@ export class KBService implements IGBKBService { conversationalService.sendAudio(min, step, answer.content); } - private async playMarkdown( - min: GBMinInstance, - answer: GuaribasAnswer, - channel: string, - step: GBDialogStep, - conversationalService: IGBConversationalService - ) { - const user = await min.userProfile.get(step.context, {}); - - // Calls language translator. - - let text = await min.conversationalService.translate( - min, - answer.content, - user.systemUser.locale - ? user.systemUser.locale - : min.core.getParam(min.instance, 'Locale', GBConfigService.get('LOCALE')) - ); - GBLog.info(`Translated text(playMarkdown): ${text}.`); - - - var renderer = new marked.Renderer(); - renderer.oldImage = renderer.image; - renderer.image = function (href, title, text) { - var videos = ['webm', 'mp4', 'mov']; - var filetype = href.split('.').pop(); - if (videos.indexOf(filetype) > -1) { - var out = '' - return out; - } else { - return renderer.oldImage(href, title, text); - } - }; - - // Converts from Markdown to HTML. - - marked.setOptions({ - renderer: renderer, - gfm: true, - tables: true, - breaks: false, - pedantic: false, - sanitize: false, - smartLists: true, - smartypants: false, - xhtml: false - }); - - // MSFT Translator breaks markdown, so we need to fix it: - - text = text.replace('! [', '![').replace('] (', ']('); - - text = text.replace(`[[embed url=`, process.env.BOT_URL + '/').replace(']]', ''); // TODO: Improve it. - text = text.replace(`](kb`, "]("+ process.env.BOT_URL + '/kb'); // TODO: Improve it. - - // According to the channel, formats the output optimized to it. - - if (channel === 'webchat' && GBConfigService.get('DISABLE_WEB') !== 'true') { - const html = marked(text); - await this.sendMarkdownToWeb(min, step, conversationalService, html, answer); - } else if (channel === 'whatsapp') { - await conversationalService.sendMarkdownToMobile(min, step, user.userSystemId, text); - } else { - const html = marked(text); - await min.conversationalService.sendText(min, step, html); - } - } - - private async sendMarkdownToWeb( - min, - step: GBDialogStep, - conversationalService: IGBConversationalService, - html: string, - answer: GuaribasAnswer - ) { - const locale = step.context.activity.locale; - await min.conversationalService.sendText(min, step, Messages[locale].will_answer_projector); - html = html.replace(/src\=\"kb\//gi, `src=\"../kb/`); - await conversationalService.sendEvent(min, step, 'play', { - playerType: 'markdown', - data: { - content: html, - answer: answer, - prevId: answer.prevId, - nextId: answer.nextId - } - }); - } - private async playUrl( min, conversationalService: IGBConversationalService,