fix(core.gbapp): #336 timeout in API fixed.

This commit is contained in:
rodrigorodriguez 2023-03-26 19:33:58 -03:00
parent 7bdc57a4a1
commit 0c443618a6
10 changed files with 122 additions and 74 deletions

1
.vscode/launch.json vendored
View file

@ -15,7 +15,6 @@
"args": [ "args": [
"--no-deprecation", "--no-deprecation",
"--loader ts-node/esm", "--loader ts-node/esm",
"--openssl-legacy-provider",
"--require ${workspaceRoot}/suppress-node-warnings.cjs", "--require ${workspaceRoot}/suppress-node-warnings.cjs",
], ],
"skipFiles": [ "skipFiles": [

View file

@ -13,7 +13,7 @@ console.log(`██ █ ███ █ █ ██ ██ ██
console.log(`██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ `); console.log(`██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ `);
console.log(`██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ `); console.log(`██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ `);
console.log(` █████ █████ █ ███ █████ ██ ██ ██ ██ ██████ ████ █████ █ ███ 3.0`); console.log(` █████ █████ █ ███ █████ ██ ██ ██ ██ ██████ ████ █████ █ ███ 3.0`);
process.stdout.write(` botserver@${pjson.version}, botlib@${pjson.dependencies.botlib}, botbuilder@${pjson.dependencies.botbuilder}, node@${process.version.replace('v', '')}, ${process.platform} ${process.arch}`); process.stdout.write(` botserver@${pjson.version}, botlib@${pjson.dependencies.botlib}, botbuilder@${pjson.dependencies.botbuilder}, node@${process.version.replace('v', '')}, ${process.platform} ${process.arch} `);
var now = () => { var now = () => {
return new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '') + ' UTC'; return new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '') + ' UTC';
@ -28,7 +28,8 @@ try {
}; };
var processDist = () => { var processDist = () => {
if (!Fs.existsSync('dist')) { if (!Fs.existsSync('dist')) {
console.log(`${now()} - Compiling...`); console.log(`\n`);
console.log(`Generall Bots: Compiling...`);
exec(Path.join(__dirname, 'node_modules/.bin/tsc'), (err, stdout, stderr) => { exec(Path.join(__dirname, 'node_modules/.bin/tsc'), (err, stdout, stderr) => {
if (err) { if (err) {
console.error(err); console.error(err);
@ -44,7 +45,8 @@ try {
// Installing modules if it has not been done yet. // Installing modules if it has not been done yet.
if (!Fs.existsSync('node_modules')) { if (!Fs.existsSync('node_modules')) {
console.log(`${now()} - Installing modules for the first time, please wait...`); console.log(`\n`);
console.log(`Generall Bots: Installing modules for the first time, please wait...`);
exec('npm install', (err, stdout, stderr) => { exec('npm install', (err, stdout, stderr) => {
if (err) { if (err) {
console.error(err); console.error(err);

View file

@ -3,13 +3,13 @@
ECHO General Bots Command Line ECHO General Bots Command Line
IF EXIST node_modules goto COMPILE IF EXIST node_modules goto COMPILE
ECHO Installing Packages for the first time use... ECHO Installing Packages for the first time use (it may take several minutes)...
CALL npm install --silent CALL npm install --silent
:COMPILE :COMPILE
IF EXIST dist goto ALLSET IF EXIST dist goto ALLSET
ECHO Compiling... ECHO Compiling...
CALL node_modules\.bin\tsc npm run build
:ALLSET :ALLSET
node boot.mjs npm run start

View file

@ -35,7 +35,7 @@
"build-gbui": "cd packages/default.gbui && echo SKIP_PREFLIGHT_CHECK=true >.env && npm install && npm run build", "build-gbui": "cd packages/default.gbui && echo SKIP_PREFLIGHT_CHECK=true >.env && npm install && npm run build",
"build-docs": "typedoc --options typedoc.json src/", "build-docs": "typedoc --options typedoc.json src/",
"test": "node test.js", "test": "node test.js",
"start": "NODE_NO_WARNINGS=1 node ./boot.mjs --loader ts-node/esm --require ./suppress-node-warnings.cjs ", "start": "NODE_NO_WARNINGS=1 node ./boot.mjs --loader ts-node/esm --require ./suppress-node-warnings.cjs",
"reverse-proxy": "node_modules/.bin/ngrok http 4242", "reverse-proxy": "node_modules/.bin/ngrok http 4242",
"watch:build": "tsc --watch", "watch:build": "tsc --watch",
"posttypedoc": "shx cp .nojekyll docs/reference/.nojekyll", "posttypedoc": "shx cp .nojekyll docs/reference/.nojekyll",
@ -119,9 +119,11 @@
"koa": "2.13.4", "koa": "2.13.4",
"koa-body": "6.0.1", "koa-body": "6.0.1",
"koa-router": "12.0.0", "koa-router": "12.0.0",
"line-replace": "2.0.1",
"lodash": "4.17.21", "lodash": "4.17.21",
"luxon": "3.1.0", "luxon": "3.1.0",
"mammoth": "1.5.1", "mammoth": "1.5.1",
"mime-types": "^2.1.35",
"moment": "1.3.0", "moment": "1.3.0",
"ms-rest-azure": "3.0.0", "ms-rest-azure": "3.0.0",
"nexmo": "2.9.1", "nexmo": "2.9.1",
@ -182,6 +184,7 @@
"yarn": "1.22.19" "yarn": "1.22.19"
}, },
"devDependencies": { "devDependencies": {
"@types/qrcode": "1.5.0",
"@types/url-join": "4.0.1", "@types/url-join": "4.0.1",
"ban-sensitive-files": "1.9.18", "ban-sensitive-files": "1.9.18",
"commitizen": "4.2.2", "commitizen": "4.2.2",

View file

@ -36,39 +36,31 @@
'use strict'; 'use strict';
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBInstance, IGBPackage } from 'botlib'; import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
import { GuaribasSchedule } from '../core.gbapp/models/GBModel.js'; import { GuaribasSchedule } from '../core.gbapp/models/GBModel.js';
import { Sequelize } from 'sequelize-typescript'; import { Sequelize } from 'sequelize-typescript';
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 Koa from 'koa'; import Koa from 'koa';
import cors from '@koa/cors'; import cors from '@koa/cors';
import { createRpcServer } from '@push-rpc/core';
import { createHttpKoaMiddleware } from '@push-rpc/http'; import { createHttpKoaMiddleware } from '@push-rpc/http';
import { HttpServerOptions } from '@push-rpc/http/dist/server.js'; import { HttpServerOptions } from '@push-rpc/http/dist/server.js';
import { GBServer } from '../../src/app.js'; import { GBServer } from '../../src/app.js';
import { } from '@push-rpc/core'; import { SocketServer } from '@push-rpc/core';
import * as koaBody from 'koa-body'; import * as koaBody from 'koa-body';
import { GBVMService } from './services/GBVMService.js';
import { GBLogEx } from '../core.gbapp/services/GBLogEx.js';
import { CollectionUtil } from 'pragmatismo-io-framework';
export function createKoaHttpServer( export function createKoaHttpServer(
port: number, port: number,
getRemoteId: (ctx: Koa.Context) => string, getRemoteId: (ctx: Koa.Context) => string,
opts: Partial<HttpServerOptions> = {} opts: Partial<HttpServerOptions> = {}
): SocketServer { ): SocketServer {
const { onError, onConnection, middleware } = createHttpKoaMiddleware(getRemoteId, opts); const { onError, onConnection, middleware } =
createHttpKoaMiddleware(getRemoteId, opts);
const app = new Koa(); const app = new Koa();
app.use(cors({ origin: '*' })); app.use(cors({ origin: '*' }));
app.use(koaBody.koaBody({ multipart: true })); app.use(koaBody.koaBody({ multipart: true }));
app.use(middleware); app.use(middleware);
const server = app.listen(port); const server = app.listen(port);
const SERVER_TIMEOUT = 60 * 1000; const SERVER_TIMEOUT = 60 * 60 * 24 * 1000; // Equals to client RPC set .
server.timeout = SERVER_TIMEOUT; server.timeout = SERVER_TIMEOUT;
return { return {

View file

@ -46,7 +46,7 @@ import { Messages } from '../strings.js';
import * as Fs from 'fs'; import * as Fs from 'fs';
import { CollectionUtil } from 'pragmatismo-io-framework'; import { CollectionUtil } from 'pragmatismo-io-framework';
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js'; import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
import phoneUtil from 'google-libphonenumber'; import phoneUtil from 'google-libphonenumber';
import phone from 'phone'; import phone from 'phone';
import DateDiff from 'date-diff'; import DateDiff from 'date-diff';
import tesseract from 'node-tesseract-ocr'; import tesseract from 'node-tesseract-ocr';
@ -58,7 +58,9 @@ import { WebAutomationServices } from './WebAutomationServices.js';
import urljoin from 'url-join'; import urljoin from 'url-join';
import QrScanner from 'qr-scanner'; import QrScanner from 'qr-scanner';
import pkg from 'whatsapp-web.js'; import pkg from 'whatsapp-web.js';
import { ActivityTypes } from 'botbuilder';
const { List, Buttons } = pkg; const { List, Buttons } = pkg;
import mime from 'mime-types';
/** /**
* Default check interval for user replay * Default check interval for user replay
@ -204,28 +206,28 @@ export class DialogKeywords {
* *
* @example EXIT * @example EXIT
*/ */
public async exit({ }) { } public async exit({}) {}
/** /**
* Get active tasks. * Get active tasks.
* *
* @example list = ACTIVE TASKS * @example list = ACTIVE TASKS
*/ */
public async getActiveTasks({ pid }) { } public async getActiveTasks({ pid }) {}
/** /**
* Creates a new deal. * Creates a new deal.
* *
* @example CREATE DEAL dealname,contato,empresa,amount * @example CREATE DEAL dealname,contato,empresa,amount
*/ */
public async createDeal({ pid, dealName, contact, company, amount }) { } public async createDeal({ pid, dealName, contact, company, amount }) {}
/** /**
* Finds contacts in XRM. * Finds contacts in XRM.
* *
* @example list = FIND CONTACT "Sandra" * @example list = FIND CONTACT "Sandra"
*/ */
public async fndContact({ pid, name }) { } public async fndContact({ pid, name }) {}
public getContentLocaleWithCulture(contentLocale) { public getContentLocaleWithCulture(contentLocale) {
switch (contentLocale) { switch (contentLocale) {
@ -495,7 +497,7 @@ export class DialogKeywords {
*/ */
public async sendFileTo({ pid, mobile, filename, caption }) { public async sendFileTo({ pid, mobile, filename, caption }) {
GBLog.info(`BASIC: SEND FILE TO '${mobile}',filename '${filename}'.`); GBLog.info(`BASIC: SEND FILE TO '${mobile}',filename '${filename}'.`);
return await this.internalSendFile({ pid, mobile, filename, caption }); return await this.internalSendFile({ pid, mobile, channel: null, filename, caption });
} }
/** /**
@ -505,9 +507,10 @@ export class DialogKeywords {
* *
*/ */
public async sendFile({ pid, filename, caption }) { public async sendFile({ pid, filename, caption }) {
const { min, user, proc } = await DialogKeywords.getProcessInfo(pid);
GBLog.info(`BASIC: SEND FILE (to: ${user.userSystemId},filename '${filename}'.`);
const mobile = await this.userMobile({ pid }); const mobile = await this.userMobile({ pid });
GBLog.info(`BASIC: SEND FILE (current: ${mobile},filename '${filename}'.`); return await this.internalSendFile({ pid, channel: proc.channel, mobile, filename, caption });
return await this.internalSendFile({ pid, mobile, filename, caption });
} }
/** /**
@ -676,7 +679,7 @@ export class DialogKeywords {
* @example MENU * @example MENU
* *
*/ */
public async showMenu({ }) { public async showMenu({}) {
// https://github.com/GeneralBots/BotServer/issues/237 // https://github.com/GeneralBots/BotServer/issues/237
// return await beginDialog('/menu'); // return await beginDialog('/menu');
} }
@ -1031,25 +1034,15 @@ export class DialogKeywords {
static getGBAIPath(botId, packageType = null, packageName = null) { static getGBAIPath(botId, packageType = null, packageName = null) {
let gbai = `${botId}.gbai`; let gbai = `${botId}.gbai`;
if (!packageType && !packageName) { if (!packageType && !packageName) {
return GBConfigService.get('DEV_GBAI') ? return GBConfigService.get('DEV_GBAI') ? GBConfigService.get('DEV_GBAI') : gbai;
GBConfigService.get('DEV_GBAI') :
gbai;
} }
if (GBConfigService.get('DEV_GBAI')) { if (GBConfigService.get('DEV_GBAI')) {
gbai = GBConfigService.get('DEV_GBAI'); gbai = GBConfigService.get('DEV_GBAI');
botId = gbai.replace(/\.[^/.]+$/, ""); botId = gbai.replace(/\.[^/.]+$/, '');
return urljoin(GBConfigService.get('DEV_GBAI'), return urljoin(GBConfigService.get('DEV_GBAI'), packageName ? packageName : `${botId}.${packageType}`);
packageName ? } else {
packageName : return urljoin(gbai, packageName ? packageName : `${botId}.${packageType}`);
`${botId}.${packageType}`);
}
else {
return urljoin(gbai,
packageName ?
packageName :
`${botId}.${packageType}`);
} }
} }
@ -1094,7 +1087,8 @@ export class DialogKeywords {
return { return {
min, min,
user, user,
params params,
proc
}; };
} }
@ -1121,21 +1115,22 @@ export class DialogKeywords {
/** /**
* Processes the sending of the file. * Processes the sending of the file.
*/ */
private async internalSendFile({ pid, mobile, filename, caption }) { private async internalSendFile({ pid, channel, mobile, filename, caption }) {
// Handles SEND FILE TO mobile,element in Web Automation. // Handles SEND FILE TO mobile,element in Web Automation.
const { min, user } = await DialogKeywords.getProcessInfo(pid); const { min, user } = await DialogKeywords.getProcessInfo(pid);
const element = filename._page ? filename._page : filename.screenshot ? filename : null; const element = filename._page ? filename._page : filename.screenshot ? filename : null;
let url;
if (element) { if (element) {
const gbaiName = DialogKeywords.getGBAIPath(min.botId); const gbaiName = DialogKeywords.getGBAIPath(min.botId);
const localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.jpg`); const localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.jpg`);
await element.screenshot({ path: localName, fullPage: true }); await element.screenshot({ path: localName, fullPage: true });
const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName)); url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', Path.basename(localName));
GBLog.info(`BASIC: WebAutomation: Sending the file ${url} to mobile ${mobile}.`); GBLog.info(`BASIC: WebAutomation: Sending the file ${url} to mobile ${mobile}.`);
await min.conversationalService.sendFile(min, null, mobile, url, caption);
} }
// Handles Markdown. // Handles Markdown.
@ -1148,25 +1143,37 @@ export class DialogKeywords {
await min.conversationalService['playMarkdown'](min, md, DialogKeywords.getChannel(), mobile); await min.conversationalService['playMarkdown'](min, md, DialogKeywords.getChannel(), mobile);
} else { } else {
const gbaiName = DialogKeywords.getGBAIPath(min.botId, `gbkb`); const gbaiName = DialogKeywords.getGBAIPath(min.botId, `gbkb`);
GBLog.info(`BASIC: Sending the file ${filename} to mobile ${mobile}.`); GBLog.info(`BASIC: Sending the file ${filename} to mobile ${mobile}.`);
let url: string;
if (!filename.startsWith('https://')) { if (!filename.startsWith('https://')) {
url = urlJoin( url = urlJoin(GBServer.globals.publicAddress, 'kb', gbaiName, 'assets', filename);
GBServer.globals.publicAddress,
'kb',
gbaiName,
'assets',
filename
);
} else { } else {
url = filename; url = filename;
} }
await min.conversationalService.sendFile(min, null, mobile, url, caption);
} }
if (url){
const reply = { type: ActivityTypes.Message, text: caption };
const imageData = await (await fetch(url)).arrayBuffer();
const base64Image = Buffer.from(imageData).toString('base64');
const contentType = mime.lookup(url);
reply['attachments'] = [];
reply['attachments'].push({
name: filename,
contentType: contentType,
contentUrl: `data:${contentType};base64,${base64Image}`
});
if (channel === 'omnichannel') {
await min.conversationalService.sendFile(min, null, mobile, url, caption);
} else {
await min.conversationalService['sendOnConversation'](min, user, reply);
}
}
} }
/** /**
* Generates a new QRCode. * Generates a new QRCode.

View file

@ -52,6 +52,7 @@ import { KeywordsExpressions } from './KeywordsExpressions.js';
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js'; import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
import { GuaribasUser } from '../../security.gbapp/models/index.js'; import { GuaribasUser } from '../../security.gbapp/models/index.js';
import { SystemKeywords } from './SystemKeywords.js'; import { SystemKeywords } from './SystemKeywords.js';
import lineReplace from 'line-replace';
/** /**
* @fileoverview Decision was to priorize security(isolation) and debugging, * @fileoverview Decision was to priorize security(isolation) and debugging,
@ -113,7 +114,7 @@ export class GBVMService extends GBService {
} }
// Process node_modules install. // Process node_modules install.
const node_modules = urlJoin(folder, 'node_modules'); const node_modules = urlJoin(process.env.PWD, folder, 'node_modules');
if (!Fs.existsSync(node_modules)) { if (!Fs.existsSync(node_modules)) {
const packageJson = ` const packageJson = `
{ {
@ -136,6 +137,34 @@ export class GBVMService extends GBService {
GBLogEx.info(min, `BASIC: Installing .gbdialog node_modules for ${min.botId}...`); GBLogEx.info(min, `BASIC: Installing .gbdialog node_modules for ${min.botId}...`);
const npmPath = urlJoin(process.env.PWD, 'node_modules', '.bin', 'npm'); const npmPath = urlJoin(process.env.PWD, 'node_modules', '.bin', 'npm');
child_process.execSync(`${npmPath} install`, { cwd: folder }); child_process.execSync(`${npmPath} install`, { cwd: folder });
// // Hacks push-rpc to put timeout.
// const inject1 = `
// const { AbortController } = require("node-abort-controller");
// var controller_1 = new AbortController();
// var signal = controller_1.signal;
// setTimeout(function () { controller_1.abort(); }, 24 * 60 * 60 * 1000);`;
// const inject2 = `signal: signal,`;
// const js = Path.join(process.env.PWD, folder, 'node_modules/@push-rpc/http/dist/client.js');
// lineReplace({
// file: js,
// line: 75,
// text: inject1,
// addNewLine: true,
// callback: ({ file, line, text, replacedText, error }) => {
// lineReplace({
// file: js,
// line: 82,
// text: inject2,
// addNewLine: true,
// callback: ({ file, line, text, replacedText, error }) => {
// GBLogEx.info(min, `BASIC: Patching node_modules for ${min.botId} done.`);
// }
// });
// }
// });
} }
// Hot swap for .vbs files. // Hot swap for .vbs files.
@ -209,16 +238,17 @@ export class GBVMService extends GBService {
const createHttpClient = require("@push-rpc/http").createHttpClient; const createHttpClient = require("@push-rpc/http").createHttpClient;
// Setups interprocess communication from .gbdialog run-time to the BotServer API. // Setups interprocess communication from .gbdialog run-time to the BotServer API.
const optsRPC = {callTimeout: this.callTimeout};
let url; let url;
url = 'http://localhost:${GBVMService.API_PORT}/api/v3/${min.botId}/dk'; url = 'http://localhost:${GBVMService.API_PORT}/api/v3/${min.botId}/dk';
const dk = (await createRpcClient(0, () => createHttpClient(url))).remote; const dk = (await createRpcClient(0, () => createHttpClient(url), optsRPC)).remote;
url = 'http://localhost:${GBVMService.API_PORT}/api/v3/${min.botId}/sys'; url = 'http://localhost:${GBVMService.API_PORT}/api/v3/${min.botId}/sys';
const sys = (await createRpcClient(0, () => createHttpClient(url))).remote; const sys = (await createRpcClient(0, () => createHttpClient(url), optsRPC)).remote;
url = 'http://localhost:${GBVMService.API_PORT}/api/v3/${min.botId}/wa'; url = 'http://localhost:${GBVMService.API_PORT}/api/v3/${min.botId}/wa';
const wa = (await createRpcClient(0, () => createHttpClient(url))).remote; const wa = (await createRpcClient(0, () => createHttpClient(url), optsRPC)).remote;
url = 'http://localhost:${GBVMService.API_PORT}/api/v3/${min.botId}/img'; url = 'http://localhost:${GBVMService.API_PORT}/api/v3/${min.botId}/img';
const img = (await createRpcClient(0, () => createHttpClient(url))).remote; const img = (await createRpcClient(0, () => createHttpClient(url), optsRPC)).remote;
// Unmarshalls Local variables from server VM. // Unmarshalls Local variables from server VM.
@ -227,6 +257,7 @@ export class GBVMService extends GBService {
let username = this.username; let username = this.username;
let mobile = this.mobile; let mobile = this.mobile;
let from = this.from; let from = this.from;
let channel = this.channel;
let ENTER = this.ENTER; let ENTER = this.ENTER;
let headers = this.headers; let headers = this.headers;
let data = this.data; let data = this.data;
@ -372,17 +403,18 @@ export class GBVMService extends GBService {
} }
const botId = min.botId; const botId = min.botId;
const path = DialogKeywords.getGBAIPath(min.botId,`gbdialog`); const path = DialogKeywords.getGBAIPath(min.botId, `gbdialog`);
const gbdialogPath = urlJoin(process.cwd(), 'work', path); const gbdialogPath = urlJoin(process.cwd(), 'work', path);
const scriptPath = urlJoin(gbdialogPath, `${text}.js`); const scriptPath = urlJoin(gbdialogPath, `${text}.js`);
let code = min.sandBoxMap[text]; let code = min.sandBoxMap[text];
const channel = step? step.context.activity.channelId : 'web';
const pid = GBAdminService.getNumberIdentifier(); const pid = GBAdminService.getNumberIdentifier();
GBServer.globals.processes[pid] = { GBServer.globals.processes[pid] = {
pid: pid, pid: pid,
userId: user.userId, userId: user.userId,
instanceId: min.instance.instanceId instanceId: min.instance.instanceId,
channel: channel
}; };
const dk = new DialogKeywords(); const dk = new DialogKeywords();
const sys = new SystemKeywords(); const sys = new SystemKeywords();
@ -400,6 +432,8 @@ export class GBVMService extends GBService {
sandbox['httpPs'] = ''; sandbox['httpPs'] = '';
sandbox['pid'] = pid; sandbox['pid'] = pid;
sandbox['contentLocale'] = contentLocale; sandbox['contentLocale'] = contentLocale;
sandbox['callTimeout'] = 60 * 60 * 24 * 1000;
sandbox['channel'] = channel;
let result; let result;
@ -411,7 +445,7 @@ export class GBVMService extends GBService {
console: 'inherit', console: 'inherit',
wrapper: 'commonjs', wrapper: 'commonjs',
require: { require: {
builtin: ['stream', 'http', 'https', 'url', 'zlib', 'net', 'tls', 'crypto', ], builtin: ['stream', 'http', 'https', 'url', 'zlib', 'net', 'tls', 'crypto'],
root: ['./'], root: ['./'],
external: true, external: true,
context: 'sandbox' context: 'sandbox'

View file

@ -304,6 +304,17 @@ export class GBConversationalService {
return GBMinService.userMobile(step); return GBMinService.userMobile(step);
} }
public async sendFile2(
min: GBMinInstance,
step: GBDialogStep,
mobile: string,
url: string,
caption: string,
channel: string
): Promise<any> {
return await this.sendFile(min, step, mobile, url , caption);
}
public async sendFile( public async sendFile(
min: GBMinInstance, min: GBMinInstance,
step: GBDialogStep, step: GBDialogStep,

View file

@ -462,7 +462,7 @@ export class GBMinService {
this.createCheckHealthAddress(GBServer.globals.server, min, min.instance); this.createCheckHealthAddress(GBServer.globals.server, min, min.instance);
GBDeployer.mountGBKBAssets(`${instance.botId}.gbkb`, instance.botId, `${instance.botId}.gbkb`); GBDeployer.mountGBKBAssets(`${botId}.gbkb`, botId, `${botId}.gbkb`);
} }
public static isChatAPI(req: any, res: any) { public static isChatAPI(req: any, res: any) {