new(basic.gblib): GPT-3 automatically dialog generation.
This commit is contained in:
parent
db7ed36707
commit
a9ce03b353
13 changed files with 512 additions and 172 deletions
BIN
blank.docx
Normal file
BIN
blank.docx
Normal file
Binary file not shown.
BIN
blank.xlsx
Normal file
BIN
blank.xlsx
Normal file
Binary file not shown.
1
boot.mjs
1
boot.mjs
|
@ -6,6 +6,7 @@ import { exec } from 'child_process';
|
||||||
import pjson from './package.json' assert { type: 'json' };
|
import pjson from './package.json' assert { type: 'json' };
|
||||||
|
|
||||||
// Displays version of Node JS being used at runtime and others attributes.
|
// Displays version of Node JS being used at runtime and others attributes.
|
||||||
|
|
||||||
console.log(``);
|
console.log(``);
|
||||||
console.log(``);
|
console.log(``);
|
||||||
console.log(` █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® `);
|
console.log(` █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® `);
|
||||||
|
|
|
@ -559,7 +559,7 @@ export class DialogKeywords {
|
||||||
// }
|
// }
|
||||||
let { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
let { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||||
const sec = new SecService();
|
const sec = new SecService();
|
||||||
await sec.setParam(user.userId, name, value);
|
await sec.setParam(user.userId, name , value);
|
||||||
GBLog.info(`BASIC: ${name} = ${value} (botId: ${min.botId})`);
|
GBLog.info(`BASIC: ${name} = ${value} (botId: ${min.botId})`);
|
||||||
return { min, user, params };
|
return { min, user, params };
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,41 +137,13 @@ 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.
|
||||||
const fullFilename = urlJoin(folder, filename);
|
const fullFilename = urlJoin(folder, filename);
|
||||||
if (process.env.DEV_HOTSWAP) {
|
if (process.env.DEV_HOTSWAP) {
|
||||||
Fs.watchFile(fullFilename, async () => {
|
Fs.watchFile(fullFilename, async () => {
|
||||||
await this.translateBASIC(fullFilename, mainName, min);
|
await this.translateBASIC(fullFilename, min);
|
||||||
const parsedCode: string = Fs.readFileSync(jsfile, 'utf8');
|
const parsedCode: string = Fs.readFileSync(jsfile, 'utf8');
|
||||||
min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode;
|
min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode;
|
||||||
});
|
});
|
||||||
|
@ -184,17 +156,17 @@ export class GBVMService extends GBService {
|
||||||
const jsStat = Fs.statSync(jsfile);
|
const jsStat = Fs.statSync(jsfile);
|
||||||
const interval = 30000; // If compiled is older 30 seconds, then recompile.
|
const interval = 30000; // If compiled is older 30 seconds, then recompile.
|
||||||
if (compiledAt.isFile() && compiledAt['mtimeMs'] > jsStat['mtimeMs'] + interval) {
|
if (compiledAt.isFile() && compiledAt['mtimeMs'] > jsStat['mtimeMs'] + interval) {
|
||||||
await this.translateBASIC(fullFilename, mainName, min);
|
await this.translateBASIC(fullFilename, min);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await this.translateBASIC(fullFilename, mainName, min);
|
await this.translateBASIC(fullFilename, min);
|
||||||
}
|
}
|
||||||
const parsedCode: string = Fs.readFileSync(jsfile, 'utf8');
|
const parsedCode: string = Fs.readFileSync(jsfile, 'utf8');
|
||||||
min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode;
|
min.sandBoxMap[mainName.toLowerCase().trim()] = parsedCode;
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async translateBASIC(filename: any, mainName: string, min: GBMinInstance) {
|
public async translateBASIC(filename: any, min: GBMinInstance) {
|
||||||
// Converts General Bots BASIC into regular VBS
|
// Converts General Bots BASIC into regular VBS
|
||||||
|
|
||||||
let basicCode: string = Fs.readFileSync(filename, 'utf8');
|
let basicCode: string = Fs.readFileSync(filename, 'utf8');
|
||||||
|
@ -264,9 +236,11 @@ export class GBVMService extends GBService {
|
||||||
let list = this.list;
|
let list = this.list;
|
||||||
let httpUsername = this.httpUsername;
|
let httpUsername = this.httpUsername;
|
||||||
let httpPs = this.httpPs;
|
let httpPs = this.httpPs;
|
||||||
let page = null;
|
|
||||||
let today = this.today;
|
let today = this.today;
|
||||||
let now = this.now;
|
let now = this.now;
|
||||||
|
let page = null;
|
||||||
|
let files = [];
|
||||||
|
let col = 1;
|
||||||
|
|
||||||
// Transfers NLP auto variables into global object.
|
// Transfers NLP auto variables into global object.
|
||||||
|
|
||||||
|
@ -351,18 +325,25 @@ export class GBVMService extends GBService {
|
||||||
var lines = code.split('\n');
|
var lines = code.split('\n');
|
||||||
const keywords = KeywordsExpressions.getKeywords();
|
const keywords = KeywordsExpressions.getKeywords();
|
||||||
let current = 41;
|
let current = 41;
|
||||||
const map = {};
|
const map = {};
|
||||||
|
|
||||||
for (let i = 1; i <= lines.length; i++) {
|
for (let i = 1; i <= lines.length; i++) {
|
||||||
|
let line = lines[i - 1];
|
||||||
|
|
||||||
|
// Remove lines before statments.
|
||||||
|
|
||||||
|
line = line.replace(/^\s*\d+\s*/gi,'');
|
||||||
|
|
||||||
for (let j = 0; j < keywords.length; j++) {
|
for (let j = 0; j < keywords.length; j++) {
|
||||||
lines[i - 1] = lines[i - 1].replace(keywords[j][0], keywords[j][1]);
|
line = line.replace(keywords[j][0], keywords[j][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add additional lines returned from replacement.
|
// Add additional lines returned from replacement.
|
||||||
|
|
||||||
let add = lines[i - 1].split(/\r\n|\r|\n/).length;
|
let add = line.split(/\r\n|\r|\n/).length;
|
||||||
current = current + (add ? add : 0);
|
current = current + (add ? add : 0);
|
||||||
map[i] = current;
|
map[i] = current;
|
||||||
|
lines[i - 1] = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = `${lines.join('\n')}\n`;
|
code = `${lines.join('\n')}\n`;
|
||||||
|
@ -419,7 +400,8 @@ export class GBVMService extends GBService {
|
||||||
};
|
};
|
||||||
const dk = new DialogKeywords();
|
const dk = new DialogKeywords();
|
||||||
const sys = new SystemKeywords();
|
const sys = new SystemKeywords();
|
||||||
|
await dk.setFilter ({pid: pid, value: null });
|
||||||
|
|
||||||
sandbox['variables'] = variables;
|
sandbox['variables'] = variables;
|
||||||
sandbox['id'] = sys.getRandomId();
|
sandbox['id'] = sys.getRandomId();
|
||||||
sandbox['username'] = await dk.userName({ pid });
|
sandbox['username'] = await dk.userName({ pid });
|
||||||
|
|
|
@ -32,7 +32,9 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBVMService } from "./GBVMService.js";
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
|
import { GBVMService } from './GBVMService.js';
|
||||||
|
import Path from 'path';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image processing services of conversation to be called by BASIC.
|
* Image processing services of conversation to be called by BASIC.
|
||||||
|
@ -46,7 +48,7 @@ export class KeywordsExpressions {
|
||||||
if (accum.isConcatting) {
|
if (accum.isConcatting) {
|
||||||
accum.soFar[accum.soFar.length - 1] += ',' + curr;
|
accum.soFar[accum.soFar.length - 1] += ',' + curr;
|
||||||
} else {
|
} else {
|
||||||
if(curr===""){
|
if (curr === '') {
|
||||||
curr = null;
|
curr = null;
|
||||||
}
|
}
|
||||||
accum.soFar.push(curr);
|
accum.soFar.push(curr);
|
||||||
|
@ -67,15 +69,20 @@ export class KeywordsExpressions {
|
||||||
names.forEach(name => {
|
names.forEach(name => {
|
||||||
let value = items[i];
|
let value = items[i];
|
||||||
i++;
|
i++;
|
||||||
json = `${json} "${name}": ${value} ${names.length == i ? '' : ','}`;
|
json = `${json} "${name}": ${value === undefined ? null : value} ${names.length == i ? '' : ','}`;
|
||||||
});
|
});
|
||||||
json = `${json}`;
|
json = `${json}`;
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static isNumber(n) {
|
||||||
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of BASIC keyword and their JS match.
|
* Returns the list of BASIC keyword and their JS match.
|
||||||
|
* Based on https://github.com/uweg/vbscript-to-typescript.
|
||||||
*/
|
*/
|
||||||
public static getKeywords() {
|
public static getKeywords() {
|
||||||
// Keywords from General Bots BASIC.
|
// Keywords from General Bots BASIC.
|
||||||
|
@ -91,14 +98,134 @@ export class KeywordsExpressions {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
keywords[i++] = [
|
||||||
|
/^\s*INPUT(.*)/gim,
|
||||||
|
($0, $1, $2) => {
|
||||||
|
|
||||||
|
let separator;
|
||||||
|
if ($1.indexOf(',') > -1){
|
||||||
|
separator = ',';
|
||||||
|
}
|
||||||
|
else if ($1.indexOf(';') > -1){
|
||||||
|
separator = ';';
|
||||||
|
}
|
||||||
|
let parts;
|
||||||
|
if ( separator && (parts = $1.split(separator)) && parts.length > 1){
|
||||||
|
return `
|
||||||
|
TALK ${parts[0]}
|
||||||
|
HEAR ${parts[1]}`;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return `
|
||||||
|
HEAR ${$1}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
keywords[i++] = [
|
||||||
|
/^\s*WRITE(.*)/gim,
|
||||||
|
($0, $1, $2) => {
|
||||||
|
return `PRINT${$1}`;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
keywords[i++] = [/^\s*REM.*/gim, ''];
|
keywords[i++] = [/^\s*REM.*/gim, ''];
|
||||||
|
|
||||||
|
keywords[i++] = [/^\s*CLOSE.*/gim, ''];
|
||||||
|
|
||||||
|
// Always autoclose keyword.
|
||||||
|
|
||||||
|
keywords[i++] = [/^\s*CLOSE.*/gim, ''];
|
||||||
|
|
||||||
keywords[i++] = [/^\s*\'.*/gim, ''];
|
keywords[i++] = [/^\s*\'.*/gim, ''];
|
||||||
|
|
||||||
|
keywords[i++] = [
|
||||||
|
/^\s*PRINT ([\s\S]*)/gim,
|
||||||
|
($0, $1, $2) => {
|
||||||
|
let sessionName;
|
||||||
|
let kind = null;
|
||||||
|
let pos;
|
||||||
|
$1 = $1.trim();
|
||||||
|
|
||||||
|
if ($1.substr(0, 1) === '#') {
|
||||||
|
let sessionName = $1.substr(1, $1.indexOf(',') - 1);
|
||||||
|
$1 = $1.replace(/\; \"\,\"/gi, '');
|
||||||
|
$1 = $1.substr($1.indexOf(',') + 1);
|
||||||
|
|
||||||
|
let separator;
|
||||||
|
if ($1.indexOf(',') > -1){
|
||||||
|
separator = ',';
|
||||||
|
}
|
||||||
|
else if ($1.indexOf(';') > -1){
|
||||||
|
separator = ';';
|
||||||
|
}
|
||||||
|
let items;
|
||||||
|
if (separator && (items = $1.split(separator)) && items.length > 1) {
|
||||||
|
return `await sys.save({pid: pid, file: files[${sessionName}], args:[${items.join(',')}]})`;
|
||||||
|
} else {
|
||||||
|
return `await sys.set({pid: pid, file: files[${sessionName}], address: col++, name: "${items[0]}", value: ${items[0]}})`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return `await dk.talk({pid: pid, text: ${$1}})`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
keywords[i++] = [
|
||||||
|
/^\s*open([\s\S]*)/gim,
|
||||||
|
($0, $1, $2) => {
|
||||||
|
let sessionName;
|
||||||
|
let kind = null;
|
||||||
|
let pos;
|
||||||
|
|
||||||
|
$1 = $1.replace('FOR APPEND', '');
|
||||||
|
$1 = $1.replace('FOR OUTPUT', '');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ((pos = $1.match(/\s*AS\s*\#/gi))) {
|
||||||
|
kind = 'AS';
|
||||||
|
} else if ((pos = $1.match(/\s*WITH\s*\#/gi))) {
|
||||||
|
kind = 'WITH';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos) {
|
||||||
|
let part = $1.substr($1.lastIndexOf(pos[0]));
|
||||||
|
sessionName = `${part.substr(part.indexOf('#') + 1)}`;
|
||||||
|
$1 = $1.substr(0, $1.lastIndexOf(pos[0]));
|
||||||
|
}
|
||||||
|
$1 = $1.trim();
|
||||||
|
if (!$1.startsWith('"') && !$1.startsWith("'")) {
|
||||||
|
$1 = `"${$1}"`;
|
||||||
|
}
|
||||||
|
const params = this.getParams($1, ['url', 'username', 'password']);
|
||||||
|
|
||||||
|
// Checks if it is opening a file or a webpage.
|
||||||
|
|
||||||
|
if (kind === 'AS' && KeywordsExpressions.isNumber(sessionName)) {
|
||||||
|
const jParams = JSON.parse(`{${params}}`);
|
||||||
|
const filename = `${jParams.url.substr(0, jParams.url.lastIndexOf("."))}.xlsx`;
|
||||||
|
let code =
|
||||||
|
`
|
||||||
|
col = 1
|
||||||
|
await sys.save({pid: pid,file: "${filename}", args: [id] })
|
||||||
|
await dk.setFilter ({pid: pid, value: "id=" + id })
|
||||||
|
files[${sessionName}] = "${filename}"
|
||||||
|
`;
|
||||||
|
return code;
|
||||||
|
} else {
|
||||||
|
sessionName = `"${sessionName}"`;
|
||||||
|
kind = `"${kind}"`;
|
||||||
|
return `page = await wa.openPage({pid: pid, handle: page, sessionKind: ${kind}, sessionName: ${sessionName}, ${params}})`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*((?:[a-z]+.?)(?:(?:\w+).)(?:\w+)*)\s*=\s*SELECT\s*(.*)/gim,
|
/^\s*((?:[a-z]+.?)(?:(?:\w+).)(?:\w+)*)\s*=\s*SELECT\s*(.*)/gim,
|
||||||
($0, $1, $2) => {
|
($0, $1, $2) => {
|
||||||
let tableName = /\s*FROM\s*(\w+)/.exec($2)[1];
|
let tableName = /\s*FROM\s*(\w+\$*)/.exec($2)[1];
|
||||||
let sql = `SELECT ${$2}`.replace(tableName, '?');
|
let sql = `SELECT ${$2}`.replace(tableName, '?');
|
||||||
return `${$1} = await sys.executeSQL({pid: pid, data:${$1}, sql:"${sql}", tableName:"${tableName}"})\n`;
|
return `${$1} = await sys.executeSQL({pid: pid, data:${$1}, sql:"${sql}", tableName:"${tableName}"})\n`;
|
||||||
}
|
}
|
||||||
|
@ -114,8 +241,6 @@ export class KeywordsExpressions {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// Based on https://github.com/uweg/vbscript-to-typescript.
|
|
||||||
|
|
||||||
keywords[i++] = [/^\s*else(?!{)/gim, '}\nelse {'];
|
keywords[i++] = [/^\s*else(?!{)/gim, '}\nelse {'];
|
||||||
|
|
||||||
keywords[i++] = [/^\s*select case +(.*)/gim, 'switch ($1) {'];
|
keywords[i++] = [/^\s*select case +(.*)/gim, 'switch ($1) {'];
|
||||||
|
@ -141,30 +266,42 @@ export class KeywordsExpressions {
|
||||||
keywords[i++] = [/^\s*loop *$/gim, '}'];
|
keywords[i++] = [/^\s*loop *$/gim, '}'];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*open\s*(.*)/gim,
|
/^\s*open([\s\S]*)/gim,
|
||||||
($0, $1, $2) => {
|
($0, $1, $2) => {
|
||||||
let sessionName;
|
let sessionName;
|
||||||
let kind = null;
|
let kind = null;
|
||||||
let pos;
|
let pos;
|
||||||
|
|
||||||
if (pos = $1.match(/\s*AS\s*\#/)) {
|
$1 = $1.replace(' FOR APPEND', '');
|
||||||
kind = '"AS"';
|
|
||||||
} else if (pos = $1.match(/\s*WITH\s*\#/)) {
|
if ((pos = $1.match(/\s*AS\s*\#/))) {
|
||||||
kind = '"WITH"';
|
kind = 'AS';
|
||||||
|
} else if ((pos = $1.match(/\s*WITH\s*\#/))) {
|
||||||
|
kind = 'WITH';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos) {
|
if (pos) {
|
||||||
let part = $1.substr($1.lastIndexOf(pos[0]));
|
let part = $1.substr($1.lastIndexOf(pos[0]));
|
||||||
sessionName = `"${part.substr(part.indexOf('#') + 1)}"`;
|
sessionName = `${part.substr(part.indexOf('#') + 1)}`;
|
||||||
$1 = $1.substr(0, $1.lastIndexOf(pos[0]));
|
$1 = $1.substr(0, $1.lastIndexOf(pos[0]));
|
||||||
}
|
}
|
||||||
|
$1 = $1.trim();
|
||||||
if (!$1.startsWith('"') && !$1.startsWith("'")) {
|
if (!$1.startsWith('"') && !$1.startsWith("'")) {
|
||||||
$1 = `"${$1}"`;
|
$1 = `"${$1}"`;
|
||||||
}
|
}
|
||||||
const params = this.getParams($1, ['url', 'username', 'password']);
|
const params = this.getParams($1, ['url', 'username', 'password']);
|
||||||
|
|
||||||
return `page = await wa.openPage({pid: pid, handle: page, sessionKind: ${kind}, sessionName: ${sessionName}, ${params}})`;
|
// Checks if it is opening a file or a webpage.
|
||||||
|
|
||||||
|
if (kind === 'AS' && KeywordsExpressions.isNumber(sessionName)) {
|
||||||
|
const jParams = JSON.parse(`{${params}}`);
|
||||||
|
const filename = `${Path.basename(jParams.url, 'txt')}xlsx`;
|
||||||
|
return `files[${sessionName}] = "${filename}"`;
|
||||||
|
} else {
|
||||||
|
sessionName = `"${sessionName}"`;
|
||||||
|
kind = `"${kind}"`;
|
||||||
|
return `page = await wa.openPage({pid: pid, handle: page, sessionKind: ${kind}, sessionName: ${sessionName}, ${params}})`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -176,112 +313,112 @@ export class KeywordsExpressions {
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as (\w+( \w+)*.xlsx)/gim,
|
/^\s*hear (\w+\$*) as (\w+( \w+)*.xlsx)/gim,
|
||||||
($0, $1, $2) => {
|
($0, $1, $2) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"sheet", arg: "${$2}"})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"sheet", arg: "${$2}"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*login/gim,
|
/^\s*hear (\w+\$*) as\s*login/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"login"})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"login"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*email/gim,
|
/^\s*hear (\w+\$*) as\s*email/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"email"})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"email"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*integer/gim,
|
/^\s*hear (\w+\$*) as\s*integer/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"integer"})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"integer"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*file/gim,
|
/^\s*hear (\w+\$*) as\s*file/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"file"})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"file"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*boolean/gim,
|
/^\s*hear (\w+\$*) as\s*boolean/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"boolean"})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"boolean"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*name/gim,
|
/^\s*hear (\w+\$*) as\s*name/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"name"})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"name"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*date/gim,
|
/^\s*hear (\w+\$*) as\s*date/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"date"})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"date"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*hour/gim,
|
/^\s*hear (\w+\$*) as\s*hour/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"hour"})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"hour"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*phone/gim,
|
/^\s*hear (\w+\$*) as\s*phone/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"phone"})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"phone"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*money/gim,
|
/^\s*hear (\w+\$*) as\s*money/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"money")}`;
|
return `${$1} = await dk.hear({pid: pid, kind:"money")}`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*qrcode/gim,
|
/^\s*hear (\w+\$*) as\s*qrcode/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"qrcode")}`;
|
return `${$1} = await dk.hear({pid: pid, kind:"qrcode")}`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*language/gim,
|
/^\s*hear (\w+\$*) as\s*language/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"language")}`;
|
return `${$1} = await dk.hear({pid: pid, kind:"language")}`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*zipcode/gim,
|
/^\s*hear (\w+\$*) as\s*zipcode/gim,
|
||||||
($0, $1) => {
|
($0, $1) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"zipcode")}`;
|
return `${$1} = await dk.hear({pid: pid, kind:"zipcode")}`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*hear (\w+) as\s*(.*)/gim,
|
/^\s*hear (\w+\$*) as\s*(.*)/gim,
|
||||||
($0, $1, $2) => {
|
($0, $1, $2) => {
|
||||||
return `${$1} = await dk.hear({pid: pid, kind:"menu", args: [${$2}]})`;
|
return `${$1} = await dk.hear({pid: pid, kind:"menu", args: [${$2}]})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*(hear)\s*(\w+)/gim,
|
/^\s*(hear)\s*(\w+\$*)/gim,
|
||||||
($0, $1, $2) => {
|
($0, $1, $2) => {
|
||||||
return `${$2} = await dk.hear({pid: pid})`;
|
return `${$2} = await dk.hear({pid: pid})`;
|
||||||
}
|
}
|
||||||
|
@ -345,21 +482,21 @@ export class KeywordsExpressions {
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*((?:[a-z]+.?)(?:(?:\w+).)(?:\w+)*)\s*=\s*sort\s*(\w+)\s*by(.*)/gim,
|
/^\s*((?:[a-z]+.?)(?:(?:\w+).)(?:\w+)*)\s*=\s*sort\s*(\w+\$*)\s*by(.*)/gim,
|
||||||
($0, $1, $2, $3) => {
|
($0, $1, $2, $3) => {
|
||||||
return `${$1} = await sys.sortBy({pid: pid, array: ${$2}, memberName: "${$3}"})`;
|
return `${$1} = await sys.sortBy({pid: pid, array: ${$2}, memberName: "${$3}"})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*see\s*text\s*of\s*(\w+)\s*as\s*(\w+)\s*/gim,
|
/^\s*see\s*text\s*of\s*(\w+\$*)\s*as\s*(\w+\$*)\s*/gim,
|
||||||
($0, $1, $2, $3) => {
|
($0, $1, $2, $3) => {
|
||||||
return `${$2} = await sys.seeText({pid: pid, url: ${$1})`;
|
return `${$2} = await sys.seeText({pid: pid, url: ${$1})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*see\s*caption\s*of\s*(\w+)\s*as(.*)/gim,
|
/^\s*see\s*caption\s*of\s*(\w+\$*)\s*as(.*)/gim,
|
||||||
($0, $1, $2, $3) => {
|
($0, $1, $2, $3) => {
|
||||||
return `${$2} = await sys.seeCaption({pid: pid, url: ${$1})`;
|
return `${$2} = await sys.seeCaption({pid: pid, url: ${$1})`;
|
||||||
}
|
}
|
||||||
|
@ -618,7 +755,6 @@ export class KeywordsExpressions {
|
||||||
// Uses auto quote if this is a frase with more then one word.
|
// Uses auto quote if this is a frase with more then one word.
|
||||||
|
|
||||||
if (/\s/.test($3) && $3.substr(0, 1) !== '"') {
|
if (/\s/.test($3) && $3.substr(0, 1) !== '"') {
|
||||||
|
|
||||||
$3 = `"${$3}"`;
|
$3 = `"${$3}"`;
|
||||||
}
|
}
|
||||||
return `await dk.talk ({pid: pid, text: ${$3}})`;
|
return `await dk.talk ({pid: pid, text: ${$3}})`;
|
||||||
|
@ -772,19 +908,19 @@ export class KeywordsExpressions {
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*save\s*(\w+)\s*as\s*(.*)/gim,
|
/^\s*save\s*(\w+\$*)\s*as\s*(.*)/gim,
|
||||||
($0, $1, $2, $3) => {
|
($0, $1, $2, $3) => {
|
||||||
return `await sys.saveFile({pid: pid, file: ${$2}, data: ${$1}})`;
|
return `await sys.saveFile({pid: pid, file: ${$2}, data: ${$1}})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
keywords[i++] = [
|
keywords[i++] = [
|
||||||
/^\s*(save)(\s*)(.*\.xlsx)(.*)/gim,
|
/^\s*(save)(\s*)(.*\.xlsx)(.*)/gim,
|
||||||
($0, $1, $2, $3, $4) => {
|
($0, $1, $2, $3, $4) => {
|
||||||
$3 = $3.replace (/\'/g, "")
|
$3 = $3.replace(/\'/g, '');
|
||||||
$3 = $3.replace (/\"/g, "")
|
$3 = $3.replace(/\"/g, '');
|
||||||
$4 = $4.substr(2)
|
$4 = $4.substr(2);
|
||||||
return `await sys.save({pid: pid,file: "${$3}" , args: [${$4}]})`;
|
return `await sys.save({pid: pid, file: "${$3}", args: [${$4}]})`;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ import DynamicsWebApi from 'dynamics-web-api';
|
||||||
import * as MSAL from '@azure/msal-node';
|
import * as MSAL from '@azure/msal-node';
|
||||||
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
||||||
import { WebAutomationServices } from './WebAutomationServices.js';
|
import { WebAutomationServices } from './WebAutomationServices.js';
|
||||||
|
import { KeywordsExpressions } from './KeywordsExpressions.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview General Bots server core.
|
* @fileoverview General Bots server core.
|
||||||
|
@ -471,7 +472,7 @@ export class SystemKeywords {
|
||||||
* @example SET page, "elementHTMLSelector", "text"
|
* @example SET page, "elementHTMLSelector", "text"
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public async set({ pid, handle, file, address, value }): Promise<any> {
|
public async set({ pid, handle, file, address, value, name = null }): Promise<any> {
|
||||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||||
|
|
||||||
// Handles calls for HTML stuff
|
// Handles calls for HTML stuff
|
||||||
|
@ -485,14 +486,6 @@ export class SystemKeywords {
|
||||||
|
|
||||||
// TODO: Add a semaphore between FILTER and SET.
|
// TODO: Add a semaphore between FILTER and SET.
|
||||||
|
|
||||||
// Processes FILTER option to ensure parallel SET calls.
|
|
||||||
|
|
||||||
const filter = await DialogKeywords.getOption({ pid, name });
|
|
||||||
if (filter) {
|
|
||||||
const row = this.find({ pid, handle: null, args: [filter] });
|
|
||||||
address += row['line'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles calls for BASIC persistence on sheet files.
|
// Handles calls for BASIC persistence on sheet files.
|
||||||
|
|
||||||
GBLog.info(`BASIC: Defining '${address}' in '${file}' to '${value}' (SET). `);
|
GBLog.info(`BASIC: Defining '${address}' in '${file}' to '${value}' (SET). `);
|
||||||
|
@ -501,16 +494,53 @@ export class SystemKeywords {
|
||||||
|
|
||||||
const botId = min.instance.botId;
|
const botId = min.instance.botId;
|
||||||
const path = DialogKeywords.getGBAIPath(botId, 'gbdata');
|
const path = DialogKeywords.getGBAIPath(botId, 'gbdata');
|
||||||
|
let document = await this.internalGetDocument(client, baseUrl, path, file);
|
||||||
|
let sheets = await client.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets`).get();
|
||||||
|
let body = { values: [[]] };
|
||||||
|
|
||||||
|
// Processes FILTER option to ensure parallel SET calls.
|
||||||
|
|
||||||
|
const filter = await DialogKeywords.getOption({ pid, name: 'filter' });
|
||||||
|
let titleAddress;
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
// Transforms address number (col index) to letter based.
|
||||||
|
// Eg.: REM This is A column and index automatically specified by filter.
|
||||||
|
// SET file.xlsx, 1, 4000
|
||||||
|
|
||||||
|
if (KeywordsExpressions.isNumber(address)) {
|
||||||
|
address = `${this.numberToLetters(address)}`;
|
||||||
|
titleAddress = `${address}1:${address}1`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processes SET FILTER directive to calculate address.
|
||||||
|
|
||||||
|
body.values[0][0] = 'id';
|
||||||
|
const addressId = 'A1:A1';
|
||||||
|
await client
|
||||||
|
.api(
|
||||||
|
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${addressId}')`
|
||||||
|
)
|
||||||
|
.patch(body);
|
||||||
|
|
||||||
|
const row = await this.find({ pid, handle: null, args: [file, filter] });
|
||||||
|
if (row) {
|
||||||
|
address += row['line']; // Eg.: "A" + 1 = "A1".
|
||||||
|
}
|
||||||
|
}
|
||||||
address = address.indexOf(':') !== -1 ? address : address + ':' + address;
|
address = address.indexOf(':') !== -1 ? address : address + ':' + address;
|
||||||
|
|
||||||
let document = await this.internalGetDocument(client, baseUrl, path, file);
|
if (titleAddress) {
|
||||||
|
body.values[0][0] = name.trim().replace(/[^a-zA-Z]/gi, '');
|
||||||
|
|
||||||
|
await client
|
||||||
|
.api(
|
||||||
|
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${titleAddress}')`
|
||||||
|
)
|
||||||
|
.patch(body);
|
||||||
|
}
|
||||||
|
|
||||||
let body = { values: [[]] };
|
|
||||||
body.values[0][0] = value;
|
body.values[0][0] = value;
|
||||||
|
|
||||||
let sheets = await client.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets`).get();
|
|
||||||
|
|
||||||
await client
|
await client
|
||||||
.api(
|
.api(
|
||||||
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${address}')`
|
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${address}')`
|
||||||
|
@ -529,7 +559,10 @@ export class SystemKeywords {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!documents || documents.length === 0) {
|
if (!documents || documents.length === 0) {
|
||||||
throw `File '${file}' specified on GBasic command not found. Check the .gbdata or the .gbdialog associated.`;
|
throw new Error(
|
||||||
|
`File '${file}' specified on GBasic command not found. Check the .gbdata or the .gbdialog associated.`,
|
||||||
|
{ cause: 404 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return documents[0];
|
return documents[0];
|
||||||
|
@ -575,36 +608,84 @@ export class SystemKeywords {
|
||||||
*/
|
*/
|
||||||
public async save({ pid, file, args }): Promise<any> {
|
public async save({ pid, file, args }): Promise<any> {
|
||||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||||
args.shift();
|
|
||||||
GBLog.info(`BASIC: Saving '${file}' (SAVE). Args: ${args.join(',')}.`);
|
GBLog.info(`BASIC: Saving '${file}' (SAVE). Args: ${args.join(',')}.`);
|
||||||
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||||
const botId = min.instance.botId;
|
const botId = min.instance.botId;
|
||||||
const path = DialogKeywords.getGBAIPath(botId, 'gbdata');
|
const path = DialogKeywords.getGBAIPath(botId, 'gbdata');
|
||||||
|
|
||||||
let document = await this.internalGetDocument(client, baseUrl, path, file);
|
let sheets;
|
||||||
let sheets = await client.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets`).get();
|
let document;
|
||||||
|
try {
|
||||||
|
document = await this.internalGetDocument(client, baseUrl, path, file);
|
||||||
|
sheets = await client.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets`).get();
|
||||||
|
} catch (e) {
|
||||||
|
if (e.cause === 404) {
|
||||||
|
// Creates the file.
|
||||||
|
|
||||||
await client
|
const blank = Path.join(process.env.PWD, 'blank.xlsx');
|
||||||
.api(
|
const data = Fs.readFileSync(blank);
|
||||||
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='A2:DX2')/insert`
|
await client.api(`${baseUrl}/drive/root:/${path}/${file}:/content`).put(data);
|
||||||
)
|
|
||||||
.post({});
|
|
||||||
|
|
||||||
if (args.length > 128) {
|
// Tries to open again.
|
||||||
throw `File '${file}' has a SAVE call with more than 128 arguments. Check the .gbdialog associated.`;
|
|
||||||
|
document = await this.internalGetDocument(client, baseUrl, path, file);
|
||||||
|
sheets = await client.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets`).get();
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let address;
|
||||||
let body = { values: [[]] };
|
let body = { values: [[]] };
|
||||||
|
|
||||||
const address = `A2:${this.numberToLetters(args.length - 1)}2`;
|
// Processes FILTER option to ensure parallel SET calls.
|
||||||
|
|
||||||
|
const filter = await DialogKeywords.getOption({ pid, name: 'filter' });
|
||||||
|
if (filter) {
|
||||||
|
|
||||||
|
// Creates id row.
|
||||||
|
|
||||||
|
body.values[0][0] = 'id';
|
||||||
|
const addressId = 'A1:A1';
|
||||||
|
await client
|
||||||
|
.api(
|
||||||
|
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${addressId}')`
|
||||||
|
)
|
||||||
|
.patch(body);
|
||||||
|
body.values[0][0] = undefined ;
|
||||||
|
|
||||||
|
// FINDs the filtered row to be updated.
|
||||||
|
|
||||||
|
const row = await this.find({ pid, handle: null, args: [file, filter] });
|
||||||
|
if (row) {
|
||||||
|
address = `A${row['line']}:${this.numberToLetters(args.length)}${row['line']}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Editing or saving detection.
|
||||||
|
|
||||||
|
if (!address) {
|
||||||
|
await client
|
||||||
|
.api(
|
||||||
|
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='A2:DX2')/insert`
|
||||||
|
)
|
||||||
|
.post({});
|
||||||
|
address = `A2:${this.numberToLetters(args.length - 1)}2`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fills rows object to call sheet API.
|
||||||
|
|
||||||
for (let index = 0; index < args.length; index++) {
|
for (let index = 0; index < args.length; index++) {
|
||||||
let value = args[index];
|
let value = args[index];
|
||||||
if (value && (await this.isValidDate({ pid, dt: value }))) {
|
if (value && (await this.isValidDate({ pid, dt: value }))) {
|
||||||
value = `'${value}`;
|
value = `'${value}`;
|
||||||
}
|
}
|
||||||
body.values[0][index] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// If filter is defined, skips id column.
|
||||||
|
|
||||||
|
body.values[0][filter ? index + 1 : index] = value;
|
||||||
|
}
|
||||||
await client
|
await client
|
||||||
.api(
|
.api(
|
||||||
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${address}')`
|
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${address}')`
|
||||||
|
@ -675,11 +756,7 @@ export class SystemKeywords {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async isValidNumber({ pid, number }) {
|
public async isValidNumber({ pid, number }) {
|
||||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
return KeywordsExpressions.isNumber(number);
|
||||||
if (number === '') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return !isNaN(number);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public isValidHour({ pid, value }) {
|
public isValidHour({ pid, value }) {
|
||||||
|
@ -1179,6 +1256,33 @@ export class SystemKeywords {
|
||||||
await client.api(`https://graph.microsoft.com/v1.0/drives/${driveId}/items/${itemId}/invite`).post(body);
|
await client.api(`https://graph.microsoft.com/v1.0/drives/${driveId}/items/${itemId}/invite`).post(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async internalCreateDocument(min, path, content) {
|
||||||
|
GBLog.info(`BASIC: CREATE DOCUMENT '${path}...'`);
|
||||||
|
let { baseUrl, client } = await GBDeployer.internalGetDriveClient(min);
|
||||||
|
const gbaiName = DialogKeywords.getGBAIPath(min.botId);
|
||||||
|
const tmpDocx = urlJoin(gbaiName, path);
|
||||||
|
|
||||||
|
// Templates a blank {content} tag inside the blank.docx.
|
||||||
|
|
||||||
|
const blank = Path.join(process.env.PWD, 'blank.docx');
|
||||||
|
let buf = Fs.readFileSync(blank);
|
||||||
|
let zip = new PizZip(buf);
|
||||||
|
let doc = new Docxtemplater();
|
||||||
|
doc.setOptions({ linebreaks: true });
|
||||||
|
doc.loadZip(zip);
|
||||||
|
doc.setData({ content: content }).render();
|
||||||
|
buf = doc.getZip().generate({ type: 'nodebuffer', compression: 'DEFLATE' });
|
||||||
|
|
||||||
|
// Performs the upload.
|
||||||
|
|
||||||
|
await client.api(`${baseUrl}/drive/root:/${tmpDocx}:/content`).put(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async createDocument({ pid, path, content }) {
|
||||||
|
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||||
|
this.internalCreateDocument(min, path, content);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies a drive file from a place to another .
|
* Copies a drive file from a place to another .
|
||||||
*
|
*
|
||||||
|
@ -1224,8 +1328,9 @@ export class SystemKeywords {
|
||||||
parentReference: { driveId: folder.parentReference.driveId, id: folder.id },
|
parentReference: { driveId: folder.parentReference.driveId, id: folder.id },
|
||||||
name: `${Path.basename(dest)}`
|
name: `${Path.basename(dest)}`
|
||||||
};
|
};
|
||||||
|
const file = await client.api(`${baseUrl}/drive/items/${srcFile.id}/copy`).post(destFile);
|
||||||
return await client.api(`${baseUrl}/drive/items/${srcFile.id}/copy`).post(destFile);
|
GBLog.info(`BASIC: FINISHED COPY '${src}' to '${dest}'`);
|
||||||
|
return file;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.code === 'itemNotFound') {
|
if (error.code === 'itemNotFound') {
|
||||||
GBLog.info(`BASIC: COPY source file not found: ${srcPath}.`);
|
GBLog.info(`BASIC: COPY source file not found: ${srcPath}.`);
|
||||||
|
@ -1234,7 +1339,6 @@ export class SystemKeywords {
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
GBLog.info(`BASIC: FINISHED COPY '${src}' to '${dest}'`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1468,10 +1572,6 @@ export class SystemKeywords {
|
||||||
localName = Path.join('work', gbaiName, 'cache', `tmp${GBAdminService.getRndReadableIdentifier()}.docx`);
|
localName = Path.join('work', gbaiName, 'cache', `tmp${GBAdminService.getRndReadableIdentifier()}.docx`);
|
||||||
Fs.writeFileSync(localName, buf, { encoding: null });
|
Fs.writeFileSync(localName, buf, { encoding: null });
|
||||||
|
|
||||||
// Loads the file as binary content.
|
|
||||||
|
|
||||||
let zip = new PizZip(buf);
|
|
||||||
|
|
||||||
// Replace image path on all elements of data.
|
// Replace image path on all elements of data.
|
||||||
|
|
||||||
const images = [];
|
const images = [];
|
||||||
|
@ -1537,6 +1637,9 @@ export class SystemKeywords {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Loads the file as binary content.
|
||||||
|
|
||||||
|
let zip = new PizZip(buf);
|
||||||
let doc = new Docxtemplater();
|
let doc = new Docxtemplater();
|
||||||
doc.setOptions({ paragraphLoop: true, linebreaks: true });
|
doc.setOptions({ paragraphLoop: true, linebreaks: true });
|
||||||
doc.loadZip(zip);
|
doc.loadZip(zip);
|
||||||
|
|
|
@ -166,7 +166,6 @@ export class GBMinService {
|
||||||
// Calls mountBot event to all bots.
|
// Calls mountBot event to all bots.
|
||||||
let i = 1;
|
let i = 1;
|
||||||
|
|
||||||
|
|
||||||
if (instances.length > 1) {
|
if (instances.length > 1) {
|
||||||
this.bar1 = new cliProgress.SingleBar(
|
this.bar1 = new cliProgress.SingleBar(
|
||||||
{
|
{
|
||||||
|
@ -179,19 +178,20 @@ export class GBMinService {
|
||||||
this.bar1.start(instances.length, i, { botId: 'Boot' });
|
this.bar1.start(instances.length, i, { botId: 'Boot' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await CollectionUtil.asyncForEach(
|
||||||
await CollectionUtil.asyncForEach(instances, (async instance => {
|
instances,
|
||||||
try {
|
(async instance => {
|
||||||
await this['mountBot'](instance);
|
try {
|
||||||
} catch (error) {
|
await this['mountBot'](instance);
|
||||||
GBLog.error(`Error mounting bot ${instance.botId}: ${error.message}\n${error.stack}`);
|
} catch (error) {
|
||||||
}
|
GBLog.error(`Error mounting bot ${instance.botId}: ${error.message}\n${error.stack}`);
|
||||||
finally {
|
} finally {
|
||||||
if (this.bar1) {
|
if (this.bar1) {
|
||||||
this.bar1.update(i++, { botId: instance.botId });
|
this.bar1.update(i++, { botId: instance.botId });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}).bind(this)
|
||||||
}).bind(this));
|
);
|
||||||
|
|
||||||
if (this.bar1) {
|
if (this.bar1) {
|
||||||
this.bar1.stop();
|
this.bar1.stop();
|
||||||
|
@ -200,10 +200,10 @@ export class GBMinService {
|
||||||
pingSendTimeout: null,
|
pingSendTimeout: null,
|
||||||
keepAliveTimeout: null,
|
keepAliveTimeout: null,
|
||||||
listeners: {
|
listeners: {
|
||||||
unsubscribed(subscriptions: number): void { },
|
unsubscribed(subscriptions: number): void {},
|
||||||
subscribed(subscriptions: number): void { },
|
subscribed(subscriptions: number): void {},
|
||||||
disconnected(remoteId: string, connections: number): void { },
|
disconnected(remoteId: string, connections: number): void {},
|
||||||
connected(remoteId: string, connections: number): void { },
|
connected(remoteId: string, connections: number): void {},
|
||||||
messageIn(...params): void {
|
messageIn(...params): void {
|
||||||
GBLogEx.info(0, '[IN] ' + params);
|
GBLogEx.info(0, '[IN] ' + params);
|
||||||
},
|
},
|
||||||
|
@ -237,8 +237,6 @@ export class GBMinService {
|
||||||
|
|
||||||
GBLogEx.info(0, 'API RPC HTTP Server started.');
|
GBLogEx.info(0, 'API RPC HTTP Server started.');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// // Loads schedules.
|
// // Loads schedules.
|
||||||
// GBLog.info(`Preparing SET SCHEDULE dialog calls...`);
|
// GBLog.info(`Preparing SET SCHEDULE dialog calls...`);
|
||||||
|
|
||||||
|
@ -286,7 +284,7 @@ export class GBMinService {
|
||||||
/**
|
/**
|
||||||
* Unmounts the bot web site (default.gbui) secure domain, if any.
|
* Unmounts the bot web site (default.gbui) secure domain, if any.
|
||||||
*/
|
*/
|
||||||
public async unloadDomain(instance: IGBInstance) { }
|
public async unloadDomain(instance: IGBInstance) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mount the instance by creating an BOT Framework bot object,
|
* Mount the instance by creating an BOT Framework bot object,
|
||||||
|
@ -331,7 +329,7 @@ export class GBMinService {
|
||||||
|
|
||||||
const gbai = DialogKeywords.getGBAIPath(min.botId);
|
const gbai = DialogKeywords.getGBAIPath(min.botId);
|
||||||
let dir = `work/${gbai}/cache`;
|
let dir = `work/${gbai}/cache`;
|
||||||
const botId = gbai.replace(/\.[^/.]+$/, "");
|
const botId = gbai.replace(/\.[^/.]+$/, '');
|
||||||
|
|
||||||
if (!Fs.existsSync(dir)) {
|
if (!Fs.existsSync(dir)) {
|
||||||
mkdirp.sync(dir);
|
mkdirp.sync(dir);
|
||||||
|
@ -563,8 +561,9 @@ export class GBMinService {
|
||||||
min.instance.authenticatorTenant,
|
min.instance.authenticatorTenant,
|
||||||
'/oauth2/authorize'
|
'/oauth2/authorize'
|
||||||
);
|
);
|
||||||
authorizationUrl = `${authorizationUrl}?response_type=code&client_id=${min.instance.marketplaceId
|
authorizationUrl = `${authorizationUrl}?response_type=code&client_id=${
|
||||||
}&redirect_uri=${urlJoin(min.instance.botEndpoint, min.instance.botId, 'token')}`;
|
min.instance.marketplaceId
|
||||||
|
}&redirect_uri=${urlJoin(min.instance.botEndpoint, min.instance.botId, 'token')}`;
|
||||||
GBLog.info(`HandleOAuthRequests: ${authorizationUrl}.`);
|
GBLog.info(`HandleOAuthRequests: ${authorizationUrl}.`);
|
||||||
res.redirect(authorizationUrl);
|
res.redirect(authorizationUrl);
|
||||||
});
|
});
|
||||||
|
@ -1065,8 +1064,9 @@ export class GBMinService {
|
||||||
await this.processEventActivity(min, user, context, step);
|
await this.processEventActivity(min, user, context, step);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const msg = `ERROR: ${error.message} ${error.error ? error.error.body : ''} ${error.error ? (error.error.stack ? error.error.stack : '') : ''
|
const msg = `ERROR: ${error.message} ${error.error ? error.error.body : ''} ${
|
||||||
}`;
|
error.error ? (error.error.stack ? error.error.stack : '') : ''
|
||||||
|
}`;
|
||||||
GBLog.error(msg);
|
GBLog.error(msg);
|
||||||
|
|
||||||
await min.conversationalService.sendText(
|
await min.conversationalService.sendText(
|
||||||
|
@ -1085,8 +1085,7 @@ export class GBMinService {
|
||||||
if (error.code === 401) {
|
if (error.code === 401) {
|
||||||
GBLog.error('Calling processActivity due to Signing Key could not be retrieved error.');
|
GBLog.error('Calling processActivity due to Signing Key could not be retrieved error.');
|
||||||
await adapter['processActivity'](req, res, handler);
|
await adapter['processActivity'](req, res, handler);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1275,7 +1274,9 @@ export class GBMinService {
|
||||||
// Files in .gbdialog can be called directly by typing its name normalized into JS .
|
// Files in .gbdialog can be called directly by typing its name normalized into JS .
|
||||||
|
|
||||||
const isVMCall = Object.keys(min.scriptMap).find(key => min.scriptMap[key] === context.activity.text) !== undefined;
|
const isVMCall = Object.keys(min.scriptMap).find(key => min.scriptMap[key] === context.activity.text) !== undefined;
|
||||||
if (isVMCall) {
|
if (/create dialog|creative dialog|create a dialog|criar diálogo|criar diálogo/gi.test(context.activity.text)) {
|
||||||
|
await step.beginDialog('/dialog');
|
||||||
|
} else if (isVMCall) {
|
||||||
await GBVMService.callVM(context.activity.text, min, step, user, this.deployer, false);
|
await GBVMService.callVM(context.activity.text, min, step, user, this.deployer, false);
|
||||||
} else if (context.activity.text.charAt(0) === '/') {
|
} else if (context.activity.text.charAt(0) === '/') {
|
||||||
const text = context.activity.text;
|
const text = context.activity.text;
|
||||||
|
|
|
@ -326,7 +326,7 @@ class GBUIApp extends React.Component {
|
||||||
ref={chat => {
|
ref={chat => {
|
||||||
this.chat = chat;
|
this.chat = chat;
|
||||||
}}
|
}}
|
||||||
locale={'pt-br'}
|
locale={'en-us'}
|
||||||
directLine={this.state.line}
|
directLine={this.state.line}
|
||||||
webSpeechPonyfillFactory={window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
|
webSpeechPonyfillFactory={window.WebChat.createCognitiveServicesSpeechServicesPonyfillFactory({
|
||||||
credentials: { authorizationToken: token, region: 'westus' }
|
credentials: { authorizationToken: token, region: 'westus' }
|
||||||
|
|
|
@ -50,6 +50,9 @@ import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
||||||
import { GBImporter } from '../../core.gbapp/services/GBImporterService.js';
|
import { GBImporter } from '../../core.gbapp/services/GBImporterService.js';
|
||||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
|
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
|
||||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
||||||
|
import Fs from 'fs';
|
||||||
|
import urlJoin from 'url-join';
|
||||||
|
import { SystemKeywords } from '../../basic.gblib/services/SystemKeywords.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog arguments.
|
* Dialog arguments.
|
||||||
|
@ -78,6 +81,7 @@ export class AskDialog extends IGBDialog {
|
||||||
min.dialogs.add(new WaterfallDialog('/answerEvent', AskDialog.getAnswerEventDialog(service, min)));
|
min.dialogs.add(new WaterfallDialog('/answerEvent', AskDialog.getAnswerEventDialog(service, min)));
|
||||||
min.dialogs.add(new WaterfallDialog('/answer', AskDialog.getAnswerDialog(min, service)));
|
min.dialogs.add(new WaterfallDialog('/answer', AskDialog.getAnswerDialog(min, service)));
|
||||||
min.dialogs.add(new WaterfallDialog('/ask', AskDialog.getAskDialog(min)));
|
min.dialogs.add(new WaterfallDialog('/ask', AskDialog.getAskDialog(min)));
|
||||||
|
min.dialogs.add(new WaterfallDialog('/dialog', AskDialog.getLLVMDialog(min, service)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static getAskDialog(min: GBMinInstance) {
|
private static getAskDialog(min: GBMinInstance) {
|
||||||
|
@ -234,7 +238,7 @@ export class AskDialog extends IGBDialog {
|
||||||
}
|
}
|
||||||
// TODO: https://github.com/GeneralBots/BotServer/issues/9
|
// TODO: https://github.com/GeneralBots/BotServer/issues/9
|
||||||
// else if (user.subjects && user.subjects.length > 0) {
|
// else if (user.subjects && user.subjects.length > 0) {
|
||||||
// // ...second time running Search, now with no filter.
|
// // ..second time running Search, now with no filter.
|
||||||
|
|
||||||
// const resultsB = await service.ask(min.instance, text, searchScore, undefined);
|
// const resultsB = await service.ask(min.instance, text, searchScore, undefined);
|
||||||
|
|
||||||
|
@ -304,6 +308,7 @@ export class AskDialog extends IGBDialog {
|
||||||
}
|
}
|
||||||
const CHATGPT_TIMEOUT = 60 * 1000;
|
const CHATGPT_TIMEOUT = 60 * 1000;
|
||||||
GBLog.info(`ChatGPT being used...`);
|
GBLog.info(`ChatGPT being used...`);
|
||||||
|
|
||||||
const response = await GBServer.globals.chatGPT.sendMessage(text, { timeoutMs: CHATGPT_TIMEOUT });
|
const response = await GBServer.globals.chatGPT.sendMessage(text, { timeoutMs: CHATGPT_TIMEOUT });
|
||||||
|
|
||||||
if (!response) {
|
if (!response) {
|
||||||
|
@ -363,4 +368,77 @@ export class AskDialog extends IGBDialog {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static getLLVMDialog(min: GBMinInstance, service: KBService) {
|
||||||
|
return [
|
||||||
|
async step => {
|
||||||
|
if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) {
|
||||||
|
return await step.beginDialog('/auth');
|
||||||
|
} else {
|
||||||
|
return await step.next(step.options);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async step => {
|
||||||
|
return await min.conversationalService.prompt(min, step, 'Please, describe the dialog scene.');
|
||||||
|
},
|
||||||
|
async step => {
|
||||||
|
step.options.dialog = step.result;
|
||||||
|
return await min.conversationalService.prompt(min, step, 'How would you call this?');
|
||||||
|
},
|
||||||
|
async step => {
|
||||||
|
if (GBServer.globals.chatGPT) {
|
||||||
|
let input = `Write a BASIC program that ${step.options.dialog.toLowerCase()}. And does not explain.`;
|
||||||
|
|
||||||
|
await min.conversationalService.sendText(min, step, 'Thank you. The dialog is being written right now...');
|
||||||
|
|
||||||
|
const CHATGPT_TIMEOUT = 3 * 60 * 1000;
|
||||||
|
GBLog.info(`ChatGPT Code: ${input}`);
|
||||||
|
let response = await GBServer.globals.chatGPT.sendMessage(input, {
|
||||||
|
timeoutMs: CHATGPT_TIMEOUT
|
||||||
|
});
|
||||||
|
|
||||||
|
// Removes instructions, just code.
|
||||||
|
|
||||||
|
response = response.replace(/Copy code/gim, '\n');
|
||||||
|
let lines = response.split('\n')
|
||||||
|
let filteredLines = lines.filter(line => /\s*\d+\s*.*/.test(line))
|
||||||
|
response = filteredLines.join('\n');
|
||||||
|
|
||||||
|
// Gets dialog name and file handling
|
||||||
|
|
||||||
|
let dialogName = step.result.replace('.', '');
|
||||||
|
const docx = urlJoin(`${min.botId}.gbdialog`, `${dialogName}.docx`);
|
||||||
|
const sys = new SystemKeywords();
|
||||||
|
const document = await sys.internalCreateDocument(min, docx, response);
|
||||||
|
await service.addQA(min, dialogName, dialogName);
|
||||||
|
|
||||||
|
let message = `Waiting for publishing...`;
|
||||||
|
await min.conversationalService.sendText(min, step, message);
|
||||||
|
|
||||||
|
await step.replaceDialog('/publish', { confirm: true });
|
||||||
|
|
||||||
|
message = `Dialog is ready! Let's run:`;
|
||||||
|
await min.conversationalService.sendText(min, step, message);
|
||||||
|
|
||||||
|
|
||||||
|
let sec = new SecService();
|
||||||
|
const member = step.context.activity.from;
|
||||||
|
const user = await sec.ensureUser(
|
||||||
|
min.instance.instanceId,
|
||||||
|
member.id,
|
||||||
|
member.name,
|
||||||
|
'',
|
||||||
|
'web',
|
||||||
|
member.name,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
await step.endDialog();
|
||||||
|
|
||||||
|
await GBVMService.callVM(dialogName.toLowerCase(),
|
||||||
|
min, step, user, this.deployer, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -529,7 +529,7 @@ export class KBService implements IGBKBService {
|
||||||
const isBasic = answer.toLowerCase().startsWith('/basic');
|
const isBasic = answer.toLowerCase().startsWith('/basic');
|
||||||
if (/TALK\s*\".*\"/gi.test(answer) || isBasic) {
|
if (/TALK\s*\".*\"/gi.test(answer) || isBasic) {
|
||||||
const code = isBasic ? answer.substr(6) : answer;
|
const code = isBasic ? answer.substr(6) : answer;
|
||||||
const path = DialogKeywords.getGBAIPath(min.botId,`gbdialog`);
|
const path = DialogKeywords.getGBAIPath(min.botId, `gbdialog`);
|
||||||
const scriptName = `tmp${GBAdminService.getRndReadableIdentifier()}.docx`;
|
const scriptName = `tmp${GBAdminService.getRndReadableIdentifier()}.docx`;
|
||||||
const localName = Path.join('work', path, `${scriptName}`);
|
const localName = Path.join('work', path, `${scriptName}`);
|
||||||
Fs.writeFileSync(localName, code, { encoding: null });
|
Fs.writeFileSync(localName, code, { encoding: null });
|
||||||
|
@ -604,17 +604,11 @@ export class KBService implements IGBKBService {
|
||||||
answer.content.endsWith('.xlsx')
|
answer.content.endsWith('.xlsx')
|
||||||
) {
|
) {
|
||||||
const path = DialogKeywords.getGBAIPath(min.botId, `gbkb`);
|
const path = DialogKeywords.getGBAIPath(min.botId, `gbkb`);
|
||||||
const doc = urlJoin(
|
const doc = urlJoin(GBServer.globals.publicAddress, 'kb', path, 'assets', answer.content);
|
||||||
GBServer.globals.publicAddress,
|
|
||||||
'kb',
|
|
||||||
path,
|
|
||||||
'assets',
|
|
||||||
answer.content
|
|
||||||
);
|
|
||||||
const url = `http://view.officeapps.live.com/op/view.aspx?src=${doc}`;
|
const url = `http://view.officeapps.live.com/op/view.aspx?src=${doc}`;
|
||||||
await this.playUrl(min, min.conversationalService, step, url, channel);
|
await this.playUrl(min, min.conversationalService, step, url, channel);
|
||||||
} else if (answer.content.endsWith('.pdf')) {
|
} else if (answer.content.endsWith('.pdf')) {
|
||||||
const path = DialogKeywords.getGBAIPath(min.botId,`gbkb`);
|
const path = DialogKeywords.getGBAIPath(min.botId, `gbkb`);
|
||||||
const url = urlJoin('kb', path, 'assets', answer.content);
|
const url = urlJoin('kb', path, 'assets', answer.content);
|
||||||
await this.playUrl(min, min.conversationalService, step, url, channel);
|
await this.playUrl(min, min.conversationalService, step, url, channel);
|
||||||
} else if (answer.format === '.md') {
|
} else if (answer.format === '.md') {
|
||||||
|
@ -627,6 +621,37 @@ export class KBService implements IGBKBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async addQA(min, questionText, answerText) {
|
||||||
|
const pkg = await GuaribasPackage.findOne({
|
||||||
|
where: { instanceId: min.instance.instanceId }
|
||||||
|
});
|
||||||
|
|
||||||
|
const question = {
|
||||||
|
from: 'autodialog',
|
||||||
|
to: '',
|
||||||
|
subject1: '',
|
||||||
|
subject2: '',
|
||||||
|
subject3: '',
|
||||||
|
subject4: '',
|
||||||
|
content: questionText.replace(/["]+/g, ''),
|
||||||
|
instanceId: min.instance.instanceId,
|
||||||
|
skipIndex: false,
|
||||||
|
packageId: pkg.packageId
|
||||||
|
};
|
||||||
|
const answer = {
|
||||||
|
instanceId: min.instance.instanceId,
|
||||||
|
content: answerText,
|
||||||
|
format: '.txt',
|
||||||
|
media: null,
|
||||||
|
packageId: pkg.packageId,
|
||||||
|
prevId: 0
|
||||||
|
};
|
||||||
|
const a =await GuaribasAnswer.create(answer);
|
||||||
|
question['answerId'] = a.answerId;
|
||||||
|
const q = await GuaribasQuestion.create(question);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public async importKbPackage(
|
public async importKbPackage(
|
||||||
min: GBMinInstance,
|
min: GBMinInstance,
|
||||||
localPath: string,
|
localPath: string,
|
||||||
|
@ -692,9 +717,12 @@ export class KBService implements IGBKBService {
|
||||||
'cache',
|
'cache',
|
||||||
`img-docx${GBAdminService.getRndReadableIdentifier()}.png`
|
`img-docx${GBAdminService.getRndReadableIdentifier()}.png`
|
||||||
);
|
);
|
||||||
const url = urlJoin(GBServer.globals.publicAddress,
|
const url = urlJoin(
|
||||||
DialogKeywords.getGBAIPath(instance.botId).replace(/\.[^/.]+$/, "")
|
GBServer.globals.publicAddress,
|
||||||
, 'cache', Path.basename(localName));
|
DialogKeywords.getGBAIPath(instance.botId).replace(/\.[^/.]+$/, ''),
|
||||||
|
'cache',
|
||||||
|
Path.basename(localName)
|
||||||
|
);
|
||||||
const buffer = await image.read();
|
const buffer = await image.read();
|
||||||
Fs.writeFileSync(localName, buffer, { encoding: null });
|
Fs.writeFileSync(localName, buffer, { encoding: null });
|
||||||
return { src: url };
|
return { src: url };
|
||||||
|
@ -965,7 +993,7 @@ export class KBService implements IGBKBService {
|
||||||
let category = categoryReg[1];
|
let category = categoryReg[1];
|
||||||
|
|
||||||
if (category === 'number') {
|
if (category === 'number') {
|
||||||
min['nerEngine'].addRegexEntity('number','pt', '/d+/gi');
|
min['nerEngine'].addRegexEntity('number', 'pt', '/d+/gi');
|
||||||
}
|
}
|
||||||
if (nameReg) {
|
if (nameReg) {
|
||||||
let name = nameReg[1];
|
let name = nameReg[1];
|
||||||
|
@ -996,13 +1024,8 @@ export class KBService implements IGBKBService {
|
||||||
|
|
||||||
GBLog.info(`[GBDeployer] Start Bot Server Side Rendering... ${localPath}`);
|
GBLog.info(`[GBDeployer] Start Bot Server Side Rendering... ${localPath}`);
|
||||||
const html = await GBSSR.getHTML(min);
|
const html = await GBSSR.getHTML(min);
|
||||||
let path = DialogKeywords.getGBAIPath(min.botId,`gbui`);
|
let path = DialogKeywords.getGBAIPath(min.botId, `gbui`);
|
||||||
path = Path.join(
|
path = Path.join(process.env.PWD, 'work', path, 'index.html');
|
||||||
process.env.PWD,
|
|
||||||
'work',
|
|
||||||
path,
|
|
||||||
'index.html'
|
|
||||||
);
|
|
||||||
GBLogEx.info(min, `[GBDeployer] Saving SSR HTML in ${path}.`);
|
GBLogEx.info(min, `[GBDeployer] Saving SSR HTML in ${path}.`);
|
||||||
Fs.writeFileSync(path, html, 'utf8');
|
Fs.writeFileSync(path, html, 'utf8');
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,7 @@ export class SecService extends GBService {
|
||||||
{
|
{
|
||||||
obj = {};
|
obj = {};
|
||||||
}
|
}
|
||||||
obj['name'] = value;
|
obj[name] = value;
|
||||||
user.params = JSON.stringify(obj);
|
user.params = JSON.stringify(obj);
|
||||||
return await user.save();
|
return await user.save();
|
||||||
}
|
}
|
||||||
|
|
22
src/app.ts
22
src/app.ts
|
@ -52,11 +52,13 @@ import { GBDeployer } from '../packages/core.gbapp/services/GBDeployer.js';
|
||||||
import { GBImporter } from '../packages/core.gbapp/services/GBImporterService.js';
|
import { GBImporter } from '../packages/core.gbapp/services/GBImporterService.js';
|
||||||
import { GBMinService } from '../packages/core.gbapp/services/GBMinService.js';
|
import { GBMinService } from '../packages/core.gbapp/services/GBMinService.js';
|
||||||
import auth from 'basic-auth';
|
import auth from 'basic-auth';
|
||||||
|
import { ChatGPTAPIBrowser } from 'chatgpt';
|
||||||
import child_process from 'child_process';
|
import child_process from 'child_process';
|
||||||
import * as winston from 'winston-logs-display';
|
import * as winston from 'winston-logs-display';
|
||||||
import { RootData } from './RootData.js';
|
import { RootData } from './RootData.js';
|
||||||
import { GBSSR } from '../packages/core.gbapp/services/GBSSR.js';
|
import { GBSSR } from '../packages/core.gbapp/services/GBSSR.js';
|
||||||
import { Mutex } from 'async-mutex';
|
import { Mutex } from 'async-mutex';
|
||||||
|
import { GBVMService } from '../packages/basic.gblib/services/GBVMService.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General Bots open-core entry point.
|
* General Bots open-core entry point.
|
||||||
|
@ -82,7 +84,7 @@ export class GBServer {
|
||||||
GBLog.error(`Running TEST_SHELL ERROR: ${error}...`);
|
GBLog.error(`Running TEST_SHELL ERROR: ${error}...`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const server = express();
|
const server = express();
|
||||||
|
|
||||||
GBServer.globals.server = server;
|
GBServer.globals.server = server;
|
||||||
|
@ -215,6 +217,22 @@ export class GBServer {
|
||||||
GBServer.globals.minService = minService;
|
GBServer.globals.minService = minService;
|
||||||
await minService.buildMin(instances);
|
await minService.buildMin(instances);
|
||||||
|
|
||||||
|
if (process.env.OPENAI_EMAIL) {
|
||||||
|
if (!GBServer.globals.chatGPT) {
|
||||||
|
GBServer.globals.chatGPT = new ChatGPTAPIBrowser({
|
||||||
|
email: process.env.OPENAI_EMAIL,
|
||||||
|
password: process.env.OPENAI_PASSWORD,
|
||||||
|
markdown: false
|
||||||
|
});
|
||||||
|
await GBServer.globals.chatGPT.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// let s = new GBVMService();
|
||||||
|
// await s.translateBASIC('work/gptA.vbs', GBServer.globals.minBoot );
|
||||||
|
// await s.translateBASIC('work/gptB.vbs', GBServer.globals.minBoot );
|
||||||
|
// await s.translateBASIC('work/gptC.vbs', GBServer.globals.minBoot );
|
||||||
|
// process.exit(9);
|
||||||
if (process.env.ENABLE_WEBLOG) {
|
if (process.env.ENABLE_WEBLOG) {
|
||||||
// If global log enabled, reorders transports adding web logging.
|
// If global log enabled, reorders transports adding web logging.
|
||||||
|
|
||||||
|
@ -257,8 +275,6 @@ export class GBServer {
|
||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
if (process.env.CERTIFICATE_PFX) {
|
if (process.env.CERTIFICATE_PFX) {
|
||||||
const options1 = {
|
const options1 = {
|
||||||
passphrase: process.env.CERTIFICATE_PASSPHRASE,
|
passphrase: process.env.CERTIFICATE_PASSPHRASE,
|
||||||
|
|
Loading…
Add table
Reference in a new issue