new(all): GBLogEx published.

This commit is contained in:
Rodrigo Rodriguez 2024-04-21 23:39:39 -03:00
parent ade7ee18b1
commit 76c3783ff9
28 changed files with 286 additions and 504 deletions

View file

@ -55,6 +55,7 @@ import Fs from 'fs';
import { GBServer } from '../../../src/app.js'; import { GBServer } from '../../../src/app.js';
import { GuaribasUser } from '../../security.gbapp/models/index.js'; import { GuaribasUser } from '../../security.gbapp/models/index.js';
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js'; import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
* Services for server administration. * Services for server administration.
@ -257,7 +258,7 @@ export class GBAdminService implements IGBAdminService {
const minBoot = GBServer.globals.minBoot; const minBoot = GBServer.globals.minBoot;
instanceId = minBoot.instance.instanceId; instanceId = minBoot.instance.instanceId;
} }
GBLog.info(`Acquiring token for instanceId: ${instanceId} ${tokenName} (root: ${root}).`); GBLogEx.info(instanceId, `Acquiring token for instanceId: ${instanceId} ${tokenName} (root: ${root}).`);
let expiresOnV; let expiresOnV;
try { try {

View file

@ -40,6 +40,7 @@ import { GBAdminService } from '../../../packages/admin.gbapp/services/GBAdminSe
import { GBConfigService } from '../../../packages/core.gbapp/services/GBConfigService.js'; import { GBConfigService } from '../../../packages/core.gbapp/services/GBConfigService.js';
import scanf from 'scanf'; import scanf from 'scanf';
import { AzureDeployerService } from '../services/AzureDeployerService.js'; import { AzureDeployerService } from '../services/AzureDeployerService.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
* Handles command-line dialog for getting info for Boot Bot. * Handles command-line dialog for getting info for Boot Bot.
@ -188,7 +189,7 @@ generate manually an App ID and App Secret.\n`
const map = {}; const map = {};
let index = 1; let index = 1;
list.forEach(element => { list.forEach(element => {
GBLog.info(`${index}: ${element.displayName} (${element.subscriptionId})`); GBLogEx.info(0, `${index}: ${element.displayName} (${element.subscriptionId})`);
map[index++] = element; map[index++] = element;
}); });
let subscriptionIndex; let subscriptionIndex;

View file

@ -54,6 +54,7 @@ import { Spinner } from 'cli-spinner';
import * as publicIp from 'public-ip'; import * as publicIp from 'public-ip';
import { AccessToken, TokenCredential } from '@azure/core-auth'; import { AccessToken, TokenCredential } from '@azure/core-auth';
import { GBUtil } from '../../../src/util.js'; import { GBUtil } from '../../../src/util.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
const WebSiteResponseTimeout = 900; const WebSiteResponseTimeout = 900;
const iconUrl = 'https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/generalbots-logo-squared.png'; const iconUrl = 'https://github.com/pragmatismo-io/BotServer/blob/master/docs/images/generalbots-logo-squared.png';
@ -291,7 +292,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
if (!JSON.parse(res.bodyAsText).id) { if (!JSON.parse(res.bodyAsText).id) {
throw res.bodyAsText; throw res.bodyAsText;
} }
GBLog.info(`Bot proxy updated at: ${endpoint}.`); GBLogEx.info(0, `Bot proxy updated at: ${endpoint}.`);
} }
public async updateBot(botId: string, group: string, name: string, description: string, endpoint: string) { public async updateBot(botId: string, group: string, name: string, description: string, endpoint: string) {
@ -320,7 +321,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
if (!JSON.parse(res.bodyAsText).id) { if (!JSON.parse(res.bodyAsText).id) {
throw res.bodyAsText; throw res.bodyAsText;
} }
GBLog.info(`Bot updated at: ${endpoint}.`); GBLogEx.info(0, `Bot updated at: ${endpoint}.`);
} }
public async deleteBot(botId: string, group: string) { public async deleteBot(botId: string, group: string) {
@ -340,7 +341,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
if (res.bodyAsText !== '') { if (res.bodyAsText !== '') {
throw res.bodyAsText; throw res.bodyAsText;
} }
GBLog.info(`Bot ${botId} was deleted from the provider.`); GBLogEx.info(0, `Bot ${botId} was deleted from the provider.`);
} }
public async openStorageFirewall(groupName: string, serverName: string) { public async openStorageFirewall(groupName: string, serverName: string) {
@ -384,7 +385,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
let keys: any; let keys: any;
const name = instance.botId; const name = instance.botId;
GBLog.info(`Enabling resource providers...`); GBLogEx.info(0, `Enabling resource providers...`);
await this.enableResourceProviders('Microsoft.CognitiveServices'); await this.enableResourceProviders('Microsoft.CognitiveServices');
await this.enableResourceProviders('Microsoft.BotService'); await this.enableResourceProviders('Microsoft.BotService');
@ -392,20 +393,20 @@ export class AzureDeployerService implements IGBInstallationDeployer {
await this.enableResourceProviders('Microsoft.Web'); await this.enableResourceProviders('Microsoft.Web');
await this.enableResourceProviders('Microsoft.Sql'); await this.enableResourceProviders('Microsoft.Sql');
GBLog.info(`Deploying Deploy Group (It may take a few minutes)...`); GBLogEx.info(0, `Deploying Deploy Group (It may take a few minutes)...`);
await this.createDeployGroup(name, instance.cloudLocation); await this.createDeployGroup(name, instance.cloudLocation);
let serverFarm; let serverFarm;
let serverName; let serverName;
if (process.env.DEPLOY_WEB) { if (process.env.DEPLOY_WEB) {
GBLog.info(`Deploying Bot Server...`); GBLogEx.info(0, `Deploying Bot Server...`);
serverFarm = await this.createHostingPlan(name, `${name}-server-plan`, instance.cloudLocation); serverFarm = await this.createHostingPlan(name, `${name}-server-plan`, instance.cloudLocation);
serverName = `${name}-server`; serverName = `${name}-server`;
await this.createServer(serverFarm.id, name, serverName, instance.cloudLocation); await this.createServer(serverFarm.id, name, serverName, instance.cloudLocation);
} }
GBLog.info(`Deploying Bot Storage...`); GBLogEx.info(0, `Deploying Bot Storage...`);
const administratorLogin = `sa${GBAdminService.getRndReadableIdentifier()}`; const administratorLogin = `sa${GBAdminService.getRndReadableIdentifier()}`;
const administratorPassword = GBAdminService.getRndPassword(); const administratorPassword = GBAdminService.getRndPassword();
const storageServer = `${name.toLowerCase()}-storage-server`; const storageServer = `${name.toLowerCase()}-storage-server`;
@ -426,7 +427,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
instance.storageServer = `${storageServer}.database.windows.net`; instance.storageServer = `${storageServer}.database.windows.net`;
// TODO: Enable in .env // TODO: Enable in .env
// GBLog.info(`Deploying Search...`); // GBLogEx.info(min, `Deploying Search...`);
// const searchName = `${name}-search`.toLowerCase(); // const searchName = `${name}-search`.toLowerCase();
// await this.createSearch(name, searchName, instance.cloudLocation); // await this.createSearch(name, searchName, instance.cloudLocation);
// const searchKeys = await this.searchClient.adminKeys.get(name, searchName); // const searchKeys = await this.searchClient.adminKeys.get(name, searchName);
@ -435,27 +436,27 @@ export class AzureDeployerService implements IGBInstallationDeployer {
// instance.searchIndexer = 'azuresql-indexer'; // instance.searchIndexer = 'azuresql-indexer';
// instance.searchKey = searchKeys.primaryKey; // instance.searchKey = searchKeys.primaryKey;
// GBLog.info(`Deploying Speech...`); // GBLogEx.info(min, `Deploying Speech...`);
// const speech = await this.createSpeech(name, `${name}speech`, instance.cloudLocation); // const speech = await this.createSpeech(name, `${name}speech`, instance.cloudLocation);
// keys = await this.cognitiveClient.accounts.listKeys(name, speech.name); // keys = await this.cognitiveClient.accounts.listKeys(name, speech.name);
// instance.speechEndpoint = speech.properties.endpoint; // instance.speechEndpoint = speech.properties.endpoint;
// instance.speechKey = keys.key1; // instance.speechKey = keys.key1;
// GBLog.info(`Deploying Text Analytics...`); // GBLogEx.info(min, `Deploying Text Analytics...`);
// const textAnalytics = await this.createTextAnalytics(name, `${name}-textanalytics`, instance.cloudLocation); // const textAnalytics = await this.createTextAnalytics(name, `${name}-textanalytics`, instance.cloudLocation);
// instance.textAnalyticsEndpoint = textAnalytics.properties.endpoint.replace(`/text/analytics/v2.0`, ''); // instance.textAnalyticsEndpoint = textAnalytics.properties.endpoint.replace(`/text/analytics/v2.0`, '');
GBLog.info(`Deploying SpellChecker...`); GBLogEx.info(0, `Deploying SpellChecker...`);
const spellChecker = await this.createSpellChecker(name, `${name}-spellchecker`); const spellChecker = await this.createSpellChecker(name, `${name}-spellchecker`);
instance.spellcheckerEndpoint = spellChecker.properties.endpoint; instance.spellcheckerEndpoint = spellChecker.properties.endpoint;
// GBLog.info(`Deploying NLP...`); // GBLogEx.info(min, `Deploying NLP...`);
// const nlp = await this.createNLP(name, `${name}-nlp`, instance.cloudLocation); // const nlp = await this.createNLP(name, `${name}-nlp`, instance.cloudLocation);
// const nlpa = await this.createNLPAuthoring(name, `${name}-nlpa`, instance.cloudLocation); // const nlpa = await this.createNLPAuthoring(name, `${name}-nlpa`, instance.cloudLocation);
// instance.nlpEndpoint = nlp.properties.endpoint; // instance.nlpEndpoint = nlp.properties.endpoint;
GBLog.info(`Deploying Bot...`); GBLogEx.info(0, `Deploying Bot...`);
instance.botEndpoint = 'TODO: remove this column.'; instance.botEndpoint = 'TODO: remove this column.';
instance = await this.internalDeployBot( instance = await this.internalDeployBot(
@ -474,7 +475,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
instance.cloudSubscriptionId instance.cloudSubscriptionId
); );
GBLog.info(`Waiting one minute to finish NLP service and keys creation...`); GBLogEx.info(0, `Waiting one minute to finish NLP service and keys creation...`);
await GBUtil.sleep(60000); await GBUtil.sleep(60000);
// keys = await this.cognitiveClient.accounts.listKeys(name, textAnalytics.name); // keys = await this.cognitiveClient.accounts.listKeys(name, textAnalytics.name);
// instance.textAnalyticsKey = keys.key1; // instance.textAnalyticsKey = keys.key1;
@ -489,7 +490,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
// instance.nlpAppId = nlpAppId; // instance.nlpAppId = nlpAppId;
if (process.env.DEPLOY_WEB) { if (process.env.DEPLOY_WEB) {
GBLog.info('Updating server environment variables...'); GBLogEx.info(0, 'Updating server environment variables...');
await this.updateWebisteConfig(name, serverName, serverFarm.id, instance); await this.updateWebisteConfig(name, serverName, serverFarm.id, instance);
} }
spinner.stop(); spinner.stop();
@ -656,7 +657,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
database = await this.storageClient.servers.beginCreateOrUpdateAndWait(group, name, params); database = await this.storageClient.servers.beginCreateOrUpdateAndWait(group, name, params);
} catch (error) { } catch (error) {
// Try again (MSFT issues). // Try again (MSFT issues).
GBLog.info('Storage (server) creation failed. Retrying...'); GBLogEx.info(0, 'Storage (server) creation failed. Retrying...');
database = await this.storageClient.servers.beginCreateOrUpdateAndWait(group, name, params); database = await this.storageClient.servers.beginCreateOrUpdateAndWait(group, name, params);
} }
@ -848,7 +849,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
} catch (error) { } catch (error) {
// Try again (MSFT issues). // Try again (MSFT issues).
GBLog.info('Storage (database) creation failed. Retrying...'); GBLogEx.info(0, 'Storage (database) creation failed. Retrying...');
database = await this.storageClient.databases.beginCreateOrUpdateAndWait(group, serverName, name, params); database = await this.storageClient.databases.beginCreateOrUpdateAndWait(group, serverName, name, params);
} }
return database; return database;
@ -966,11 +967,11 @@ export class AzureDeployerService implements IGBInstallationDeployer {
} catch (e) { } catch (e) {
if (!tryed) { if (!tryed) {
tryed = true; tryed = true;
GBLog.info('Retrying Deploying Bot Server...'); GBLogEx.info(0, 'Retrying Deploying Bot Server...');
try { try {
return await create(); return await create();
} catch (error) { } catch (error) {
GBLog.info('Server creation failed at all on MSAzure, stopping...'); GBLogEx.info(0, 'Server creation failed at all on MSAzure, stopping...');
throw error; throw error;
} }
} }

View file

@ -38,6 +38,7 @@ import Fs from 'fs';
import SwaggerClient from 'swagger-client'; import SwaggerClient from 'swagger-client';
import { spawn } from 'child_process'; import { spawn } from 'child_process';
import { CodeServices } from '../../gpt.gblib/services/CodeServices.js'; import { CodeServices } from '../../gpt.gblib/services/CodeServices.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
* Web Automation services of conversation to be called by BASIC. * Web Automation services of conversation to be called by BASIC.
@ -45,7 +46,7 @@ import { CodeServices } from '../../gpt.gblib/services/CodeServices.js';
export class DebuggerService { export class DebuggerService {
public async setBreakpoint({ botId, line }) { public async setBreakpoint({ botId, line }) {
GBLog.info(`BASIC: Enabled breakpoint for ${botId} on ${line}.`); GBLogEx.info(botId, `BASIC: Enabled breakpoint for ${botId} on ${line}.`);
GBServer.globals.debuggers[botId].breaks.push(Number.parseInt(line)); GBServer.globals.debuggers[botId].breaks.push(Number.parseInt(line));
} }
@ -112,7 +113,7 @@ export class DebuggerService {
if (activities.length) { if (activities.length) {
activities.forEach(activity => { activities.forEach(activity => {
messages.push({ text: activity.text }); messages.push({ text: activity.text });
GBLog.info(`Debugger sending text to API: ${activity.text}`); GBLogEx.info(botId, `Debugger sending text to API: ${activity.text}`);
}); });
} }
} }
@ -145,11 +146,11 @@ export class DebuggerService {
error = `Cannot DEBUG an already running process. ${botId}`; error = `Cannot DEBUG an already running process. ${botId}`;
return { error: error }; return { error: error };
} else if (GBServer.globals.debuggers[botId].state === 2) { } else if (GBServer.globals.debuggers[botId].state === 2) {
GBLog.info(`BASIC: Releasing execution ${botId} in DEBUG mode.`); GBLogEx.info(botId, `BASIC: Releasing execution ${botId} in DEBUG mode.`);
await this.resume({ botId }); await this.resume({ botId });
return { status: 'OK' }; return { status: 'OK' };
} else { } else {
GBLog.info(`BASIC: Running ${botId} in DEBUG mode.`); GBLogEx.info(botId, `BASIC: Running ${botId} in DEBUG mode.`);
GBServer.globals.debuggers[botId].state = 1; GBServer.globals.debuggers[botId].state = 1;
GBServer.globals.debuggers[botId].stateInfo = 'Running (Debug)'; GBServer.globals.debuggers[botId].stateInfo = 'Running (Debug)';

View file

@ -148,7 +148,7 @@ export class DialogKeywords {
const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName)); const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName));
GBLog.info(`BASIC: Visualization: Chart generated at ${url}.`); GBLogEx.info(min, `BASIC: Visualization: Chart generated at ${url}.`);
return url; return url;
} }
@ -157,8 +157,9 @@ export class DialogKeywords {
* Returns the OCR of image file. * Returns the OCR of image file.
* *
*/ */
public async getOCR({ localFile }) { public async getOCR({pid, localFile }) {
GBLog.info(`BASIC: OCR processing on ${localFile}.`); const { min, user } = await DialogKeywords.getProcessInfo(pid);
GBLogEx.info(min, `BASIC: OCR processing on ${localFile}.`);
const config = { const config = {
lang: 'eng', lang: 'eng',
@ -272,9 +273,9 @@ export class DialogKeywords {
); );
let dt = SystemKeywords.getDateFromLocaleString(pid, date, contentLocale); let dt = SystemKeywords.getDateFromLocaleString(pid, date, contentLocale);
GBLog.info(`BASIC WEEKDAY contentLocale: ${this.getContentLocaleWithCulture(contentLocale)}`); GBLogEx.info(min, `BASIC WEEKDAY contentLocale: ${this.getContentLocaleWithCulture(contentLocale)}`);
GBLog.info(`BASIC WEEKDAY date: ${dt}`); GBLogEx.info(min, `BASIC WEEKDAY date: ${dt}`);
GBLog.info(dt.toLocaleString(this.getContentLocaleWithCulture(contentLocale), { weekday: 'short' })); GBLogEx.info(min, dt.toLocaleString(this.getContentLocaleWithCulture(contentLocale), { weekday: 'short' }));
if (dt) { if (dt) {
if (!(dt instanceof Date)) { if (!(dt instanceof Date)) {
@ -527,14 +528,14 @@ export class DialogKeywords {
* *
*/ */
public async sendEmail({ pid, to, subject, body }) { public async sendEmail({ pid, to, subject, body }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
if (!body) { if (!body) {
body = ""; body = "";
}; };
// tslint:disable-next-line:no-console // tslint:disable-next-line:no-console
GBLog.info(`[E-mail]: to:${to},subject: ${subject},body: ${body}.`); GBLogEx.info(min, `[E-mail]: to:${to},subject: ${subject},body: ${body}.`);
const emailToken = process.env.EMAIL_API_KEY; const emailToken = process.env.EMAIL_API_KEY;
// Inline word document used as e-mail body. // Inline word document used as e-mail body.
@ -571,7 +572,7 @@ export class DialogKeywords {
*/ */
public async sendFileTo({ pid, mobile, filename, caption }) { public async sendFileTo({ pid, mobile, filename, caption }) {
const { min, user, proc } = await DialogKeywords.getProcessInfo(pid); const { min, user, proc } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: SEND FILE TO '${mobile}',filename '${filename}'.`); GBLogEx.info(min, `BASIC: SEND FILE TO '${mobile}',filename '${filename}'.`);
return await this.internalSendFile({ pid, mobile, channel: proc.channel, filename, caption }); return await this.internalSendFile({ pid, mobile, channel: proc.channel, filename, caption });
} }
@ -583,7 +584,7 @@ export class DialogKeywords {
*/ */
public async sendFile({ pid, filename, caption }) { public async sendFile({ pid, filename, caption }) {
const { min, user, proc } = await DialogKeywords.getProcessInfo(pid); const { min, user, proc } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: SEND FILE (to: ${user.userSystemId},filename '${filename}'.`); GBLogEx.info(min, `BASIC: SEND FILE (to: ${user.userSystemId},filename '${filename}'.`);
const mobile = await this.userMobile({ pid }); const mobile = await this.userMobile({ pid });
return await this.internalSendFile({ pid, channel: proc.channel, mobile, filename, caption }); return await this.internalSendFile({ pid, channel: proc.channel, mobile, filename, caption });
} }
@ -668,7 +669,7 @@ export class DialogKeywords {
// throw new Error(`Not possible to define ${name} as it is a reserved system param name.`); // throw new Error(`Not possible to define ${name} as it is a reserved system param name.`);
// } // }
let { min, user, params } = await DialogKeywords.getProcessInfo(pid); let { min, user, params } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: ${name} = ${value} (botId: ${min.botId})`); GBLogEx.info(min, `BASIC: ${name} = ${value} (botId: ${min.botId})`);
const sec = new SecService(); const sec = new SecService();
if (user) { if (user) {
await sec.setParam(user.userId, name, value); await sec.setParam(user.userId, name, value);
@ -931,9 +932,9 @@ export class DialogKeywords {
await this.talk({ pid: pid, text: button }); await this.talk({ pid: pid, text: button });
} }
GBLog.info(`BASIC: HEAR with [${args.toString()}] (Asking for input).`); GBLogEx.info(min, `BASIC: HEAR with [${args.toString()}] (Asking for input).`);
} else { } else {
GBLog.info('BASIC: HEAR (Asking for input).'); GBLogEx.info(min, 'BASIC: HEAR (Asking for input).');
} }
// Wait for the user to answer. // Wait for the user to answer.
@ -966,7 +967,7 @@ export class DialogKeywords {
return m.name === args; return m.name === args;
}); });
if (document === undefined || document.length === 0) { if (document === undefined || document.length === 0) {
GBLog.info(`${args} not found on .gbdata folder, check the package.`); GBLogEx.info(min, `${args} not found on .gbdata folder, check the package.`);
return null; return null;
} }
@ -1007,7 +1008,7 @@ export class DialogKeywords {
return await this.hear({ pid, kind, args }); return await this.hear({ pid, kind, args });
} }
} else if (kind === 'file') { } else if (kind === 'file') {
GBLog.info(`BASIC (${min.botId}): Upload done for ${answer.filename}.`); GBLogEx.info(min, `BASIC (${min.botId}): Upload done for ${answer.filename}.`);
const handle = WebAutomationServices.cyrb53({ pid, str: min.botId + answer.filename }); const handle = WebAutomationServices.cyrb53({ pid, str: min.botId + answer.filename });
GBServer.globals.files[handle] = answer; GBServer.globals.files[handle] = answer;
result = handle; result = handle;
@ -1128,7 +1129,7 @@ export class DialogKeywords {
result = phoneNumber; result = phoneNumber;
} else if (kind === 'qr-scanner') { } else if (kind === 'qr-scanner') {
//https://github.com/GeneralBots/BotServer/issues/171 //https://github.com/GeneralBots/BotServer/issues/171
GBLog.info(`BASIC (${min.botId}): Upload done for ${answer.filename}.`); GBLogEx.info(min, `BASIC (${min.botId}): Upload done for ${answer.filename}.`);
const handle = WebAutomationServices.cyrb53({ pid, str: min.botId + answer.filename }); const handle = WebAutomationServices.cyrb53({ pid, str: min.botId + answer.filename });
GBServer.globals.files[handle] = answer; GBServer.globals.files[handle] = answer;
QrScanner.scanImage(GBServer.globals.files[handle]) QrScanner.scanImage(GBServer.globals.files[handle])
@ -1272,7 +1273,7 @@ export class DialogKeywords {
}); });
let messages = []; let messages = [];
GBLog.info(`MessageBot: Starting message polling ${conversation.conversationId}).`); GBLogEx.info(min, `MessageBot: Starting message polling ${conversation.conversationId}).`);
let count = API_RETRIES; let count = API_RETRIES;
while (count--) { while (count--) {
@ -1367,7 +1368,7 @@ export class DialogKeywords {
*/ */
public async talk({ pid, text }) { public async talk({ pid, text }) {
const { min, user, step } = await DialogKeywords.getProcessInfo(pid); const { min, user, step } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: TALK '${text} step:${step}'.`); GBLogEx.info(min, `BASIC: TALK '${text} step:${step}'.`);
if (user) { if (user) {
// TODO: const translate = user ? user.basicOptions.translatorOn : false; // TODO: const translate = user ? user.basicOptions.translatorOn : false;
@ -1415,7 +1416,7 @@ export class DialogKeywords {
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName)); url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName));
GBLog.info(`BASIC: WebAutomation: Sending ${url} to ${mobile} (${channel}).`); GBLogEx.info(min, `BASIC: WebAutomation: Sending ${url} to ${mobile} (${channel}).`);
} }
// GBFILE object. // GBFILE object.
@ -1424,17 +1425,17 @@ export class DialogKeywords {
url = filename.url; url = filename.url;
nameOnly = Path.basename(filename.localName); nameOnly = Path.basename(filename.localName);
GBLog.info(`BASIC: Sending the GBFILE ${url} to ${mobile} (${channel}).`); GBLogEx.info(min, `BASIC: Sending the GBFILE ${url} to ${mobile} (${channel}).`);
} }
// Handles Markdown. // Handles Markdown.
else if (filename.indexOf('.md') !== -1) { else if (filename.indexOf('.md') !== -1) {
GBLog.info(`BASIC: Sending the contents of ${filename} markdown to mobile ${mobile}.`); GBLogEx.info(min, `BASIC: Sending the contents of ${filename} markdown to mobile ${mobile}.`);
const md = await min.kbService.getAnswerTextByMediaName(min.instance.instanceId, filename); const md = await min.kbService.getAnswerTextByMediaName(min.instance.instanceId, filename);
if (!md) { if (!md) {
GBLog.info(`BASIC: Markdown file ${filename} not found on database for ${min.instance.botId}.`); GBLogEx.info(min, `BASIC: Markdown file ${filename} not found on database for ${min.instance.botId}.`);
} }
await min.conversationalService['playMarkdown'](min, md, DialogKeywords.getChannel(), null, mobile); await min.conversationalService['playMarkdown'](min, md, DialogKeywords.getChannel(), null, mobile);
@ -1452,7 +1453,7 @@ export class DialogKeywords {
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
const fileUrl = urlJoin('/', gbaiName, `${min.botId}.gbdrive`, filename); const fileUrl = urlJoin('/', gbaiName, `${min.botId}.gbdrive`, filename);
GBLog.info(`BASIC: Direct send from .gbdrive: ${fileUrl} to ${mobile}.`); GBLogEx.info(min, `BASIC: Direct send from .gbdrive: ${fileUrl} to ${mobile}.`);
const sys = new SystemKeywords(); const sys = new SystemKeywords();

View file

@ -329,7 +329,7 @@ export class GBVMService extends GBService {
const logging: boolean | Function = const logging: boolean | Function =
GBConfigService.get('STORAGE_LOGGING') === 'true' GBConfigService.get('STORAGE_LOGGING') === 'true'
? (str: string): void => { ? (str: string): void => {
GBLog.info(str); GBLogEx.info(min, str);
} }
: false; : false;

View file

@ -41,6 +41,7 @@ import { CollectionUtil } from 'pragmatismo-io-framework';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js'; import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
import { GBServer } from '../../../src/app.js'; import { GBServer } from '../../../src/app.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
* Image processing services of conversation to be called by BASIC. * Image processing services of conversation to be called by BASIC.
@ -52,7 +53,8 @@ export class ImageProcessingServices {
* @example file = SHARPEN file * @example file = SHARPEN file
*/ */
public async sharpen({ pid, file: file }) { public async sharpen({ pid, file: file }) {
GBLog.info(`BASIC: Image Processing SHARPEN ${file}.`); const { min, user } = await DialogKeywords.getProcessInfo(pid);
GBLogEx.info(min, `BASIC: Image Processing SHARPEN ${file}.`);
const gbfile = DialogKeywords.getFileByHandle(file); const gbfile = DialogKeywords.getFileByHandle(file);
const data = await sharp(gbfile.data) const data = await sharp(gbfile.data)
@ -106,7 +108,8 @@ export class ImageProcessingServices {
* @example file = BLUR file * @example file = BLUR file
*/ */
public async blur({ pid, file: file }) { public async blur({ pid, file: file }) {
GBLog.info(`BASIC: Image Processing SHARPEN ${file}.`); const { min, user } = await DialogKeywords.getProcessInfo(pid);
GBLogEx.info(min, `BASIC: Image Processing SHARPEN ${file}.`);
const gbfile = DialogKeywords.getFileByHandle(file); const gbfile = DialogKeywords.getFileByHandle(file);
const data = await sharp(gbfile.data) const data = await sharp(gbfile.data)

View file

@ -119,7 +119,7 @@ export class SystemKeywords {
'Default Content Language', 'Default Content Language',
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE') GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
); );
GBLog.info(`GBVision (caption): '${caption.text}' (Confidence: ${caption.confidence.toFixed(2)})`); GBLogEx.info(min, `GBVision (caption): '${caption.text}' (Confidence: ${caption.confidence.toFixed(2)})`);
return await min.conversationalService.translate(min, caption.text, contentLocale); return await min.conversationalService.translate(min, caption.text, contentLocale);
} }
@ -130,6 +130,7 @@ export class SystemKeywords {
* *
*/ */
public async seeText({ pid, url }) { public async seeText({ pid, url }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const computerVisionClient = new ComputerVisionClient.ComputerVisionClient( const computerVisionClient = new ComputerVisionClient.ComputerVisionClient(
new ApiKeyCredentials.ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': process.env.VISION_KEY } }), new ApiKeyCredentials.ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': process.env.VISION_KEY } }),
process.env.VISION_ENDPOINT process.env.VISION_ENDPOINT
@ -151,7 +152,7 @@ export class SystemKeywords {
} }
} }
GBLog.info(`GBVision (text): '${final}'`); GBLogEx.info(min, `GBVision (text): '${final}'`);
return final; return final;
} }
@ -323,7 +324,7 @@ export class SystemKeywords {
localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.png`); localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.png`);
await page.screenshot({ path: localName, fullPage: true }); await page.screenshot({ path: localName, fullPage: true });
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName)); url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName));
GBLog.info(`BASIC: Table image generated at ${url} .`); GBLogEx.info(min, `BASIC: Table image generated at ${url} .`);
} }
// Handles PDF generation. // Handles PDF generation.
@ -332,7 +333,7 @@ export class SystemKeywords {
localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.pdf`); localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.pdf`);
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName)); url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName));
let pdf = await page.pdf({ format: 'A4' }); let pdf = await page.pdf({ format: 'A4' });
GBLog.info(`BASIC: Table PDF generated at ${url} .`); GBLogEx.info(min, `BASIC: Table PDF generated at ${url} .`);
} }
await browser.close(); await browser.close();
@ -466,8 +467,9 @@ export class SystemKeywords {
* *
*/ */
public async wait({ pid, seconds }) { public async wait({ pid, seconds }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
// tslint:disable-next-line no-string-based-set-timeout // tslint:disable-next-line no-string-based-set-timeout
GBLog.info(`BASIC: WAIT for ${seconds} second(s).`); GBLogEx.info(min, `BASIC: WAIT for ${seconds} second(s).`);
const timeout = async (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); const timeout = async (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
await timeout(seconds * 1000); await timeout(seconds * 1000);
} }
@ -480,7 +482,7 @@ export class SystemKeywords {
*/ */
public async talkTo({ pid, mobile, message }) { public async talkTo({ pid, mobile, message }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid); const { min, user } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: Talking '${message}' to a specific user (${mobile}) (TALK TO). `); GBLogEx.info(min, `BASIC: Talking '${message}' to a specific user (${mobile}) (TALK TO). `);
await min.conversationalService.sendMarkdownToMobile(min, null, mobile, message); await min.conversationalService.sendMarkdownToMobile(min, null, mobile, message);
} }
@ -506,7 +508,7 @@ export class SystemKeywords {
*/ */
public async sendSmsTo({ pid, mobile, message }) { public async sendSmsTo({ pid, mobile, message }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid); const { min, user } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: SEND SMS TO '${mobile}', message '${message}'.`); GBLogEx.info(min, `BASIC: SEND SMS TO '${mobile}', message '${message}'.`);
await min.conversationalService.sendSms(min, mobile, message); await min.conversationalService.sendSms(min, mobile, message);
} }
@ -525,7 +527,7 @@ export class SystemKeywords {
// Handles calls for HTML stuff // Handles calls for HTML stuff
if (handle && WebAutomationServices.isSelector(file)) { if (handle && WebAutomationServices.isSelector(file)) {
GBLog.info(`BASIC: Web automation SET ${file}' to '${address}' . `); GBLogEx.info(min, `BASIC: Web automation SET ${file}' to '${address}' . `);
await new WebAutomationServices().setElementText({ pid, handle, selector: file, text: address }); await new WebAutomationServices().setElementText({ pid, handle, selector: file, text: address });
return; return;
@ -543,7 +545,7 @@ export class SystemKeywords {
// Handles calls for BASIC persistence on sheet files. // Handles calls for BASIC persistence on sheet files.
GBLog.info(`BASIC: Defining '${address}' in '${file}' to '${value}' (SET). `); GBLogEx.info(min, `BASIC: Defining '${address}' in '${file}' to '${value}' (SET). `);
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
@ -630,7 +632,7 @@ export class SystemKeywords {
*/ */
public async saveFile({ pid, file, data }): Promise<any> { public async saveFile({ pid, file, data }): Promise<any> {
const { min, user } = await DialogKeywords.getProcessInfo(pid); const { min, user } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: Saving '${file}' (SAVE file).`); GBLogEx.info(min, `BASIC: Saving '${file}' (SAVE file).`);
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
const botId = min.instance.botId; const botId = min.instance.botId;
const path = DialogKeywords.getGBAIPath(min.botId, `gbdrive`); const path = DialogKeywords.getGBAIPath(min.botId, `gbdrive`);
@ -646,9 +648,9 @@ export class SystemKeywords {
await client.api(`${baseUrl}/drive/root:/${path}/${file}:/content`).put(data); await client.api(`${baseUrl}/drive/root:/${path}/${file}:/content`).put(data);
} catch (error) { } catch (error) {
if (error.code === 'itemNotFound') { if (error.code === 'itemNotFound') {
GBLog.info(`BASIC: BASIC source file not found: ${file}.`); GBLogEx.info(min, `BASIC: BASIC source file not found: ${file}.`);
} else if (error.code === 'nameAlreadyExists') { } else if (error.code === 'nameAlreadyExists') {
GBLog.info(`BASIC: BASIC destination file already exists: ${file}.`); GBLogEx.info(min, `BASIC: BASIC destination file already exists: ${file}.`);
} }
throw error; throw error;
} }
@ -664,7 +666,7 @@ export class SystemKeywords {
*/ */
public async uploadFile({ pid, file }): Promise<any> { public async uploadFile({ pid, file }): Promise<any> {
const { min, user } = await DialogKeywords.getProcessInfo(pid); const { min, user } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: UPLOAD '${file.name}' ${file.size} bytes.`); GBLogEx.info(min, `BASIC: UPLOAD '${file.name}' ${file.size} bytes.`);
// Checks if it is a GB FILE object. // Checks if it is a GB FILE object.
@ -741,7 +743,7 @@ export class SystemKeywords {
*/ */
public async saveToStorageBatch({ pid, table, rows }): Promise<void> { public async saveToStorageBatch({ pid, table, rows }): Promise<void> {
const { min } = await DialogKeywords.getProcessInfo(pid); const { min } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: Saving batch to storage '${table}' (SAVE).`); GBLogEx.info(min, `BASIC: Saving batch to storage '${table}' (SAVE).`);
if (rows.length === 0) { if (rows.length === 0) {
@ -789,7 +791,7 @@ export class SystemKeywords {
} }
const { min } = await DialogKeywords.getProcessInfo(pid); const { min } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: Saving to storage '${table}' (SAVE).`); GBLogEx.info(min, `BASIC: Saving to storage '${table}' (SAVE).`);
const definition = this.getTableFromName(table, min); const definition = this.getTableFromName(table, min);
@ -820,8 +822,8 @@ export class SystemKeywords {
} }
public async saveToStorageWithJSON({ pid, table, fieldsValues, fieldsNames }): Promise<any> { public async saveToStorageWithJSON({ pid, table, fieldsValues, fieldsNames }): Promise<any> {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: Saving to storage '${table}' (SAVE).`); GBLogEx.info(min, `BASIC: Saving to storage '${table}' (SAVE).`);
const minBoot = GBServer.globals.minBoot as any; const minBoot = GBServer.globals.minBoot as any;
const definition = minBoot.core.sequelize.models[table]; const definition = minBoot.core.sequelize.models[table];
@ -855,7 +857,7 @@ export class SystemKeywords {
} }
const { min } = await DialogKeywords.getProcessInfo(pid); const { min } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: Saving '${file}' (SAVE). Args: ${args.join(',')}.`); GBLogEx.info(min, `BASIC: Saving '${file}' (SAVE). Args: ${args.join(',')}.`);
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
const botId = min.instance.botId; const botId = min.instance.botId;
const path = DialogKeywords.getGBAIPath(botId, 'gbdata'); const path = DialogKeywords.getGBAIPath(botId, 'gbdata');
@ -956,7 +958,7 @@ export class SystemKeywords {
qs qs
}); });
} else { } else {
GBLog.info(`BASIC: GET '${addressOrHeaders}' in '${file}'.`); GBLogEx.info(min, `BASIC: GET '${addressOrHeaders}' in '${file}'.`);
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
const botId = min.instance.botId; const botId = min.instance.botId;
(''); ('');
@ -975,7 +977,7 @@ export class SystemKeywords {
.get(); .get();
let val = results.text[0][0]; let val = results.text[0][0];
GBLog.info(`BASIC: Getting '${file}' (GET). Value= ${val}.`); GBLogEx.info(min, `BASIC: Getting '${file}' (GET). Value= ${val}.`);
return val; return val;
} }
} }
@ -1072,7 +1074,7 @@ export class SystemKeywords {
} else { } else {
maxLines = maxLines; maxLines = maxLines;
} }
GBLog.info(`BASIC: FIND running on ${file} (maxLines: ${maxLines}) and args: ${JSON.stringify(args)}...`); GBLogEx.info(min, `BASIC: FIND running on ${file} (maxLines: ${maxLines}) and args: ${JSON.stringify(args)}...`);
// Choose data sources based on file type (HTML Table, data variable or sheet file) // Choose data sources based on file type (HTML Table, data variable or sheet file)
@ -1246,7 +1248,7 @@ export class SystemKeywords {
case 'string': case 'string':
const v1 = GBConversationalService.removeDiacritics(result.toLowerCase().trim()); const v1 = GBConversationalService.removeDiacritics(result.toLowerCase().trim());
const v2 = GBConversationalService.removeDiacritics(filter.value.toLowerCase().trim()); const v2 = GBConversationalService.removeDiacritics(filter.value.toLowerCase().trim());
GBLog.info(`FIND filter: ${v1} ${filter.operator} ${v2}.`); GBLogEx.info(min, `FIND filter: ${v1} ${filter.operator} ${v2}.`);
switch (filter.operator) { switch (filter.operator) {
case '=': case '=':
@ -1365,13 +1367,13 @@ export class SystemKeywords {
const outputArray = await DialogKeywords.getOption({ pid, name: 'output' }); const outputArray = await DialogKeywords.getOption({ pid, name: 'output' });
if (table.length === 1) { if (table.length === 1) {
GBLog.info(`BASIC: FIND returned no results (zero rows).`); GBLogEx.info(min, `BASIC: FIND returned no results (zero rows).`);
return null; return null;
} else if (table.length === 2 && !outputArray) { } else if (table.length === 2 && !outputArray) {
GBLog.info(`BASIC: FIND returned single result: ${table[0]}.`); GBLogEx.info(min, `BASIC: FIND returned single result: ${table[0]}.`);
return table[1]; return table[1];
} else { } else {
GBLog.info(`BASIC: FIND returned multiple results (Count): ${table.length - 1}.`); GBLogEx.info(min, `BASIC: FIND returned multiple results (Count): ${table.length - 1}.`);
return table; return table;
} }
} }
@ -1532,7 +1534,7 @@ export class SystemKeywords {
} }
public async internalCreateDocument(min, path, content) { public async internalCreateDocument(min, path, content) {
GBLog.info(`BASIC: CREATE DOCUMENT '${path}...'`); GBLogEx.info(min, `BASIC: CREATE DOCUMENT '${path}...'`);
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
const gbaiName = DialogKeywords.getGBAIPath(min.botId); const gbaiName = DialogKeywords.getGBAIPath(min.botId);
const tmpDocx = urlJoin(gbaiName, path); const tmpDocx = urlJoin(gbaiName, path);
@ -1568,7 +1570,7 @@ export class SystemKeywords {
*/ */
public async copyFile({ pid, src, dest }) { public async copyFile({ pid, src, dest }) {
const { min, user, params } = await DialogKeywords.getProcessInfo(pid); const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: BEGINING COPY '${src}' to '${dest}'`); GBLogEx.info(min, `BASIC: BEGINING COPY '${src}' to '${dest}'`);
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
const botId = min.instance.botId; const botId = min.instance.botId;
@ -1604,13 +1606,13 @@ export class SystemKeywords {
name: `${Path.basename(dest)}` name: `${Path.basename(dest)}`
}; };
const file = await client.api(`${baseUrl}/drive/items/${srcFile.id}/copy`).post(destFile); const file = await client.api(`${baseUrl}/drive/items/${srcFile.id}/copy`).post(destFile);
GBLog.info(`BASIC: FINISHED COPY '${src}' to '${dest}'`); GBLogEx.info(min, `BASIC: FINISHED COPY '${src}' to '${dest}'`);
return file; return file;
} catch (error) { } catch (error) {
if (error.code === 'itemNotFound') { if (error.code === 'itemNotFound') {
GBLog.info(`BASIC: COPY source file not found: ${srcPath}.`); GBLogEx.info(min, `BASIC: COPY source file not found: ${srcPath}.`);
} else if (error.code === 'nameAlreadyExists') { } else if (error.code === 'nameAlreadyExists') {
GBLog.info(`BASIC: COPY destination file already exists: ${dstPath}.`); GBLogEx.info(min, `BASIC: COPY destination file already exists: ${dstPath}.`);
} }
throw error; throw error;
} }
@ -1630,7 +1632,7 @@ export class SystemKeywords {
public async convert({ pid, src, dest }) { public async convert({ pid, src, dest }) {
const { min, user, params } = await DialogKeywords.getProcessInfo(pid); const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: CONVERT '${src}' to '${dest}'`); GBLogEx.info(min, `BASIC: CONVERT '${src}' to '${dest}'`);
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
const botId = min.instance.botId; const botId = min.instance.botId;
@ -1676,9 +1678,9 @@ export class SystemKeywords {
await client.api(`${baseUrl}/drive/root:/${dstPath}:/content`).put(result); await client.api(`${baseUrl}/drive/root:/${dstPath}:/content`).put(result);
} catch (error) { } catch (error) {
if (error.code === 'itemNotFound') { if (error.code === 'itemNotFound') {
GBLog.info(`BASIC: CONVERT source file not found: ${srcPath}.`); GBLogEx.info(min, `BASIC: CONVERT source file not found: ${srcPath}.`);
} else if (error.code === 'nameAlreadyExists') { } else if (error.code === 'nameAlreadyExists') {
GBLog.info(`BASIC: CONVERT destination file already exists: ${dstPath}.`); GBLogEx.info(min, `BASIC: CONVERT destination file already exists: ${dstPath}.`);
} }
throw error; throw error;
} }
@ -1780,17 +1782,17 @@ export class SystemKeywords {
if (result.status === 401) { if (result.status === 401) {
GBLog.info(`Waiting 5 secs. before retrynig HTTP 401 GET: ${url}`); GBLogEx.info(min, `Waiting 5 secs. before retrynig HTTP 401 GET: ${url}`);
await GBUtil.sleep(5 * 1000); await GBUtil.sleep(5 * 1000);
throw new Error(`BASIC: HTTP:${result.status} retry: ${result.statusText}.`); throw new Error(`BASIC: HTTP:${result.status} retry: ${result.statusText}.`);
} }
if (result.status === 429) { if (result.status === 429) {
GBLog.info(`Waiting 1min. before retrying HTTP 429 GET: ${url}`); GBLogEx.info(min, `Waiting 1min. before retrying HTTP 429 GET: ${url}`);
await GBUtil.sleep(60 * 1000); await GBUtil.sleep(60 * 1000);
throw new Error(`BASIC: HTTP:${result.status} retry: ${result.statusText}.`); throw new Error(`BASIC: HTTP:${result.status} retry: ${result.statusText}.`);
} }
if (result.status === 503) { if (result.status === 503) {
GBLog.info(`Waiting 1h before retrynig GET 503: ${url}`); GBLogEx.info(min, `Waiting 1h before retrynig GET 503: ${url}`);
await GBUtil.sleep(60 * 60 * 1000); await GBUtil.sleep(60 * 60 * 1000);
throw new Error(`BASIC: HTTP:${result.status} retry: ${result.statusText}.`); throw new Error(`BASIC: HTTP:${result.status} retry: ${result.statusText}.`);
} }
@ -1841,7 +1843,7 @@ export class SystemKeywords {
continuationToken = res.next?.headers['MS-ContinuationToken']; continuationToken = res.next?.headers['MS-ContinuationToken'];
if (continuationToken) { if (continuationToken) {
GBLog.info(`Updating continuationToken for ${url}.`); GBLogEx.info(min, `Updating continuationToken for ${url}.`);
await DialogKeywords.setOption({ pid, name: 'continuationToken', value: continuationToken }); await DialogKeywords.setOption({ pid, name: 'continuationToken', value: continuationToken });
} }
} }
@ -1865,6 +1867,7 @@ export class SystemKeywords {
* *
*/ */
public async putByHttp({ pid, url, data, headers }) { public async putByHttp({ pid, url, data, headers }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const options = { const options = {
json: data, json: data,
headers: headers, headers: headers,
@ -1881,7 +1884,7 @@ export class SystemKeywords {
let result = await fetch(url, options); let result = await fetch(url, options);
const text = await result.text(); const text = await result.text();
GBLog.info(`BASIC: PUT ${url} (${data}): ${text}`); GBLogEx.info(min, `BASIC: PUT ${url} (${data}): ${text}`);
if (result.status != 200 && result.status != 201) { if (result.status != 200 && result.status != 201) {
throw new Error(`BASIC: PUT ${result.status}: ${result.statusText}.`) throw new Error(`BASIC: PUT ${result.status}: ${result.statusText}.`)
@ -1901,6 +1904,7 @@ export class SystemKeywords {
* *
*/ */
public async postByHttp({ pid, url, data, headers }) { public async postByHttp({ pid, url, data, headers }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const options = { const options = {
headers: headers, headers: headers,
method: 'POST' method: 'POST'
@ -1916,7 +1920,7 @@ export class SystemKeywords {
let result = await fetch(url, options); let result = await fetch(url, options);
const text = await result.text(); const text = await result.text();
GBLog.info(`BASIC: POST ${url} (${data}): ${text}`); GBLogEx.info(min, `BASIC: POST ${url} (${data}): ${text}`);
if (result.status != 200 && result.status != 201) { if (result.status != 200 && result.status != 201) {
throw new Error(`BASIC: POST ${result.status}: ${result.statusText}.`) throw new Error(`BASIC: POST ${result.status}: ${result.statusText}.`)
@ -2159,19 +2163,18 @@ export class SystemKeywords {
* *
*/ */
public async merge({ pid, file, data, key1, key2 }): Promise<any> { public async merge({ pid, file, data, key1, key2 }): Promise<any> {
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
if (!data || data.length === 0) { if (!data || data.length === 0) {
GBLog.verbose(`BASIC: MERGE running on ${file}: NO DATA.`); GBLog.verbose(`BASIC: MERGE running on ${file}: NO DATA.`);
return data; return data;
} }
GBLog.info(`BASIC: MERGE running on ${file} and key1: ${key1}, key2: ${key2}...`); GBLogEx.info(min, `BASIC: MERGE running on ${file} and key1: ${key1}, key2: ${key2}...`);
if (!this.cachedMerge[pid]) { if (!this.cachedMerge[pid]) {
this.cachedMerge[pid] = { file: {} } this.cachedMerge[pid] = { file: {} }
} }
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
// Check if is a tree or flat object. // Check if is a tree or flat object.
@ -2237,7 +2240,7 @@ export class SystemKeywords {
page++; page++;
count = paged.length; count = paged.length;
GBLog.info(`BASIC: MERGE cached: ${rows.length} from page: ${page}.`); GBLogEx.info(min, `BASIC: MERGE cached: ${rows.length} from page: ${page}.`);
} }
}, },
@ -2475,7 +2478,7 @@ export class SystemKeywords {
await this.saveToStorageBatch({ pid, table: file, rows: fieldsValuesList }); await this.saveToStorageBatch({ pid, table: file, rows: fieldsValuesList });
} }
GBLog.info(`BASIC: MERGE results: adds:${adds}, updates:${updates} , skipped: ${skipped}.`); GBLogEx.info(min, `BASIC: MERGE results: adds:${adds}, updates:${updates} , skipped: ${skipped}.`);
return { title:file, adds, updates, skipped }; return { title:file, adds, updates, skipped };
} }
@ -2493,7 +2496,7 @@ export class SystemKeywords {
const access_token_secret = min.core.getParam(min.instance, 'Twitter Access Token Secret', null); const access_token_secret = min.core.getParam(min.instance, 'Twitter Access Token Secret', null);
if (!consumer_key || !consumer_secret || !access_token_key || !access_token_secret) { if (!consumer_key || !consumer_secret || !access_token_key || !access_token_secret) {
GBLog.info('Twitter not configured in .gbot.'); GBLogEx.info(min, 'Twitter not configured in .gbot.');
} }
const client = new TwitterApi({ const client = new TwitterApi({
@ -2504,7 +2507,7 @@ export class SystemKeywords {
}); });
await client.v2.tweet(text); await client.v2.tweet(text);
GBLog.info(`Twitter Automation: ${text}.`); GBLogEx.info(min, `Twitter Automation: ${text}.`);
} }
/** /**
@ -2516,7 +2519,7 @@ export class SystemKeywords {
const { min, user } = await DialogKeywords.getProcessInfo(pid); const { min, user } = await DialogKeywords.getProcessInfo(pid);
const prompt = `rewrite this sentence in a better way: ${text}`; const prompt = `rewrite this sentence in a better way: ${text}`;
const answer = await ChatServices.continue(min, prompt, 0); const answer = await ChatServices.continue(min, prompt, 0);
GBLog.info(`BASIC: REWRITE ${text} TO ${answer}`); GBLogEx.info(min, `BASIC: REWRITE ${text} TO ${answer}`);
return answer; return answer;
} }
@ -2541,7 +2544,7 @@ export class SystemKeywords {
const apiUrl = 'https://apisandbox.cieloecommerce.cielo.com.br/1/sales/'; const apiUrl = 'https://apisandbox.cieloecommerce.cielo.com.br/1/sales/';
const requestId = GBAdminService.generateUuid(); const requestId = GBAdminService.generateUuid();
GBLog.info(`GBPay: ${requestId}, ${orderId}, ${ammount}... `); GBLogEx.info(min, `GBPay: ${requestId}, ${orderId}, ${ammount}... `);
const requestData = { const requestData = {
MerchantOrderId: orderId, MerchantOrderId: orderId,
@ -2580,7 +2583,7 @@ export class SystemKeywords {
Fs.writeFileSync(localName, buf, { encoding: null }); Fs.writeFileSync(localName, buf, { encoding: null });
const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName)); const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName));
GBLog.info(`GBPay: ${data.MerchantOrderId} OK: ${url}.`); GBLogEx.info(min, `GBPay: ${data.MerchantOrderId} OK: ${url}.`);
return { return {
name: Path.basename(localName), name: Path.basename(localName),
@ -2603,7 +2606,7 @@ export class SystemKeywords {
private async internalAutoSave({ min, handle }) { private async internalAutoSave({ min, handle }) {
const file = GBServer.globals.files[handle]; const file = GBServer.globals.files[handle];
GBLog.info(`BASIC: Auto saving '${file.filename}' (SAVE file).`); GBLogEx.info(min, `BASIC: Auto saving '${file.filename}' (SAVE file).`);
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
const path = DialogKeywords.getGBAIPath(min.botId, `gbdrive`); const path = DialogKeywords.getGBAIPath(min.botId, `gbdrive`);
@ -2627,7 +2630,7 @@ export class SystemKeywords {
public async deleteFromStorage({ pid, table, criteria }) { public async deleteFromStorage({ pid, table, criteria }) {
const { min } = await DialogKeywords.getProcessInfo(pid); const { min } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: DELETE (storage) '${table}' where ${criteria}.`); GBLogEx.info(min, `BASIC: DELETE (storage) '${table}' where ${criteria}.`);
const definition = this.getTableFromName(table, min); const definition = this.getTableFromName(table, min);
const filter = await SystemKeywords.getFilter(criteria); const filter = await SystemKeywords.getFilter(criteria);
@ -2651,7 +2654,7 @@ export class SystemKeywords {
public async deleteFile({ pid, file }) { public async deleteFile({ pid, file }) {
const { min } = await DialogKeywords.getProcessInfo(pid); const { min } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: DELETE '${file.name}'.`); GBLogEx.info(min, `BASIC: DELETE '${file.name}'.`);
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min); let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
const gbaiPath = DialogKeywords.getGBAIPath(min.botId); const gbaiPath = DialogKeywords.getGBAIPath(min.botId);

View file

@ -215,9 +215,11 @@ export class WebAutomationServices {
* *
* @example GET page,"frameSelector,"elementSelector" * @example GET page,"frameSelector,"elementSelector"
*/ */
public async getByFrame({ handle, frame, selector }) { public async getByFrame({pid, handle, frame, selector }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const page = WebAutomationServices.getPageByHandle(handle); const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation GET element by frame: ${selector}.`); GBLogEx.info(min, `BASIC: Web Automation GET element by frame: ${selector}.`);
await page.waitForSelector(frame); await page.waitForSelector(frame);
let frameHandle = await page.$(frame); let frameHandle = await page.$(frame);
const f = await frameHandle.contentFrame(); const f = await frameHandle.contentFrame();
@ -236,8 +238,10 @@ export class WebAutomationServices {
* Simulates a mouse hover an web page element. * Simulates a mouse hover an web page element.
*/ */
public async hover({ pid, handle, selector }) { public async hover({ pid, handle, selector }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const page = WebAutomationServices.getPageByHandle(handle); const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation HOVER element: ${selector}.`); GBLogEx.info(min, `BASIC: Web Automation HOVER element: ${selector}.`);
await this.getBySelector({ handle, selector: selector, pid }); await this.getBySelector({ handle, selector: selector, pid });
await page.hover(selector); await page.hover(selector);
await this.debugStepWeb(pid, page); await this.debugStepWeb(pid, page);
@ -249,8 +253,10 @@ export class WebAutomationServices {
* @example CLICK "#idElement" * @example CLICK "#idElement"
*/ */
public async click({ pid, handle, frameOrSelector, selector }) { public async click({ pid, handle, frameOrSelector, selector }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const page = WebAutomationServices.getPageByHandle(handle); const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation CLICK element: ${frameOrSelector}.`); GBLogEx.info(min, `BASIC: Web Automation CLICK element: ${frameOrSelector}.`);
if (selector) { if (selector) {
await page.waitForSelector(frameOrSelector); await page.waitForSelector(frameOrSelector);
let frameHandle = await page.$(frameOrSelector); let frameHandle = await page.$(frameOrSelector);
@ -289,9 +295,11 @@ export class WebAutomationServices {
* *
* @example PRESS ENTER ON page * @example PRESS ENTER ON page
*/ */
public async pressKey({ handle, char, frame }) { public async pressKey({pid, handle, char, frame }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const page = WebAutomationServices.getPageByHandle(handle); const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation PRESS ${char} ON element: ${frame}.`); GBLogEx.info(min, `BASIC: Web Automation PRESS ${char} ON element: ${frame}.`);
if (char.toLowerCase() === 'enter') { if (char.toLowerCase() === 'enter') {
char = '\n'; char = '\n';
} }
@ -306,8 +314,10 @@ export class WebAutomationServices {
} }
public async linkByText({ pid, handle, text, index }) { public async linkByText({ pid, handle, text, index }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const page = WebAutomationServices.getPageByHandle(handle); const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation CLICK LINK TEXT: ${text} ${index}.`); GBLogEx.info(min, `BASIC: Web Automation CLICK LINK TEXT: ${text} ${index}.`);
if (!index) { if (!index) {
index = 1; index = 1;
} }
@ -317,8 +327,10 @@ export class WebAutomationServices {
} }
public async clickButton({ pid, handle, text, index }) { public async clickButton({ pid, handle, text, index }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const page = WebAutomationServices.getPageByHandle(handle); const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation CLICK BUTTON: ${text} ${index}.`); GBLogEx.info(min, `BASIC: Web Automation CLICK BUTTON: ${text} ${index}.`);
if (!index) { if (!index) {
index = 1; index = 1;
} }
@ -336,7 +348,7 @@ export class WebAutomationServices {
public async screenshot({ pid, handle, selector }) { public async screenshot({ pid, handle, selector }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid); const { min, user } = await DialogKeywords.getProcessInfo(pid);
const page = WebAutomationServices.getPageByHandle(handle); const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation SCREENSHOT ${selector}.`); GBLogEx.info(min, `BASIC: Web Automation SCREENSHOT ${selector}.`);
const gbaiName = DialogKeywords.getGBAIPath(min.botId); const gbaiName = DialogKeywords.getGBAIPath(min.botId);
const localName = Path.join('work', gbaiName, 'cache', `screen-${GBAdminService.getRndReadableIdentifier()}.jpg`); const localName = Path.join('work', gbaiName, 'cache', `screen-${GBAdminService.getRndReadableIdentifier()}.jpg`);
@ -344,7 +356,7 @@ export class WebAutomationServices {
await page.screenshot({ path: localName }); await page.screenshot({ path: localName });
const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName)); const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName));
GBLog.info(`BASIC: WebAutomation: Screenshot captured at ${url}.`); GBLogEx.info(min, `BASIC: WebAutomation: Screenshot captured at ${url}.`);
return { data: null, localName: localName, url: url }; return { data: null, localName: localName, url: url };
} }
@ -355,9 +367,11 @@ export class WebAutomationServices {
* @example SET page,"selector","text" * @example SET page,"selector","text"
*/ */
public async setElementText({ pid, handle, selector, text }) { public async setElementText({ pid, handle, selector, text }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
text = `${text}`; text = `${text}`;
const page = WebAutomationServices.getPageByHandle(handle); const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation TYPE on ${selector}: ${text}.`); GBLogEx.info(min, `BASIC: Web Automation TYPE on ${selector}: ${text}.`);
const e = await this.getBySelector({ handle, selector, pid }); const e = await this.getBySelector({ handle, selector, pid });
await e.click({ clickCount: 3 }); await e.click({ clickCount: 3 });
await page.keyboard.press('Backspace'); await page.keyboard.press('Backspace');
@ -397,7 +411,7 @@ export class WebAutomationServices {
const cookies = await page.cookies(); const cookies = await page.cookies();
options.headers.Cookie = cookies.map(ck => ck.name + '=' + ck.value).join(';'); options.headers.Cookie = cookies.map(ck => ck.name + '=' + ck.value).join(';');
GBLog.info(`BASIC: DOWNLOADING '${options.uri}...'`); GBLogEx.info(min, `BASIC: DOWNLOADING '${options.uri}...'`);
let local; let local;
let filename; let filename;
@ -443,7 +457,7 @@ export class WebAutomationServices {
file = await client.api(`${baseUrl}/drive/root:/${dstPath}:/content`).put(result); file = await client.api(`${baseUrl}/drive/root:/${dstPath}:/content`).put(result);
} catch (error) { } catch (error) {
if (error.code === 'nameAlreadyExists') { if (error.code === 'nameAlreadyExists') {
GBLog.info(`BASIC: DOWNLOAD destination file already exists: ${dstPath}.`); GBLogEx.info(min, `BASIC: DOWNLOAD destination file already exists: ${dstPath}.`);
} }
throw error; throw error;
} }
@ -469,8 +483,10 @@ export class WebAutomationServices {
public async getTextOf({ pid, handle, frameOrSelector, selector }) { public async getTextOf({ pid, handle, frameOrSelector, selector }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const page = WebAutomationServices.getPageByHandle(handle); const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation CLICK element: ${frameOrSelector}.`); GBLogEx.info(min, `BASIC: Web Automation CLICK element: ${frameOrSelector}.`);
if (frameOrSelector) { if (frameOrSelector) {
const result = await page.$eval( const result = await page.$eval(
frameOrSelector, frameOrSelector,

View file

@ -175,7 +175,7 @@ export const createVm2Pool = ({ min, max, ...limits }) => {
GBServer.globals.debuggers[limits.botId].state = 0; GBServer.globals.debuggers[limits.botId].state = 0;
GBServer.globals.debuggers[limits.botId].stateInfo = 'Fail'; GBServer.globals.debuggers[limits.botId].stateInfo = 'Fail';
} else if (stderrCache.includes('Debugger attached.')) { } else if (stderrCache.includes('Debugger attached.')) {
GBLog.info(`BASIC: General Bots Debugger attached to Node .gbdialog process for ${limits.botId}.`); GBLogEx.info(min, `BASIC: General Bots Debugger attached to Node .gbdialog process for ${limits.botId}.`);
} }
}); });
@ -216,7 +216,7 @@ export const createVm2Pool = ({ min, max, ...limits }) => {
// Processes breakpoint hits. // Processes breakpoint hits.
if (hitBreakpoints.length >= 1) { if (hitBreakpoints.length >= 1) {
GBLog.info(`BASIC: Break at line ${frame.location.lineNumber + 1}`); // (zero-based) GBLogEx.info(min, `BASIC: Break at line ${frame.location.lineNumber + 1}`); // (zero-based)
GBServer.globals.debuggers[limits.botId].state = 2; GBServer.globals.debuggers[limits.botId].state = 2;
GBServer.globals.debuggers[limits.botId].stateInfo = 'Break'; GBServer.globals.debuggers[limits.botId].stateInfo = 'Break';
@ -232,9 +232,9 @@ export const createVm2Pool = ({ min, max, ...limits }) => {
lineNumber: brk lineNumber: brk
} }
}); });
GBLog.info(`BASIC break defined ${breakpointId} for ${limits.botId}`); GBLogEx.info(min, `BASIC break defined ${breakpointId} for ${limits.botId}`);
} catch (error) { } catch (error) {
GBLog.info(`BASIC error defining ${brk} for ${limits.botId}. ${error}`); GBLogEx.info(min, `BASIC error defining ${brk} for ${limits.botId}. ${error}`);
} }
}); });
await client.Debugger.resume(); await client.Debugger.resume();

View file

@ -1,68 +0,0 @@
/*****************************************************************************\
| ® |
| |
| |
| |
| |
| |
| General Bots Copyright (c) pragmatismo.cloud. 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.cloud. |
| 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 { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
import { Sequelize } from 'sequelize-typescript';
import { ConsoleDirectLine } from './services/ConsoleDirectLine.js';
/**
* Package for console.glib.
*/
export class GBConsolePackage implements IGBPackage {
public sysPackages: IGBPackage[];
public channel: ConsoleDirectLine;
public async getDialogs (min: GBMinInstance) {
GBLog.verbose(`getDialogs called.`);
}
public async loadPackage (core: IGBCoreService, sequelize: Sequelize): Promise<void> {
GBLog.verbose(`loadPackage called.`);
}
public async unloadPackage (core: IGBCoreService): Promise<void> {
GBLog.verbose(`unloadPackage called.`);
}
public async unloadBot (min: GBMinInstance): Promise<void> {
GBLog.verbose(`unloadBot called.`);
}
public async onNewSession (min: GBMinInstance, step: GBDialogStep): Promise<void> {
GBLog.verbose(`onNewSession called.`);
}
public async onExchangeData (min: GBMinInstance, kind: string, data: any) {
GBLog.verbose(`onExchangeData called.`);
}
public async loadBot (min: GBMinInstance): Promise<void> {
this.channel = new ConsoleDirectLine(min.instance.webchatKey);
}
}

View file

@ -1,176 +0,0 @@
import Swagger from 'swagger-client';
import rp from 'request-promise';
import { GBLog, GBService } from 'botlib';
/**
* Bot simulator in terminal window.
*/
export class ConsoleDirectLine extends GBService {
public pollInterval: number = 1000;
public directLineSecret: string = '';
public directLineClientName: string = 'DirectLineClient';
public directLineSpecUrl: string = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
constructor (directLineSecret: string) {
super();
this.directLineSecret = directLineSecret;
// tslint:disable-next-line:no-unsafe-any
const directLineClient = rp(this.directLineSpecUrl)
.then((spec: string) => {
// tslint:disable-next-line:no-unsafe-any
return new Swagger({
spec: JSON.parse(spec.trim()),
usePromise: true
});
})
.then(client => {
// tslint:disable-next-line:no-unsafe-any
client.clientAuthorizations.add(
'AuthorizationBotConnector',
// tslint:disable-next-line:no-unsafe-any
new Swagger.ApiKeyAuthorization('Authorization', `Bearer ${directLineSecret}`, 'header')
);
return client;
})
.catch(err => {
GBLog.error(`Error initializing DirectLine client ${err}`);
});
const _this_ = this;
// tslint:disable-next-line:no-unsafe-any
directLineClient.then(client => {
// tslint:disable-next-line:no-unsafe-any
client.Conversations.Conversations_StartConversation()
.then(response => {
// tslint:disable-next-line:no-unsafe-any
return response.obj.conversationId;
})
.then(conversationId => {
_this_.sendMessagesFromConsole(client, conversationId);
_this_.pollMessages(client, conversationId);
})
.catch(err => {
GBLog.error(`Error starting conversation ${err}`);
});
});
}
public sendMessagesFromConsole (client, conversationId) {
const _this_ = this;
process.stdin.resume();
const stdin = process.stdin;
process.stdout.write('Command> ');
stdin.addListener('data', e => {
// tslint:disable-next-line:no-unsafe-any
const input: string = e.toString().trim();
if (input !== undefined) {
// exit
if (input.toLowerCase() === 'exit') {
return process.exit();
}
// tslint:disable-next-line:no-unsafe-any
client.Conversations.Conversations_PostActivity({
conversationId: conversationId,
activity: {
textFormat: 'plain',
text: input,
type: 'message',
from: {
id: _this_.directLineClientName,
name: _this_.directLineClientName
}
}
}).catch(err => {
GBLog.error(`Error sending message: ${err}`);
});
process.stdout.write('Command> ');
}
});
}
public pollMessages (client, conversationId) {
const _this_ = this;
GBLog.info(`Starting polling message for conversationId: ${conversationId}`);
let watermark;
setInterval(() => {
// tslint:disable-next-line:no-unsafe-any
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
.then(response => {
// tslint:disable-next-line:no-unsafe-any
watermark = response.obj.watermark;
// tslint:disable-next-line:no-unsafe-any
return response.obj.activities;
})
.then(_this_.printMessages, _this_.directLineClientName);
// tslint:disable-next-line:align
}, this.pollInterval);
}
// tslint:disable:no-unsafe-any
public printMessages (activities, directLineClientName) {
if (activities && activities.length) {
// ignore own messages
activities = activities.filter(m => {
return m.from.id !== directLineClientName;
});
if (activities.length) {
// print other messages
activities.forEach(activity => {
GBLog.info(activity.text);
// tslint:disable-next-line:align
}, this);
process.stdout.write('Command> ');
}
}
}
// tslint:enable:no-unsafe-any
// tslint:disable:no-unsafe-any
public printMessage (activity) {
if (activity.text) {
GBLog.info(activity.text);
}
if (activity.attachments) {
activity.attachments.forEach(attachment => {
switch (attachment.contentType) {
case 'application/vnd.microsoft.card.hero':
this.renderHeroCard(attachment);
break;
case 'image/png':
GBLog.info(`Opening the requested image ${attachment.contentUrl}`);
open(attachment.contentUrl);
break;
default:
GBLog.info(`Unknown contentType: ${attachment.contentType}`);
break;
}
});
}
}
// tslint:enable:no-unsafe-any
// tslint:disable:no-unsafe-any
public renderHeroCard (attachment) {
const width = 70;
const contentLine = content => {
return `${' '.repeat((width - content.length) / 2)}content${' '.repeat((width - content.length) / 2)}`;
};
GBLog.info(`/${'*'.repeat(width + 1)}`);
GBLog.info(`*${contentLine(attachment.content.title)}*`);
GBLog.info(`*${' '.repeat(width)}*`);
GBLog.info(`*${contentLine(attachment.content.text)}*`);
GBLog.info(`${'*'.repeat(width + 1)}/`);
}
// tslint:enable:no-unsafe-any
}

View file

@ -40,6 +40,7 @@ import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
import { GBServer } from '../../../src/app.js'; import { GBServer } from '../../../src/app.js';
import { GBConversationalService } from '../services/GBConversationalService.js'; import { GBConversationalService } from '../services/GBConversationalService.js';
import { Messages } from '../strings.js'; import { Messages } from '../strings.js';
import { GBLogEx } from '../services/GBLogEx.js';
/** /**
* Dialog for Welcoming people. * Dialog for Welcoming people.
@ -96,7 +97,7 @@ export class WelcomeDialog extends IGBDialog {
step.context.activity.type === 'message' && step.context.activity.type === 'message' &&
step.context.activity.text !== '' step.context.activity.text !== ''
) { ) {
GBLog.info(`/answer being called from WelcomeDialog.`); GBLogEx.info(min, `/answer being called from WelcomeDialog.`);
await step.replaceDialog('/answer', { query: step.context.activity.text }); await step.replaceDialog('/answer', { query: step.context.activity.text });
} }
} }

View file

@ -316,17 +316,17 @@ export class GBConversationalService {
mobile = this.userMobile(step); mobile = this.userMobile(step);
if (mobile) { if (mobile) {
GBLog.info(`Sending file ${url} to ${mobile}...`); GBLogEx.info(min, `Sending file ${url} to ${mobile}...`);
const filename = url.substring(url.lastIndexOf('/') + 1); const filename = url.substring(url.lastIndexOf('/') + 1);
await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption); await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption);
} else { } else {
GBLog.info( GBLogEx.info(min,
`Sending ${url} as file attachment not available in this channel ${step.context.activity['mobile']}...` `Sending ${url} as file attachment not available in this channel ${step.context.activity['mobile']}...`
); );
await min.conversationalService.sendText(min, step, url); await min.conversationalService.sendText(min, step, url);
} }
} else { } else {
GBLog.info(`Sending file ${url} to ${mobile}...`); GBLogEx.info(min, `Sending file ${url} to ${mobile}...`);
const filename = url.substring(url.lastIndexOf('/') + 1); const filename = url.substring(url.lastIndexOf('/') + 1);
await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption); await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption);
} }
@ -334,14 +334,14 @@ export class GBConversationalService {
public async sendAudio(min: GBMinInstance, step: GBDialogStep, url: string): Promise<any> { public async sendAudio(min: GBMinInstance, step: GBDialogStep, url: string): Promise<any> {
const mobile = step.context.activity['mobile']; const mobile = step.context.activity['mobile'];
GBLog.info(`Sending audio to ${mobile} in URL: ${url}.`); GBLogEx.info(min, `Sending audio to ${mobile} in URL: ${url}.`);
await min.whatsAppDirectLine.sendAudioToDevice(mobile, url); await min.whatsAppDirectLine.sendAudioToDevice(mobile, url);
} }
public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise<any> { public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise<any> {
if ( step.context.activity.channelId !== 'msteams' && if ( step.context.activity.channelId !== 'msteams' &&
step.context.activity.channelId !== 'omnichannel') { step.context.activity.channelId !== 'omnichannel') {
GBLog.info( GBLogEx.info(min,
`Sending event ${name}:${typeof value === 'object' ? JSON.stringify(value) : value ? value : ''} to client...` `Sending event ${name}:${typeof value === 'object' ? JSON.stringify(value) : value ? value : ''} to client...`
); );
const msg = MessageFactory.text(''); const msg = MessageFactory.text('');
@ -360,7 +360,7 @@ export class GBConversationalService {
if (botNumber) { if (botNumber) {
GBLog.info(`Sending SMS from ${botNumber} to ${mobile} with text: '${text}'.`); GBLogEx.info(min, `Sending SMS from ${botNumber} to ${mobile} with text: '${text}'.`);
const accountSid = process.env.TWILIO_ACCOUNT_SID; const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN; const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = twilio(null, authToken, { accountSid: accountSid }); const client = twilio(null, authToken, { accountSid: accountSid });
@ -426,7 +426,7 @@ export class GBConversationalService {
} }
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}...`); GBLogEx.info(min, `Sending message ${message} to ${mobile}...`);
return min.whatsAppDirectLine ? await min.whatsAppDirectLine.sendToDevice(mobile, message, conversationId) : return min.whatsAppDirectLine ? await min.whatsAppDirectLine.sendToDevice(mobile, message, conversationId) :
await this.sendSms(min, mobile, message); await this.sendSms(min, mobile, message);
} }
@ -804,10 +804,10 @@ export class GBConversationalService {
} }
if (currentText !== '') { if (currentText !== '') {
if (!mobile) { if (!mobile) {
GBLog.info(`Sending .MD file to Web.`); GBLogEx.info(min, `Sending .MD file to Web.`);
await step.context.sendActivity(currentText); await step.context.sendActivity(currentText);
} else { } else {
GBLog.info(`Sending .MD file to mobile: ${mobile}.`); GBLogEx.info(min, `Sending .MD file to mobile: ${mobile}.`);
await this.sendToMobile(min, mobile, currentText, null); await this.sendToMobile(min, mobile, currentText, null);
} }
} }
@ -888,7 +888,7 @@ export class GBConversationalService {
return false; return false;
} }
GBLog.info( GBLogEx.info(min,
`NLP called: ${intent}, entities: ${nlp.entities.length}, score: ${score} > required (nlpScore): ${instanceScore}` `NLP called: ${intent}, entities: ${nlp.entities.length}, score: ${score} > required (nlpScore): ${instanceScore}`
); );
@ -912,7 +912,7 @@ export class GBConversationalService {
} }
GBLog.info(`NLP NOT called: score: ${score} > required (nlpScore): ${instanceScore}`); GBLogEx.info(min, `NLP NOT called: score: ${score} > required (nlpScore): ${instanceScore}`);
return false; return false;
} }
@ -938,7 +938,7 @@ export class GBConversationalService {
text = text.charAt(0).toUpperCase() + text.slice(1); text = text.charAt(0).toUpperCase() + text.slice(1);
const data = await AzureText.getSpelledText(key, text); const data = await AzureText.getSpelledText(key, text);
if (data !== text) { if (data !== text) {
GBLog.info(`Spelling>: ${data}`); GBLogEx.info(min, `Spelling>: ${data}`);
text = data; text = data;
} }
} }
@ -1090,7 +1090,7 @@ export class GBConversationalService {
} }
}); });
} }
GBLog.info(`Tokens (processMessageActivity): ${textProcessed}.`); GBLogEx.info(min, `Tokens (processMessageActivity): ${textProcessed}.`);
// Spells check the input text before translating, // Spells check the input text before translating,
// keeping fixed tokens as specified in Config. // keeping fixed tokens as specified in Config.
@ -1147,7 +1147,7 @@ export class GBConversationalService {
text = text.replace(new RegExp(`${item.replacementToken}`, 'gi'), item.text); text = text.replace(new RegExp(`${item.replacementToken}`, 'gi'), item.text);
}); });
} }
GBLog.info(`After (processMessageActivity): ${text}.`); GBLogEx.info(min, `After (processMessageActivity): ${text}.`);
return text; return text;
} }
@ -1235,7 +1235,7 @@ export class GBConversationalService {
} }
} }
public async broadcast(min: GBMinInstance, message: string) { public async broadcast(min: GBMinInstance, message: string) {
GBLog.info(`Sending broadcast notifications...`); GBLogEx.info(min, `Sending broadcast notifications...`);
const service = new SecService(); const service = new SecService();
const users = await service.getAllUsers(min.instance.instanceId); const users = await service.getAllUsers(min.instance.instanceId);
@ -1243,7 +1243,7 @@ export class GBConversationalService {
if (user.conversationReference) { if (user.conversationReference) {
await this.sendOnConversation(min, user, message); await this.sendOnConversation(min, user, message);
} else { } else {
GBLog.info(`User: ${user.Id} with no conversation ID while broadcasting.`); GBLogEx.info(min, `User: ${user.Id} with no conversation ID while broadcasting.`);
} }
}); });
} }

View file

@ -61,6 +61,7 @@ import ngrok from 'ngrok';
import Path from 'path'; import Path from 'path';
import { file } from 'googleapis/build/src/apis/file/index.js'; import { file } from 'googleapis/build/src/apis/file/index.js';
import { GBUtil } from '../../../src/util.js'; import { GBUtil } from '../../../src/util.js';
import { GBLogEx } from './GBLogEx.js';
/** /**
* GBCoreService contains main logic for handling storage services related * GBCoreService contains main logic for handling storage services related
@ -135,7 +136,7 @@ export class GBCoreService implements IGBCoreService {
const logging: boolean | Function = const logging: boolean | Function =
GBConfigService.get('STORAGE_LOGGING') === 'true' GBConfigService.get('STORAGE_LOGGING') === 'true'
? (str: string): void => { ? (str: string): void => {
GBLog.info(str); GBLogEx.info(0, str);
} }
: false; : false;
@ -178,7 +179,7 @@ export class GBCoreService implements IGBCoreService {
try { try {
await this.sequelize.authenticate(); await this.sequelize.authenticate();
} catch (error) { } catch (error) {
GBLog.info('Opening storage firewall on infrastructure...'); GBLogEx.info(0, 'Opening storage firewall on infrastructure...');
// tslint:disable:no-unsafe-any // tslint:disable:no-unsafe-any
if (error.parent.code === 'ELOGIN') { if (error.parent.code === 'ELOGIN') {
await this.openStorageFrontier(installationDeployer); await this.openStorageFrontier(installationDeployer);
@ -195,7 +196,7 @@ export class GBCoreService implements IGBCoreService {
public async syncDatabaseStructure() { public async syncDatabaseStructure() {
if (GBConfigService.get('STORAGE_SYNC') === 'true') { if (GBConfigService.get('STORAGE_SYNC') === 'true') {
const alter = GBConfigService.get('STORAGE_SYNC_ALTER') === 'true'; const alter = GBConfigService.get('STORAGE_SYNC_ALTER') === 'true';
GBLog.info('Syncing database...'); GBLogEx.info(0, 'Syncing database...');
return await this.sequelize.sync({ return await this.sequelize.sync({
alter: alter, alter: alter,
@ -203,7 +204,7 @@ export class GBCoreService implements IGBCoreService {
}); });
} else { } else {
const msg = `Database synchronization is disabled.`; const msg = `Database synchronization is disabled.`;
GBLog.info(msg); GBLogEx.info(0, msg);
} }
} }
@ -419,14 +420,14 @@ ENDPOINT_UPDATE=true
installationDeployer: IGBInstallationDeployer, installationDeployer: IGBInstallationDeployer,
proxyAddress: string proxyAddress: string
) { ) {
GBLog.info(`Loading instances from storage...`); GBLogEx.info(0, `Loading instances from storage...`);
let instances: IGBInstance[]; let instances: IGBInstance[];
try { try {
instances = await core.loadInstances(); instances = await core.loadInstances();
const group = GBConfigService.get('CLOUD_GROUP')??GBConfigService.get('BOT_ID'); const group = GBConfigService.get('CLOUD_GROUP')??GBConfigService.get('BOT_ID');
if (process.env.ENDPOINT_UPDATE === 'true') { if (process.env.ENDPOINT_UPDATE === 'true') {
await CollectionUtil.asyncForEach(instances, async instance => { await CollectionUtil.asyncForEach(instances, async instance => {
GBLog.info(`Updating bot endpoint for ${instance.botId}...`); GBLogEx.info(instance.instanceId, `Updating bot endpoint for ${instance.botId}...`);
try { try {
await installationDeployer.updateBotProxy( await installationDeployer.updateBotProxy(
@ -456,7 +457,7 @@ ENDPOINT_UPDATE=true
Try setting STORAGE_SYNC to true in .env file. Error: ${error.message}.` Try setting STORAGE_SYNC to true in .env file. Error: ${error.message}.`
); );
} else { } else {
GBLog.info(`Storage is empty. After collecting storage structure from all .gbapps it will get synced.`); GBLogEx.info(0, `Storage is empty. After collecting storage structure from all .gbapps it will get synced.`);
} }
} else { } else {
throw new Error(`Cannot connect to operating storage: ${error.message}.`); throw new Error(`Cannot connect to operating storage: ${error.message}.`);
@ -492,7 +493,7 @@ ENDPOINT_UPDATE=true
GBHubSpotPackage GBHubSpotPackage
], ],
async e => { async e => {
GBLog.info(`Loading sys package: ${e.name}...`); GBLogEx.info(0, `Loading sys package: ${e.name}...`);
const p = Object.create(e.prototype) as IGBPackage; const p = Object.create(e.prototype) as IGBPackage;
sysPackages.push(p); sysPackages.push(p);
@ -543,7 +544,7 @@ ENDPOINT_UPDATE=true
deployer, deployer,
freeTier freeTier
) { ) {
GBLog.info(`Deploying cognitive infrastructure (on the cloud / on premises)...`); GBLogEx.info(0, `Deploying cognitive infrastructure (on the cloud / on premises)...`);
try { try {
const { instance, credentials, subscriptionId, installationDeployer } const { instance, credentials, subscriptionId, installationDeployer }
= await StartDialog.createBaseInstance(deployer, freeTier); = await StartDialog.createBaseInstance(deployer, freeTier);
@ -557,7 +558,7 @@ ENDPOINT_UPDATE=true
await this.writeEnv(changedInstance); await this.writeEnv(changedInstance);
GBConfigService.init(); GBConfigService.init();
GBLog.info(`File .env written. Preparing storage and search for the first time...`); GBLogEx.info(0, `File .env written. Preparing storage and search for the first time...`);
await this.openStorageFrontier(installationDeployer); await this.openStorageFrontier(installationDeployer);
await this.initStorage(); await this.initStorage();

View file

@ -154,7 +154,7 @@ export class GBDeployer implements IGBDeployer {
// For each folder, checks its extensions looking for valid packages. // For each folder, checks its extensions looking for valid packages.
if (element === '.') { if (element === '.') {
GBLog.info(`Ignoring ${element}...`); GBLogEx.info(0, `Ignoring ${element}...`);
} else { } else {
const name = Path.basename(element); const name = Path.basename(element);
@ -182,9 +182,9 @@ export class GBDeployer implements IGBDeployer {
// Start the process of searching. // Start the process of searching.
GBLog.info(`Deploying Application packages...`); GBLogEx.info(0, `Deploying Application packages...`);
await CollectionUtil.asyncForEach(paths, async e => { await CollectionUtil.asyncForEach(paths, async e => {
GBLog.info(`Looking in: ${e}...`); GBLogEx.info(0, `Looking in: ${e}...`);
await scanPackageDirectory(e); await scanPackageDirectory(e);
}); });
@ -204,7 +204,7 @@ export class GBDeployer implements IGBDeployer {
} }
await this.deployAppPackages(list, core, appPackages); await this.deployAppPackages(list, core, appPackages);
GBLog.info(`App Package deployment done.`); GBLogEx.info(0, `App Package deployment done.`);
} }
/** /**
@ -859,11 +859,11 @@ export class GBDeployer implements IGBDeployer {
// Install modules and compiles the web app. // Install modules and compiles the web app.
GBLog.info(`Installing modules default.gbui (It may take a few minutes)...`); GBLogEx.info(0, `Installing modules default.gbui (It may take a few minutes)...`);
child_process.execSync(`${npm} install`, { cwd: root }); child_process.execSync(`${npm} install`, { cwd: root });
GBLog.info(`Transpiling default.gbui...`); GBLogEx.info(0, `Transpiling default.gbui...`);
child_process.execSync(`${npm} run build`, { cwd: root }); child_process.execSync(`${npm} run build`, { cwd: root });
} }
} }
@ -923,11 +923,11 @@ export class GBDeployer implements IGBDeployer {
) { ) {
// Runs `npm install` for the package. // Runs `npm install` for the package.
GBLog.info(`Deploying General Bots Application (.gbapp) or Library (.gblib): ${Path.basename(gbappPath)}...`); GBLogEx.info(0, `Deploying General Bots Application (.gbapp) or Library (.gblib): ${Path.basename(gbappPath)}...`);
let folder = Path.join(gbappPath, 'node_modules'); let folder = Path.join(gbappPath, 'node_modules');
if (process.env.GBAPP_DISABLE_COMPILE !== 'true') { if (process.env.GBAPP_DISABLE_COMPILE !== 'true') {
if (!Fs.existsSync(folder)) { if (!Fs.existsSync(folder)) {
GBLog.info(`Installing modules for ${gbappPath}...`); GBLogEx.info(0, `Installing modules for ${gbappPath}...`);
child_process.execSync('npm install', { cwd: gbappPath }); child_process.execSync('npm install', { cwd: gbappPath });
} }
} }
@ -937,7 +937,7 @@ export class GBDeployer implements IGBDeployer {
// Runs TSC in .gbapp folder. // Runs TSC in .gbapp folder.
if (process.env.GBAPP_DISABLE_COMPILE !== 'true') { if (process.env.GBAPP_DISABLE_COMPILE !== 'true') {
GBLog.info(`Compiling: ${gbappPath}.`); GBLogEx.info(0, `Compiling: ${gbappPath}.`);
child_process.execSync(Path.join(process.env.PWD, 'node_modules/.bin/tsc'), { cwd: gbappPath }); child_process.execSync(Path.join(process.env.PWD, 'node_modules/.bin/tsc'), { cwd: gbappPath });
} }
@ -957,7 +957,7 @@ export class GBDeployer implements IGBDeployer {
} }
} }
} }
GBLog.info(`.gbapp or .gblib deployed: ${gbappPath}.`); GBLogEx.info(0, `.gbapp or .gblib deployed: ${gbappPath}.`);
appPackagesProcessed++; appPackagesProcessed++;
} catch (error) { } catch (error) {
GBLog.error(`Error compiling package, message: ${error.message}\n${error.stack}`); GBLog.error(`Error compiling package, message: ${error.message}\n${error.stack}`);

View file

@ -57,6 +57,7 @@ export class GBLogEx {
} }
public static async info(minOrInstanceId: any, message: string) { public static async info(minOrInstanceId: any, message: string) {
if (typeof minOrInstanceId === 'object') { if (typeof minOrInstanceId === 'object') {
minOrInstanceId = minOrInstanceId.instance.instanceId; minOrInstanceId = minOrInstanceId.instance.instanceId;
} }

View file

@ -205,11 +205,11 @@ export class GBMinService {
// Loads schedules. // Loads schedules.
GBLog.info(`Loading SET SCHEDULE entries...`); GBLogEx.info(0, `Loading SET SCHEDULE entries...`);
const service = new ScheduleServices(); const service = new ScheduleServices();
await service.scheduleAll(); await service.scheduleAll();
GBLog.info(`All Bot instances loaded.`); GBLogEx.info(0, `All Bot instances loaded.`);
} }
/** /**
@ -365,7 +365,7 @@ export class GBMinService {
// Test code. // Test code.
if (process.env.TEST_MESSAGE) { if (process.env.TEST_MESSAGE) {
GBLog.info(`Starting auto test with '${process.env.TEST_MESSAGE}'.`); GBLogEx.info(min, `Starting auto test with '${process.env.TEST_MESSAGE}'.`);
const client = await new SwaggerClient({ const client = await new SwaggerClient({
spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')), spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')),
@ -402,7 +402,7 @@ export class GBMinService {
const manifest = `${instance.botId}-Teams.zip`; const manifest = `${instance.botId}-Teams.zip`;
const packageTeams = urlJoin(`work`, DialogKeywords.getGBAIPath(instance.botId), manifest); const packageTeams = urlJoin(`work`, DialogKeywords.getGBAIPath(instance.botId), manifest);
if (!Fs.existsSync(packageTeams)) { if (!Fs.existsSync(packageTeams)) {
GBLog.info('Generating MS Teams manifest....'); GBLogEx.info(min, 'Generating MS Teams manifest....');
const data = await this.deployer.getBotManifest(instance); const data = await this.deployer.getBotManifest(instance);
Fs.writeFileSync(packageTeams, data); Fs.writeFileSync(packageTeams, data);
} }
@ -622,7 +622,7 @@ export class GBMinService {
); );
authorizationUrl = `${authorizationUrl}?response_type=code&client_id=${min.instance.marketplaceId authorizationUrl = `${authorizationUrl}?response_type=code&client_id=${min.instance.marketplaceId
}&redirect_uri=${urlJoin(process.env.BOT_URL, min.instance.botId, 'token')}`; }&redirect_uri=${urlJoin(process.env.BOT_URL, min.instance.botId, 'token')}`;
GBLog.info(`HandleOAuthRequests: ${authorizationUrl}.`); GBLogEx.info(min, `HandleOAuthRequests: ${authorizationUrl}.`);
res.redirect(authorizationUrl); res.redirect(authorizationUrl);
}); });
} }
@ -638,7 +638,6 @@ export class GBMinService {
botId = GBConfigService.get('BOT_ID'); botId = GBConfigService.get('BOT_ID');
} }
GBLog.info(`Client requested instance for: ${botId}.`);
// Loads by the botId itself or by the activationCode field. // Loads by the botId itself or by the activationCode field.
@ -646,6 +645,7 @@ export class GBMinService {
if (instance === null) { if (instance === null) {
instance = await this.core.loadInstanceByActivationCode(botId); instance = await this.core.loadInstanceByActivationCode(botId);
} }
GBLogEx.info(instance.instanceId, `Client requested instance for: ${botId}.`);
if (instance !== null) { if (instance !== null) {
// Gets the webchat token, speech token and theme. // Gets the webchat token, speech token and theme.
@ -1068,7 +1068,7 @@ export class GBMinService {
const startDialog = min.core.getParam(min.instance, 'Start Dialog', null); const startDialog = min.core.getParam(min.instance, 'Start Dialog', null);
if (startDialog) { if (startDialog) {
await sec.setParam(userId, 'welcomed', 'true'); await sec.setParam(userId, 'welcomed', 'true');
GBLog.info(`Auto start (teams) dialog is now being called: ${startDialog} for ${min.instance.botId}...`); GBLogEx.info(min, `Auto start (teams) dialog is now being called: ${startDialog} for ${min.instance.botId}...`);
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid); await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
} }
} }
@ -1076,7 +1076,7 @@ export class GBMinService {
// Required for F0 handling of persisted conversations. // Required for F0 handling of persisted conversations.
GBLog.info( GBLogEx.info(min,
`Input> ${context.activity.text} (type: ${context.activity.type}, name: ${context.activity.name}, channelId: ${context.activity.channelId})` `Input> ${context.activity.text} (type: ${context.activity.type}, name: ${context.activity.name}, channelId: ${context.activity.channelId})`
); );
@ -1087,13 +1087,13 @@ export class GBMinService {
if (context.activity.type === 'installationUpdate') { if (context.activity.type === 'installationUpdate') {
GBLog.info(`Bot installed on Teams.`); GBLogEx.info(min, `Bot installed on Teams.`);
} else if (context.activity.type === 'conversationUpdate' && context.activity.membersAdded.length > 0) { } else if (context.activity.type === 'conversationUpdate' && context.activity.membersAdded.length > 0) {
// Check if a bot or a human participant is being added to the conversation. // Check if a bot or a human participant is being added to the conversation.
const member = context.activity.membersAdded[0]; const member = context.activity.membersAdded[0];
if (context.activity.membersAdded[0].id === context.activity.recipient.id) { if (context.activity.membersAdded[0].id === context.activity.recipient.id) {
GBLog.info(`Bot added to conversation, starting chat...`); GBLogEx.info(min, `Bot added to conversation, starting chat...`);
// Calls onNewSession event on each .gbapp package. // Calls onNewSession event on each .gbapp package.
@ -1114,14 +1114,14 @@ export class GBMinService {
) { ) {
min['conversationWelcomed'][step.context.activity.conversation.id] = true; min['conversationWelcomed'][step.context.activity.conversation.id] = true;
GBLog.info( GBLogEx.info(min,
`Auto start (web 1) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...` `Auto start (web 1) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`
); );
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid); await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
} }
} }
} else { } else {
GBLog.info(`Person added to conversation: ${member.name}`); GBLogEx.info(min, `Person added to conversation: ${member.name}`);
return; return;
} }
@ -1190,7 +1190,7 @@ export class GBMinService {
const startDialog = min.core.getParam(min.instance, 'Start Dialog', null); const startDialog = min.core.getParam(min.instance, 'Start Dialog', null);
if (startDialog && !min['conversationWelcomed'][step.context.activity.conversation.id]) { if (startDialog && !min['conversationWelcomed'][step.context.activity.conversation.id]) {
user.welcomed = true; user.welcomed = true;
GBLog.info(`Auto start (web 2) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`); GBLogEx.info(min, `Auto start (web 2) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`);
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid); await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
} }
} else if (context.activity.name === 'updateToken') { } else if (context.activity.name === 'updateToken') {
@ -1262,7 +1262,7 @@ export class GBMinService {
// a upload with no Dialog, so run Auto Save to .gbdrive. // a upload with no Dialog, so run Auto Save to .gbdrive.
const t = new SystemKeywords(); const t = new SystemKeywords();
GBLog.info(`BASIC (${min.botId}): Upload done for ${attachmentData.fileName}.`); GBLogEx.info(min, `BASIC (${min.botId}): Upload done for ${attachmentData.fileName}.`);
const handle = WebAutomationServices.cyrb53({ pid: 0, str: min.botId + attachmentData.fileName }); const handle = WebAutomationServices.cyrb53({ pid: 0, str: min.botId + attachmentData.fileName });
let data = Fs.readFileSync(attachmentData.localPath); let data = Fs.readFileSync(attachmentData.localPath);
@ -1418,7 +1418,7 @@ export class GBMinService {
) { ) {
await sec.setParam(userId, 'welcomed', 'true'); await sec.setParam(userId, 'welcomed', 'true');
min['conversationWelcomed'][step.context.activity.conversation.id] = true; min['conversationWelcomed'][step.context.activity.conversation.id] = true;
GBLog.info( GBLogEx.info(min,
`Auto start (4) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...` `Auto start (4) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`
); );
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid); await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
@ -1504,7 +1504,7 @@ export class GBMinService {
if (user.agentMode === 'self') { if (user.agentMode === 'self') {
const manualUser = await sec.getUserFromAgentSystemId(user.userSystemId); const manualUser = await sec.getUserFromAgentSystemId(user.userSystemId);
GBLog.info(`HUMAN AGENT (${user.userId}) TO USER ${manualUser.userSystemId}: ${text}`); GBLogEx.info(min, `HUMAN AGENT (${user.userId}) TO USER ${manualUser.userSystemId}: ${text}`);
const cmd = 'SEND FILE '; const cmd = 'SEND FILE ';
if (text.startsWith(cmd)) { if (text.startsWith(cmd)) {
@ -1566,7 +1566,7 @@ export class GBMinService {
} }
}); });
data.step = null; data.step = null;
GBLog.info(`/answer being called from processMessageActivity (nextDialog=${nextDialog}).`); GBLogEx.info(min, `/answer being called from processMessageActivity (nextDialog=${nextDialog}).`);
await step.beginDialog(nextDialog ? nextDialog : '/answer', { await step.beginDialog(nextDialog ? nextDialog : '/answer', {
data: data, data: data,
query: text, query: text,

View file

@ -36,6 +36,7 @@ import Fs from 'fs';
import { GBLog, GBMinInstance, GBService } from 'botlib'; import { GBLog, GBMinInstance, GBService } from 'botlib';
import { GBServer } from '../../../src/app.js'; import { GBServer } from '../../../src/app.js';
import { SecService } from '../../security.gbapp/services/SecService.js'; import { SecService } from '../../security.gbapp/services/SecService.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
* Support for Google Chat. * Support for Google Chat.
@ -116,7 +117,7 @@ export class GoogleChatDirectLine extends GBService {
} }
public async check () { public async check () {
GBLog.info(`GBGoogleChat: Checking server...`); GBLogEx.info(0, `GBGoogleChat: Checking server...`);
} }
public async receiver (message) { public async receiver (message) {
@ -132,7 +133,7 @@ export class GoogleChatDirectLine extends GBService {
text = event.message.text; text = event.message.text;
fromName = event.message.sender.displayName; fromName = event.message.sender.displayName;
from = event.message.sender.email; from = event.message.sender.email;
GBLog.info(`Received message from ${from} (${fromName}): ${text}.`); GBLogEx.info(0, `Received message from ${from} (${fromName}): ${text}.`);
} }
message.ack(); message.ack();
@ -141,13 +142,13 @@ export class GoogleChatDirectLine extends GBService {
await sec.updateConversationReferenceById(user.userId, threadName); await sec.updateConversationReferenceById(user.userId, threadName);
GBLog.info(`GBGoogleChat: RCV ${from}: ${text})`); GBLogEx.info(0, `GBGoogleChat: RCV ${from}: ${text})`);
const client = await this.directLineClient; const client = await this.directLineClient;
const conversationId = GoogleChatDirectLine.conversationIds[from]; const conversationId = GoogleChatDirectLine.conversationIds[from];
if (GoogleChatDirectLine.conversationIds[from] === undefined) { if (GoogleChatDirectLine.conversationIds[from] === undefined) {
GBLog.info(`GBGoogleChat: Starting new conversation on Bot.`); GBLogEx.info(0, `GBGoogleChat: Starting new conversation on Bot.`);
const response = await client.Conversations.Conversations_StartConversation(); const response = await client.Conversations.Conversations_StartConversation();
const generatedConversationId = response.obj.conversationId; const generatedConversationId = response.obj.conversationId;
@ -178,7 +179,7 @@ export class GoogleChatDirectLine extends GBService {
} }
public pollMessages (client, conversationId, threadName, from, fromName) { public pollMessages (client, conversationId, threadName, from, fromName) {
GBLog.info(`GBGoogleChat: Starting message polling(${from}, ${conversationId}).`); GBLogEx.info(0, `GBGoogleChat: Starting message polling(${from}, ${conversationId}).`);
let watermark: any; let watermark: any;
@ -217,7 +218,7 @@ export class GoogleChatDirectLine extends GBService {
let output = ''; let output = '';
if (activity.text) { if (activity.text) {
GBLog.info(`GBGoogleChat: SND ${from}(${fromName}): ${activity.text}`); GBLogEx.info(0, `GBGoogleChat: SND ${from}(${fromName}): ${activity.text}`);
output = activity.text; output = activity.text;
} }
@ -225,11 +226,11 @@ export class GoogleChatDirectLine extends GBService {
activity.attachments.forEach(attachment => { activity.attachments.forEach(attachment => {
switch (attachment.contentType) { switch (attachment.contentType) {
case 'image/png': case 'image/png':
GBLog.info(`Opening the requested image ${attachment.contentUrl}`); GBLogEx.info(0, `Opening the requested image ${attachment.contentUrl}`);
output += `\n${attachment.contentUrl}`; output += `\n${attachment.contentUrl}`;
break; break;
default: default:
GBLog.info(`Unknown content type: ${attachment.contentType}`); GBLogEx.info(0, `Unknown content type: ${attachment.contentType}`);
} }
}); });
} }
@ -255,8 +256,8 @@ export class GoogleChatDirectLine extends GBService {
text: msg text: msg
} }
}); });
GBLog.info(res);
GBLog.info(`Message [${msg}] sent to ${from}: `); GBLogEx.info(0, `Message [${msg}] sent to ${from}: `);
} catch (error) { } catch (error) {
GBLog.error(`Error sending message to GoogleChat provider ${error.message}`); GBLog.error(`Error sending message to GoogleChat provider ${error.message}`);
} }

View file

@ -75,20 +75,21 @@ function isChatGeneration(
class CustomHandler extends BaseCallbackHandler { class CustomHandler extends BaseCallbackHandler {
name = "custom_handler"; name = "custom_handler";
handleLLMNewToken(token: string) { handleLLMNewToken(token: string) {
GBLog.info(`LLM: token: ${JSON.stringify(token)}`); GBLogEx.info(0, `LLM: token: ${JSON.stringify(token)}`);
} }
handleLLMStart(llm: Serialized, _prompts: string[]) { handleLLMStart(llm: Serialized, _prompts: string[]) {
GBLog.info(`LLM: handleLLMStart ${JSON.stringify(llm)}, Prompts: ${_prompts.join('\n')}`); GBLogEx.info(0, `LLM: handleLLMStart ${JSON.stringify(llm)}, Prompts: ${_prompts.join('\n')}`);
} }
handleChainStart(chain: Serialized) { handleChainStart(chain: Serialized) {
GBLog.info(`LLM: handleChainStart: ${JSON.stringify(chain)}`); GBLogEx.info(0, `LLM: handleChainStart: ${JSON.stringify(chain)}`);
} }
handleToolStart(tool: Serialized) { handleToolStart(tool: Serialized) {
GBLog.info(`LLM: handleToolStart: ${JSON.stringify(tool)}`); GBLogEx.info(0, `LLM: handleToolStart: ${JSON.stringify(tool)}`);
} }
} }
@ -364,7 +365,7 @@ export class ChatServices {
const name = output['func'][0].function.name; const name = output['func'][0].function.name;
const args = JSON.parse(output['func'][0].function.arguments); const args = JSON.parse(output['func'][0].function.arguments);
GBLog.info(`Running .gbdialog '${name}' as GPT tool...`); GBLogEx.info(min, `Running .gbdialog '${name}' as GPT tool...`);
const pid = GBVMService.createProcessInfo(null, min, 'gpt', null); const pid = GBVMService.createProcessInfo(null, min, 'gpt', null);
return await GBVMService.callVM(name, min, false, pid, false, args); return await GBVMService.callVM(name, min, false, pid, false, args);
@ -445,7 +446,7 @@ export class ChatServices {
} }
else { else {
GBLog.info(`Invalid Answer Mode in Config.xlsx: ${LLMMode}.`); GBLogEx.info(min, `Invalid Answer Mode in Config.xlsx: ${LLMMode}.`);
} }
await memory.saveContext( await memory.saveContext(
@ -457,7 +458,7 @@ export class ChatServices {
} }
); );
GBLog.info(`GPT Result: ${result.toString()}`); GBLogEx.info(min, `GPT Result: ${result.toString()}`);
return { answer: result.toString(), sources, questionId: 0, page }; return { answer: result.toString(), sources, questionId: 0, page };
} }

View file

@ -50,6 +50,7 @@ import urlJoin from 'url-join';
import { SystemKeywords } from '../../basic.gblib/services/SystemKeywords.js'; import { SystemKeywords } from '../../basic.gblib/services/SystemKeywords.js';
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js'; import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
import Path from 'path'; import Path from 'path';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
* Dialog arguments. * Dialog arguments.
@ -155,7 +156,7 @@ export class AskDialog extends IGBDialog {
}); });
if (!handled) { if (!handled) {
data.step = null; data.step = null;
GBLog.info(`/answer being called from getAskDialog.`); GBLogEx.info(min, `/answer being called from getAskDialog.`);
await step.beginDialog(nextDialog ? nextDialog : '/answer', { await step.beginDialog(nextDialog ? nextDialog : '/answer', {
data: data, data: data,
query: text, query: text,
@ -268,7 +269,7 @@ export class AskDialog extends IGBDialog {
GBLog.info(`SEARCH called but NO answer could be found (zero results).`); GBLogEx.info(min, `SEARCH called but NO answer could be found (zero results).`);
// Not found. // Not found.
@ -349,7 +350,7 @@ export class AskDialog extends IGBDialog {
await min.conversationalService.sendText(min, step, 'Thank you. The dialog is being written right now...'); await min.conversationalService.sendText(min, step, 'Thank you. The dialog is being written right now...');
const CHATGPT_TIMEOUT = 3 * 60 * 1000; const CHATGPT_TIMEOUT = 3 * 60 * 1000;
GBLog.info(`ChatGPT Code: ${input}`); GBLogEx.info(min, `ChatGPT Code: ${input}`);
let response = await GBServer.globals.chatGPT.sendMessage(input, { let response = await GBServer.globals.chatGPT.sendMessage(input, {
timeoutMs: CHATGPT_TIMEOUT timeoutMs: CHATGPT_TIMEOUT
}); });

View file

@ -300,13 +300,13 @@ export class KBService implements IGBKBService {
contentLocale contentLocale
); );
GBLog.info(`Translated query (prompt): ${query}.`); GBLogEx.info(min, `Translated query (prompt): ${query}.`);
// Try simple search first. // Try simple search first.
const data = await this.getAnswerByText(instance.instanceId, query.trim()); const data = await this.getAnswerByText(instance.instanceId, query.trim());
if (data) { if (data) {
GBLog.info(`Simple SEARCH called.`); GBLogEx.info(min, `Simple SEARCH called.`);
return { answer: data.answer, questionId: data.question.questionId }; return { answer: data.answer, questionId: data.question.questionId };
} }
@ -359,11 +359,11 @@ export class KBService implements IGBKBService {
if (returnedScore >= searchScore) { if (returnedScore >= searchScore) {
const value = await this.getAnswerById(instance.instanceId, result.document.answerId); const value = await this.getAnswerById(instance.instanceId, result.document.answerId);
if (value !== null) { if (value !== null) {
GBLog.info(`SEARCH WILL BE USED with score: ${returnedScore} > required (searchScore): ${searchScore}`); GBLogEx.info(min, `SEARCH WILL BE USED with score: ${returnedScore} > required (searchScore): ${searchScore}`);
return { answer: value, questionId: result.document.questionId }; return { answer: value, questionId: result.document.questionId };
} else { } else {
GBLog.info( GBLogEx.info(min,
`Index problem. SEARCH WILL NOT be used as answerId ${result.document.answerId} was not found in database, `Index problem. SEARCH WILL NOT be used as answerId ${result.document.answerId} was not found in database,
returnedScore: ${returnedScore} < required (searchScore): ${searchScore}` returnedScore: ${returnedScore} < required (searchScore): ${searchScore}`
); );
@ -373,7 +373,7 @@ export class KBService implements IGBKBService {
} }
} }
} }
GBLog.info( GBLogEx.info(min,
`SEARCH returned LOW level score, calling NLP if any, `SEARCH returned LOW level score, calling NLP if any,
returnedScore: ${returnedScore} < required (searchScore): ${searchScore}` returnedScore: ${returnedScore} < required (searchScore): ${searchScore}`
); );
@ -447,7 +447,7 @@ export class KBService implements IGBKBService {
min: GBMinInstance, min: GBMinInstance,
packageId: number packageId: number
): Promise<GuaribasQuestion[]> { ): Promise<GuaribasQuestion[]> {
GBLog.info(`Now reading file ${filePath}...`); GBLogEx.info(min, `Now reading file ${filePath}...`);
const workbook = new Excel.Workbook(); const workbook = new Excel.Workbook();
const data = await workbook.xlsx.readFile(filePath); const data = await workbook.xlsx.readFile(filePath);
@ -469,7 +469,7 @@ export class KBService implements IGBKBService {
const answers = []; const answers = [];
const questions = []; const questions = [];
GBLog.info(`Processing ${rows.length} rows from tabular file ${filePath}...`); GBLogEx.info(min, `Processing ${rows.length} rows from tabular file ${filePath}...`);
await asyncPromise.eachSeries(rows, async line => { await asyncPromise.eachSeries(rows, async line => {
// Skips the first line. // Skips the first line.
@ -503,7 +503,7 @@ export class KBService implements IGBKBService {
let media = null; let media = null;
if (typeof answer !== 'string') { if (typeof answer !== 'string') {
GBLog.info(`[GBImporter] Answer is NULL related to Question '${question}'.`); GBLogEx.info(min, `[GBImporter] Answer is NULL related to Question '${question}'.`);
answer = answer =
'Existe um problema na base de conhecimento. Fui treinado para entender sua pergunta, avise a quem me criou que a resposta não foi informada para esta pergunta.'; 'Existe um problema na base de conhecimento. Fui treinado para entender sua pergunta, avise a quem me criou que a resposta não foi informada para esta pergunta.';
} else if (answer.indexOf('.md') > -1 || answer.indexOf('.docx') > -1) { } else if (answer.indexOf('.md') > -1 || answer.indexOf('.docx') > -1) {
@ -522,7 +522,7 @@ export class KBService implements IGBKBService {
media = path.basename(mediaFilename); media = path.basename(mediaFilename);
} else { } else {
if (answer.indexOf('.md') > -1) { if (answer.indexOf('.md') > -1) {
GBLog.info(`[GBImporter] File not found: ${mediaFilename}.`); GBLogEx.info(min, `[GBImporter] File not found: ${mediaFilename}.`);
answer = ''; answer = '';
} }
} }
@ -857,7 +857,7 @@ export class KBService implements IGBKBService {
): Promise<any> { ): Promise<any> {
const files = await walkPromise(urlJoin(localPath, 'docs')); const files = await walkPromise(urlJoin(localPath, 'docs'));
if (!files[0]) { if (!files[0]) {
GBLog.info( GBLogEx.info(min,
`[GBDeployer] docs folder not created yet in .gbkb. To use Reading Comprehension, create this folder at root and put a document to get read by the.` `[GBDeployer] docs folder not created yet in .gbkb. To use Reading Comprehension, create this folder at root and put a document to get read by the.`
); );
} else { } else {
@ -1088,7 +1088,7 @@ export class KBService implements IGBKBService {
public async deployKb(core: IGBCoreService, deployer: GBDeployer, localPath: string, min: GBMinInstance) { public async deployKb(core: IGBCoreService, deployer: GBDeployer, localPath: string, min: GBMinInstance) {
const packageName = Path.basename(localPath); const packageName = Path.basename(localPath);
const instance = await core.loadInstanceByBotId(min.botId); const instance = await core.loadInstanceByBotId(min.botId);
GBLog.info(`[GBDeployer] Importing: ${localPath}`); GBLogEx.info(min, `[GBDeployer] Importing: ${localPath}`);
const p = await deployer.deployPackageToStorage(instance.instanceId, packageName); const p = await deployer.deployPackageToStorage(instance.instanceId, packageName);
await this.importKbPackage(min, localPath, p, instance); await this.importKbPackage(min, localPath, p, instance);
@ -1100,14 +1100,14 @@ export class KBService implements IGBKBService {
min['groupCache'] = await KBService.getGroupReplies(instance.instanceId); min['groupCache'] = await KBService.getGroupReplies(instance.instanceId);
await KBService.RefreshNER(min); await KBService.RefreshNER(min);
GBLog.info(`[GBDeployer] Start Bot Server Side Rendering... ${localPath}`); GBLogEx.info(min, `[GBDeployer] Start Bot Server Side Rendering... ${localPath}`);
const html = await GBSSR.getHTML(min); const html = await GBSSR.getHTML(min);
let path = DialogKeywords.getGBAIPath(min.botId, `gbui`); let path = DialogKeywords.getGBAIPath(min.botId, `gbui`);
path = Path.join(process.env.PWD, 'work', path, 'index.html'); path = Path.join(process.env.PWD, 'work', path, 'index.html');
GBLogEx.info(min, `[GBDeployer] Saving SSR HTML in ${path}.`); GBLogEx.info(min, `[GBDeployer] Saving SSR HTML in ${path}.`);
Fs.writeFileSync(path, html, 'utf8'); Fs.writeFileSync(path, html, 'utf8');
GBLog.info(`[GBDeployer] Finished import of ${localPath}`); GBLogEx.info(min, `[GBDeployer] Finished import of ${localPath}`);
} }
private async playAudio( private async playAudio(
@ -1161,19 +1161,6 @@ export class KBService implements IGBKBService {
}); });
} }
public async readComprehension(instanceId: number, doc: string, question: string) {
const url =
`http://${process.env.GBMODELS_SERVER}/reading-comprehension` +
new URLSearchParams({ question: question, key: process.env.GBMODELS_KEY });
const form = new FormData();
form.append('content', doc);
const options = {
body: form
};
GBLog.info(`[General Bots Models]: ReadComprehension for ${question}.`);
return await fetch(url, options);
}
private async getTextFromFile(filename: string) { private async getTextFromFile(filename: string) {
return new Promise<string>(async (resolve, reject) => { return new Promise<string>(async (resolve, reject) => {
textract.fromFileWithPath(filename, { preserveLineBreaks: true }, (error, text) => { textract.fromFileWithPath(filename, { preserveLineBreaks: true }, (error, text) => {

View file

@ -37,6 +37,7 @@
import { TokenResponse } from 'botbuilder'; import { TokenResponse } from 'botbuilder';
import { GBLog, GBMinInstance, IGBDialog } from 'botlib'; import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
import { Messages } from '../strings.js'; import { Messages } from '../strings.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
* Dialogs for handling Menu control. * Dialogs for handling Menu control.
@ -54,7 +55,7 @@ export class OAuthDialog extends IGBDialog {
async step => { async step => {
const tokenResponse: TokenResponse = step.result; const tokenResponse: TokenResponse = step.result;
if (tokenResponse) { if (tokenResponse) {
GBLog.info('Token acquired.'); GBLogEx.info(min, 'Token acquired.');
return await step.endDialog(tokenResponse); return await step.endDialog(tokenResponse);
} else { } else {

View file

@ -38,6 +38,7 @@ import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js'; import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
import { Messages } from '../strings.js'; import { Messages } from '../strings.js';
import libphonenumber from 'google-libphonenumber'; import libphonenumber from 'google-libphonenumber';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
* Dialogs for handling Menu control. * Dialogs for handling Menu control.
@ -144,7 +145,7 @@ export class ProfileDialog extends IGBDialog {
`${step.activeDialog.state.options.mobileCode} is your General Bots creation code.` `${step.activeDialog.state.options.mobileCode} is your General Bots creation code.`
); );
} else { } else {
GBLog.info(`WhatsApp not configured. Here is the code: ${step.activeDialog.state.options.mobileCode}.`); GBLogEx.info(min, `WhatsApp not configured. Here is the code: ${step.activeDialog.state.options.mobileCode}.`);
} }
await step.prompt('textPrompt', Messages[locale].confirm_mobile); await step.prompt('textPrompt', Messages[locale].confirm_mobile);

View file

@ -39,6 +39,7 @@ import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
import { Messages } from '../strings.js'; import { Messages } from '../strings.js';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js'; import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
import { SecService } from '../services/SecService.js'; import { SecService } from '../services/SecService.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
* Dialogs for handling Menu control. * Dialogs for handling Menu control.
*/ */
@ -64,7 +65,7 @@ export class SMSAuthDialog extends IGBDialog {
// Generates a new mobile code. // Generates a new mobile code.
let code = GBAdminService.getMobileCode(); let code = GBAdminService.getMobileCode();
GBLog.info(`SMS Auth: Generated new code: ${code} is being sent.`); GBLogEx.info(min, `SMS Auth: Generated new code: ${code} is being sent.`);
step.activeDialog.state.resetInfo.sentCode = code; step.activeDialog.state.resetInfo.sentCode = code;
step.activeDialog.state.resetInfo.mobile = mobile; step.activeDialog.state.resetInfo.mobile = mobile;
@ -86,7 +87,7 @@ export class SMSAuthDialog extends IGBDialog {
let sec = new SecService(); let sec = new SecService();
const member = step.context.activity.from; const member = step.context.activity.from;
GBLog.info(`SMS Auth: User Authenticated.`); GBLogEx.info(min, `SMS Auth: User Authenticated.`);
await step.context.sendActivity(Messages[locale].authenticated); await step.context.sendActivity(Messages[locale].authenticated);
return await step.endDialog(step.activeDialog.state.resetInfo.mobile); return await step.endDialog(step.activeDialog.state.resetInfo.mobile);

View file

@ -7,6 +7,7 @@ import { DialogKeywords } from '../../../packages/basic.gblib/services/DialogKey
import * as Fs from 'fs'; import * as Fs from 'fs';
import mkdirp from 'mkdirp'; import mkdirp from 'mkdirp';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
@ -204,9 +205,9 @@ export class SecService extends GBService {
} }
}); });
} }
GBLog.info(`Selected agentId: ${agentSystemId}`); GBLogEx.info(min, `Selected agentId: ${agentSystemId}`);
await this.updateHumanAgent(userSystemId, min.instance.instanceId, agentSystemId); await this.updateHumanAgent(userSystemId, min.instance.instanceId, agentSystemId);
GBLog.info(`Updated agentId to: ${agentSystemId}`); GBLogEx.info(min, `Updated agentId to: ${agentSystemId}`);
return agentSystemId; return agentSystemId;
} }

View file

@ -53,6 +53,7 @@ import { GBUtil } from '../../../src/util.js';
const { WAState, Client, MessageMedia } = pkg; const { WAState, Client, MessageMedia } = pkg;
import twilio from 'twilio'; import twilio from 'twilio';
import { GBVMService } from '../../basic.gblib/services/GBVMService.js'; import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/** /**
@ -318,7 +319,7 @@ export class WhatsappDirectLine extends GBService {
} }
text = text.replace(/\@\d+ /gi, ''); text = text.replace(/\@\d+ /gi, '');
GBLog.info(`GBWhatsapp: RCV ${from}(${fromName}): ${text})`); GBLogEx.info(0, `GBWhatsapp: RCV ${from}(${fromName}): ${text})`);
let botGroupID = WhatsappDirectLine.botGroups[this.min.botId]; let botGroupID = WhatsappDirectLine.botGroups[this.min.botId];
let botShortcuts = this.min.core.getParam<string>(this.min.instance, 'WhatsApp Group Shortcuts', null); let botShortcuts = this.min.core.getParam<string>(this.min.instance, 'WhatsApp Group Shortcuts', null);
@ -465,7 +466,7 @@ export class WhatsappDirectLine extends GBService {
await sec.updateHumanAgent(manualUser.userSystemId, this.min.instance.instanceId, null); await sec.updateHumanAgent(manualUser.userSystemId, this.min.instance.instanceId, null);
await sec.updateHumanAgent(user.agentSystemId, this.min.instance.instanceId, null); await sec.updateHumanAgent(user.agentSystemId, this.min.instance.instanceId, null);
} else { } else {
GBLog.info(`HUMAN AGENT (${manualUser.agentSystemId}) TO USER ${manualUser.userSystemId}: ${text}`); GBLogEx.info(this.min, `HUMAN AGENT (${manualUser.agentSystemId}) TO USER ${manualUser.userSystemId}: ${text}`);
await this.sendToDeviceEx(manualUser.userSystemId, `AGENT: *${text}*`, locale, null); await this.sendToDeviceEx(manualUser.userSystemId, `AGENT: *${text}*`, locale, null);
} }
} }
@ -481,7 +482,7 @@ export class WhatsappDirectLine extends GBService {
} else if (text === '/qt' || GBMinService.isGlobalQuitUtterance(locale, text)) { } else if (text === '/qt' || GBMinService.isGlobalQuitUtterance(locale, text)) {
await this.endTransfer(from, locale, user, agent, sec); await this.endTransfer(from, locale, user, agent, sec);
} else { } else {
GBLog.info(`USER (${from}) TO AGENT ${agent.userSystemId}: ${text}`); GBLogEx.info(this.min, `USER (${from}) TO AGENT ${agent.userSystemId}: ${text}`);
const prompt = `the person said: ${text}. what can I tell her?`; const prompt = `the person said: ${text}. what can I tell her?`;
const answer = await ChatServices.continue(this.min, prompt, 0); const answer = await ChatServices.continue(this.min, prompt, 0);
@ -501,7 +502,7 @@ export class WhatsappDirectLine extends GBService {
} }
} else if (user.agentMode === 'bot' || user.agentMode === null || user.agentMode === undefined) { } else if (user.agentMode === 'bot' || user.agentMode === null || user.agentMode === undefined) {
if (WhatsappDirectLine.conversationIds[botId + from + group] === undefined) { if (WhatsappDirectLine.conversationIds[botId + from + group] === undefined) {
GBLog.info(`GBWhatsapp: Starting new conversation on Bot.`); GBLogEx.info(this.min, `GBWhatsapp: Starting new conversation on Bot.`);
const response = await client.apis.Conversations.Conversations_StartConversation(); const response = await client.apis.Conversations.Conversations_StartConversation();
const generatedConversationId = response.obj.conversationId; const generatedConversationId = response.obj.conversationId;
@ -579,7 +580,7 @@ export class WhatsappDirectLine extends GBService {
} }
public pollMessages(client, conversationId, from, fromName) { public pollMessages(client, conversationId, from, fromName) {
GBLog.info(`GBWhatsapp: Starting message polling(${from}, ${conversationId}).`); GBLogEx.info(this.min, `GBWhatsapp: Starting message polling(${from}, ${conversationId}).`);
let watermark: any; let watermark: any;
@ -621,7 +622,7 @@ export class WhatsappDirectLine extends GBService {
let output = ''; let output = '';
if (activity.text) { if (activity.text) {
GBLog.info(`GBWhatsapp: SND ${to}(${toName}): ${activity.text}`); GBLogEx.info(this.min, `GBWhatsapp: SND ${to}(${toName}): ${activity.text}`);
output = activity.text; output = activity.text;
} }
@ -638,7 +639,7 @@ export class WhatsappDirectLine extends GBService {
return; return;
default: default:
GBLog.info(`Unknown content type: ${attachment.contentType}`); GBLogEx.info(this.min, `Unknown content type: ${attachment.contentType}`);
} }
}); });
} }
@ -673,7 +674,7 @@ export class WhatsappDirectLine extends GBService {
try { try {
// tslint:disable-next-line: await-promise // tslint:disable-next-line: await-promise
const result = await fetch(url, options); const result = await fetch(url, options);
GBLog.info(`File ${url} sent to ${to}: ${result}`); GBLogEx.info(this.min, `File ${url} sent to ${to}: ${result}`);
} catch (error) { } catch (error) {
GBLog.error(`Error sending file to Whatsapp provider ${error.message}`); GBLog.error(`Error sending file to Whatsapp provider ${error.message}`);
} }
@ -694,7 +695,7 @@ export class WhatsappDirectLine extends GBService {
if (options) { if (options) {
try { try {
const result = await fetch(url, options); const result = await fetch(url, options);
GBLog.info(`Audio ${url} sent to ${to}: ${result}`); GBLogEx.info(this.min, `Audio ${url} sent to ${to}: ${result}`);
} catch (error) { } catch (error) {
GBLog.error(`Error sending audio message to Whatsapp provider ${error.message}`); GBLog.error(`Error sending audio message to Whatsapp provider ${error.message}`);
} }
@ -756,7 +757,7 @@ export class WhatsappDirectLine extends GBService {
await this.customClient.sendMessage(to, msg); await this.customClient.sendMessage(to, msg);
} }
else { else {
GBLog.info(`WhatsApp OFFLINE ${to}: ${msg}`); GBLogEx.info(this.min, `WhatsApp OFFLINE ${to}: ${msg}`);
} }
break; break;
@ -765,7 +766,7 @@ export class WhatsappDirectLine extends GBService {
if (options) { if (options) {
try { try {
GBLog.info(`Message [${msg}] is being sent to ${to}...`); GBLogEx.info(this.min, `Message [${msg}] is being sent to ${to}...`);
await fetch(url, options); await fetch(url, options);
} catch (error) { } catch (error) {
GBLog.error(`Error sending message to Whatsapp provider ${error.message}`); GBLog.error(`Error sending message to Whatsapp provider ${error.message}`);
@ -827,7 +828,7 @@ export class WhatsappDirectLine extends GBService {
botId = botId??GBServer.globals.minBoot.botId; botId = botId??GBServer.globals.minBoot.botId;
GBLog.info(`A WhatsApp mobile requested instance for: ${botId}.`); GBLogEx.info(this.min, `A WhatsApp mobile requested instance for: ${botId}.`);
let urlMin: any = GBServer.globals.minInstances.filter(p => p.instance.botId === botId)[0]; let urlMin: any = GBServer.globals.minInstances.filter(p => p.instance.botId === botId)[0];
// Detects user typed language and updates their locale profile if applies. // Detects user typed language and updates their locale profile if applies.
@ -837,7 +838,7 @@ export class WhatsappDirectLine extends GBService {
const botNumber = urlMin ? urlMin.core.getParam(urlMin.instance, 'Bot Number', null) : null; const botNumber = urlMin ? urlMin.core.getParam(urlMin.instance, 'Bot Number', null) : null;
if (botNumber && GBServer.globals.minBoot.botId !== urlMin.botId) { if (botNumber && GBServer.globals.minBoot.botId !== urlMin.botId) {
GBLog.info(`${id} fixed by bot number talked to: ${botId}.`); GBLogEx.info(this.min, `${id} fixed by bot number talked to: ${botId}.`);
let locale = user?.locale ? user.locale : min.core.getParam( let locale = user?.locale ? user.locale : min.core.getParam(
min.instance, min.instance,
'Default User Language', 'Default User Language',
@ -856,7 +857,7 @@ export class WhatsappDirectLine extends GBService {
if (text != '' && detectLanguage) { if (text != '' && detectLanguage) {
locale = await min.conversationalService.getLanguage(min, text); locale = await min.conversationalService.getLanguage(min, text);
GBLog.info(`${locale} defined for first time mobile: ${id}.`); GBLogEx.info(this.min, `${locale} defined for first time mobile: ${id}.`);
} }
} }
@ -904,7 +905,7 @@ export class WhatsappDirectLine extends GBService {
} }
if (group) { if (group) {
GBLog.info(`Group: ${group}`); GBLogEx.info(this.min, `Group: ${group}`);
function getKeyByValue(object, value) { function getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value); return Object.keys(object).find(key => object[key] === value);
} }
@ -958,7 +959,7 @@ export class WhatsappDirectLine extends GBService {
: activeMin.core.getParam(activeMin.instance, 'Start Dialog', null); : activeMin.core.getParam(activeMin.instance, 'Start Dialog', null);
if (startDialog) { if (startDialog) {
GBLog.info(`Calling /start to Auto start ${startDialog} for ${activeMin.instance.instanceId}...`); GBLogEx.info(this.min, `Calling /start to Auto start ${startDialog} for ${activeMin.instance.instanceId}...`);
if (provider === 'GeneralBots') { if (provider === 'GeneralBots') {
req.body = `/start`; req.body = `/start`;
} }
@ -977,7 +978,7 @@ export class WhatsappDirectLine extends GBService {
// User wants to switch bots. // User wants to switch bots.
if (toSwitchMin) { if (toSwitchMin) {
GBLog.info(`Switching bots from ${botId} to ${toSwitchMin.botId}...`); GBLogEx.info(this.min, `Switching bots from ${botId} to ${toSwitchMin.botId}...`);
// So gets the new bot instance information and prepares to // So gets the new bot instance information and prepares to
// auto start dialog if any is specified. // auto start dialog if any is specified.
@ -990,7 +991,7 @@ export class WhatsappDirectLine extends GBService {
if (startDialog) { if (startDialog) {
GBLog.info(`Calling /start for Auto start : ${startDialog} for ${activeMin.instance.botId}...`); GBLogEx.info(this.min, `Calling /start for Auto start : ${startDialog} for ${activeMin.instance.botId}...`);
if (provider === 'GeneralBots') { if (provider === 'GeneralBots') {
req.body = `/start`; req.body = `/start`;
} }

View file

@ -60,6 +60,7 @@ import { RootData } from './RootData.js';
import { GBSSR } from '../packages/core.gbapp/services/GBSSR.js'; import { GBSSR } from '../packages/core.gbapp/services/GBSSR.js';
import { Mutex } from 'async-mutex'; import { Mutex } from 'async-mutex';
import httpProxy from 'http-proxy'; import httpProxy from 'http-proxy';
import { GBLogEx } from '../packages/core.gbapp/services/GBLogEx.js';
/** /**
* General Bots open-core entry point. * General Bots open-core entry point.
@ -72,13 +73,13 @@ export class GBServer {
*/ */
public static run() { public static run() {
GBLog.info(`The Bot Server is in STARTING mode...`); GBLogEx.info(0, `The Bot Server is in STARTING mode...`);
GBServer.globals = new RootData(); GBServer.globals = new RootData();
GBConfigService.init(); GBConfigService.init();
const port = GBConfigService.getServerPort(); const port = GBConfigService.getServerPort();
if (process.env.TEST_SHELL) { if (process.env.TEST_SHELL) {
GBLog.info(`Running TEST_SHELL: ${process.env.TEST_SHELL}...`); GBLogEx.info(0, `Running TEST_SHELL: ${process.env.TEST_SHELL}...`);
try { try {
child_process.execSync(process.env.TEST_SHELL); child_process.execSync(process.env.TEST_SHELL);
} catch (error) { } catch (error) {
@ -108,7 +109,7 @@ export class GBServer {
server.use(bodyParser.urlencoded({ limit: '1mb', extended: true })); server.use(bodyParser.urlencoded({ limit: '1mb', extended: true }));
process.on('SIGTERM', () => { process.on('SIGTERM', () => {
GBLog.info('SIGTERM signal received.'); GBLogEx.info(0, 'SIGTERM signal received.');
}); });
process.on('uncaughtException', (err, p) => { process.on('uncaughtException', (err, p) => {
@ -132,7 +133,7 @@ export class GBServer {
(async () => { (async () => {
try { try {
GBLog.info(`Now accepting connections on ${port}...`); GBLogEx.info(0, `Now accepting connections on ${port}...`);
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
// Reads basic configuration, initialize minimal services. // Reads basic configuration, initialize minimal services.
@ -151,11 +152,11 @@ export class GBServer {
} else { } else {
GBServer.globals.publicAddress = await core.ensureProxy(port); GBServer.globals.publicAddress = await core.ensureProxy(port);
process.env.BOT_URL = GBServer.globals.publicAddress; process.env.BOT_URL = GBServer.globals.publicAddress;
GBLog.info(`Auto-proxy address at: ${process.env.BOT_URL}...`); GBLogEx.info(0, `Auto-proxy address at: ${process.env.BOT_URL}...`);
} }
} else { } else {
const serverAddress = process.env.BOT_URL; const serverAddress = process.env.BOT_URL;
GBLog.info(`.env address at ${serverAddress}...`); GBLogEx.info(0, `.env address at ${serverAddress}...`);
GBServer.globals.publicAddress = serverAddress; GBServer.globals.publicAddress = serverAddress;
} }
@ -181,9 +182,9 @@ export class GBServer {
// Deploys system and user packages. // Deploys system and user packages.
GBLog.info(`Deploying System packages...`); GBLogEx.info(0, `Deploying System packages...`);
GBServer.globals.sysPackages = await core.loadSysPackages(core); GBServer.globals.sysPackages = await core.loadSysPackages(core);
GBLog.info(`Connecting to Bot Storage...`); GBLogEx.info(0, `Connecting to Bot Storage...`);
await core.checkStorage(azureDeployer); await core.checkStorage(azureDeployer);
await deployer.deployPackages(core, server, GBServer.globals.appPackages); await deployer.deployPackages(core, server, GBServer.globals.appPackages);
await core.syncDatabaseStructure(); await core.syncDatabaseStructure();
@ -198,7 +199,7 @@ export class GBServer {
deployer.setupDefaultGBUI(); deployer.setupDefaultGBUI();
} }
GBLog.info(`Publishing instances...`); GBLogEx.info(0, `Publishing instances...`);
const instances: IGBInstance[] = await core.loadAllInstances( const instances: IGBInstance[] = await core.loadAllInstances(
core, core,
azureDeployer, azureDeployer,
@ -277,7 +278,7 @@ export class GBServer {
const proxy = httpProxy.createProxyServer({}); const proxy = httpProxy.createProxyServer({});
if (host === process.env.API_HOST) { if (host === process.env.API_HOST) {
GBLog.info(`Redirecting to API...`); GBLogEx.info(0, `Redirecting to API...`);
return proxy.web(req, res, { target: 'http://localhost:1111' }); // Express server return proxy.web(req, res, { target: 'http://localhost:1111' }); // Express server
} else { } else {
await GBSSR.ssrFilter(req, res, next); await GBSSR.ssrFilter(req, res, next);
@ -285,7 +286,7 @@ export class GBServer {
} }
}); });
GBLog.info(`The Bot Server is in RUNNING mode...`); GBLogEx.info(0, `The Bot Server is in RUNNING mode...`);
// Opens Navigator. // Opens Navigator.