diff --git a/package.json b/package.json index 1bfd603c..cd516c2b 100644 --- a/package.json +++ b/package.json @@ -141,6 +141,7 @@ "sequelize": "6.25.7", "sequelize-cli": "6.5.2", "sequelize-typescript": "2.1.5", + "sharp": "^0.31.3", "simple-git": "3.15.0", "speakingurl": "14.0.1", "ssr-for-bots": "1.0.1-c", diff --git a/packages/basic.gblib/index.ts b/packages/basic.gblib/index.ts index f56a7e58..8dc34b22 100644 --- a/packages/basic.gblib/index.ts +++ b/packages/basic.gblib/index.ts @@ -41,10 +41,11 @@ import { GuaribasSchedule } from '../core.gbapp/models/GBModel.js'; import { Sequelize } from 'sequelize-typescript'; import { createServerRouter } from 'typescript-rest-rpc/lib/server.js'; import { DialogKeywords } from './services/DialogKeywords.js'; -import * as koaBody from 'koa-body'; import { SystemKeywords } from './services/SystemKeywords.js'; import { WebAutomationKeywords } from './services/WebAutomationKeywords.js'; +import { ImageProcessing } from './services/ImageProcessing.js'; import { DebuggerService } from './services/DebuggerService.js'; +import * as koaBody from 'koa-body'; import Koa from 'koa'; const app = new Koa(); @@ -83,15 +84,18 @@ export class GBBasicPackage implements IGBPackage { const wa = new WebAutomationKeywords(min, null, dk); const sys = new SystemKeywords(min, null, dk, wa); const dbg = new DebuggerService(min, null, dk); + const img = new ImageProcessing(min, null, dk); dk.wa = wa; wa.sys = sys; const dialogRouter = createServerRouter(`/api/v2/${min.botId}/dialog`, dk); const waRouter = createServerRouter(`/api/v2/${min.botId}/webautomation`, wa); const sysRouter = createServerRouter(`/api/v2/${min.botId}/system`, sys); const dbgRouter = createServerRouter(`/api/v2/${min.botId}/debugger`, dbg); + const imgRouter = createServerRouter(`/api/v2/${min.botId}/imageprocessing`, dbg); app.use(dialogRouter.routes()); app.use(sysRouter.routes()); app.use(waRouter.routes()); app.use(dbgRouter.routes()); + app.use(imgRouter.routes()); } } diff --git a/packages/basic.gblib/services/GBVMService.ts b/packages/basic.gblib/services/GBVMService.ts index 9b4887d1..fa5f9d01 100644 --- a/packages/basic.gblib/services/GBVMService.ts +++ b/packages/basic.gblib/services/GBVMService.ts @@ -200,6 +200,7 @@ export class GBVMService extends GBService { 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'); // Local variables. @@ -999,6 +1000,14 @@ export class GBVMService extends GBService { return `await sys.set ({pid: pid, ${params}})`; } ]; + keywords[i++] = [ + /^\s*(\w+)\s*\=\s*SHARPEN\s*(.*)/gim, + ($0, $1, $2, $3) => { + return ` + ${$1} = await img.sharpen({pid: pid, args: [${$2}]})`; + } + ]; + return keywords; } @@ -1044,7 +1053,7 @@ export class GBVMService extends GBService { const pid = GBAdminService.getNumberIdentifier(); GBServer.globals.processes[pid] = { pid: pid, - userId: user.systemUser.userId, + userId: user.userId, instanceId: min.instance.instanceId }; diff --git a/packages/basic.gblib/services/ImageProcessing.ts b/packages/basic.gblib/services/ImageProcessing.ts new file mode 100644 index 00000000..4a36c330 --- /dev/null +++ b/packages/basic.gblib/services/ImageProcessing.ts @@ -0,0 +1,97 @@ +/*****************************************************************************\ +| ( )_ _ | +| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ | +| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' v `\ /'_`\ | +| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__,\| (˅) |( (_) ) | +| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' | +| | | ( )_) | | +| (_) \___/' | +| | +| 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 { GBLog, GBMinInstance } from 'botlib'; +import { DialogKeywords } from './DialogKeywords.js'; +import sharp from 'sharp'; + +/** + * Image processing services of conversation to be called by BASIC. + */ +export class ImageProcessing { + /** + * Reference to minimal bot instance. + */ + public min: GBMinInstance; + + /** + * Reference to the base system keywords functions to be called. + */ + public dk: DialogKeywords; + + /** + * Current user object to get BASIC properties read. + */ + public user; + + sys: any; + + /** + * When creating this keyword facade,a bot instance is + * specified among the deployer service. + */ + constructor(min: GBMinInstance, user, dk) { + this.min = min; + this.user = user; + this.dk = dk; + } + + /** + * Returns the page object. + * + * @example OPEN "https://wikipedia.org" + */ + public async sharpen({ pid, file: file }) { + GBLog.info(`BASIC: Image Processing SHARPEN ${file}.`); + + const gbfile = DialogKeywords.getFileByHandle(file); + const data = await sharp(gbfile.data) + .sharpen({ + sigma: 2, + m1: 0, + m2: 3, + x1: 3, + y2: 15, + y3: 15 + }) + .toBuffer(); + + const newFile = { + filename: gbfile.filename, + data: data + + }; + return; + } +} diff --git a/packages/basic.gblib/services/SystemKeywords.ts b/packages/basic.gblib/services/SystemKeywords.ts index 42555a4e..a9c4aa71 100644 --- a/packages/basic.gblib/services/SystemKeywords.ts +++ b/packages/basic.gblib/services/SystemKeywords.ts @@ -517,7 +517,7 @@ export class SystemKeywords { GBLog.info(`BASIC: Saving '${file}' (SAVE file).`); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min); const botId = this.min.instance.botId; - const path = `/${botId}.gbai/${botId}.gbdata`; + const path = `/${botId}.gbai/${botId}.gbdrive`; // Checks if it is a GB FILE object. @@ -526,6 +526,7 @@ export class SystemKeywords { } try { + data = GBServer.globals.files[data].data; await client.api(`${baseUrl}/drive/root:/${path}/${file}:/content`).put(data); } catch (error) { if (error.code === 'itemNotFound') { diff --git a/packages/core.gbapp/dialogs/LanguageDialog.ts b/packages/core.gbapp/dialogs/LanguageDialog.ts index 84fbd8f1..f380c8f1 100644 --- a/packages/core.gbapp/dialogs/LanguageDialog.ts +++ b/packages/core.gbapp/dialogs/LanguageDialog.ts @@ -71,8 +71,7 @@ export class LanguageDialog extends IGBDialog { return await min.conversationalService.prompt(min, step, Messages[locale].which_language); }, async step => { - const locale = step.context.activity.locale; - const user = await min.userProfile.get(step.context, {}); + const locale = step.context.activity.locale; const list = [ { name: 'english', code: 'en' }, @@ -103,9 +102,9 @@ export class LanguageDialog extends IGBDialog { }); let sec = new SecService(); - user.systemUser = await sec.updateUserLocale(user.systemUser.userId, translatorLocale); + let user = await sec.getUserFromSystemId(step.context.activity.from.id); + user = await sec.updateUserLocale(user.userId, translatorLocale); - await min.userProfile.set(step.context, user); await min.conversationalService.sendText(min, step, Messages[locale].language_chosen); await step.replaceDialog('/ask', { firstTime: true }); diff --git a/packages/core.gbapp/services/GBConversationalService.ts b/packages/core.gbapp/services/GBConversationalService.ts index 9ac1824d..1786a256 100644 --- a/packages/core.gbapp/services/GBConversationalService.ts +++ b/packages/core.gbapp/services/GBConversationalService.ts @@ -528,8 +528,8 @@ export class GBConversationalService { text = await min.conversationalService.translate( min, answer, - user.systemUser.locale - ? user.systemUser.locale + user.locale + ? user.locale : min.core.getParam(min.instance, 'Locale', GBConfigService.get('LOCALE')) ); GBLog.verbose(`Translated text(playMarkdown): ${text}.`); @@ -985,15 +985,15 @@ export class GBConversationalService { } public async prompt (min: GBMinInstance, step: GBDialogStep, text: string) { - const user = await min.userProfile.get(step.context, {}); - const systemUser = user.systemUser; + let sec = new SecService(); + let user = await sec.getUserFromSystemId(step.context.activity.from.id); if (text && text !== '') { text = await min.conversationalService.translate( min, text, - systemUser.locale - ? systemUser.locale + user.locale + ? user.locale : min.core.getParam(min.instance, 'Locale', GBConfigService.get('LOCALE')) ); GBLog.verbose(`Translated text(prompt): ${text}.`); @@ -1011,8 +1011,8 @@ export class GBConversationalService { public async sendTextWithOptions (min: GBMinInstance, step, text, translate, keepTextList) { const member = step.context.activity.from; - const user = await min.userProfile.get(step.context, {}); - const systemUser = user.systemUser; + let sec = new SecService(); + let user = await sec.getUserFromSystemId(step.context.activity.from.id); if (translate) { let replacements = []; @@ -1032,7 +1032,7 @@ export class GBConversationalService { }); } - const locale = systemUser ? systemUser.locale : null; + const locale = user.locale; text = await min.conversationalService.translate( min, text, @@ -1051,10 +1051,12 @@ export class GBConversationalService { } const analytics = new AnalyticsService(); - if (!user.conversation) { - user.conversation = await analytics.createConversation(user); + const conversation = null; + if (!user.conversationId) { + const conversation = await analytics.createConversation(user); + user.conversationId = conversation.conversationId; } - analytics.createMessage(min.instance.instanceId, user.conversation, null, text); + analytics.createMessage(min.instance.instanceId, conversation, null, text); if (!isNaN(member.id) && !member.id.startsWith('1000')) { const to = step.context.activity.group ? step.context.activity.group : member.id; @@ -1080,7 +1082,7 @@ export class GBConversationalService { if (user.conversationReference) { await this.sendOnConversation(min, user, message); } else { - GBLog.info(`User: ${user.systemUserId} with no conversation ID while broadcasting.`); + GBLog.info(`User: ${user.Id} with no conversation ID while broadcasting.`); } }); } diff --git a/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts b/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts index aa628a64..4e0f84c2 100644 --- a/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts +++ b/packages/customer-satisfaction.gbapp/dialogs/FeedbackDialog.ts @@ -92,7 +92,7 @@ export class FeedbackDialog extends IGBDialog { await sec.ensureUser(min.instance.instanceId, args.to, 'Name', '', 'whatsapp', 'Name', null); - await sec.assignHumanAgent(min, args.to, profile.systemUser.userSystemId); + await sec.assignHumanAgent(min, args.to, profile.userSystemId); await min.conversationalService.sendText( min, step, @@ -101,7 +101,7 @@ export class FeedbackDialog extends IGBDialog { } else { await min.conversationalService.sendText(min, step, Messages[locale].please_wait_transfering); const agentSystemId = await sec.assignHumanAgent(min, from); - profile.systemUser = await sec.getUserFromAgentSystemId(agentSystemId); + await min.userProfile.set(step.context, profile); if (agentSystemId.charAt(2) === ':' || agentSystemId.indexOf('@') > -1) { @@ -139,9 +139,9 @@ export class FeedbackDialog extends IGBDialog { const sec = new SecService(); const userSystemId = GBMinService.userMobile(step); - const user = await min.userProfile.get(step.context, {}); + let user = await sec.getUserFromSystemId(userSystemId); - if (user.systemUser.agentMode === 'self') { + if (user.agentMode === 'self') { const manualUser = await sec.getUserFromAgentSystemId(userSystemId); await min.whatsAppDirectLine.sendToDeviceEx( @@ -170,19 +170,19 @@ export class FeedbackDialog extends IGBDialog { await sec.updateHumanAgent(userSystemId, min.instance.instanceId, null); await sec.updateHumanAgent(manualUser.userSystemId, min.instance.instanceId, null); - user.systemUser = await sec.getUserFromSystemId(userSystemId); + user = await sec.getUserFromSystemId(userSystemId); await min.userProfile.set(step.context, user); - } else if (user.systemUser.agentMode === 'human') { - const agent = await sec.getUserFromSystemId(user.systemUser.agentSystemId); + } else if (user.agentMode === 'human') { + const agent = await sec.getUserFromSystemId(user.agentSystemId); await min.whatsAppDirectLine.sendToDeviceEx( - user.systemUser.userSystemId, + user.userSystemId, Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id ); - if (user.systemUser.agentSystemId.charAt(2) === ':' || userSystemId.indexOf('@') > -1) { + if (user.agentSystemId.charAt(2) === ':' || userSystemId.indexOf('@') > -1) { // Agent is from Teams or Google Chat. await min.conversationalService.sendText( min, @@ -191,25 +191,25 @@ export class FeedbackDialog extends IGBDialog { ); } else { await min.whatsAppDirectLine.sendToDeviceEx( - user.systemUser.agentSystemId, + user.agentSystemId, Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id ); } - await sec.updateHumanAgent(user.systemUser.userSystemId, min.instance.instanceId, null); + await sec.updateHumanAgent(user.userSystemId, min.instance.instanceId, null); await sec.updateHumanAgent(agent.userSystemId, min.instance.instanceId, null); - user.systemUser = await sec.getUserFromSystemId(userSystemId); + user = await sec.getUserFromSystemId(userSystemId); await min.userProfile.set(step.context, user); } else { - if (user.systemUser.userSystemId.charAt(2) === ':' || userSystemId.indexOf('@') > -1) { + if (user.userSystemId.charAt(2) === ':' || userSystemId.indexOf('@') > -1) { // Agent is from Teams or Google Chat. await min.conversationalService.sendText(min, step, 'Nenhum atendimento em andamento.'); } else { await min.whatsAppDirectLine.sendToDeviceEx( - user.systemUser.userSystemId, + user.userSystemId, 'Nenhum atendimento em andamento.', locale, step.context.activity.conversation.id @@ -276,7 +276,7 @@ export class FeedbackDialog extends IGBDialog { min.instance.instanceId, user.conversation.conversationId, step.result, - user.systemUser.locale + user.locale ); if (rate > 0.5) { diff --git a/packages/customer-satisfaction.gbapp/dialogs/QualityDialog.ts b/packages/customer-satisfaction.gbapp/dialogs/QualityDialog.ts index 55b892f7..ad6d9cc5 100644 --- a/packages/customer-satisfaction.gbapp/dialogs/QualityDialog.ts +++ b/packages/customer-satisfaction.gbapp/dialogs/QualityDialog.ts @@ -103,7 +103,7 @@ export class QualityDialog extends IGBDialog { min.instance.instanceId, user.conversation, step.result, - user.systemUser.locale + user.locale ); // Goes to the ask loop. diff --git a/packages/kb.gbapp/dialogs/AskDialog.ts b/packages/kb.gbapp/dialogs/AskDialog.ts index 1d90bd07..35d956d3 100644 --- a/packages/kb.gbapp/dialogs/AskDialog.ts +++ b/packages/kb.gbapp/dialogs/AskDialog.ts @@ -282,8 +282,8 @@ export class AskDialog extends IGBDialog { text = await min.conversationalService.translate( min, text, - user.systemUser.locale - ? user.systemUser.locale + user.locale + ? user.locale : min.core.getParam(min.instance, 'Locale', GBConfigService.get('LOCALE')) ); await min.conversationalService.sendText(min, step, answerText); diff --git a/src/app.ts b/src/app.ts index e9b5cb43..3136cb98 100644 --- a/src/app.ts +++ b/src/app.ts @@ -85,6 +85,7 @@ export class GBServer { GBServer.globals.server = server; GBServer.globals.processes = {}; + GBServer.globals.files = {}; GBServer.globals.appPackages = []; GBServer.globals.sysPackages = []; GBServer.globals.minInstances = [];