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 { GuaribasUser } from '../../security.gbapp/models/index.js';
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/**
* Services for server administration.
@ -257,7 +258,7 @@ export class GBAdminService implements IGBAdminService {
const minBoot = GBServer.globals.minBoot;
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;
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 scanf from 'scanf';
import { AzureDeployerService } from '../services/AzureDeployerService.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/**
* 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 = {};
let index = 1;
list.forEach(element => {
GBLog.info(`${index}: ${element.displayName} (${element.subscriptionId})`);
GBLogEx.info(0, `${index}: ${element.displayName} (${element.subscriptionId})`);
map[index++] = element;
});
let subscriptionIndex;

View file

@ -54,6 +54,7 @@ import { Spinner } from 'cli-spinner';
import * as publicIp from 'public-ip';
import { AccessToken, TokenCredential } from '@azure/core-auth';
import { GBUtil } from '../../../src/util.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
const WebSiteResponseTimeout = 900;
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) {
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) {
@ -320,7 +321,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
if (!JSON.parse(res.bodyAsText).id) {
throw res.bodyAsText;
}
GBLog.info(`Bot updated at: ${endpoint}.`);
GBLogEx.info(0, `Bot updated at: ${endpoint}.`);
}
public async deleteBot(botId: string, group: string) {
@ -340,7 +341,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
if (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) {
@ -384,7 +385,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
let keys: any;
const name = instance.botId;
GBLog.info(`Enabling resource providers...`);
GBLogEx.info(0, `Enabling resource providers...`);
await this.enableResourceProviders('Microsoft.CognitiveServices');
await this.enableResourceProviders('Microsoft.BotService');
@ -392,20 +393,20 @@ export class AzureDeployerService implements IGBInstallationDeployer {
await this.enableResourceProviders('Microsoft.Web');
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);
let serverFarm;
let serverName;
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);
serverName = `${name}-server`;
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 administratorPassword = GBAdminService.getRndPassword();
const storageServer = `${name.toLowerCase()}-storage-server`;
@ -426,7 +427,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
instance.storageServer = `${storageServer}.database.windows.net`;
// TODO: Enable in .env
// GBLog.info(`Deploying Search...`);
// GBLogEx.info(min, `Deploying Search...`);
// const searchName = `${name}-search`.toLowerCase();
// await this.createSearch(name, searchName, instance.cloudLocation);
// const searchKeys = await this.searchClient.adminKeys.get(name, searchName);
@ -435,27 +436,27 @@ export class AzureDeployerService implements IGBInstallationDeployer {
// instance.searchIndexer = 'azuresql-indexer';
// instance.searchKey = searchKeys.primaryKey;
// GBLog.info(`Deploying Speech...`);
// GBLogEx.info(min, `Deploying Speech...`);
// const speech = await this.createSpeech(name, `${name}speech`, instance.cloudLocation);
// keys = await this.cognitiveClient.accounts.listKeys(name, speech.name);
// instance.speechEndpoint = speech.properties.endpoint;
// 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);
// 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`);
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 nlpa = await this.createNLPAuthoring(name, `${name}-nlpa`, instance.cloudLocation);
// instance.nlpEndpoint = nlp.properties.endpoint;
GBLog.info(`Deploying Bot...`);
GBLogEx.info(0, `Deploying Bot...`);
instance.botEndpoint = 'TODO: remove this column.';
instance = await this.internalDeployBot(
@ -474,7 +475,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
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);
// keys = await this.cognitiveClient.accounts.listKeys(name, textAnalytics.name);
// instance.textAnalyticsKey = keys.key1;
@ -489,7 +490,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
// instance.nlpAppId = nlpAppId;
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);
}
spinner.stop();
@ -656,7 +657,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
database = await this.storageClient.servers.beginCreateOrUpdateAndWait(group, name, params);
} catch (error) {
// 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);
}
@ -848,7 +849,7 @@ export class AzureDeployerService implements IGBInstallationDeployer {
} catch (error) {
// 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);
}
return database;
@ -966,11 +967,11 @@ export class AzureDeployerService implements IGBInstallationDeployer {
} catch (e) {
if (!tryed) {
tryed = true;
GBLog.info('Retrying Deploying Bot Server...');
GBLogEx.info(0, 'Retrying Deploying Bot Server...');
try {
return await create();
} 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;
}
}

View file

@ -38,6 +38,7 @@ import Fs from 'fs';
import SwaggerClient from 'swagger-client';
import { spawn } from 'child_process';
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.
@ -45,7 +46,7 @@ import { CodeServices } from '../../gpt.gblib/services/CodeServices.js';
export class DebuggerService {
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));
}
@ -112,7 +113,7 @@ export class DebuggerService {
if (activities.length) {
activities.forEach(activity => {
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}`;
return { error: error };
} 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 });
return { status: 'OK' };
} 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].stateInfo = 'Running (Debug)';

View file

@ -148,7 +148,7 @@ export class DialogKeywords {
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;
}
@ -157,8 +157,9 @@ export class DialogKeywords {
* Returns the OCR of image file.
*
*/
public async getOCR({ localFile }) {
GBLog.info(`BASIC: OCR processing on ${localFile}.`);
public async getOCR({pid, localFile }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
GBLogEx.info(min, `BASIC: OCR processing on ${localFile}.`);
const config = {
lang: 'eng',
@ -272,9 +273,9 @@ export class DialogKeywords {
);
let dt = SystemKeywords.getDateFromLocaleString(pid, date, contentLocale);
GBLog.info(`BASIC WEEKDAY contentLocale: ${this.getContentLocaleWithCulture(contentLocale)}`);
GBLog.info(`BASIC WEEKDAY date: ${dt}`);
GBLog.info(dt.toLocaleString(this.getContentLocaleWithCulture(contentLocale), { weekday: 'short' }));
GBLogEx.info(min, `BASIC WEEKDAY contentLocale: ${this.getContentLocaleWithCulture(contentLocale)}`);
GBLogEx.info(min, `BASIC WEEKDAY date: ${dt}`);
GBLogEx.info(min, dt.toLocaleString(this.getContentLocaleWithCulture(contentLocale), { weekday: 'short' }));
if (dt) {
if (!(dt instanceof Date)) {
@ -527,14 +528,14 @@ export class DialogKeywords {
*
*/
public async sendEmail({ pid, to, subject, body }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
if (!body) {
body = "";
};
// 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;
// Inline word document used as e-mail body.
@ -571,7 +572,7 @@ export class DialogKeywords {
*/
public async sendFileTo({ pid, mobile, filename, caption }) {
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 });
}
@ -583,7 +584,7 @@ export class DialogKeywords {
*/
public async sendFile({ pid, filename, caption }) {
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 });
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.`);
// }
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();
if (user) {
await sec.setParam(user.userId, name, value);
@ -931,9 +932,9 @@ export class DialogKeywords {
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 {
GBLog.info('BASIC: HEAR (Asking for input).');
GBLogEx.info(min, 'BASIC: HEAR (Asking for input).');
}
// Wait for the user to answer.
@ -966,7 +967,7 @@ export class DialogKeywords {
return m.name === args;
});
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;
}
@ -1007,7 +1008,7 @@ export class DialogKeywords {
return await this.hear({ pid, kind, args });
}
} 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 });
GBServer.globals.files[handle] = answer;
result = handle;
@ -1128,7 +1129,7 @@ export class DialogKeywords {
result = phoneNumber;
} else if (kind === 'qr-scanner') {
//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 });
GBServer.globals.files[handle] = answer;
QrScanner.scanImage(GBServer.globals.files[handle])
@ -1272,7 +1273,7 @@ export class DialogKeywords {
});
let messages = [];
GBLog.info(`MessageBot: Starting message polling ${conversation.conversationId}).`);
GBLogEx.info(min, `MessageBot: Starting message polling ${conversation.conversationId}).`);
let count = API_RETRIES;
while (count--) {
@ -1367,7 +1368,7 @@ export class DialogKeywords {
*/
public async talk({ pid, text }) {
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) {
// 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));
GBLog.info(`BASIC: WebAutomation: Sending ${url} to ${mobile} (${channel}).`);
GBLogEx.info(min, `BASIC: WebAutomation: Sending ${url} to ${mobile} (${channel}).`);
}
// GBFILE object.
@ -1424,17 +1425,17 @@ export class DialogKeywords {
url = filename.url;
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.
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);
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);
@ -1452,7 +1453,7 @@ export class DialogKeywords {
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
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();

View file

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

View file

@ -41,6 +41,7 @@ import { CollectionUtil } from 'pragmatismo-io-framework';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
import urlJoin from 'url-join';
import { GBServer } from '../../../src/app.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/**
* Image processing services of conversation to be called by BASIC.
@ -52,7 +53,8 @@ export class ImageProcessingServices {
* @example file = SHARPEN 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 data = await sharp(gbfile.data)
@ -106,7 +108,8 @@ export class ImageProcessingServices {
* @example file = BLUR 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 data = await sharp(gbfile.data)

View file

@ -119,7 +119,7 @@ export class SystemKeywords {
'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);
}
@ -130,6 +130,7 @@ export class SystemKeywords {
*
*/
public async seeText({ pid, url }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const computerVisionClient = new ComputerVisionClient.ComputerVisionClient(
new ApiKeyCredentials.ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': process.env.VISION_KEY } }),
process.env.VISION_ENDPOINT
@ -151,7 +152,7 @@ export class SystemKeywords {
}
}
GBLog.info(`GBVision (text): '${final}'`);
GBLogEx.info(min, `GBVision (text): '${final}'`);
return final;
}
@ -323,7 +324,7 @@ export class SystemKeywords {
localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.png`);
await page.screenshot({ path: localName, fullPage: true });
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.
@ -332,7 +333,7 @@ export class SystemKeywords {
localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.pdf`);
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName));
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();
@ -466,8 +467,9 @@ export class SystemKeywords {
*
*/
public async wait({ pid, seconds }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
// 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));
await timeout(seconds * 1000);
}
@ -480,7 +482,7 @@ export class SystemKeywords {
*/
public async talkTo({ pid, mobile, message }) {
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);
}
@ -506,7 +508,7 @@ export class SystemKeywords {
*/
public async sendSmsTo({ pid, mobile, message }) {
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);
}
@ -525,7 +527,7 @@ export class SystemKeywords {
// Handles calls for HTML stuff
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 });
return;
@ -543,7 +545,7 @@ export class SystemKeywords {
// 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);
@ -630,7 +632,7 @@ export class SystemKeywords {
*/
public async saveFile({ pid, file, data }): Promise<any> {
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);
const botId = min.instance.botId;
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);
} catch (error) {
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') {
GBLog.info(`BASIC: BASIC destination file already exists: ${file}.`);
GBLogEx.info(min, `BASIC: BASIC destination file already exists: ${file}.`);
}
throw error;
}
@ -664,7 +666,7 @@ export class SystemKeywords {
*/
public async uploadFile({ pid, file }): Promise<any> {
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.
@ -741,7 +743,7 @@ export class SystemKeywords {
*/
public async saveToStorageBatch({ pid, table, rows }): Promise<void> {
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) {
@ -789,7 +791,7 @@ export class SystemKeywords {
}
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);
@ -820,8 +822,8 @@ export class SystemKeywords {
}
public async saveToStorageWithJSON({ pid, table, fieldsValues, fieldsNames }): Promise<any> {
GBLog.info(`BASIC: Saving to storage '${table}' (SAVE).`);
const { min, user } = await DialogKeywords.getProcessInfo(pid);
GBLogEx.info(min, `BASIC: Saving to storage '${table}' (SAVE).`);
const minBoot = GBServer.globals.minBoot as any;
const definition = minBoot.core.sequelize.models[table];
@ -855,7 +857,7 @@ export class SystemKeywords {
}
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);
const botId = min.instance.botId;
const path = DialogKeywords.getGBAIPath(botId, 'gbdata');
@ -956,7 +958,7 @@ export class SystemKeywords {
qs
});
} else {
GBLog.info(`BASIC: GET '${addressOrHeaders}' in '${file}'.`);
GBLogEx.info(min, `BASIC: GET '${addressOrHeaders}' in '${file}'.`);
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
const botId = min.instance.botId;
('');
@ -975,7 +977,7 @@ export class SystemKeywords {
.get();
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;
}
}
@ -1072,7 +1074,7 @@ export class SystemKeywords {
} else {
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)
@ -1246,7 +1248,7 @@ export class SystemKeywords {
case 'string':
const v1 = GBConversationalService.removeDiacritics(result.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) {
case '=':
@ -1365,13 +1367,13 @@ export class SystemKeywords {
const outputArray = await DialogKeywords.getOption({ pid, name: 'output' });
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;
} 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];
} 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;
}
}
@ -1532,7 +1534,7 @@ export class SystemKeywords {
}
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);
const gbaiName = DialogKeywords.getGBAIPath(min.botId);
const tmpDocx = urlJoin(gbaiName, path);
@ -1568,7 +1570,7 @@ export class SystemKeywords {
*/
public async copyFile({ pid, src, dest }) {
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);
const botId = min.instance.botId;
@ -1604,13 +1606,13 @@ export class SystemKeywords {
name: `${Path.basename(dest)}`
};
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;
} catch (error) {
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') {
GBLog.info(`BASIC: COPY destination file already exists: ${dstPath}.`);
GBLogEx.info(min, `BASIC: COPY destination file already exists: ${dstPath}.`);
}
throw error;
}
@ -1630,7 +1632,7 @@ export class SystemKeywords {
public async convert({ pid, src, dest }) {
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);
const botId = min.instance.botId;
@ -1676,9 +1678,9 @@ export class SystemKeywords {
await client.api(`${baseUrl}/drive/root:/${dstPath}:/content`).put(result);
} catch (error) {
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') {
GBLog.info(`BASIC: CONVERT destination file already exists: ${dstPath}.`);
GBLogEx.info(min, `BASIC: CONVERT destination file already exists: ${dstPath}.`);
}
throw error;
}
@ -1780,17 +1782,17 @@ export class SystemKeywords {
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);
throw new Error(`BASIC: HTTP:${result.status} retry: ${result.statusText}.`);
}
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);
throw new Error(`BASIC: HTTP:${result.status} retry: ${result.statusText}.`);
}
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);
throw new Error(`BASIC: HTTP:${result.status} retry: ${result.statusText}.`);
}
@ -1841,7 +1843,7 @@ export class SystemKeywords {
continuationToken = res.next?.headers['MS-ContinuationToken'];
if (continuationToken) {
GBLog.info(`Updating continuationToken for ${url}.`);
GBLogEx.info(min, `Updating continuationToken for ${url}.`);
await DialogKeywords.setOption({ pid, name: 'continuationToken', value: continuationToken });
}
}
@ -1865,6 +1867,7 @@ export class SystemKeywords {
*
*/
public async putByHttp({ pid, url, data, headers }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const options = {
json: data,
headers: headers,
@ -1881,7 +1884,7 @@ export class SystemKeywords {
let result = await fetch(url, options);
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) {
throw new Error(`BASIC: PUT ${result.status}: ${result.statusText}.`)
@ -1901,6 +1904,7 @@ export class SystemKeywords {
*
*/
public async postByHttp({ pid, url, data, headers }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const options = {
headers: headers,
method: 'POST'
@ -1916,7 +1920,7 @@ export class SystemKeywords {
let result = await fetch(url, options);
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) {
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> {
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
if (!data || data.length === 0) {
GBLog.verbose(`BASIC: MERGE running on ${file}: NO 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]) {
this.cachedMerge[pid] = { file: {} }
}
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
// Check if is a tree or flat object.
@ -2237,7 +2240,7 @@ export class SystemKeywords {
page++;
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 });
}
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 };
}
@ -2493,7 +2496,7 @@ export class SystemKeywords {
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) {
GBLog.info('Twitter not configured in .gbot.');
GBLogEx.info(min, 'Twitter not configured in .gbot.');
}
const client = new TwitterApi({
@ -2504,7 +2507,7 @@ export class SystemKeywords {
});
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 prompt = `rewrite this sentence in a better way: ${text}`;
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;
}
@ -2541,7 +2544,7 @@ export class SystemKeywords {
const apiUrl = 'https://apisandbox.cieloecommerce.cielo.com.br/1/sales/';
const requestId = GBAdminService.generateUuid();
GBLog.info(`GBPay: ${requestId}, ${orderId}, ${ammount}... `);
GBLogEx.info(min, `GBPay: ${requestId}, ${orderId}, ${ammount}... `);
const requestData = {
MerchantOrderId: orderId,
@ -2580,7 +2583,7 @@ export class SystemKeywords {
Fs.writeFileSync(localName, buf, { encoding: null });
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 {
name: Path.basename(localName),
@ -2603,7 +2606,7 @@ export class SystemKeywords {
private async internalAutoSave({ min, 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);
const path = DialogKeywords.getGBAIPath(min.botId, `gbdrive`);
@ -2627,7 +2630,7 @@ export class SystemKeywords {
public async deleteFromStorage({ pid, table, criteria }) {
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 filter = await SystemKeywords.getFilter(criteria);
@ -2651,7 +2654,7 @@ export class SystemKeywords {
public async deleteFile({ pid, file }) {
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);
const gbaiPath = DialogKeywords.getGBAIPath(min.botId);

View file

@ -215,9 +215,11 @@ export class WebAutomationServices {
*
* @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);
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);
let frameHandle = await page.$(frame);
const f = await frameHandle.contentFrame();
@ -236,8 +238,10 @@ export class WebAutomationServices {
* Simulates a mouse hover an web page element.
*/
public async hover({ pid, handle, selector }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
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 page.hover(selector);
await this.debugStepWeb(pid, page);
@ -249,8 +253,10 @@ export class WebAutomationServices {
* @example CLICK "#idElement"
*/
public async click({ pid, handle, frameOrSelector, selector }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation CLICK element: ${frameOrSelector}.`);
GBLogEx.info(min, `BASIC: Web Automation CLICK element: ${frameOrSelector}.`);
if (selector) {
await page.waitForSelector(frameOrSelector);
let frameHandle = await page.$(frameOrSelector);
@ -289,9 +295,11 @@ export class WebAutomationServices {
*
* @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);
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') {
char = '\n';
}
@ -306,8 +314,10 @@ export class WebAutomationServices {
}
public async linkByText({ pid, handle, text, index }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
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) {
index = 1;
}
@ -317,8 +327,10 @@ export class WebAutomationServices {
}
public async clickButton({ pid, handle, text, index }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
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) {
index = 1;
}
@ -336,7 +348,7 @@ export class WebAutomationServices {
public async screenshot({ pid, handle, selector }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
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 localName = Path.join('work', gbaiName, 'cache', `screen-${GBAdminService.getRndReadableIdentifier()}.jpg`);
@ -344,7 +356,7 @@ export class WebAutomationServices {
await page.screenshot({ path: 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 };
}
@ -355,9 +367,11 @@ export class WebAutomationServices {
* @example SET page,"selector","text"
*/
public async setElementText({ pid, handle, selector, text }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
text = `${text}`;
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 });
await e.click({ clickCount: 3 });
await page.keyboard.press('Backspace');
@ -397,7 +411,7 @@ export class WebAutomationServices {
const cookies = await page.cookies();
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 filename;
@ -443,7 +457,7 @@ export class WebAutomationServices {
file = await client.api(`${baseUrl}/drive/root:/${dstPath}:/content`).put(result);
} catch (error) {
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;
}
@ -469,8 +483,10 @@ export class WebAutomationServices {
public async getTextOf({ pid, handle, frameOrSelector, selector }) {
const { min, user } = await DialogKeywords.getProcessInfo(pid);
const page = WebAutomationServices.getPageByHandle(handle);
GBLog.info(`BASIC: Web Automation CLICK element: ${frameOrSelector}.`);
GBLogEx.info(min, `BASIC: Web Automation CLICK element: ${frameOrSelector}.`);
if (frameOrSelector) {
const result = await page.$eval(
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].stateInfo = 'Fail';
} 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.
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].stateInfo = 'Break';
@ -232,9 +232,9 @@ export const createVm2Pool = ({ min, max, ...limits }) => {
lineNumber: brk
}
});
GBLog.info(`BASIC break defined ${breakpointId} for ${limits.botId}`);
GBLogEx.info(min, `BASIC break defined ${breakpointId} for ${limits.botId}`);
} 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();

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 { GBConversationalService } from '../services/GBConversationalService.js';
import { Messages } from '../strings.js';
import { GBLogEx } from '../services/GBLogEx.js';
/**
* Dialog for Welcoming people.
@ -96,7 +97,7 @@ export class WelcomeDialog extends IGBDialog {
step.context.activity.type === 'message' &&
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 });
}
}

View file

@ -316,17 +316,17 @@ export class GBConversationalService {
mobile = this.userMobile(step);
if (mobile) {
GBLog.info(`Sending file ${url} to ${mobile}...`);
GBLogEx.info(min, `Sending file ${url} to ${mobile}...`);
const filename = url.substring(url.lastIndexOf('/') + 1);
await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption);
} else {
GBLog.info(
GBLogEx.info(min,
`Sending ${url} as file attachment not available in this channel ${step.context.activity['mobile']}...`
);
await min.conversationalService.sendText(min, step, url);
}
} else {
GBLog.info(`Sending file ${url} to ${mobile}...`);
GBLogEx.info(min, `Sending file ${url} to ${mobile}...`);
const filename = url.substring(url.lastIndexOf('/') + 1);
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> {
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);
}
public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise<any> {
if ( step.context.activity.channelId !== 'msteams' &&
step.context.activity.channelId !== 'omnichannel') {
GBLog.info(
GBLogEx.info(min,
`Sending event ${name}:${typeof value === 'object' ? JSON.stringify(value) : value ? value : ''} to client...`
);
const msg = MessageFactory.text('');
@ -360,7 +360,7 @@ export class GBConversationalService {
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 authToken = process.env.TWILIO_AUTH_TOKEN;
const client = twilio(null, authToken, { accountSid: accountSid });
@ -426,7 +426,7 @@ export class GBConversationalService {
}
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) :
await this.sendSms(min, mobile, message);
}
@ -804,10 +804,10 @@ export class GBConversationalService {
}
if (currentText !== '') {
if (!mobile) {
GBLog.info(`Sending .MD file to Web.`);
GBLogEx.info(min, `Sending .MD file to Web.`);
await step.context.sendActivity(currentText);
} 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);
}
}
@ -888,7 +888,7 @@ export class GBConversationalService {
return false;
}
GBLog.info(
GBLogEx.info(min,
`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;
}
@ -938,7 +938,7 @@ export class GBConversationalService {
text = text.charAt(0).toUpperCase() + text.slice(1);
const data = await AzureText.getSpelledText(key, text);
if (data !== text) {
GBLog.info(`Spelling>: ${data}`);
GBLogEx.info(min, `Spelling>: ${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,
// keeping fixed tokens as specified in Config.
@ -1147,7 +1147,7 @@ export class GBConversationalService {
text = text.replace(new RegExp(`${item.replacementToken}`, 'gi'), item.text);
});
}
GBLog.info(`After (processMessageActivity): ${text}.`);
GBLogEx.info(min, `After (processMessageActivity): ${text}.`);
return text;
}
@ -1235,7 +1235,7 @@ export class GBConversationalService {
}
}
public async broadcast(min: GBMinInstance, message: string) {
GBLog.info(`Sending broadcast notifications...`);
GBLogEx.info(min, `Sending broadcast notifications...`);
const service = new SecService();
const users = await service.getAllUsers(min.instance.instanceId);
@ -1243,7 +1243,7 @@ export class GBConversationalService {
if (user.conversationReference) {
await this.sendOnConversation(min, user, message);
} 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 { file } from 'googleapis/build/src/apis/file/index.js';
import { GBUtil } from '../../../src/util.js';
import { GBLogEx } from './GBLogEx.js';
/**
* GBCoreService contains main logic for handling storage services related
@ -135,7 +136,7 @@ export class GBCoreService implements IGBCoreService {
const logging: boolean | Function =
GBConfigService.get('STORAGE_LOGGING') === 'true'
? (str: string): void => {
GBLog.info(str);
GBLogEx.info(0, str);
}
: false;
@ -178,7 +179,7 @@ export class GBCoreService implements IGBCoreService {
try {
await this.sequelize.authenticate();
} catch (error) {
GBLog.info('Opening storage firewall on infrastructure...');
GBLogEx.info(0, 'Opening storage firewall on infrastructure...');
// tslint:disable:no-unsafe-any
if (error.parent.code === 'ELOGIN') {
await this.openStorageFrontier(installationDeployer);
@ -195,7 +196,7 @@ export class GBCoreService implements IGBCoreService {
public async syncDatabaseStructure() {
if (GBConfigService.get('STORAGE_SYNC') === 'true') {
const alter = GBConfigService.get('STORAGE_SYNC_ALTER') === 'true';
GBLog.info('Syncing database...');
GBLogEx.info(0, 'Syncing database...');
return await this.sequelize.sync({
alter: alter,
@ -203,7 +204,7 @@ export class GBCoreService implements IGBCoreService {
});
} else {
const msg = `Database synchronization is disabled.`;
GBLog.info(msg);
GBLogEx.info(0, msg);
}
}
@ -419,14 +420,14 @@ ENDPOINT_UPDATE=true
installationDeployer: IGBInstallationDeployer,
proxyAddress: string
) {
GBLog.info(`Loading instances from storage...`);
GBLogEx.info(0, `Loading instances from storage...`);
let instances: IGBInstance[];
try {
instances = await core.loadInstances();
const group = GBConfigService.get('CLOUD_GROUP')??GBConfigService.get('BOT_ID');
if (process.env.ENDPOINT_UPDATE === 'true') {
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 {
await installationDeployer.updateBotProxy(
@ -456,7 +457,7 @@ ENDPOINT_UPDATE=true
Try setting STORAGE_SYNC to true in .env file. Error: ${error.message}.`
);
} 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 {
throw new Error(`Cannot connect to operating storage: ${error.message}.`);
@ -492,7 +493,7 @@ ENDPOINT_UPDATE=true
GBHubSpotPackage
],
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;
sysPackages.push(p);
@ -543,7 +544,7 @@ ENDPOINT_UPDATE=true
deployer,
freeTier
) {
GBLog.info(`Deploying cognitive infrastructure (on the cloud / on premises)...`);
GBLogEx.info(0, `Deploying cognitive infrastructure (on the cloud / on premises)...`);
try {
const { instance, credentials, subscriptionId, installationDeployer }
= await StartDialog.createBaseInstance(deployer, freeTier);
@ -557,7 +558,7 @@ ENDPOINT_UPDATE=true
await this.writeEnv(changedInstance);
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.initStorage();

View file

@ -154,7 +154,7 @@ export class GBDeployer implements IGBDeployer {
// For each folder, checks its extensions looking for valid packages.
if (element === '.') {
GBLog.info(`Ignoring ${element}...`);
GBLogEx.info(0, `Ignoring ${element}...`);
} else {
const name = Path.basename(element);
@ -182,9 +182,9 @@ export class GBDeployer implements IGBDeployer {
// Start the process of searching.
GBLog.info(`Deploying Application packages...`);
GBLogEx.info(0, `Deploying Application packages...`);
await CollectionUtil.asyncForEach(paths, async e => {
GBLog.info(`Looking in: ${e}...`);
GBLogEx.info(0, `Looking in: ${e}...`);
await scanPackageDirectory(e);
});
@ -204,7 +204,7 @@ export class GBDeployer implements IGBDeployer {
}
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.
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 });
GBLog.info(`Transpiling default.gbui...`);
GBLogEx.info(0, `Transpiling default.gbui...`);
child_process.execSync(`${npm} run build`, { cwd: root });
}
}
@ -923,11 +923,11 @@ export class GBDeployer implements IGBDeployer {
) {
// 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');
if (process.env.GBAPP_DISABLE_COMPILE !== 'true') {
if (!Fs.existsSync(folder)) {
GBLog.info(`Installing modules for ${gbappPath}...`);
GBLogEx.info(0, `Installing modules for ${gbappPath}...`);
child_process.execSync('npm install', { cwd: gbappPath });
}
}
@ -937,7 +937,7 @@ export class GBDeployer implements IGBDeployer {
// Runs TSC in .gbapp folder.
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 });
}
@ -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++;
} catch (error) {
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) {
if (typeof minOrInstanceId === 'object') {
minOrInstanceId = minOrInstanceId.instance.instanceId;
}

View file

@ -205,11 +205,11 @@ export class GBMinService {
// Loads schedules.
GBLog.info(`Loading SET SCHEDULE entries...`);
GBLogEx.info(0, `Loading SET SCHEDULE entries...`);
const service = new ScheduleServices();
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.
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({
spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')),
@ -402,7 +402,7 @@ export class GBMinService {
const manifest = `${instance.botId}-Teams.zip`;
const packageTeams = urlJoin(`work`, DialogKeywords.getGBAIPath(instance.botId), manifest);
if (!Fs.existsSync(packageTeams)) {
GBLog.info('Generating MS Teams manifest....');
GBLogEx.info(min, 'Generating MS Teams manifest....');
const data = await this.deployer.getBotManifest(instance);
Fs.writeFileSync(packageTeams, data);
}
@ -622,7 +622,7 @@ export class GBMinService {
);
authorizationUrl = `${authorizationUrl}?response_type=code&client_id=${min.instance.marketplaceId
}&redirect_uri=${urlJoin(process.env.BOT_URL, min.instance.botId, 'token')}`;
GBLog.info(`HandleOAuthRequests: ${authorizationUrl}.`);
GBLogEx.info(min, `HandleOAuthRequests: ${authorizationUrl}.`);
res.redirect(authorizationUrl);
});
}
@ -637,15 +637,15 @@ export class GBMinService {
if (botId === '[default]' || botId === undefined) {
botId = GBConfigService.get('BOT_ID');
}
GBLog.info(`Client requested instance for: ${botId}.`);
// Loads by the botId itself or by the activationCode field.
let instance = await this.core.loadInstanceByBotId(botId);
if (instance === null) {
instance = await this.core.loadInstanceByActivationCode(botId);
}
GBLogEx.info(instance.instanceId, `Client requested instance for: ${botId}.`);
if (instance !== null) {
// 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);
if (startDialog) {
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);
}
}
@ -1076,7 +1076,7 @@ export class GBMinService {
// 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})`
);
@ -1087,13 +1087,13 @@ export class GBMinService {
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) {
// Check if a bot or a human participant is being added to the conversation.
const member = context.activity.membersAdded[0];
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.
@ -1114,14 +1114,14 @@ export class GBMinService {
) {
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}...`
);
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
}
}
} else {
GBLog.info(`Person added to conversation: ${member.name}`);
GBLogEx.info(min, `Person added to conversation: ${member.name}`);
return;
}
@ -1190,7 +1190,7 @@ export class GBMinService {
const startDialog = min.core.getParam(min.instance, 'Start Dialog', null);
if (startDialog && !min['conversationWelcomed'][step.context.activity.conversation.id]) {
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);
}
} else if (context.activity.name === 'updateToken') {
@ -1262,7 +1262,7 @@ export class GBMinService {
// a upload with no Dialog, so run Auto Save to .gbdrive.
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 });
let data = Fs.readFileSync(attachmentData.localPath);
@ -1418,7 +1418,7 @@ export class GBMinService {
) {
await sec.setParam(userId, 'welcomed', '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}...`
);
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
@ -1504,7 +1504,7 @@ export class GBMinService {
if (user.agentMode === 'self') {
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 ';
if (text.startsWith(cmd)) {
@ -1566,7 +1566,7 @@ export class GBMinService {
}
});
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', {
data: data,
query: text,

View file

@ -36,6 +36,7 @@ import Fs from 'fs';
import { GBLog, GBMinInstance, GBService } from 'botlib';
import { GBServer } from '../../../src/app.js';
import { SecService } from '../../security.gbapp/services/SecService.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/**
* Support for Google Chat.
@ -116,7 +117,7 @@ export class GoogleChatDirectLine extends GBService {
}
public async check () {
GBLog.info(`GBGoogleChat: Checking server...`);
GBLogEx.info(0, `GBGoogleChat: Checking server...`);
}
public async receiver (message) {
@ -132,7 +133,7 @@ export class GoogleChatDirectLine extends GBService {
text = event.message.text;
fromName = event.message.sender.displayName;
from = event.message.sender.email;
GBLog.info(`Received message from ${from} (${fromName}): ${text}.`);
GBLogEx.info(0, `Received message from ${from} (${fromName}): ${text}.`);
}
message.ack();
@ -141,13 +142,13 @@ export class GoogleChatDirectLine extends GBService {
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 conversationId = GoogleChatDirectLine.conversationIds[from];
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 generatedConversationId = response.obj.conversationId;
@ -178,7 +179,7 @@ export class GoogleChatDirectLine extends GBService {
}
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;
@ -217,7 +218,7 @@ export class GoogleChatDirectLine extends GBService {
let output = '';
if (activity.text) {
GBLog.info(`GBGoogleChat: SND ${from}(${fromName}): ${activity.text}`);
GBLogEx.info(0, `GBGoogleChat: SND ${from}(${fromName}): ${activity.text}`);
output = activity.text;
}
@ -225,11 +226,11 @@ export class GoogleChatDirectLine extends GBService {
activity.attachments.forEach(attachment => {
switch (attachment.contentType) {
case 'image/png':
GBLog.info(`Opening the requested image ${attachment.contentUrl}`);
GBLogEx.info(0, `Opening the requested image ${attachment.contentUrl}`);
output += `\n${attachment.contentUrl}`;
break;
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
}
});
GBLog.info(res);
GBLog.info(`Message [${msg}] sent to ${from}: `);
GBLogEx.info(0, `Message [${msg}] sent to ${from}: `);
} catch (error) {
GBLog.error(`Error sending message to GoogleChat provider ${error.message}`);
}

View file

@ -74,21 +74,22 @@ function isChatGeneration(
class CustomHandler extends BaseCallbackHandler {
name = "custom_handler";
handleLLMNewToken(token: string) {
GBLog.info(`LLM: token: ${JSON.stringify(token)}`);
GBLogEx.info(0, `LLM: token: ${JSON.stringify(token)}`);
}
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) {
GBLog.info(`LLM: handleChainStart: ${JSON.stringify(chain)}`);
GBLogEx.info(0, `LLM: handleChainStart: ${JSON.stringify(chain)}`);
}
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 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);
return await GBVMService.callVM(name, min, false, pid, false, args);
@ -445,7 +446,7 @@ export class ChatServices {
}
else {
GBLog.info(`Invalid Answer Mode in Config.xlsx: ${LLMMode}.`);
GBLogEx.info(min, `Invalid Answer Mode in Config.xlsx: ${LLMMode}.`);
}
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 };
}

View file

@ -50,6 +50,7 @@ import urlJoin from 'url-join';
import { SystemKeywords } from '../../basic.gblib/services/SystemKeywords.js';
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
import Path from 'path';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/**
* Dialog arguments.
@ -155,7 +156,7 @@ export class AskDialog extends IGBDialog {
});
if (!handled) {
data.step = null;
GBLog.info(`/answer being called from getAskDialog.`);
GBLogEx.info(min, `/answer being called from getAskDialog.`);
await step.beginDialog(nextDialog ? nextDialog : '/answer', {
data: data,
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.
@ -349,7 +350,7 @@ export class AskDialog extends IGBDialog {
await min.conversationalService.sendText(min, step, 'Thank you. The dialog is being written right now...');
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, {
timeoutMs: CHATGPT_TIMEOUT
});

View file

@ -300,13 +300,13 @@ export class KBService implements IGBKBService {
contentLocale
);
GBLog.info(`Translated query (prompt): ${query}.`);
GBLogEx.info(min, `Translated query (prompt): ${query}.`);
// Try simple search first.
const data = await this.getAnswerByText(instance.instanceId, query.trim());
if (data) {
GBLog.info(`Simple SEARCH called.`);
GBLogEx.info(min, `Simple SEARCH called.`);
return { answer: data.answer, questionId: data.question.questionId };
}
@ -359,11 +359,11 @@ export class KBService implements IGBKBService {
if (returnedScore >= searchScore) {
const value = await this.getAnswerById(instance.instanceId, result.document.answerId);
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 };
} else {
GBLog.info(
GBLogEx.info(min,
`Index problem. SEARCH WILL NOT be used as answerId ${result.document.answerId} was not found in database,
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,
returnedScore: ${returnedScore} < required (searchScore): ${searchScore}`
);
@ -447,7 +447,7 @@ export class KBService implements IGBKBService {
min: GBMinInstance,
packageId: number
): Promise<GuaribasQuestion[]> {
GBLog.info(`Now reading file ${filePath}...`);
GBLogEx.info(min, `Now reading file ${filePath}...`);
const workbook = new Excel.Workbook();
const data = await workbook.xlsx.readFile(filePath);
@ -469,7 +469,7 @@ export class KBService implements IGBKBService {
const answers = [];
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 => {
// Skips the first line.
@ -503,7 +503,7 @@ export class KBService implements IGBKBService {
let media = null;
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 =
'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) {
@ -522,7 +522,7 @@ export class KBService implements IGBKBService {
media = path.basename(mediaFilename);
} else {
if (answer.indexOf('.md') > -1) {
GBLog.info(`[GBImporter] File not found: ${mediaFilename}.`);
GBLogEx.info(min, `[GBImporter] File not found: ${mediaFilename}.`);
answer = '';
}
}
@ -857,7 +857,7 @@ export class KBService implements IGBKBService {
): Promise<any> {
const files = await walkPromise(urlJoin(localPath, 'docs'));
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.`
);
} else {
@ -1088,7 +1088,7 @@ export class KBService implements IGBKBService {
public async deployKb(core: IGBCoreService, deployer: GBDeployer, localPath: string, min: GBMinInstance) {
const packageName = Path.basename(localPath);
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);
await this.importKbPackage(min, localPath, p, instance);
@ -1100,14 +1100,14 @@ export class KBService implements IGBKBService {
min['groupCache'] = await KBService.getGroupReplies(instance.instanceId);
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);
let path = DialogKeywords.getGBAIPath(min.botId, `gbui`);
path = Path.join(process.env.PWD, 'work', path, 'index.html');
GBLogEx.info(min, `[GBDeployer] Saving SSR HTML in ${path}.`);
Fs.writeFileSync(path, html, 'utf8');
GBLog.info(`[GBDeployer] Finished import of ${localPath}`);
GBLogEx.info(min, `[GBDeployer] Finished import of ${localPath}`);
}
private async playAudio(
@ -1161,20 +1161,7 @@ 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) => {
textract.fromFileWithPath(filename, { preserveLineBreaks: true }, (error, text) => {
if (error) {

View file

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

View file

@ -38,6 +38,7 @@ import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
import { Messages } from '../strings.js';
import libphonenumber from 'google-libphonenumber';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/**
* 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.`
);
} 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);

View file

@ -39,6 +39,7 @@ import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
import { Messages } from '../strings.js';
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
import { SecService } from '../services/SecService.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
/**
* Dialogs for handling Menu control.
*/
@ -64,7 +65,7 @@ export class SMSAuthDialog extends IGBDialog {
// Generates a new mobile code.
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.mobile = mobile;
@ -86,7 +87,7 @@ export class SMSAuthDialog extends IGBDialog {
let sec = new SecService();
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);
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 mkdirp from 'mkdirp';
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);
GBLog.info(`Updated agentId to: ${agentSystemId}`);
GBLogEx.info(min, `Updated agentId to: ${agentSystemId}`);
return agentSystemId;
}

View file

@ -53,6 +53,7 @@ import { GBUtil } from '../../../src/util.js';
const { WAState, Client, MessageMedia } = pkg;
import twilio from 'twilio';
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, '');
GBLog.info(`GBWhatsapp: RCV ${from}(${fromName}): ${text})`);
GBLogEx.info(0, `GBWhatsapp: RCV ${from}(${fromName}): ${text})`);
let botGroupID = WhatsappDirectLine.botGroups[this.min.botId];
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(user.agentSystemId, this.min.instance.instanceId, null);
} 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);
}
}
@ -481,7 +482,7 @@ export class WhatsappDirectLine extends GBService {
} else if (text === '/qt' || GBMinService.isGlobalQuitUtterance(locale, text)) {
await this.endTransfer(from, locale, user, agent, sec);
} 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 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) {
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 generatedConversationId = response.obj.conversationId;
@ -579,7 +580,7 @@ export class WhatsappDirectLine extends GBService {
}
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;
@ -621,7 +622,7 @@ export class WhatsappDirectLine extends GBService {
let output = '';
if (activity.text) {
GBLog.info(`GBWhatsapp: SND ${to}(${toName}): ${activity.text}`);
GBLogEx.info(this.min, `GBWhatsapp: SND ${to}(${toName}): ${activity.text}`);
output = activity.text;
}
@ -638,7 +639,7 @@ export class WhatsappDirectLine extends GBService {
return;
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 {
// tslint:disable-next-line: await-promise
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) {
GBLog.error(`Error sending file to Whatsapp provider ${error.message}`);
}
@ -694,7 +695,7 @@ export class WhatsappDirectLine extends GBService {
if (options) {
try {
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) {
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);
}
else {
GBLog.info(`WhatsApp OFFLINE ${to}: ${msg}`);
GBLogEx.info(this.min, `WhatsApp OFFLINE ${to}: ${msg}`);
}
break;
@ -765,7 +766,7 @@ export class WhatsappDirectLine extends GBService {
if (options) {
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);
} catch (error) {
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;
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];
// 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;
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(
min.instance,
'Default User Language',
@ -856,7 +857,7 @@ export class WhatsappDirectLine extends GBService {
if (text != '' && detectLanguage) {
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) {
GBLog.info(`Group: ${group}`);
GBLogEx.info(this.min, `Group: ${group}`);
function getKeyByValue(object, 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);
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') {
req.body = `/start`;
}
@ -977,7 +978,7 @@ export class WhatsappDirectLine extends GBService {
// User wants to switch bots.
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
// auto start dialog if any is specified.
@ -990,7 +991,7 @@ export class WhatsappDirectLine extends GBService {
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') {
req.body = `/start`;
}

View file

@ -60,6 +60,7 @@ import { RootData } from './RootData.js';
import { GBSSR } from '../packages/core.gbapp/services/GBSSR.js';
import { Mutex } from 'async-mutex';
import httpProxy from 'http-proxy';
import { GBLogEx } from '../packages/core.gbapp/services/GBLogEx.js';
/**
* General Bots open-core entry point.
@ -72,13 +73,13 @@ export class GBServer {
*/
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();
GBConfigService.init();
const port = GBConfigService.getServerPort();
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 {
child_process.execSync(process.env.TEST_SHELL);
} catch (error) {
@ -108,7 +109,7 @@ export class GBServer {
server.use(bodyParser.urlencoded({ limit: '1mb', extended: true }));
process.on('SIGTERM', () => {
GBLog.info('SIGTERM signal received.');
GBLogEx.info(0, 'SIGTERM signal received.');
});
process.on('uncaughtException', (err, p) => {
@ -132,7 +133,7 @@ export class GBServer {
(async () => {
try {
GBLog.info(`Now accepting connections on ${port}...`);
GBLogEx.info(0, `Now accepting connections on ${port}...`);
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
// Reads basic configuration, initialize minimal services.
@ -151,11 +152,11 @@ export class GBServer {
} else {
GBServer.globals.publicAddress = await core.ensureProxy(port);
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 {
const serverAddress = process.env.BOT_URL;
GBLog.info(`.env address at ${serverAddress}...`);
GBLogEx.info(0, `.env address at ${serverAddress}...`);
GBServer.globals.publicAddress = serverAddress;
}
@ -181,9 +182,9 @@ export class GBServer {
// Deploys system and user packages.
GBLog.info(`Deploying System packages...`);
GBLogEx.info(0, `Deploying System packages...`);
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 deployer.deployPackages(core, server, GBServer.globals.appPackages);
await core.syncDatabaseStructure();
@ -198,7 +199,7 @@ export class GBServer {
deployer.setupDefaultGBUI();
}
GBLog.info(`Publishing instances...`);
GBLogEx.info(0, `Publishing instances...`);
const instances: IGBInstance[] = await core.loadAllInstances(
core,
azureDeployer,
@ -277,7 +278,7 @@ export class GBServer {
const proxy = httpProxy.createProxyServer({});
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
} else {
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.