fix(basic.gblib): Upgrade to https://github.com/vasyas/push-rpc.
This commit is contained in:
parent
4314a37916
commit
f3b7c1d77e
11 changed files with 235 additions and 340 deletions
|
@ -67,6 +67,9 @@
|
|||
"@microsoft/microsoft-graph-client": "3.0.4",
|
||||
"@nlpjs/basic": "4.26.1",
|
||||
"@nosferatu500/textract": "3.1.2",
|
||||
"@push-rpc/core": "^1.5.7",
|
||||
"@push-rpc/http": "^1.5.7",
|
||||
"@push-rpc/websocket": "^1.5.7",
|
||||
"@semantic-release/changelog": "5.0.1",
|
||||
"@semantic-release/exec": "5.0.0",
|
||||
"@semantic-release/git": "9.0.0",
|
||||
|
@ -171,6 +174,7 @@
|
|||
"whatsapp-web.js": "github:pedroslopez/whatsapp-web.js#fix-buttons-list",
|
||||
"winston": "3.8.2",
|
||||
"winston-logs-display": "1.0.0",
|
||||
"ws": "^8.12.1",
|
||||
"yarn": "1.22.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -39,16 +39,43 @@
|
|||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
||||
import { GuaribasSchedule } from '../core.gbapp/models/GBModel.js';
|
||||
import { Sequelize } from 'sequelize-typescript';
|
||||
import { createServerRouter } from 'typescript-rest-rpc/lib/server.js';
|
||||
import { DialogKeywords } from './services/DialogKeywords.js';
|
||||
import { SystemKeywords } from './services/SystemKeywords.js';
|
||||
import { WebAutomationServices } from './services/WebAutomationServices.js';
|
||||
import { ImageProcessingServices } from './services/ImageProcessingServices.js';
|
||||
import { DebuggerService } from './services/DebuggerService.js';
|
||||
import * as koaBody from 'koa-body';
|
||||
import Koa from 'koa';
|
||||
|
||||
import {createRpcServer, createRpcClient} from "@push-rpc/core"
|
||||
import {createKoaHttpMiddleware, createExpressHttpMiddleware, createHttpClient} from "@push-rpc/http"
|
||||
import { GBServer } from '../../src/app.js';
|
||||
const app = new Koa();
|
||||
import {SocketServer} from "@push-rpc/core"
|
||||
import * as koaBody from "koa-body"
|
||||
|
||||
|
||||
export function createKoaHttpServer(
|
||||
port: number,
|
||||
getRemoteId: (ctx: Koa.Context) => string
|
||||
): SocketServer {
|
||||
const {onError, onConnection, middleware} = createKoaHttpMiddleware(getRemoteId)
|
||||
|
||||
const app = new Koa()
|
||||
app.use(koaBody.koaBody({multipart: true}))
|
||||
app.use(middleware)
|
||||
const server = app.listen(port)
|
||||
|
||||
return {
|
||||
onError,
|
||||
onConnection,
|
||||
close(cb) {
|
||||
server.close(cb)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Package for core.gbapp.
|
||||
|
@ -60,9 +87,49 @@ export class GBBasicPackage implements IGBPackage {
|
|||
|
||||
public async loadPackage (core: IGBCoreService, sequelize: Sequelize): Promise<void> {
|
||||
core.sequelize.addModels([GuaribasSchedule]);
|
||||
//app.use(koaBody.koaBody({ multipart: true, }));
|
||||
|
||||
app.listen(1111);
|
||||
const dk = new DialogKeywords();
|
||||
const wa = new WebAutomationServices();
|
||||
const sys = new SystemKeywords();
|
||||
const dbg = new DebuggerService();
|
||||
const img = new ImageProcessingServices();
|
||||
|
||||
// remote id is required for assigning separate HTTP requests to a single session
|
||||
function getRemoteId(ctx: Koa.Context) {
|
||||
return "1" // share a single session for now, real impl could use cookies or some other meaning for HTTP sessions
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GBServer.globals.server.dk = createRpcServer(dk, createKoaHttpServer(5555, getRemoteId),{
|
||||
listeners: {
|
||||
unsubscribed(subscriptions: number): void {},
|
||||
subscribed(subscriptions: number): void {},
|
||||
disconnected(remoteId: string, connections: number): void {
|
||||
console.log(`Client ${remoteId} disconnected`)
|
||||
},
|
||||
connected(remoteId: string, connections: number): void {
|
||||
console.log(`New client ${remoteId} connected`)
|
||||
},
|
||||
messageIn(...params): void {
|
||||
console.log("IN ", params)
|
||||
},
|
||||
messageOut(...params): void {
|
||||
console.log("OUT ", params)
|
||||
},
|
||||
},
|
||||
pingSendTimeout: null,
|
||||
keepAliveTimeout: null,
|
||||
})
|
||||
|
||||
console.log("RPC Server started at ws://localhost:5555")
|
||||
|
||||
// GBServer.globals.wa = createRpcServer(wa, createWebsocketServer({port: 1112}));
|
||||
// GBServer.globals.sys = createRpcServer(sys, createWebsocketServer({port: 1113}));
|
||||
// GBServer.globals.dbg = createRpcServer(dbg, createWebsocketServer({port: 1114}));
|
||||
// GBServer.globals.img = createRpcServer(img, createWebsocketServer({port: 1115}));
|
||||
}
|
||||
|
||||
public async getDialogs (min: GBMinInstance) {
|
||||
|
@ -81,28 +148,16 @@ export class GBBasicPackage implements IGBPackage {
|
|||
GBLog.verbose(`onExchangeData called.`);
|
||||
}
|
||||
public async loadBot (min: GBMinInstance): Promise<void> {
|
||||
const dk = new DialogKeywords(min, null, null);
|
||||
const wa = new WebAutomationServices(min, null, dk);
|
||||
const sys = new SystemKeywords(min, null, dk, wa);
|
||||
const dbg = new DebuggerService(min, null, dk);
|
||||
const img = new ImageProcessingServices(min, null, dk);
|
||||
dk.wa = wa;
|
||||
wa.sys = sys;
|
||||
const dialogRouter = createServerRouter(`/api/v2/${min.botId}/dialog`, dk);
|
||||
const waRouter = createServerRouter(`/api/v2/${min.botId}/webautomation`, wa);
|
||||
const sysRouter = createServerRouter(`/api/v2/${min.botId}/system`, sys);
|
||||
const dbgRouter = createServerRouter(`/api/v2/${min.botId}/debugger`, dbg);
|
||||
const imgRouter = createServerRouter(`/api/v2/${min.botId}/imageprocessing`, dbg);
|
||||
app.use(dialogRouter.routes());
|
||||
app.use(sysRouter.routes());
|
||||
app.use(waRouter.routes());
|
||||
app.use(dbgRouter.routes());
|
||||
app.use(imgRouter.routes());
|
||||
app.use(async (ctx, next) => {
|
||||
if(ctx['status'] === 404){
|
||||
ctx.status = 404
|
||||
ctx.body = {msg:'emmmmmmm, seems 404'};
|
||||
}
|
||||
});
|
||||
|
||||
const botId = min.botId;
|
||||
GBServer.globals.debuggers[botId] = {};
|
||||
GBServer.globals.debuggers[botId].state = 0;
|
||||
GBServer.globals.debuggers[botId].breaks = [];
|
||||
GBServer.globals.debuggers[botId].stateInfo = 'Stopped';
|
||||
GBServer.globals.debuggers[botId].childProcess = null;
|
||||
GBServer.globals.debuggers[botId].client = null;
|
||||
GBServer.globals.debuggers[botId].conversationsMap = {};
|
||||
GBServer.globals.debuggers[botId].watermarkMap = {};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,44 +44,6 @@ import { spawn } from 'child_process';
|
|||
* Web Automation services of conversation to be called by BASIC.
|
||||
*/
|
||||
export class DebuggerService {
|
||||
/**
|
||||
* Reference to minimal bot instance.
|
||||
*/
|
||||
public min: GBMinInstance;
|
||||
|
||||
/**
|
||||
* Reference to the base system keywords functions to be called.
|
||||
*/
|
||||
public dk: DialogKeywords;
|
||||
|
||||
/**
|
||||
* Current user object to get BASIC properties read.
|
||||
*/
|
||||
public user;
|
||||
|
||||
/**
|
||||
* HTML browser for conversation over page interaction.
|
||||
*/
|
||||
browser: any;
|
||||
|
||||
sys: any;
|
||||
|
||||
/**
|
||||
* The number used in this execution for HEAR calls (useful for SET SCHEDULE).
|
||||
*/
|
||||
hrOn: string;
|
||||
|
||||
userId: GuaribasUser;
|
||||
debugWeb: boolean;
|
||||
lastDebugWeb: Date;
|
||||
|
||||
/**
|
||||
* SYSTEM account maxLines,when used with impersonated contexts (eg. running in SET SCHEDULE).
|
||||
*/
|
||||
maxLines: number = 2000;
|
||||
|
||||
conversationsMap = {};
|
||||
watermarkMap = {};
|
||||
static systemVariables = [
|
||||
'AggregateError',
|
||||
'Array',
|
||||
|
@ -173,28 +135,6 @@ export class DebuggerService {
|
|||
'valueOf'
|
||||
];
|
||||
|
||||
/**
|
||||
* When creating this keyword facade,a bot instance is
|
||||
* specified among the deployer service.
|
||||
*/
|
||||
constructor (min: GBMinInstance, user, dk) {
|
||||
this.min = min;
|
||||
this.user = user;
|
||||
this.dk = dk;
|
||||
|
||||
this.debugWeb = this.min.core.getParam<boolean>(this.min.instance, 'Debug Web Automation', false);
|
||||
|
||||
const botId = min.botId;
|
||||
|
||||
GBServer.globals.debuggers[botId] = {};
|
||||
GBServer.globals.debuggers[botId].state = 0;
|
||||
GBServer.globals.debuggers[botId].breaks = [];
|
||||
GBServer.globals.debuggers[botId].stateInfo = 'Stopped';
|
||||
GBServer.globals.debuggers[botId].childProcess = null;
|
||||
}
|
||||
|
||||
private client;
|
||||
|
||||
public async breakpoint ({ botId, line }) {
|
||||
GBLog.info(`BASIC: Enabled breakpoint for ${botId} on ${line}.`);
|
||||
GBServer.globals.debuggers[botId].breaks.push(Number.parseInt(line));
|
||||
|
@ -239,14 +179,18 @@ export class DebuggerService {
|
|||
}
|
||||
|
||||
public async context ({ botId }) {
|
||||
const conversationId = this.conversationsMap[botId];
|
||||
const conversationsMap = GBServer.globals.debuggers[botId].conversationsMap;
|
||||
const watermarkMap = GBServer.globals.debuggers[botId].watermarkMap;
|
||||
|
||||
const conversationId = conversationsMap[botId];
|
||||
let messages = [];
|
||||
if (this.client) {
|
||||
const response = await this.client.Conversations.Conversations_GetActivities({
|
||||
const client = GBServer.globals.debuggers[botId].client;
|
||||
if (client) {
|
||||
const response = await client.Conversations.Conversations_GetActivities({
|
||||
conversationId: conversationId,
|
||||
watermark: this.watermarkMap[botId]
|
||||
watermark: watermarkMap[botId]
|
||||
});
|
||||
this.watermarkMap[botId] = response.obj.watermark;
|
||||
watermarkMap[botId] = response.obj.watermark;
|
||||
let activities = response.obj.activites;
|
||||
|
||||
if (activities && activities.length) {
|
||||
|
@ -272,6 +216,8 @@ export class DebuggerService {
|
|||
}
|
||||
|
||||
public async getRunning ({ botId, botApiKey, scriptName }) {
|
||||
const conversationsMap = GBServer.globals.debuggers[botId].conversationsMap;
|
||||
|
||||
let error;
|
||||
botId = botId[0];
|
||||
if (!GBServer.globals.debuggers[botId]) {
|
||||
|
@ -296,20 +242,21 @@ export class DebuggerService {
|
|||
|
||||
let min: GBMinInstance = GBServer.globals.minInstances.filter(p => p.instance.botId === botId)[0];
|
||||
|
||||
this.client = await new Swagger({
|
||||
GBServer.globals.debuggers[botId].client = await new Swagger({
|
||||
spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')),
|
||||
usePromise: true
|
||||
});
|
||||
this.client.clientAuthorizations.add(
|
||||
const client = GBServer.globals.debuggers[botId].client;
|
||||
client.clientAuthorizations.add(
|
||||
'AuthorizationBotConnector',
|
||||
new Swagger.ApiKeyAuthorization('Authorization', `Bearer ${min.instance.webchatKey}`, 'header')
|
||||
);
|
||||
const response = await this.client.Conversations.Conversations_StartConversation();
|
||||
const response = await client.Conversations.Conversations_StartConversation();
|
||||
const conversationId = response.obj.conversationId;
|
||||
this.conversationsMap[botId] = conversationId;
|
||||
conversationsMap[botId] = conversationId;
|
||||
GBServer.globals.debugConversationId = conversationId;
|
||||
|
||||
this.client.Conversations.Conversations_PostActivity({
|
||||
client.Conversations.Conversations_PostActivity({
|
||||
conversationId: conversationId,
|
||||
activity: {
|
||||
textFormat: 'plain',
|
||||
|
|
|
@ -69,67 +69,6 @@ const DEFAULT_HEAR_POLL_INTERVAL = 500;
|
|||
* Base services of conversation to be called by BASIC.
|
||||
*/
|
||||
export class DialogKeywords {
|
||||
/**
|
||||
* Reference to minimal bot instance.
|
||||
*/
|
||||
public min: GBMinInstance;
|
||||
|
||||
/**
|
||||
* Reference to the base system keywords functions to be called.
|
||||
*/
|
||||
public internalSys: SystemKeywords;
|
||||
|
||||
/**
|
||||
* Current user object to get BASIC properties read.
|
||||
*/
|
||||
public user;
|
||||
|
||||
/**
|
||||
* HTML browser for conversation over page interaction.
|
||||
*/
|
||||
browser: any;
|
||||
|
||||
/**
|
||||
* The number used in this execution for HEAR calls (useful for SET SCHEDULE).
|
||||
*/
|
||||
hrOn: string;
|
||||
userId: GuaribasUser;
|
||||
debugWeb: boolean;
|
||||
lastDebugWeb: Date;
|
||||
public wa;
|
||||
|
||||
/**
|
||||
* SYSTEM account maxLines,when used with impersonated contexts (eg. running in SET SCHEDULE).
|
||||
*/
|
||||
maxLines: number = 2000;
|
||||
|
||||
public async getDeployer() {
|
||||
return this.min.deployService;
|
||||
}
|
||||
|
||||
public async getMin() {
|
||||
return this.min;
|
||||
}
|
||||
|
||||
/**
|
||||
* When creating this keyword facade,a bot instance is
|
||||
* specified among the deployer service.
|
||||
*/
|
||||
constructor(min: GBMinInstance, deployer: GBDeployer, user) {
|
||||
this.min = min;
|
||||
this.user = user;
|
||||
this.internalSys = new SystemKeywords(min, deployer, this, null);
|
||||
|
||||
this.debugWeb = this.min.core.getParam<boolean>(this.min.instance, 'Debug Web Automation', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base reference of system keyword facade,called directly
|
||||
* by the script.
|
||||
*/
|
||||
public sys(): SystemKeywords {
|
||||
return this.internalSys;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -144,7 +83,8 @@ export class DialogKeywords {
|
|||
* @param legends
|
||||
* @see https://www.npmjs.com/package/plot
|
||||
*/
|
||||
public async chart({ type, data, legends, transpose }) {
|
||||
public async chart({pid, type, data, legends, transpose }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
let table = [[]];
|
||||
|
||||
if (legends) {
|
||||
|
@ -195,12 +135,12 @@ export class DialogKeywords {
|
|||
};
|
||||
}
|
||||
|
||||
const gbaiName = `${this.min.botId}.gbai`;
|
||||
const gbaiName = `${min.botId}.gbai`;
|
||||
const localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.jpg`);
|
||||
|
||||
await ChartServices.screenshot(definition, localName);
|
||||
|
||||
const url = urlJoin(GBServer.globals.publicAddress, this.min.botId, 'cache', Path.basename(localName));
|
||||
const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName));
|
||||
|
||||
GBLog.info(`BASIC: Visualization: Chart generated at ${url}.`);
|
||||
|
||||
|
@ -228,7 +168,8 @@ export class DialogKeywords {
|
|||
*
|
||||
* @example x = TODAY
|
||||
*/
|
||||
public async getToday({}) {
|
||||
public async getToday({pid}) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
let d = new Date(),
|
||||
month = '' + (d.getMonth() + 1),
|
||||
day = '' + d.getDate(),
|
||||
|
@ -241,8 +182,8 @@ export class DialogKeywords {
|
|||
day = '0' + day;
|
||||
}
|
||||
|
||||
const contentLocale = this.min.core.getParam<string>(
|
||||
this.min.instance,
|
||||
const contentLocale = min.core.getParam(
|
||||
min.instance,
|
||||
'Default Content Language',
|
||||
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
||||
);
|
||||
|
@ -316,9 +257,10 @@ export class DialogKeywords {
|
|||
* @example day = WEEKDAY (date)
|
||||
*
|
||||
*/
|
||||
public getWeekFromDate(pid, date) {
|
||||
const contentLocale = this.min.core.getParam<string>(
|
||||
this.min.instance,
|
||||
public async getWeekFromDate({pid, date}) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
const contentLocale = min.core.getParam(
|
||||
min.instance,
|
||||
'Default Content Language',
|
||||
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
||||
);
|
||||
|
@ -465,7 +407,7 @@ export class DialogKeywords {
|
|||
return i;
|
||||
}
|
||||
|
||||
const contentLocale = this.min.core.getParam<string>(
|
||||
const contentLocale = min.core.getParam(
|
||||
min.instance,
|
||||
'Default Content Language',
|
||||
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
||||
|
@ -488,9 +430,10 @@ export class DialogKeywords {
|
|||
* @example SAVE "contacts.xlsx", name, email, NOW
|
||||
*
|
||||
*/
|
||||
public async getNow({}) {
|
||||
const contentLocale = this.min.core.getParam<string>(
|
||||
this.min.instance,
|
||||
public async getNow({pid}) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
const contentLocale = min.core.getParam(
|
||||
min.instance,
|
||||
'Default Content Language',
|
||||
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
||||
);
|
||||
|
@ -574,9 +517,10 @@ export class DialogKeywords {
|
|||
* @example SET LANGUAGE "pt"
|
||||
*
|
||||
*/
|
||||
public async setLanguage({ language }) {
|
||||
public async setLanguage({ pid, language }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
const sec = new SecService();
|
||||
await sec.updateUserLocale(this.user.userId, language);
|
||||
await sec.updateUserLocale(user.userId, language);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -587,7 +531,7 @@ export class DialogKeywords {
|
|||
*/
|
||||
public async setIdGeneration({ mode }) {
|
||||
this['idGeneration'] = mode;
|
||||
this['id'] = this.sys().getRandomId();
|
||||
this['id'] = new SystemKeywords().getRandomId();
|
||||
}
|
||||
|
||||
private isUserSystemParam(name: string): Boolean {
|
||||
|
@ -751,8 +695,7 @@ export class DialogKeywords {
|
|||
*
|
||||
*/
|
||||
public async getHear({ pid, kind, arg }) {
|
||||
const process = GBServer.globals.processes[pid];
|
||||
let { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
let { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||
|
||||
// Handles first arg as an array of args.
|
||||
|
||||
|
@ -772,8 +715,8 @@ export class DialogKeywords {
|
|||
// containing the specified user other than the actual user
|
||||
// TODO: Store hrOn in processInfo.
|
||||
|
||||
if (this.hrOn) {
|
||||
user = await sec.getUserFromAgentSystemId(this.hrOn);
|
||||
if (params.hrOn) {
|
||||
user = await sec.getUserFromAgentSystemId(params.hrOn);
|
||||
}
|
||||
|
||||
const userId = user.userId;
|
||||
|
@ -831,7 +774,7 @@ export class DialogKeywords {
|
|||
|
||||
// Retrieves the .xlsx file associated with the HEAR var AS file.xlsx.
|
||||
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
const botId = min.instance.botId;
|
||||
const path = urljoin(`${botId}.gbai`, `${botId}.gbdata`);
|
||||
let url = `${baseUrl}/drive/root:/${path}:/children`;
|
||||
|
@ -884,13 +827,13 @@ export class DialogKeywords {
|
|||
// In case of unmatch, asks the person to try again.
|
||||
|
||||
if (result === null) {
|
||||
await this.getTalk({ pid, text: `Escolha por favor um dos itens sugeridos.` });
|
||||
await this.talk({ pid, text: `Escolha por favor um dos itens sugeridos.` });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
|
||||
} else if (kind === 'file') {
|
||||
GBLog.info(`BASIC (${min.botId}): Upload done for ${answer.filename}.`);
|
||||
const handle = WebAutomationServices.cyrb53(this.min.botId + answer.filename);
|
||||
const handle = WebAutomationServices.cyrb53(min.botId + answer.filename);
|
||||
GBServer.globals.files[handle] = answer;
|
||||
result = handle;
|
||||
} else if (kind === 'boolean') {
|
||||
|
@ -907,7 +850,7 @@ export class DialogKeywords {
|
|||
const value = extractEntity(answer);
|
||||
|
||||
if (value === null) {
|
||||
await this.getTalk({ pid, text: 'Por favor, digite um e-mail válido.' });
|
||||
await this.talk({ pid, text: 'Por favor, digite um e-mail válido.' });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
|
||||
|
@ -920,7 +863,7 @@ export class DialogKeywords {
|
|||
const value = extractEntity(answer);
|
||||
|
||||
if (value === null || value.length != 1) {
|
||||
await this.getTalk({ pid, text: 'Por favor, digite um nome válido.' });
|
||||
await this.talk({ pid, text: 'Por favor, digite um nome válido.' });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
|
||||
|
@ -933,7 +876,7 @@ export class DialogKeywords {
|
|||
const value = extractEntity(answer);
|
||||
|
||||
if (value === null || value.length != 1) {
|
||||
await this.getTalk({ pid, text: 'Por favor, digite um número válido.' });
|
||||
await this.talk({ pid, text: 'Por favor, digite um número válido.' });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
|
||||
|
@ -948,7 +891,7 @@ export class DialogKeywords {
|
|||
const value = extractEntity(answer);
|
||||
|
||||
if (value === null || value.length != 1) {
|
||||
await this.getTalk({ pid, text: 'Por favor, digite uma data no formato 12/12/2020.' });
|
||||
await this.talk({ pid, text: 'Por favor, digite uma data no formato 12/12/2020.' });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
|
||||
|
@ -961,7 +904,7 @@ export class DialogKeywords {
|
|||
const value = extractEntity(answer);
|
||||
|
||||
if (value === null || value.length != 1) {
|
||||
await this.getTalk({ pid, text: 'Por favor, digite um horário no formato hh:ss.' });
|
||||
await this.talk({ pid, text: 'Por favor, digite um horário no formato hh:ss.' });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
|
||||
|
@ -980,7 +923,7 @@ export class DialogKeywords {
|
|||
const value = extractEntity(answer);
|
||||
|
||||
if (value === null || value.length != 1) {
|
||||
await this.getTalk({ pid, text: 'Por favor, digite um valor monetário.' });
|
||||
await this.talk({ pid, text: 'Por favor, digite um valor monetário.' });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
|
||||
|
@ -992,12 +935,12 @@ export class DialogKeywords {
|
|||
phoneNumber = phone(answer, { country: 'BRA' })[0];
|
||||
phoneNumber = phoneUtil.parse(phoneNumber);
|
||||
} catch (error) {
|
||||
await this.getTalk({ pid, text: Messages[locale].validation_enter_valid_mobile });
|
||||
await this.talk({ pid, text: Messages[locale].validation_enter_valid_mobile });
|
||||
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
if (!phoneUtil.isPossibleNumber(phoneNumber)) {
|
||||
await this.getTalk({ pid, text: 'Por favor, digite um número de telefone válido.' });
|
||||
await this.talk({ pid, text: 'Por favor, digite um número de telefone válido.' });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
|
||||
|
@ -1017,7 +960,7 @@ export class DialogKeywords {
|
|||
const value = extractEntity(answer);
|
||||
|
||||
if (value === null || value.length != 1) {
|
||||
await this.getTalk({ pid, text: 'Por favor, digite um CEP válido.' });
|
||||
await this.talk({ pid, text: 'Por favor, digite um CEP válido.' });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
|
||||
|
@ -1032,7 +975,7 @@ export class DialogKeywords {
|
|||
});
|
||||
|
||||
if (result === null) {
|
||||
await this.getTalk({ pid, text: `Escolha por favor um dos itens sugeridos.` });
|
||||
await this.talk({ pid, text: `Escolha por favor um dos itens sugeridos.` });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
} else if (kind === 'language') {
|
||||
|
@ -1064,7 +1007,7 @@ export class DialogKeywords {
|
|||
});
|
||||
|
||||
if (result === null) {
|
||||
await this.getTalk({ pid, text: `Escolha por favor um dos itens sugeridos.` });
|
||||
await this.talk({ pid, text: `Escolha por favor um dos itens sugeridos.` });
|
||||
return await this.getHear({ pid, kind, arg });
|
||||
}
|
||||
}
|
||||
|
@ -1077,7 +1020,8 @@ export class DialogKeywords {
|
|||
/**
|
||||
* Prepares the next dialog to be shown to the specified user.
|
||||
*/
|
||||
public async gotoDialog({ fromOrDialogName, dialogName }) {
|
||||
public async gotoDialog({ pid, fromOrDialogName, dialogName }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
if (dialogName) {
|
||||
if (dialogName.charAt(0) === '/') {
|
||||
// https://github.com/GeneralBots/BotServer/issues/308
|
||||
|
@ -1087,7 +1031,7 @@ export class DialogKeywords {
|
|||
let user = await sec.getUserFromSystemId(fromOrDialogName);
|
||||
if (!user) {
|
||||
user = await sec.ensureUser(
|
||||
this.min.instance.instanceId,
|
||||
min.instance.instanceId,
|
||||
fromOrDialogName,
|
||||
fromOrDialogName,
|
||||
null,
|
||||
|
@ -1121,7 +1065,7 @@ export class DialogKeywords {
|
|||
/**
|
||||
* Talks to the user by using the specified text.
|
||||
*/
|
||||
public async getTalk({ pid, text }) {
|
||||
public async talk({ pid, text }) {
|
||||
GBLog.info(`BASIC: TALK '${text}'.`);
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ import { DialogKeywords } from './DialogKeywords.js';
|
|||
import { KeywordsExpressions } from './KeywordsExpressions.js';
|
||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
||||
import { GuaribasUser } from '../../security.gbapp/models/index.js';
|
||||
import { SystemKeywords } from './SystemKeywords.js';
|
||||
|
||||
/**
|
||||
* @fileoverview Decision was to priorize security(isolation) and debugging,
|
||||
|
@ -340,7 +341,6 @@ export class GBVMService extends GBService {
|
|||
// Creates a class DialogKeywords which is the *this* pointer
|
||||
// in BASIC.
|
||||
|
||||
const dk = new DialogKeywords(min, deployer, null);
|
||||
const sandbox = {};
|
||||
const contentLocale = min.core.getParam<string>(
|
||||
min.instance,
|
||||
|
@ -373,9 +373,11 @@ export class GBVMService extends GBService {
|
|||
userId: user.userId,
|
||||
instanceId: min.instance.instanceId
|
||||
};
|
||||
const dk = new DialogKeywords();
|
||||
const sys = new SystemKeywords();
|
||||
|
||||
sandbox['variables'] = variables;
|
||||
sandbox['id'] = dk.sys().getRandomId();
|
||||
sandbox['id'] = sys.getRandomId();
|
||||
sandbox['username'] = await dk.userName({ pid });
|
||||
sandbox['mobile'] = await dk.userMobile({ pid });
|
||||
sandbox['from'] = await dk.userMobile({ pid });
|
||||
|
@ -398,7 +400,7 @@ export class GBVMService extends GBService {
|
|||
console: 'inherit',
|
||||
wrapper: 'commonjs',
|
||||
require: {
|
||||
builtin: ['stream', 'http', 'https', 'url', 'zlib'],
|
||||
builtin: ['stream', 'http', 'https', 'url', 'zlib', 'net', 'tls', 'crypto', ],
|
||||
root: ['./'],
|
||||
external: true,
|
||||
context: 'sandbox'
|
||||
|
|
|
@ -46,33 +46,6 @@ import { GBServer } from '../../../src/app.js';
|
|||
* Image processing services of conversation to be called by BASIC.
|
||||
*/
|
||||
export class ImageProcessingServices {
|
||||
/**
|
||||
* Reference to minimal bot instance.
|
||||
*/
|
||||
public min: GBMinInstance;
|
||||
|
||||
/**
|
||||
* Reference to the base system keywords functions to be called.
|
||||
*/
|
||||
public dk: DialogKeywords;
|
||||
|
||||
/**
|
||||
* Current user object to get BASIC properties read.
|
||||
*/
|
||||
public user;
|
||||
|
||||
sys: any;
|
||||
|
||||
/**
|
||||
* When creating this keyword facade,a bot instance is
|
||||
* specified among the deployer service.
|
||||
*/
|
||||
constructor(min: GBMinInstance, user, dk) {
|
||||
this.min = min;
|
||||
this.user = user;
|
||||
this.dk = dk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sharpen the image.
|
||||
*
|
||||
|
@ -116,7 +89,7 @@ export class ImageProcessingServices {
|
|||
paths.push(gbfile.path);
|
||||
});
|
||||
|
||||
const botId = this.min.instance.botId;
|
||||
const botId = min.instance.botId;
|
||||
const gbaiName = `${botId}.gbai`;
|
||||
const img = await joinImages(paths);
|
||||
const localName = Path.join('work', gbaiName, 'cache', `img-mrg${GBAdminService.getRndReadableIdentifier()}.png`);
|
||||
|
|
|
@ -57,6 +57,7 @@ import ImageModule from 'open-docxtemplater-image-module';
|
|||
import DynamicsWebApi from 'dynamics-web-api';
|
||||
import * as MSAL from '@azure/msal-node';
|
||||
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
||||
import { WebAutomationServices } from './WebAutomationServices.js';
|
||||
|
||||
|
||||
/**
|
||||
|
@ -67,23 +68,6 @@ import { GBConversationalService } from '../../core.gbapp/services/GBConversatio
|
|||
* BASIC system class for extra manipulation of bot behaviour.
|
||||
*/
|
||||
export class SystemKeywords {
|
||||
/**
|
||||
* Reference to minimal bot instance.
|
||||
*/
|
||||
public min: GBMinInstance;
|
||||
|
||||
dk: DialogKeywords;
|
||||
wa;
|
||||
|
||||
/**
|
||||
* When creating this keyword facade, a bot instance is
|
||||
* specified among the deployer service.
|
||||
*/
|
||||
constructor(min: GBMinInstance, deployer: GBDeployer, dk: DialogKeywords, wa) {
|
||||
this.min = min;
|
||||
this.wa = wa;
|
||||
this.dk = dk;
|
||||
}
|
||||
|
||||
public async callVM({ pid, text }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
|
@ -114,7 +98,7 @@ export class SystemKeywords {
|
|||
|
||||
let caption = (await computerVisionClient.describeImage(url)).captions[0];
|
||||
|
||||
const contentLocale = this.min.core.getParam<string>(
|
||||
const contentLocale = min.core.getParam(
|
||||
min.instance,
|
||||
'Default Content Language',
|
||||
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
||||
|
@ -158,7 +142,7 @@ export class SystemKeywords {
|
|||
public async sortBy({ pid, array, memberName }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
memberName = memberName.trim();
|
||||
const contentLocale = this.min.core.getParam<string>(
|
||||
const contentLocale = min.core.getParam(
|
||||
min.instance,
|
||||
'Default Content Language',
|
||||
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
||||
|
@ -257,7 +241,7 @@ export class SystemKeywords {
|
|||
|
||||
// Includes the associated CSS related to current theme.
|
||||
|
||||
const theme = this.dk.user.basicOptions.theme;
|
||||
const theme: string = 'white'; // TODO: params.theme;
|
||||
switch (theme) {
|
||||
case 'white':
|
||||
await page.addStyleTag({ path: 'node_modules/tabulator-tables/dist/css/tabulator_simple.min.css' });
|
||||
|
@ -342,9 +326,9 @@ export class SystemKeywords {
|
|||
if (data.data) {
|
||||
const gbfile = data.data;
|
||||
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const botId = this.min.instance.botId;
|
||||
const gbaiName = `${this.min.botId}.gbai`;
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
const botId = min.instance.botId;
|
||||
const gbaiName = `${min.botId}.gbai`;
|
||||
const tmpDocx = urlJoin(gbaiName, `${botId}.gbdrive`, `tmp${GBAdminService.getRndReadableIdentifier()}.docx`);
|
||||
|
||||
// Performs the conversion operation.
|
||||
|
@ -425,7 +409,7 @@ export class SystemKeywords {
|
|||
* Retrives a random id with a length of five, every time it is called.
|
||||
*/
|
||||
public getRandomId() {
|
||||
const idGeneration = this.dk['idGeneration'];
|
||||
const idGeneration = '1v'; // TODO: this.dk['idGeneration'];
|
||||
if (idGeneration && idGeneration.trim().toLowerCase() === 'number') {
|
||||
return GBAdminService.getNumberIdentifier();
|
||||
} else {
|
||||
|
@ -488,15 +472,15 @@ export class SystemKeywords {
|
|||
* @example SET page, "elementHTMLSelector", "text"
|
||||
*
|
||||
*/
|
||||
public async set({ pid, file, address, value }): Promise<any> {
|
||||
public async set({ pid, handle, file, address, value }): Promise<any> {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
|
||||
// Handles calls for HTML stuff
|
||||
|
||||
if (file._javascriptEnabled) {
|
||||
const page = file;
|
||||
GBLog.info(`BASIC: Web automation setting ${page}' to '${value}' (SET). `);
|
||||
await this.wa.setElementText({ page, selector: address, text: value });
|
||||
|
||||
GBLog.info(`BASIC: Web automation setting ${file}' to '${value}' (SET). `);
|
||||
await new WebAutomationServices().setElementText({ pid, handle, selector: address, text: value });
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -550,9 +534,10 @@ 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).`);
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const botId = this.min.instance.botId;
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
const botId = min.instance.botId;
|
||||
const path = `/${botId}.gbai/${botId}.gbdrive`;
|
||||
|
||||
// Checks if it is a GB FILE object.
|
||||
|
@ -581,11 +566,12 @@ export class SystemKeywords {
|
|||
*
|
||||
*/
|
||||
public async save({ pid, args }): Promise<any> {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
const file = args[0];
|
||||
args.shift();
|
||||
GBLog.info(`BASIC: Saving '${file}' (SAVE). Args: ${args.join(',')}.`);
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const botId = this.min.instance.botId;
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
const botId = min.instance.botId;
|
||||
const path = `/${botId}.gbai/${botId}.gbdata`;
|
||||
|
||||
let document = await this.internalGetDocument(client, baseUrl, path, file);
|
||||
|
@ -626,6 +612,7 @@ export class SystemKeywords {
|
|||
*
|
||||
*/
|
||||
public async get({ pid, file, addressOrHeaders, httpUsername, httpPs, qs, streaming }): Promise<any> {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
if (file.startsWith('http')) {
|
||||
return await this.getByHttp({
|
||||
pid,
|
||||
|
@ -637,8 +624,8 @@ export class SystemKeywords {
|
|||
});
|
||||
} else {
|
||||
GBLog.info(`BASIC: GET '${addressOrHeaders}' in '${file}'.`);
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const botId = this.min.instance.botId;
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
const botId = min.instance.botId;
|
||||
const path = `/${botId}.gbai/${botId}.gbdata`;
|
||||
|
||||
let document = await this.internalGetDocument(client, baseUrl, path, file);
|
||||
|
@ -659,9 +646,10 @@ export class SystemKeywords {
|
|||
}
|
||||
}
|
||||
|
||||
public isValidDate({ pid, dt }) {
|
||||
const contentLocale = this.min.core.getParam<string>(
|
||||
this.min.instance,
|
||||
public async isValidDate({ pid, dt }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
const contentLocale = min.core.getParam(
|
||||
min.instance,
|
||||
'Default Content Language',
|
||||
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
||||
);
|
||||
|
@ -678,7 +666,8 @@ export class SystemKeywords {
|
|||
return !isNaN(date.valueOf());
|
||||
}
|
||||
|
||||
public isValidNumber({ pid, number }) {
|
||||
public async isValidNumber({ pid, number }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
if (number === '') {
|
||||
return false;
|
||||
}
|
||||
|
@ -704,21 +693,22 @@ export class SystemKeywords {
|
|||
*
|
||||
*/
|
||||
public async getFind({ pid, args }): Promise<any> {
|
||||
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||
const file = args[0];
|
||||
args.shift();
|
||||
|
||||
const botId = this.min.instance.botId;
|
||||
const botId = min.instance.botId;
|
||||
const path = `/${botId}.gbai/${botId}.gbdata`;
|
||||
|
||||
// MAX LINES property.
|
||||
|
||||
let maxLines;
|
||||
if (this.dk.user && this.dk.user.basicOptions && this.dk.user.basicOptions.maxLines) {
|
||||
if (this.dk.user.basicOptions.maxLines.toString().toLowerCase() !== 'default') {
|
||||
maxLines = Number.parseInt(this.dk.user.basicOptions.maxLines).valueOf();
|
||||
if (user && params && params.maxLines) {
|
||||
if (params.maxLines.toString().toLowerCase() !== 'default') {
|
||||
maxLines = Number.parseInt(params.maxLines).valueOf();
|
||||
}
|
||||
} else {
|
||||
maxLines = this.dk.maxLines;
|
||||
maxLines = maxLines;
|
||||
}
|
||||
GBLog.info(`BASIC: FIND running on ${file} (maxLines: ${maxLines}) and args: ${JSON.stringify(args)}...`);
|
||||
|
||||
|
@ -760,7 +750,7 @@ export class SystemKeywords {
|
|||
rows[i] = result[i];
|
||||
}
|
||||
} else if (file['cTag']) {
|
||||
const gbaiName = `${this.min.botId}.gbai`;
|
||||
const gbaiName = `${min.botId}.gbai`;
|
||||
const localName = Path.join('work', gbaiName, 'cache', `csv${GBAdminService.getRndReadableIdentifier()}.csv`);
|
||||
const url = file['@microsoft.graph.downloadUrl'];
|
||||
const response = await fetch(url);
|
||||
|
@ -785,7 +775,7 @@ export class SystemKeywords {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
|
||||
let document;
|
||||
document = await this.internalGetDocument(client, baseUrl, path, file);
|
||||
|
@ -834,8 +824,8 @@ export class SystemKeywords {
|
|||
return filter;
|
||||
};
|
||||
|
||||
const contentLocale = this.min.core.getParam<string>(
|
||||
this.min.instance,
|
||||
const contentLocale = min.core.getParam(
|
||||
min.instance,
|
||||
'Default Content Language',
|
||||
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
||||
);
|
||||
|
@ -888,8 +878,8 @@ export class SystemKeywords {
|
|||
await CollectionUtil.asyncForEach(filters, async filter => {
|
||||
let result = rows[foundIndex][filter.columnIndex];
|
||||
let wholeWord = true;
|
||||
if (this.dk.user && this.dk.user.basicOptions && this.dk.user.basicOptions.wholeWord) {
|
||||
wholeWord = this.dk.user.basicOptions.wholeWord;
|
||||
if (user && params && params.wholeWord) {
|
||||
wholeWord = params.wholeWord;
|
||||
}
|
||||
|
||||
switch (filter.dataType) {
|
||||
|
@ -1101,8 +1091,9 @@ export class SystemKeywords {
|
|||
*
|
||||
*/
|
||||
public async createFolder({ pid, name }) {
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const botId = this.min.instance.botId;
|
||||
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
const botId = min.instance.botId;
|
||||
let path = `/${botId}.gbai/${botId}.gbdrive`;
|
||||
|
||||
// Extracts each part of path to call create folder to each
|
||||
|
@ -1150,8 +1141,9 @@ export class SystemKeywords {
|
|||
*
|
||||
*/
|
||||
public async shareFolder({ pid, folder, email, message }) {
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const root = urlJoin(`/${this.min.botId}.gbai/${this.min.botId}.gbdrive`, folder);
|
||||
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
const root = urlJoin(`/${min.botId}.gbai/${min.botId}.gbdrive`, folder);
|
||||
|
||||
const src = await client.api(`${baseUrl}/drive/root:/${root}`).get();
|
||||
|
||||
|
@ -1177,9 +1169,10 @@ 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}'`);
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const botId = this.min.instance.botId;
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
const botId = min.instance.botId;
|
||||
|
||||
// Normalizes all slashes.
|
||||
|
||||
|
@ -1237,9 +1230,10 @@ export class SystemKeywords {
|
|||
*
|
||||
*/
|
||||
public async convert({ pid, src, dest }) {
|
||||
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||
GBLog.info(`BASIC: CONVERT '${src}' to '${dest}'`);
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const botId = this.min.instance.botId;
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
const botId = min.instance.botId;
|
||||
|
||||
// Normalizes all slashes.
|
||||
|
||||
|
@ -1339,7 +1333,7 @@ export class SystemKeywords {
|
|||
* @example
|
||||
*
|
||||
* user = put "http://server/path", "data"
|
||||
* talk "The updated user area is" + user.area
|
||||
* talk "The updated user area is" + area
|
||||
*
|
||||
*/
|
||||
public async putByHttp({ pid, url, data, headers }) {
|
||||
|
@ -1359,7 +1353,7 @@ export class SystemKeywords {
|
|||
* @example
|
||||
*
|
||||
* user = post "http://server/path", "data"
|
||||
* talk "The updated user area is" + user.area
|
||||
* talk "The updated user area is" + area
|
||||
*
|
||||
*/
|
||||
public async postByHttp({ pid, url, data, headers }) {
|
||||
|
@ -1435,13 +1429,13 @@ export class SystemKeywords {
|
|||
*/
|
||||
public async fill({ pid, templateName, data }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
const botId = this.min.instance.botId;
|
||||
const botId = min.instance.botId;
|
||||
const gbaiName = `${botId}.gbai`;
|
||||
let localName;
|
||||
|
||||
// Downloads template from .gbdrive.
|
||||
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
let path = '/' + urlJoin(gbaiName, `${botId}.gbdrive`);
|
||||
let template = await this.internalGetDocument(client, baseUrl, path, templateName);
|
||||
let url = template['@microsoft.graph.downloadUrl'];
|
||||
|
@ -1473,7 +1467,7 @@ export class SystemKeywords {
|
|||
for (const kind of ['png', 'jpg', 'jpeg']) {
|
||||
if (value.endsWith && value.endsWith(`.${kind}`)) {
|
||||
|
||||
const { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
|
||||
path = urlJoin(gbaiName, `${botId}.gbdrive`);
|
||||
if (value.indexOf('/') !== -1) {
|
||||
|
@ -1596,16 +1590,16 @@ export class SystemKeywords {
|
|||
public async merge({ pid, file, data, key1, key2 }): Promise<any> {
|
||||
GBLog.info(`BASIC: MERGE running on ${file} and key1: ${key1}, key2: ${key2}...`);
|
||||
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||
const botId = min.instance.botId;
|
||||
const path = `/${botId}.gbai/${botId}.gbdata`;
|
||||
|
||||
// MAX LINES property.
|
||||
|
||||
let maxLines = 1000;
|
||||
if (this.dk.user && this.dk.user.basicOptions && this.dk.user.basicOptions.maxLines) {
|
||||
if (this.dk.user.basicOptions.maxLines.toString().toLowerCase() !== 'default') {
|
||||
maxLines = Number.parseInt(this.dk.user.basicOptions.maxLines).valueOf();
|
||||
if (user && params && params.maxLines) {
|
||||
if (params.maxLines.toString().toLowerCase() !== 'default') {
|
||||
maxLines = Number.parseInt(params.maxLines).valueOf();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1694,7 +1688,7 @@ export class SystemKeywords {
|
|||
const address = `${cell}:${cell}`;
|
||||
|
||||
if (value !== found[columnName]) {
|
||||
await this.set({ pid, file, address, value });
|
||||
await this.set({ pid, handle:null, file, address, value });
|
||||
merges++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,39 +46,18 @@ import { DialogKeywords } from './DialogKeywords.js';
|
|||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
|
||||
import { Mutex } from 'async-mutex';
|
||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
||||
import { SystemKeywords } from './SystemKeywords.js';
|
||||
|
||||
/**
|
||||
* Web Automation services of conversation to be called by BASIC.
|
||||
*/
|
||||
export class WebAutomationServices {
|
||||
/**
|
||||
* Reference to minimal bot instance.
|
||||
*/
|
||||
public min: GBMinInstance;
|
||||
|
||||
/**
|
||||
* Reference to the base system keywords functions to be called.
|
||||
*/
|
||||
public dk: DialogKeywords;
|
||||
|
||||
/**
|
||||
* Current user object to get BASIC properties read.
|
||||
*/
|
||||
public user;
|
||||
|
||||
/**
|
||||
* HTML browser for conversation over page interaction.
|
||||
*/
|
||||
browser: any;
|
||||
|
||||
sys: any;
|
||||
|
||||
/**
|
||||
* The number used in this execution for HEAR calls (useful for SET SCHEDULE).
|
||||
*/
|
||||
hrOn: string;
|
||||
|
||||
userId: GuaribasUser;
|
||||
debugWeb: boolean;
|
||||
lastDebugWeb: Date;
|
||||
|
||||
|
@ -102,17 +81,6 @@ export class WebAutomationServices {
|
|||
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* When creating this keyword facade,a bot instance is
|
||||
* specified among the deployer service.
|
||||
*/
|
||||
constructor(min: GBMinInstance, user, dk) {
|
||||
this.min = min;
|
||||
this.user = user;
|
||||
this.dk = dk;
|
||||
|
||||
this.debugWeb = this.min.core.getParam<boolean>(this.min.instance, 'Debug Web Automation', false);
|
||||
}
|
||||
|
||||
public async getCloseHandles({ pid }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
|
@ -185,7 +153,7 @@ export class WebAutomationServices {
|
|||
|
||||
// A new web session is being created.
|
||||
|
||||
handle = WebAutomationServices.cyrb53(this.min.botId + url);
|
||||
handle = WebAutomationServices.cyrb53(min.botId + url);
|
||||
GBServer.globals.webSessions[handle] = session = {};
|
||||
session.sessionName = sessionName;
|
||||
|
||||
|
@ -294,16 +262,17 @@ export class WebAutomationServices {
|
|||
}
|
||||
|
||||
private async debugStepWeb(pid, page) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
let refresh = true;
|
||||
if (this.lastDebugWeb) {
|
||||
refresh = new Date().getTime() - this.lastDebugWeb.getTime() > 5000;
|
||||
}
|
||||
|
||||
if (this.debugWeb && refresh) {
|
||||
const mobile = this.min.core.getParam(this.min.instance, 'Bot Admin Number', null);
|
||||
const mobile = min.core.getParam(min.instance, 'Bot Admin Number', null);
|
||||
const filename = page;
|
||||
if (mobile) {
|
||||
await this.dk.sendFileTo({ pid: pid, mobile, filename, caption: 'General Bots Debugger' });
|
||||
await new DialogKeywords().sendFileTo({ pid: pid, mobile, filename, caption: 'General Bots Debugger' });
|
||||
}
|
||||
this.lastDebugWeb = new Date();
|
||||
}
|
||||
|
@ -346,16 +315,17 @@ export class WebAutomationServices {
|
|||
*
|
||||
* @example file = SCREENSHOT page
|
||||
*/
|
||||
public async screenshot({ handle, selector }) {
|
||||
public async screenshot({pid, handle, selector }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
const page = this.getPageByHandle(handle);
|
||||
GBLog.info(`BASIC: Web Automation SCREENSHOT ${selector}.`);
|
||||
|
||||
const gbaiName = `${this.min.botId}.gbai`;
|
||||
const gbaiName = `${min.botId}.gbai`;
|
||||
const localName = Path.join('work', gbaiName, 'cache', `screen-${GBAdminService.getRndReadableIdentifier()}.jpg`);
|
||||
|
||||
await page.screenshot({ path: localName });
|
||||
|
||||
const url = urlJoin(GBServer.globals.publicAddress, this.min.botId, 'cache', Path.basename(localName));
|
||||
const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName));
|
||||
GBLog.info(`BASIC: WebAutomation: Screenshot captured at ${url}.`);
|
||||
|
||||
return url;
|
||||
|
@ -381,7 +351,8 @@ export class WebAutomationServices {
|
|||
*
|
||||
* @example file = DOWNLOAD element, folder
|
||||
*/
|
||||
public async download({ handle, selector, folder }) {
|
||||
public async download({ pid, handle, selector, folder }) {
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
const page = this.getPageByHandle(handle);
|
||||
|
||||
const element = await this.getBySelector({ handle, selector });
|
||||
|
@ -429,8 +400,8 @@ export class WebAutomationServices {
|
|||
const res = await fetch(options.uri, options);
|
||||
result = Buffer.from(await res.arrayBuffer());
|
||||
}
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(this.min);
|
||||
const botId = this.min.instance.botId;
|
||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||
const botId = min.instance.botId;
|
||||
|
||||
// Normalizes all slashes.
|
||||
|
||||
|
@ -444,7 +415,7 @@ export class WebAutomationServices {
|
|||
// Checks if the destination contains subfolders that
|
||||
// need to be created.
|
||||
|
||||
folder = await this.sys.createFolder(folder);
|
||||
folder = await new SystemKeywords().createFolder(folder);
|
||||
|
||||
// Performs the conversion operation getting a reference
|
||||
// to the source and calling /content on drive API.
|
||||
|
|
|
@ -9,7 +9,7 @@ const evaluate = async (script, scope) => {
|
|||
console: 'inherit',
|
||||
wrapper: 'none',
|
||||
require: {
|
||||
builtin: ['stream', 'http', 'https', 'url', 'buffer', 'zlib', 'isomorphic-fetch', 'punycode', 'encoding'],
|
||||
builtin: ['stream', 'http', 'https', 'url', 'buffer', 'zlib', 'isomorphic-fetch', 'punycode', 'encoding', 'net'],
|
||||
root: ['./'],
|
||||
external: true,
|
||||
context: 'sandbox'
|
||||
|
|
|
@ -911,7 +911,7 @@ export class GBMinService {
|
|||
);
|
||||
const botToken = await credentials.getToken();
|
||||
const headers = { Authorization: `Bearer ${botToken}` };
|
||||
const t = new SystemKeywords(null, null, null, null);
|
||||
const t = new SystemKeywords( );
|
||||
const data = await t.getByHttp({
|
||||
pid: 0,
|
||||
url: file.contentUrl,
|
||||
|
|
|
@ -42,7 +42,7 @@ import { GBMinService } from '../packages/core.gbapp/services/GBMinService.js';
|
|||
*/
|
||||
|
||||
export class RootData {
|
||||
public webSessions: {} // List of Web Automation sessions.
|
||||
public webSessions: {}; // List of Web Automation sessions.
|
||||
public processes: {}; // List of .gbdialog active executions.
|
||||
public files: {}; // List of uploaded files handled.
|
||||
public publicAddress: string; // URI for BotServer.
|
||||
|
@ -59,5 +59,10 @@ export class RootData {
|
|||
public debugConversationId: any; // Used to self-message during debug.
|
||||
public debuggers: any[]; // Client of attached Debugger instances by botId.
|
||||
public chatGPT: any; // ChatGPT API handle (shared Browser).
|
||||
public dk;
|
||||
public wa;
|
||||
public sys;
|
||||
public dbg;
|
||||
public img;
|
||||
indexSemaphore: any;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue