fix(core.gbapp): #336 timeout in API fixed.
This commit is contained in:
parent
7bdc57a4a1
commit
0c443618a6
10 changed files with 122 additions and 74 deletions
1
.vscode/launch.json
vendored
1
.vscode/launch.json
vendored
|
@ -15,7 +15,6 @@
|
|||
"args": [
|
||||
"--no-deprecation",
|
||||
"--loader ts-node/esm",
|
||||
"--openssl-legacy-provider",
|
||||
"--require ${workspaceRoot}/suppress-node-warnings.cjs",
|
||||
],
|
||||
"skipFiles": [
|
||||
|
|
8
boot.mjs
8
boot.mjs
|
@ -13,7 +13,7 @@ console.log(`██ █ ███ █ █ ██ ██ ██
|
|||
console.log(`██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ `);
|
||||
console.log(`██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ `);
|
||||
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 = () => {
|
||||
return new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '') + ' UTC';
|
||||
|
@ -28,7 +28,8 @@ try {
|
|||
};
|
||||
var processDist = () => {
|
||||
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) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
|
@ -44,7 +45,8 @@ try {
|
|||
// Installing modules if it has not been done yet.
|
||||
|
||||
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) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
|
|
6
gbot.cmd
6
gbot.cmd
|
@ -3,13 +3,13 @@
|
|||
ECHO General Bots Command Line
|
||||
|
||||
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
|
||||
|
||||
:COMPILE
|
||||
IF EXIST dist goto ALLSET
|
||||
ECHO Compiling...
|
||||
CALL node_modules\.bin\tsc
|
||||
npm run build
|
||||
|
||||
:ALLSET
|
||||
node boot.mjs
|
||||
npm run start
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
"build-gbui": "cd packages/default.gbui && echo SKIP_PREFLIGHT_CHECK=true >.env && npm install && npm run build",
|
||||
"build-docs": "typedoc --options typedoc.json src/",
|
||||
"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",
|
||||
"watch:build": "tsc --watch",
|
||||
"posttypedoc": "shx cp .nojekyll docs/reference/.nojekyll",
|
||||
|
@ -119,9 +119,11 @@
|
|||
"koa": "2.13.4",
|
||||
"koa-body": "6.0.1",
|
||||
"koa-router": "12.0.0",
|
||||
"line-replace": "2.0.1",
|
||||
"lodash": "4.17.21",
|
||||
"luxon": "3.1.0",
|
||||
"mammoth": "1.5.1",
|
||||
"mime-types": "^2.1.35",
|
||||
"moment": "1.3.0",
|
||||
"ms-rest-azure": "3.0.0",
|
||||
"nexmo": "2.9.1",
|
||||
|
@ -182,6 +184,7 @@
|
|||
"yarn": "1.22.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/qrcode": "1.5.0",
|
||||
"@types/url-join": "4.0.1",
|
||||
"ban-sensitive-files": "1.9.18",
|
||||
"commitizen": "4.2.2",
|
||||
|
|
|
@ -36,39 +36,31 @@
|
|||
|
||||
'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 { 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 cors from '@koa/cors';
|
||||
import { createRpcServer } from '@push-rpc/core';
|
||||
import { createHttpKoaMiddleware } from '@push-rpc/http';
|
||||
import { HttpServerOptions } from '@push-rpc/http/dist/server.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 { GBVMService } from './services/GBVMService.js';
|
||||
import { GBLogEx } from '../core.gbapp/services/GBLogEx.js';
|
||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||
|
||||
export function createKoaHttpServer(
|
||||
port: number,
|
||||
getRemoteId: (ctx: Koa.Context) => string,
|
||||
opts: Partial<HttpServerOptions> = {}
|
||||
): SocketServer {
|
||||
const { onError, onConnection, middleware } = createHttpKoaMiddleware(getRemoteId, opts);
|
||||
const { onError, onConnection, middleware } =
|
||||
createHttpKoaMiddleware(getRemoteId, opts);
|
||||
|
||||
const app = new Koa();
|
||||
app.use(cors({ origin: '*' }));
|
||||
app.use(koaBody.koaBody({ multipart: true }));
|
||||
app.use(middleware);
|
||||
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;
|
||||
|
||||
return {
|
||||
|
|
|
@ -46,7 +46,7 @@ import { Messages } from '../strings.js';
|
|||
import * as Fs from 'fs';
|
||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
||||
import phoneUtil from 'google-libphonenumber';
|
||||
import phoneUtil from 'google-libphonenumber';
|
||||
import phone from 'phone';
|
||||
import DateDiff from 'date-diff';
|
||||
import tesseract from 'node-tesseract-ocr';
|
||||
|
@ -58,7 +58,9 @@ import { WebAutomationServices } from './WebAutomationServices.js';
|
|||
import urljoin from 'url-join';
|
||||
import QrScanner from 'qr-scanner';
|
||||
import pkg from 'whatsapp-web.js';
|
||||
import { ActivityTypes } from 'botbuilder';
|
||||
const { List, Buttons } = pkg;
|
||||
import mime from 'mime-types';
|
||||
|
||||
/**
|
||||
* Default check interval for user replay
|
||||
|
@ -204,28 +206,28 @@ export class DialogKeywords {
|
|||
*
|
||||
* @example EXIT
|
||||
*/
|
||||
public async exit({ }) { }
|
||||
public async exit({}) {}
|
||||
|
||||
/**
|
||||
* Get active tasks.
|
||||
*
|
||||
* @example list = ACTIVE TASKS
|
||||
*/
|
||||
public async getActiveTasks({ pid }) { }
|
||||
public async getActiveTasks({ pid }) {}
|
||||
|
||||
/**
|
||||
* Creates a new deal.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @example list = FIND CONTACT "Sandra"
|
||||
*/
|
||||
public async fndContact({ pid, name }) { }
|
||||
public async fndContact({ pid, name }) {}
|
||||
|
||||
public getContentLocaleWithCulture(contentLocale) {
|
||||
switch (contentLocale) {
|
||||
|
@ -495,7 +497,7 @@ export class DialogKeywords {
|
|||
*/
|
||||
public async sendFileTo({ pid, mobile, filename, caption }) {
|
||||
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 }) {
|
||||
const { min, user, proc } = await DialogKeywords.getProcessInfo(pid);
|
||||
GBLog.info(`BASIC: SEND FILE (to: ${user.userSystemId},filename '${filename}'.`);
|
||||
const mobile = await this.userMobile({ pid });
|
||||
GBLog.info(`BASIC: SEND FILE (current: ${mobile},filename '${filename}'.`);
|
||||
return await this.internalSendFile({ pid, mobile, filename, caption });
|
||||
return await this.internalSendFile({ pid, channel: proc.channel, mobile, filename, caption });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -676,7 +679,7 @@ export class DialogKeywords {
|
|||
* @example MENU
|
||||
*
|
||||
*/
|
||||
public async showMenu({ }) {
|
||||
public async showMenu({}) {
|
||||
// https://github.com/GeneralBots/BotServer/issues/237
|
||||
// return await beginDialog('/menu');
|
||||
}
|
||||
|
@ -1031,25 +1034,15 @@ export class DialogKeywords {
|
|||
static getGBAIPath(botId, packageType = null, packageName = null) {
|
||||
let gbai = `${botId}.gbai`;
|
||||
if (!packageType && !packageName) {
|
||||
return GBConfigService.get('DEV_GBAI') ?
|
||||
GBConfigService.get('DEV_GBAI') :
|
||||
gbai;
|
||||
return GBConfigService.get('DEV_GBAI') ? GBConfigService.get('DEV_GBAI') : gbai;
|
||||
}
|
||||
|
||||
if (GBConfigService.get('DEV_GBAI')) {
|
||||
gbai = GBConfigService.get('DEV_GBAI');
|
||||
botId = gbai.replace(/\.[^/.]+$/, "");
|
||||
return urljoin(GBConfigService.get('DEV_GBAI'),
|
||||
packageName ?
|
||||
packageName :
|
||||
`${botId}.${packageType}`);
|
||||
}
|
||||
else {
|
||||
|
||||
return urljoin(gbai,
|
||||
packageName ?
|
||||
packageName :
|
||||
`${botId}.${packageType}`);
|
||||
botId = gbai.replace(/\.[^/.]+$/, '');
|
||||
return urljoin(GBConfigService.get('DEV_GBAI'), packageName ? packageName : `${botId}.${packageType}`);
|
||||
} else {
|
||||
return urljoin(gbai, packageName ? packageName : `${botId}.${packageType}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1094,7 +1087,8 @@ export class DialogKeywords {
|
|||
return {
|
||||
min,
|
||||
user,
|
||||
params
|
||||
params,
|
||||
proc
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1121,21 +1115,22 @@ export class DialogKeywords {
|
|||
/**
|
||||
* 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.
|
||||
|
||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||
const element = filename._page ? filename._page : filename.screenshot ? filename : null;
|
||||
let url;
|
||||
|
||||
if (element) {
|
||||
const gbaiName = DialogKeywords.getGBAIPath(min.botId);
|
||||
const localName = Path.join('work', gbaiName, 'cache', `img${GBAdminService.getRndReadableIdentifier()}.jpg`);
|
||||
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}.`);
|
||||
await min.conversationalService.sendFile(min, null, mobile, url, caption);
|
||||
|
||||
}
|
||||
|
||||
// Handles Markdown.
|
||||
|
@ -1148,25 +1143,37 @@ export class DialogKeywords {
|
|||
|
||||
await min.conversationalService['playMarkdown'](min, md, DialogKeywords.getChannel(), mobile);
|
||||
} else {
|
||||
|
||||
const gbaiName = DialogKeywords.getGBAIPath(min.botId, `gbkb`);
|
||||
|
||||
GBLog.info(`BASIC: Sending the file ${filename} to mobile ${mobile}.`);
|
||||
let url: string;
|
||||
|
||||
if (!filename.startsWith('https://')) {
|
||||
url = urlJoin(
|
||||
GBServer.globals.publicAddress,
|
||||
'kb',
|
||||
gbaiName,
|
||||
'assets',
|
||||
filename
|
||||
);
|
||||
url = urlJoin(GBServer.globals.publicAddress, 'kb', gbaiName, 'assets', filename);
|
||||
} else {
|
||||
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.
|
||||
|
|
|
@ -52,6 +52,7 @@ 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';
|
||||
import lineReplace from 'line-replace';
|
||||
|
||||
/**
|
||||
* @fileoverview Decision was to priorize security(isolation) and debugging,
|
||||
|
@ -113,7 +114,7 @@ export class GBVMService extends GBService {
|
|||
}
|
||||
|
||||
// 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)) {
|
||||
const packageJson = `
|
||||
{
|
||||
|
@ -136,6 +137,34 @@ export class GBVMService extends GBService {
|
|||
GBLogEx.info(min, `BASIC: Installing .gbdialog node_modules for ${min.botId}...`);
|
||||
const npmPath = urlJoin(process.env.PWD, 'node_modules', '.bin', 'npm');
|
||||
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.
|
||||
|
@ -209,16 +238,17 @@ export class GBVMService extends GBService {
|
|||
const createHttpClient = require("@push-rpc/http").createHttpClient;
|
||||
|
||||
// Setups interprocess communication from .gbdialog run-time to the BotServer API.
|
||||
|
||||
const optsRPC = {callTimeout: this.callTimeout};
|
||||
let url;
|
||||
|
||||
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';
|
||||
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';
|
||||
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';
|
||||
const img = (await createRpcClient(0, () => createHttpClient(url))).remote;
|
||||
const img = (await createRpcClient(0, () => createHttpClient(url), optsRPC)).remote;
|
||||
|
||||
// Unmarshalls Local variables from server VM.
|
||||
|
||||
|
@ -227,6 +257,7 @@ export class GBVMService extends GBService {
|
|||
let username = this.username;
|
||||
let mobile = this.mobile;
|
||||
let from = this.from;
|
||||
let channel = this.channel;
|
||||
let ENTER = this.ENTER;
|
||||
let headers = this.headers;
|
||||
let data = this.data;
|
||||
|
@ -302,7 +333,7 @@ export class GBVMService extends GBService {
|
|||
text = text.replace(/\”/gm, '"');
|
||||
text = text.replace(/\‘/gm, "'");
|
||||
text = text.replace(/\’/gm, "'");
|
||||
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
@ -372,17 +403,18 @@ export class GBVMService extends GBService {
|
|||
}
|
||||
|
||||
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 scriptPath = urlJoin(gbdialogPath, `${text}.js`);
|
||||
|
||||
let code = min.sandBoxMap[text];
|
||||
|
||||
const channel = step? step.context.activity.channelId : 'web';
|
||||
const pid = GBAdminService.getNumberIdentifier();
|
||||
GBServer.globals.processes[pid] = {
|
||||
pid: pid,
|
||||
userId: user.userId,
|
||||
instanceId: min.instance.instanceId
|
||||
instanceId: min.instance.instanceId,
|
||||
channel: channel
|
||||
};
|
||||
const dk = new DialogKeywords();
|
||||
const sys = new SystemKeywords();
|
||||
|
@ -400,7 +432,9 @@ export class GBVMService extends GBService {
|
|||
sandbox['httpPs'] = '';
|
||||
sandbox['pid'] = pid;
|
||||
sandbox['contentLocale'] = contentLocale;
|
||||
|
||||
sandbox['callTimeout'] = 60 * 60 * 24 * 1000;
|
||||
sandbox['channel'] = channel;
|
||||
|
||||
let result;
|
||||
|
||||
try {
|
||||
|
@ -411,7 +445,7 @@ export class GBVMService extends GBService {
|
|||
console: 'inherit',
|
||||
wrapper: 'commonjs',
|
||||
require: {
|
||||
builtin: ['stream', 'http', 'https', 'url', 'zlib', 'net', 'tls', 'crypto', ],
|
||||
builtin: ['stream', 'http', 'https', 'url', 'zlib', 'net', 'tls', 'crypto'],
|
||||
root: ['./'],
|
||||
external: true,
|
||||
context: 'sandbox'
|
||||
|
|
|
@ -304,6 +304,17 @@ export class GBConversationalService {
|
|||
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(
|
||||
min: GBMinInstance,
|
||||
step: GBDialogStep,
|
||||
|
|
|
@ -462,7 +462,7 @@ export class GBMinService {
|
|||
|
||||
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) {
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
|
||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||
import { Messages } from '../strings.js';
|
||||
import * as phone from 'google-libphonenumber';
|
||||
import * as phone from 'google-libphonenumber';
|
||||
|
||||
/**
|
||||
* Dialogs for handling Menu control.
|
||||
|
|
Loading…
Add table
Reference in a new issue