- Warming removal.
This commit is contained in:
parent
42c2a3a2d1
commit
1f5466eae4
72 changed files with 782 additions and 51722 deletions
|
|
@ -1,16 +1,15 @@
|
||||||
import { expect, test } from 'vitest';
|
import { expect, test } from 'vitest';
|
||||||
import { GBServer } from './src/app';
|
import { GBServer } from './src/app';
|
||||||
import { RootData } from './src/RootData';
|
import { RootData } from './src/RootData';
|
||||||
import { GBMinInstance } from 'botlib';
|
import { GBMinInstance } from 'botlib-legacy';
|
||||||
import { Mutex } from 'async-mutex';
|
import { Mutex } from 'async-mutex';
|
||||||
|
|
||||||
export default function init() {
|
export default function init() {
|
||||||
|
|
||||||
const min = {
|
const min = {
|
||||||
packages: null,
|
packages: null,
|
||||||
appPackages: null,
|
appPackages: null,
|
||||||
botId: 'gbtest',
|
botId: 'gbtest',
|
||||||
instance: {botId: 'gbtest'},
|
instance: { botId: 'gbtest' },
|
||||||
core: {},
|
core: {},
|
||||||
conversationalService: {},
|
conversationalService: {},
|
||||||
kbService: {},
|
kbService: {},
|
||||||
|
|
@ -26,14 +25,13 @@ export default function init() {
|
||||||
scriptMap: {},
|
scriptMap: {},
|
||||||
sandBoxMap: {},
|
sandBoxMap: {},
|
||||||
gbappServices: {}
|
gbappServices: {}
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
GBServer.globals = new RootData();
|
GBServer.globals = new RootData();
|
||||||
GBServer.globals.server = null;
|
GBServer.globals.server = null;
|
||||||
GBServer.globals.httpsServer = null;
|
GBServer.globals.httpsServer = null;
|
||||||
GBServer.globals.webSessions = {};
|
GBServer.globals.webSessions = {};
|
||||||
GBServer.globals.processes = [0, { pid: 1, proc: {step: {}}}];
|
GBServer.globals.processes = [0, { pid: 1, proc: { step: {} } }];
|
||||||
GBServer.globals.files = {};
|
GBServer.globals.files = {};
|
||||||
GBServer.globals.appPackages = [];
|
GBServer.globals.appPackages = [];
|
||||||
GBServer.globals.sysPackages = [];
|
GBServer.globals.sysPackages = [];
|
||||||
|
|
@ -43,5 +41,5 @@ export default function init() {
|
||||||
GBServer.globals.entryPointDialog = null;
|
GBServer.globals.entryPointDialog = null;
|
||||||
GBServer.globals.debuggers = [];
|
GBServer.globals.debuggers = [];
|
||||||
GBServer.globals.indexSemaphore = new Mutex();
|
GBServer.globals.indexSemaphore = new Mutex();
|
||||||
GBServer.globals.users = {1: {userId: 1}};
|
GBServer.globals.users = { 1: { userId: 1 } };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
npm install \
|
|
||||||
@azure/ms-rest-js@2.7.0 \
|
|
||||||
@azure/msal-node@3.7.3 \
|
|
||||||
@google-cloud/pubsub@5.2.0 \
|
|
||||||
@google-cloud/translate@9.2.0 \
|
|
||||||
botlib \
|
|
||||||
c3-chart-maker@0.2.8 \
|
|
||||||
docximager@0.0.4 \
|
|
||||||
docxtemplater@3.66.3 \
|
|
||||||
exceljs@4.4.0 \
|
|
||||||
get-image-colors@4.0.1 \
|
|
||||||
googleapis@159.0.0 \
|
|
||||||
ibm-watson@11.0.0 \
|
|
||||||
node-nlp@4.27.0 \
|
|
||||||
office-text-extractor@3.0.3 \
|
|
||||||
open-docxtemplater-image-module@1.0.3 \
|
|
||||||
pragmatismo-fram \
|
|
||||||
puppeteer \
|
|
||||||
svg2img@1.0.0-beta.2 \
|
|
||||||
vm2@3.9.19 \
|
|
||||||
whatsapp-web.js@1.34.1
|
|
||||||
48942
package-lock.json
generated
48942
package-lock.json
generated
File diff suppressed because it is too large
Load diff
298
package.json
298
package.json
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "botserver",
|
"name": "botserver",
|
||||||
"version": "5.0.0",
|
"version": "5.1.0",
|
||||||
"description": "General Bot Community Edition open-core server.",
|
"description": "General Bot Community Edition open-core server.",
|
||||||
"main": "./boot.mjs",
|
"main": "./boot.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
"disableAutoBuild": "1"
|
"disableAutoBuild": "1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "=22.9.0"
|
"node": "=22.19.0"
|
||||||
},
|
},
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"preferGlobal": true,
|
"preferGlobal": true,
|
||||||
|
|
@ -41,19 +41,7 @@
|
||||||
"test": "vitest",
|
"test": "vitest",
|
||||||
"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",
|
||||||
"debug": "NODE_NO_WARNINGS=1 node ./boot.mjs --loader ts-node/esm --require ./suppress-node-warnings.cjs --inspect",
|
"debug": "NODE_NO_WARNINGS=1 node ./boot.mjs --loader ts-node/esm --require ./suppress-node-warnings.cjs --inspect",
|
||||||
"reverse-proxy": "node_modules/.bin/ngrok http 4242",
|
"watch:build": "tsc --watch"
|
||||||
"watch:build": "tsc --watch",
|
|
||||||
"posttypedoc": "shx cp .nojekyll docs/reference/.nojekyll",
|
|
||||||
"ban": "ban",
|
|
||||||
"issues": "git-issues",
|
|
||||||
"license": "license-checker --production --onlyunknown --csv",
|
|
||||||
"pretty": "prettier-standard 'src/*.ts' 'packages/**/*.ts'",
|
|
||||||
"secure": "nsp check",
|
|
||||||
"size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";",
|
|
||||||
"unused-deps": "dependency-check --unused --no-dev ./package.json",
|
|
||||||
"travis-deploy-once": "travis-deploy-once --pro",
|
|
||||||
"semantic-release": "semantic-release",
|
|
||||||
"commit": "git-cz"
|
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"workerIdleMemoryLimit": "4096MB",
|
"workerIdleMemoryLimit": "4096MB",
|
||||||
|
|
@ -69,212 +57,171 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/arm-appservice": "15.0.0",
|
|
||||||
"@azure/arm-cognitiveservices": "7.5.0",
|
|
||||||
"@azure/arm-resources": "5.2.0",
|
|
||||||
"@azure/arm-search": "3.2.0",
|
|
||||||
"@azure/arm-sql": "10.0.0",
|
|
||||||
"@azure/arm-subscriptions": "5.1.0",
|
|
||||||
"@azure/cognitiveservices-computervision": "8.2.0",
|
"@azure/cognitiveservices-computervision": "8.2.0",
|
||||||
"@azure/keyvault-keys": "4.8.0",
|
|
||||||
"@azure/ms-rest-js": "2.7.0",
|
"@azure/ms-rest-js": "2.7.0",
|
||||||
"@azure/msal-node": "2.13.1",
|
"@azure/msal-node": "^3.7.3",
|
||||||
"@azure/openai": "2.0.0-beta.1",
|
"@azure/openai": "2.0.0",
|
||||||
"@azure/search-documents": "12.1.0",
|
"@azure/search-documents": "12.1.0",
|
||||||
"@azure/storage-blob": "12.24.0",
|
"@azure/storage-blob": "12.28.0",
|
||||||
"@google-cloud/pubsub": "4.7.0",
|
"@google-cloud/pubsub": "^5.2.0",
|
||||||
"@google-cloud/translate": "8.5.0",
|
"@google-cloud/translate": "^9.2.0",
|
||||||
"@hubspot/api-client": "11.2.0",
|
|
||||||
"@koa/cors": "5.0.0",
|
"@koa/cors": "5.0.0",
|
||||||
"@langchain/anthropic": "^0.3.7",
|
"@koa/router": "14.0.0",
|
||||||
"@langchain/community": "0.2.31",
|
"@langchain/anthropic": "0.3.27",
|
||||||
"@langchain/core": "^0.3.17",
|
"@langchain/community": "0.3.55",
|
||||||
"@langchain/openai": "0.2.8",
|
"@langchain/core": "0.3.75",
|
||||||
|
"@langchain/openai": "0.6.11",
|
||||||
"@microsoft/microsoft-graph-client": "3.0.7",
|
"@microsoft/microsoft-graph-client": "3.0.7",
|
||||||
"@nlpjs/basic": "4.27.0",
|
"@push-rpc/core": "1.9.3",
|
||||||
"@nosferatu500/textract": "3.1.3",
|
"@push-rpc/http": "1.9.3",
|
||||||
"@push-rpc/core": "1.9.0",
|
"@push-rpc/openapi": "1.9.3",
|
||||||
"@push-rpc/http": "1.9.0",
|
"@push-rpc/websocket": "1.9.3",
|
||||||
"@push-rpc/openapi": "1.9.0",
|
"@sequelize/core": "7.0.0-alpha.46",
|
||||||
"@push-rpc/websocket": "1.9.0",
|
"@sequelize/postgres": "7.0.0-alpha.46",
|
||||||
"@semantic-release/changelog": "6.0.3",
|
"@types/validator": "13.15.3",
|
||||||
"@semantic-release/exec": "6.0.3",
|
|
||||||
"@semantic-release/git": "10.0.1",
|
|
||||||
"@sendgrid/mail": "8.1.3",
|
|
||||||
"@sequelize/core": "7.0.0-alpha.37",
|
|
||||||
"@sequelize/postgres": "^7.0.0-alpha.43",
|
|
||||||
"@types/validator": "13.12.1",
|
|
||||||
"adm-zip": "0.5.16",
|
"adm-zip": "0.5.16",
|
||||||
"ai2html": "^0.121.1",
|
"alasql": "4.6.6",
|
||||||
"alasql": "4.5.1",
|
|
||||||
"any-shell-escape": "0.1.1",
|
"any-shell-escape": "0.1.1",
|
||||||
"arraybuffer-to-buffer": "0.0.7",
|
"arraybuffer-to-buffer": "0.0.7",
|
||||||
"async-mutex": "0.5.0",
|
"async-mutex": "0.5.0",
|
||||||
"async-promises": "0.2.3",
|
"async-promises": "0.2.3",
|
||||||
"async-retry": "1.3.3",
|
"async-retry": "1.3.3",
|
||||||
"basic-auth": "2.0.1",
|
"basic-auth": "2.0.1",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "6.0.0",
|
||||||
"billboard.js": "3.13.0",
|
"billboard.js": "3.16.0",
|
||||||
"bluebird": "3.7.2",
|
"bluebird": "3.7.2",
|
||||||
"body-parser": "1.20.2",
|
"body-parser": "2.2.0",
|
||||||
"botbuilder": "4.23.0",
|
"botbuilder": "4.23.3",
|
||||||
"botbuilder-adapter-facebook": "1.0.12",
|
"botbuilder-adapter-facebook": "1.0.12",
|
||||||
"botbuilder-ai": "4.23.0",
|
"botbuilder-ai": "4.23.3",
|
||||||
"botbuilder-dialogs": "4.23.0",
|
"botbuilder-dialogs": "4.23.3",
|
||||||
"botframework-connector": "4.23.0",
|
"botframework-connector": "4.23.3",
|
||||||
"botlib": "5.0.0",
|
"botlib-legacy": "5.1.1",
|
||||||
"c3-chart-maker": "0.2.8",
|
|
||||||
"cd": "0.3.3",
|
"cd": "0.3.3",
|
||||||
"chalk-animation": "2.0.3",
|
"chalk-animation": "2.0.3",
|
||||||
"chatgpt": "5.2.5",
|
"chrome-remote-interface": "0.33.3",
|
||||||
"chrome-remote-interface": "0.33.2",
|
|
||||||
"cli-progress": "3.12.0",
|
"cli-progress": "3.12.0",
|
||||||
"cli-spinner": "0.2.10",
|
"cli-spinner": "0.2.10",
|
||||||
"core-js": "3.38.1",
|
"core-js": "3.45.1",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"csv-database": "0.9.2",
|
"csv-database": "0.9.2",
|
||||||
"data-forge": "1.10.2",
|
"data-forge": "1.10.4",
|
||||||
"date-diff": "1.0.2",
|
"date-diff": "1.0.2",
|
||||||
"docximager": "0.0.4",
|
"docximager": "^0.0.4",
|
||||||
"docxtemplater": "3.50.0",
|
"docxtemplater": "^3.66.3",
|
||||||
"dotenv-extended": "2.9.0",
|
"dotenv-extended": "2.9.0",
|
||||||
"electron": "32.0.1",
|
"exceljs": "^4.4.0",
|
||||||
"exceljs": "4.4.0",
|
"express": "5.1.0",
|
||||||
"express": "4.19.2",
|
|
||||||
"express-remove-route": "1.0.0",
|
"express-remove-route": "1.0.0",
|
||||||
"facebook-nodejs-business-sdk": "^20.0.2",
|
"facebook-nodejs-business-sdk": "23.0.1",
|
||||||
"ffmpeg-static": "5.2.0",
|
"ffmpeg-static": "5.2.0",
|
||||||
"formidable": "^3.5.1",
|
"final-stream": "^2.0.4",
|
||||||
"get-image-colors": "4.0.1",
|
"formidable": "3.5.4",
|
||||||
"glob": "^11.0.0",
|
"get-image-colors": "^4.0.1",
|
||||||
"google-libphonenumber": "3.2.38",
|
"glob": "11.0.3",
|
||||||
"googleapis": "143.0.0",
|
"google-libphonenumber": "3.2.42",
|
||||||
|
"googleapis": "^159.0.0",
|
||||||
"hnswlib-node": "3.0.0",
|
"hnswlib-node": "3.0.0",
|
||||||
"html-to-md": "0.8.6",
|
"html-to-md": "0.8.8",
|
||||||
"http-proxy": "1.18.1",
|
"http-proxy": "1.18.1",
|
||||||
"ibm-watson": "9.1.0",
|
"ibm-watson": "^11.0.0",
|
||||||
"icojs": "^0.19.4",
|
"icojs": "0.19.5",
|
||||||
"instagram-private-api": "1.46.1",
|
"iso-639-1": "3.1.5",
|
||||||
"iso-639-1": "3.1.3",
|
|
||||||
"isomorphic-fetch": "3.0.0",
|
"isomorphic-fetch": "3.0.0",
|
||||||
"jimp": "1.6.0",
|
"jimp": "1.6.0",
|
||||||
"js-md5": "0.8.3",
|
"js-md5": "0.8.3",
|
||||||
"json-schema-to-zod": "2.4.0",
|
"json-schema-to-zod": "2.6.1",
|
||||||
"jsqr": "^1.4.0",
|
"jsqr": "1.4.0",
|
||||||
"just-indent": "0.0.1",
|
"just-indent": "0.0.1",
|
||||||
"keyv": "5.0.1",
|
"keyv": "5.5.1",
|
||||||
"koa": "2.15.3",
|
"koa": "3.0.1",
|
||||||
"koa-body": "6.0.1",
|
"koa-body": "6.0.1",
|
||||||
"koa-ratelimit": "5.1.0",
|
"koa-ratelimit": "6.0.0",
|
||||||
"koa-router": "12.0.1",
|
"langchain": "0.3.33",
|
||||||
"langchain": "0.2.17",
|
"language-tags": "2.1.0",
|
||||||
"language-tags": "1.0.9",
|
|
||||||
"line-replace": "2.0.1",
|
"line-replace": "2.0.1",
|
||||||
"livekit-server-sdk": "^2.12.0",
|
"livekit-server-sdk": "2.13.3",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
"luxon": "3.5.0",
|
"luxon": "3.7.2",
|
||||||
"mammoth": "1.8.0",
|
"mammoth": "1.10.0",
|
||||||
"mariadb": "3.3.1",
|
"mariadb": "3.4.5",
|
||||||
"mime-types": "2.1.35",
|
"mime-types": "3.0.1",
|
||||||
"minio": "^8.0.4",
|
"minio": "8.0.6",
|
||||||
"moment": "2.30.1",
|
"moment": "2.30.1",
|
||||||
"ms-rest-azure": "3.0.2",
|
"ms-rest-azure": "^3.0.2",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "2.18.1",
|
||||||
"nexmo": "2.9.1",
|
"node-cron": "4.2.1",
|
||||||
"ngrok": "5.0.0-beta.2",
|
"node-html-parser": "7.0.1",
|
||||||
"node-cron": "3.0.3",
|
"node-nlp": "^4.27.0",
|
||||||
"node-html-parser": "6.1.13",
|
"nodemailer": "7.0.6",
|
||||||
"node-nlp": "4.27.0",
|
"nodemon": "3.1.10",
|
||||||
"node-tesseract-ocr": "2.2.1",
|
"npm": "11.6.0",
|
||||||
"nodemailer": "6.10.1",
|
"office-text-extractor": "^3.0.3",
|
||||||
"nodemon": "^3.1.7",
|
"open": "10.2.0",
|
||||||
"npm": "10.8.3",
|
"open-docxtemplater-image-module": "^1.0.3",
|
||||||
"open": "10.1.0",
|
"openai": "4.62.1",
|
||||||
"open-docxtemplater-image-module": "1.0.3",
|
|
||||||
"openai": "4.57.0",
|
|
||||||
"pdf-extraction": "1.0.2",
|
"pdf-extraction": "1.0.2",
|
||||||
"pdf-parse": "1.1.1",
|
"pdf-parse": "1.1.1",
|
||||||
"pdf-to-png-converter": "3.3.0",
|
"pdf-to-png-converter": "3.7.1",
|
||||||
"pdfjs-dist": "4.6.82",
|
"pdfjs-dist": "5.4.149",
|
||||||
"pg": "^8.13.1",
|
"pg": "8.16.3",
|
||||||
"phone": "3.1.50",
|
"phone": "3.1.67",
|
||||||
"pizzip": "3.1.7",
|
"pizzip": "3.2.0",
|
||||||
"pptxtemplater": "1.0.5",
|
"pptxtemplater": "1.0.5",
|
||||||
"pragmatismo-io-framework": "1.1.1",
|
|
||||||
"prism-media": "1.3.5",
|
"prism-media": "1.3.5",
|
||||||
"public-ip": "7.0.1",
|
"public-ip": "7.0.1",
|
||||||
"punycode": "2.3.1",
|
"punycode": "2.3.1",
|
||||||
"puppeteer": "23.2.2",
|
"puppeteer": "24.20.0",
|
||||||
"puppeteer-extra": "3.3.6",
|
|
||||||
"puppeteer-extra-plugin-minmax": "1.1.2",
|
|
||||||
"puppeteer-extra-plugin-stealth": "2.11.2",
|
|
||||||
"qr-scanner": "1.4.2",
|
"qr-scanner": "1.4.2",
|
||||||
"qrcode": "1.5.4",
|
"qrcode": "1.5.4",
|
||||||
"qrcode-reader": "^1.0.4",
|
"qrcode-reader": "1.0.4",
|
||||||
"qrcode-terminal": "0.12.0",
|
"qrcode-terminal": "0.12.0",
|
||||||
"readline": "1.3.0",
|
"readline": "1.3.0",
|
||||||
"reflect-metadata": "0.2.2",
|
"reflect-metadata": "0.2.2",
|
||||||
"rimraf": "6.0.1",
|
"rimraf": "6.0.1",
|
||||||
"safe-buffer": "5.2.1",
|
"safe-buffer": "5.2.1",
|
||||||
"scanf": "1.2.0",
|
"scanf": "1.2.0",
|
||||||
"sequelize": "6.37.3",
|
"sequelize": "6.37.7",
|
||||||
"sequelize-cli": "6.6.2",
|
"sequelize-cli": "6.6.3",
|
||||||
"sequelize-typescript": "2.1.6",
|
"sequelize-typescript": "2.1.6",
|
||||||
"simple-git": "3.26.0",
|
"simple-git": "3.28.0",
|
||||||
"speakingurl": "14.0.1",
|
"speakingurl": "14.0.1",
|
||||||
"sqlite3": "5.1.7",
|
|
||||||
"ssr-for-bots": "1.0.1-c",
|
|
||||||
"strict-password-generator": "1.1.2",
|
"strict-password-generator": "1.1.2",
|
||||||
"stripe": "^18.0.0",
|
"stripe": "18.5.0",
|
||||||
"super-strong-password-generator": "2.0.2",
|
"super-strong-password-generator": "2.0.2",
|
||||||
"super-strong-password-generator-es": "2.0.2",
|
"super-strong-password-generator-es": "2.0.2",
|
||||||
"svg2img": "^1.0.0-beta.2",
|
"svg2img": "^1.0.0-beta.2",
|
||||||
"swagger-client": "3.29.2",
|
"swagger-client": "3.35.6",
|
||||||
"swagger-ui-dist": "5.17.14",
|
"swagger-ui-dist": "5.29.0",
|
||||||
"tabulator-tables": "6.2.5",
|
"tabulator-tables": "6.3.1",
|
||||||
"tedious": "18.6.1",
|
"tedious": "18.6.1",
|
||||||
"textract": "2.5.0",
|
"textract": "^2.5.0",
|
||||||
"twilio": "5.2.3",
|
"twilio": "5.9.0",
|
||||||
"twitter-api-v2": "1.17.2",
|
"twitter-api-v2": "1.27.0",
|
||||||
"typeorm": "0.3.20",
|
"typeorm": "0.3.26",
|
||||||
"typescript": "5.5.4",
|
"typescript": "5.9.2",
|
||||||
"url-join": "5.0.0",
|
"url-join": "^5.0.0",
|
||||||
"vhost": "3.0.2",
|
"vhost": "3.0.2",
|
||||||
"vm2": "3.9.19",
|
"vm2": "github:n8n-io/vm2",
|
||||||
"vm2-process": "2.1.5",
|
|
||||||
"walk-promise": "0.2.0",
|
"walk-promise": "0.2.0",
|
||||||
"washyourmouthoutwithsoap": "1.0.2",
|
"washyourmouthoutwithsoap": "1.0.2",
|
||||||
"webdav-server": "2.6.2",
|
"webdav-server": "2.6.2",
|
||||||
"webp-converter": "^2.3.3",
|
"webp-converter": "^2.3.3",
|
||||||
"whatsapp-cloud-api": "0.3.1",
|
"whatsapp-cloud-api": "0.3.1",
|
||||||
"whatsapp-web.js": "1.26.1-alpha.1",
|
"whatsapp-web.js": "^1.34.1",
|
||||||
"winston": "3.14.2",
|
"ws": "8.18.3",
|
||||||
"ws": "8.18.0",
|
"yaml": "2.8.1",
|
||||||
"yaml": "2.5.0",
|
|
||||||
"yarn": "1.22.22",
|
"yarn": "1.22.22",
|
||||||
"zod-to-json-schema": "3.23.2"
|
"zod-to-json-schema": "3.24.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash": "^4.17.20",
|
"@types/lodash": "4.17.20",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "24.3.3",
|
||||||
"@types/node-fetch": "^2.6.12",
|
|
||||||
"@types/qrcode": "1.5.5",
|
"@types/qrcode": "1.5.5",
|
||||||
"@types/url-join": "4.0.3",
|
"@typescript-eslint/eslint-plugin": "8.43.0",
|
||||||
"@typescript-eslint/eslint-plugin": "8.4.0",
|
"@typescript-eslint/parser": "8.43.0",
|
||||||
"@typescript-eslint/parser": "8.4.0",
|
"tsx": "4.20.5",
|
||||||
"ban-sensitive-files": "1.10.5",
|
"vitest": "3.2.4"
|
||||||
"commitizen": "4.3.0",
|
|
||||||
"cz-conventional-changelog": "3.3.0",
|
|
||||||
"dependency-check": "4.1.0",
|
|
||||||
"git-issues": "1.3.1",
|
|
||||||
"license-checker": "25.0.1",
|
|
||||||
"prettier-standard": "16.4.1",
|
|
||||||
"semantic-release": "24.1.0",
|
|
||||||
"simple-commit-message": "4.1.3",
|
|
||||||
"travis-deploy-once": "5.0.11",
|
|
||||||
"tslint": "6.1.3",
|
|
||||||
"tsx": "^4.19.1",
|
|
||||||
"vitest": "2.0.5"
|
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"env": {
|
"env": {
|
||||||
|
|
@ -368,5 +315,44 @@
|
||||||
"post-checkout": [],
|
"post-checkout": [],
|
||||||
"post-merge": []
|
"post-merge": []
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"lodash.trimend": "npm:lodash@4.17.21",
|
||||||
|
"lodash.isequal": "npm:lodash@4.17.21",
|
||||||
|
"node-domexception": "npm:whatwg-url@^11.0.0",
|
||||||
|
"csv-database": {
|
||||||
|
"fast-csv": "4.3.6"
|
||||||
|
},
|
||||||
|
"sequelize-typescript": {
|
||||||
|
"glob": "~9.0.0"
|
||||||
|
},
|
||||||
|
"botbuilder-adapter-facebook": {
|
||||||
|
"node-domexception": "npm:whatwg-url@^11.0.0"
|
||||||
|
},
|
||||||
|
"tough-cookie": "4.1.3",
|
||||||
|
"phin": "3.7.1",
|
||||||
|
"xmldom": "npm:@xmldom/xmldom@^0.8.10",
|
||||||
|
"form-data": "2.5.5",
|
||||||
|
"uuid": "9.0.1",
|
||||||
|
"har-validator": "5.1.5",
|
||||||
|
"request": "2.88.2",
|
||||||
|
"yaeti": "npm:events@^3.3.0",
|
||||||
|
"text-encoding": "npm:text-encoder-lite@^1.0.1",
|
||||||
|
"docximager": {
|
||||||
|
"xml2js": "^0.5.0"
|
||||||
|
},
|
||||||
|
"tar-fs": "3.1.0",
|
||||||
|
"ws": "8.18.3",
|
||||||
|
"xml2js": "^0.6.2",
|
||||||
|
"inflight": "npm:lru-cache@^10.2.0",
|
||||||
|
"rimraf": "6.0.1",
|
||||||
|
"glob": "11.0.3",
|
||||||
|
"fstream": "npm:fs-extra@^11.0.0",
|
||||||
|
"puppeteer": "24.20.0",
|
||||||
|
"fluent-ffmpeg": "npm:ffmpeg-static@^5.0.0",
|
||||||
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz",
|
||||||
|
"@nlpjs/xtables": {
|
||||||
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,19 +37,18 @@
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
|
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
|
||||||
import { GBImporter } from '../../core.gbapp/services/GBImporterService.js';
|
import { GBImporter } from '../../core.gbapp/services/GBImporterService.js';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { GBAdminService } from '../services/GBAdminService.js';
|
import { GBAdminService } from '../services/GBAdminService.js';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { SecService } from '../../security.gbapp/services/SecService.js';
|
import { SecService } from '../../security.gbapp/services/SecService.js';
|
||||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
||||||
import { GBUtil } from '../../../src/util.js';
|
import { GBUtil } from '../../../src/util.js';
|
||||||
|
|
||||||
|
|
||||||
class AdminDialog extends IGBDialog {
|
class AdminDialog extends IGBDialog {
|
||||||
public static isIntentYes(locale, utterance) {
|
public static isIntentYes(locale, utterance) {
|
||||||
return utterance.toLowerCase().match(Messages[locale].affirmative_sentences);
|
return utterance.toLowerCase().match(Messages[locale].affirmative_sentences);
|
||||||
|
|
@ -87,7 +86,7 @@ class AdminDialog extends IGBDialog {
|
||||||
const locale = step.context.activity.locale;
|
const locale = step.context.activity.locale;
|
||||||
const sensitive = step.context.activity['originalText'];
|
const sensitive = step.context.activity['originalText'];
|
||||||
|
|
||||||
if (await GBUtil.comparePassword( sensitive, min.instance.adminPass)) {
|
if (await GBUtil.comparePassword(sensitive, min.instance.adminPass)) {
|
||||||
await min.conversationalService.sendText(min, step, Messages[locale].welcome);
|
await min.conversationalService.sendText(min, step, Messages[locale].welcome);
|
||||||
|
|
||||||
return await step.endDialog(true);
|
return await step.endDialog(true);
|
||||||
|
|
@ -121,7 +120,7 @@ class AdminDialog extends IGBDialog {
|
||||||
const locale = step.context.activity.locale;
|
const locale = step.context.activity.locale;
|
||||||
const sensitive = step.context.activity['originalText'];
|
const sensitive = step.context.activity['originalText'];
|
||||||
|
|
||||||
if (await GBUtil.comparePassword( sensitive, min.instance.adminPass)) {
|
if (await GBUtil.comparePassword(sensitive, min.instance.adminPass)) {
|
||||||
await min.conversationalService.sendText(min, step, Messages[locale].welcome);
|
await min.conversationalService.sendText(min, step, Messages[locale].welcome);
|
||||||
|
|
||||||
return await min.conversationalService.prompt(min, step, Messages[locale].which_task);
|
return await min.conversationalService.prompt(min, step, Messages[locale].which_task);
|
||||||
|
|
@ -224,7 +223,8 @@ class AdminDialog extends IGBDialog {
|
||||||
await min.conversationalService.sendText(min, step, logs);
|
await min.conversationalService.sendText(min, step, logs);
|
||||||
return await step.replaceDialog('/ask', { isReturning: true });
|
return await step.replaceDialog('/ask', { isReturning: true });
|
||||||
}
|
}
|
||||||
]));
|
])
|
||||||
|
);
|
||||||
|
|
||||||
min.dialogs.add(
|
min.dialogs.add(
|
||||||
new WaterfallDialog('/publish', [
|
new WaterfallDialog('/publish', [
|
||||||
|
|
@ -302,7 +302,7 @@ class AdminDialog extends IGBDialog {
|
||||||
packages.push(filename);
|
packages.push(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(packages, async packageName => {
|
await GBUtil.asyncForEach(packages, async packageName => {
|
||||||
let cmd1;
|
let cmd1;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -330,26 +330,17 @@ class AdminDialog extends IGBDialog {
|
||||||
}
|
}
|
||||||
let sec = new SecService();
|
let sec = new SecService();
|
||||||
const member = step.context.activity.from;
|
const member = step.context.activity.from;
|
||||||
const user = await sec.ensureUser(
|
const user = await sec.ensureUser(min, member.id, member.name, '', 'web', member.name, null);
|
||||||
min,
|
|
||||||
member.id,
|
|
||||||
member.name,
|
|
||||||
'',
|
|
||||||
'web',
|
|
||||||
member.name,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
|
|
||||||
await GBAdminService.deployPackageCommand(min, user, cmd1, deployer);
|
await GBAdminService.deployPackageCommand(min, user, cmd1, deployer);
|
||||||
|
|
||||||
// .gbot updates severals keys in instantece, so min must be updated.
|
// .gbot updates severals keys in instantece, so min must be updated.
|
||||||
|
|
||||||
const activeMin = GBServer.globals.minInstances.find(p=> p.botId === min.botId);
|
const activeMin = GBServer.globals.minInstances.find(p => p.botId === min.botId);
|
||||||
|
|
||||||
if (activeMin){
|
if (activeMin) {
|
||||||
min = activeMin;
|
min = activeMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
await min.conversationalService.sendText(min, step, `Training is finished.`);
|
await min.conversationalService.sendText(min, step, `Training is finished.`);
|
||||||
|
|
||||||
|
|
@ -389,11 +380,15 @@ class AdminDialog extends IGBDialog {
|
||||||
new WaterfallDialog('/setupSecurity', [
|
new WaterfallDialog('/setupSecurity', [
|
||||||
async step => {
|
async step => {
|
||||||
min = GBServer.globals.minInstances.find(p => p.botId === min.botId);
|
min = GBServer.globals.minInstances.find(p => p.botId === min.botId);
|
||||||
const tokenName = step.activeDialog.state.tokenName = step.options['args'];
|
const tokenName = (step.activeDialog.state.tokenName = step.options['args']);
|
||||||
if (tokenName) {
|
if (tokenName) {
|
||||||
step.activeDialog.state.clientId = min.core.getParam<string>(min.instance, `${tokenName} Client ID`, null),
|
((step.activeDialog.state.clientId = min.core.getParam<string>(
|
||||||
step.activeDialog.state.host = min.core.getParam<string>(min.instance, `${tokenName} Host`, null),
|
min.instance,
|
||||||
step.activeDialog.state.tenant = min.core.getParam<string>(min.instance, `${tokenName} Tenant`, null)
|
`${tokenName} Client ID`,
|
||||||
|
null
|
||||||
|
)),
|
||||||
|
(step.activeDialog.state.host = min.core.getParam<string>(min.instance, `${tokenName} Host`, null)),
|
||||||
|
(step.activeDialog.state.tenant = min.core.getParam<string>(min.instance, `${tokenName} Tenant`, null)));
|
||||||
}
|
}
|
||||||
if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) {
|
if (step.context.activity.channelId !== 'msteams' && process.env.ENABLE_AUTH) {
|
||||||
return await step.beginDialog('/auth');
|
return await step.beginDialog('/auth');
|
||||||
|
|
@ -416,7 +411,7 @@ class AdminDialog extends IGBDialog {
|
||||||
min = GBServer.globals.minInstances.find(p => p.botId === min.botId);
|
min = GBServer.globals.minInstances.find(p => p.botId === min.botId);
|
||||||
if (step.activeDialog.state.tokenName) {
|
if (step.activeDialog.state.tokenName) {
|
||||||
return await step.next(step.options);
|
return await step.next(step.options);
|
||||||
}
|
}
|
||||||
step.activeDialog.state.authenticatorTenant = step.context.activity['originalText'];
|
step.activeDialog.state.authenticatorTenant = step.context.activity['originalText'];
|
||||||
const locale = step.context.activity.locale;
|
const locale = step.context.activity.locale;
|
||||||
const prompt = Messages[locale].enter_authenticator_authority_host_url;
|
const prompt = Messages[locale].enter_authenticator_authority_host_url;
|
||||||
|
|
@ -445,13 +440,19 @@ class AdminDialog extends IGBDialog {
|
||||||
|
|
||||||
min.adminService.setValue(min.instance.instanceId, `${tokenName}AntiCSRFAttackState`, state);
|
min.adminService.setValue(min.instance.instanceId, `${tokenName}AntiCSRFAttackState`, state);
|
||||||
|
|
||||||
const redirectUri = urlJoin(process.env.BOT_URL, min.instance.botId,
|
const redirectUri = urlJoin(
|
||||||
tokenName ? `/token?value=${tokenName}` : '/token');
|
process.env.BOT_URL,
|
||||||
|
min.instance.botId,
|
||||||
|
tokenName ? `/token?value=${tokenName}` : '/token'
|
||||||
|
);
|
||||||
const scope = tokenName ? '' : 'https://graph.microsoft.com/.default';
|
const scope = tokenName ? '' : 'https://graph.microsoft.com/.default';
|
||||||
const host = tokenName ? step.activeDialog.state.host : 'https://login.microsoftonline.com'
|
const host = tokenName ? step.activeDialog.state.host : 'https://login.microsoftonline.com';
|
||||||
const tenant = tokenName ? step.activeDialog.state.tenant : min.instance.authenticatorTenant;
|
const tenant = tokenName ? step.activeDialog.state.tenant : min.instance.authenticatorTenant;
|
||||||
const clientId = tokenName ? step.activeDialog.state.clientId : (min.instance.marketplaceId ?
|
const clientId = tokenName
|
||||||
min.instance.marketplaceId : GBConfigService.get('MARKETPLACE_ID'));
|
? step.activeDialog.state.clientId
|
||||||
|
: min.instance.marketplaceId
|
||||||
|
? min.instance.marketplaceId
|
||||||
|
: GBConfigService.get('MARKETPLACE_ID');
|
||||||
const oauth2 = tokenName ? 'oauth' : 'oauth2';
|
const oauth2 = tokenName ? 'oauth' : 'oauth2';
|
||||||
const url = `${host}/${tenant}/${oauth2}/authorize?client_id=${clientId}&response_type=code&redirect_uri=${redirectUri}&scope=${scope}&state=${state}&response_mode=query`;
|
const url = `${host}/${tenant}/${oauth2}/authorize?client_id=${clientId}&response_type=code&redirect_uri=${redirectUri}&scope=${scope}&state=${state}&response_mode=query`;
|
||||||
|
|
||||||
|
|
@ -464,4 +465,4 @@ class AdminDialog extends IGBDialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { AdminDialog };
|
export { AdminDialog };
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
import { AdminDialog } from './dialogs/AdminDialog.js';
|
import { AdminDialog } from './dialogs/AdminDialog.js';
|
||||||
import { GuaribasAdmin } from './models/AdminModel.js';
|
import { GuaribasAdmin } from './models/AdminModel.js';
|
||||||
|
|
|
||||||
|
|
@ -34,28 +34,46 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { AuthenticationContext, TokenResponse } from 'adal-node';
|
import {
|
||||||
import { GBError, GBLog, GBMinInstance, IGBAdminService, IGBCoreService, IGBDeployer, IGBInstance } from 'botlib';
|
GBError,
|
||||||
|
GBLog,
|
||||||
|
GBMinInstance,
|
||||||
|
IGBAdminService,
|
||||||
|
IGBCoreService,
|
||||||
|
IGBDeployer,
|
||||||
|
IGBInstance
|
||||||
|
} from 'botlib-legacy';
|
||||||
import { FindOptions } from 'sequelize/types';
|
import { FindOptions } from 'sequelize/types';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService.js';
|
|
||||||
import { GuaribasInstance } from '../../core.gbapp/models/GBModel.js';
|
import { GuaribasInstance } from '../../core.gbapp/models/GBModel.js';
|
||||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
||||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
|
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
|
||||||
import { GBImporter } from '../../core.gbapp/services/GBImporterService.js';
|
import { GBImporter } from '../../core.gbapp/services/GBImporterService.js';
|
||||||
import { GBSharePointService } from '../../sharepoint.gblib/services/SharePointService.js';
|
import { GBSharePointService } from '../../sharepoint.gblib/services/SharePointService.js';
|
||||||
import { GuaribasAdmin } from '../models/AdminModel.js';
|
import { GuaribasAdmin } from '../models/AdminModel.js';
|
||||||
import msRestAzure from 'ms-rest-azure';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { caseSensitive_Numbs_SpecialCharacters_PW, lowercase_PW } from 'super-strong-password-generator';
|
import { caseSensitive_Numbs_SpecialCharacters_PW, lowercase_PW } from 'super-strong-password-generator';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GuaribasUser } from '../../security.gbapp/models/index.js';
|
import { GuaribasUser } from '../../security.gbapp/models/index.js';
|
||||||
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
||||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
||||||
import { GBUtil } from '../../../src/util.js';
|
import { GBUtil } from '../../../src/util.js';
|
||||||
|
|
||||||
|
let msRestAzure: any = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const msRestAzure = await import('ms-rest-azure');
|
||||||
|
} catch (error) {}
|
||||||
|
|
||||||
|
let AuthenticationContext: any = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const adal = await import('adal-node');
|
||||||
|
AuthenticationContext = adal.AuthenticationContext;
|
||||||
|
} catch (error) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Services for server administration.
|
* Services for server administration.
|
||||||
*/
|
*/
|
||||||
|
|
@ -174,20 +192,6 @@ export class GBAdminService implements IGBAdminService {
|
||||||
const localFolder = path.join('work', gbaiPath);
|
const localFolder = path.join('work', gbaiPath);
|
||||||
|
|
||||||
await deployer['deployPackage2'](min, user, localFolder, true);
|
await deployer['deployPackage2'](min, user, localFolder, true);
|
||||||
|
|
||||||
}
|
|
||||||
public static async rebuildIndexPackageCommand(min: GBMinInstance, deployer: GBDeployer) {
|
|
||||||
const service = await AzureDeployerService.createInstance(deployer);
|
|
||||||
const searchIndex = min.instance.searchIndex
|
|
||||||
? min.instance.searchIndex
|
|
||||||
: GBServer.globals.minBoot.instance.searchIndex;
|
|
||||||
await deployer.rebuildIndex(min.instance, service.getKBSearchSchema(searchIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async syncBotServerCommand(min: GBMinInstance, deployer: GBDeployer) {
|
|
||||||
const serverName = `${min.instance.botId}-server`;
|
|
||||||
const service = await AzureDeployerService.createInstance(deployer);
|
|
||||||
service.syncBotServerRepository(min.instance.botId, serverName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setValue(instanceId: number, key: string, value: string) {
|
public async setValue(instanceId: number, key: string, value: string) {
|
||||||
|
|
@ -316,7 +320,7 @@ export class GBAdminService implements IGBAdminService {
|
||||||
if (err !== null) {
|
if (err !== null) {
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
const token = res as TokenResponse;
|
const token = res;
|
||||||
try {
|
try {
|
||||||
await this.setValue(instanceId, `${tokenName}accessToken`, token.accessToken);
|
await this.setValue(instanceId, `${tokenName}accessToken`, token.accessToken);
|
||||||
await this.setValue(instanceId, `${tokenName}refreshToken`, token.refreshToken);
|
await this.setValue(instanceId, `${tokenName}refreshToken`, token.refreshToken);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
import { GuaribasConversation, GuaribasConversationMessage } from './models/index.js';
|
import { GuaribasConversation, GuaribasConversationMessage } from './models/index.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@
|
||||||
* @fileoverview General Bots server core.
|
* @fileoverview General Bots server core.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AzureText } from 'pragmatismo-io-framework';
|
|
||||||
import { FindOptions } from 'sequelize/types';
|
import { FindOptions } from 'sequelize/types';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GuaribasUser } from '../../security.gbapp/models/index.js';
|
import { GuaribasUser } from '../../security.gbapp/models/index.js';
|
||||||
|
|
@ -42,7 +41,7 @@ import { GuaribasConversation, GuaribasConversationMessage } from '../models/ind
|
||||||
* Base services for Bot Analytics.
|
* Base services for Bot Analytics.
|
||||||
*/
|
*/
|
||||||
export class AnalyticsService {
|
export class AnalyticsService {
|
||||||
public async createConversation (user: GuaribasUser): Promise<GuaribasConversation> {
|
public async createConversation(user: GuaribasUser): Promise<GuaribasConversation> {
|
||||||
const conversation = new GuaribasConversation();
|
const conversation = new GuaribasConversation();
|
||||||
conversation.startedBy = user;
|
conversation.startedBy = user;
|
||||||
conversation.startedByUserId = user.userId;
|
conversation.startedByUserId = user.userId;
|
||||||
|
|
@ -51,41 +50,22 @@ export class AnalyticsService {
|
||||||
return await conversation.save();
|
return await conversation.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateConversationSuggestion (
|
public async updateConversationSuggestion(
|
||||||
instanceId: number,
|
instanceId: number,
|
||||||
conversationId: string,
|
conversationId: string,
|
||||||
feedback: string,
|
feedback: string,
|
||||||
locale: string
|
locale: string
|
||||||
): Promise<number> {
|
): Promise<number> {
|
||||||
const minBoot = GBServer.globals.minBoot as any;
|
const minBoot = GBServer.globals.minBoot as any;
|
||||||
const rate = await AzureText.getSentiment(
|
return 0;
|
||||||
minBoot.instance.textAnalyticsKey ? minBoot.instance.textAnalyticsKey : minBoot.instance.textAnalyticsKey,
|
|
||||||
minBoot.instance.textAnalyticsEndpoint
|
|
||||||
? minBoot.instance.textAnalyticsEndpoint
|
|
||||||
: minBoot.instance.textAnalyticsEndpoint,
|
|
||||||
locale,
|
|
||||||
feedback
|
|
||||||
);
|
|
||||||
|
|
||||||
const options = <FindOptions>{ where: {} };
|
|
||||||
options.where = { conversationId: conversationId, instanceId: instanceId };
|
|
||||||
const item = await GuaribasConversation.findOne(options);
|
|
||||||
|
|
||||||
item.feedback = feedback;
|
|
||||||
item.rate = rate;
|
|
||||||
item.rateDate = new Date();
|
|
||||||
await item.save();
|
|
||||||
|
|
||||||
return rate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createMessage (
|
public async createMessage(
|
||||||
instanceId: number,
|
instanceId: number,
|
||||||
conversationId: number,
|
conversationId: number,
|
||||||
userId: number,
|
userId: number,
|
||||||
content: string
|
content: string
|
||||||
): Promise<GuaribasConversationMessage> {
|
): Promise<GuaribasConversationMessage> {
|
||||||
|
|
||||||
const message = GuaribasConversationMessage.build();
|
const message = GuaribasConversationMessage.build();
|
||||||
message.content = typeof content === 'object' ? JSON.stringify(content) : content;
|
message.content = typeof content === 'object' ? JSON.stringify(content) : content;
|
||||||
message.instanceId = instanceId;
|
message.instanceId = instanceId;
|
||||||
|
|
|
||||||
|
|
@ -1,215 +0,0 @@
|
||||||
/*****************************************************************************\
|
|
||||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
|
||||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
|
||||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
|
||||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
|
||||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
|
||||||
| |
|
|
||||||
| General Bots Copyright (c) pragmatismo.com.br. All rights reserved. |
|
|
||||||
| Licensed under the AGPL-3.0. |
|
|
||||||
| |
|
|
||||||
| According to our dual licensing model, this program can be used either |
|
|
||||||
| under the terms of the GNU Affero General Public License, version 3, |
|
|
||||||
| or under a proprietary license. |
|
|
||||||
| |
|
|
||||||
| The texts of the GNU Affero General Public License with an additional |
|
|
||||||
| permission and of our proprietary license can be found at and |
|
|
||||||
| in the LICENSE file you have received along with this program. |
|
|
||||||
| |
|
|
||||||
| This program is distributed in the hope that it will be useful, |
|
|
||||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
|
||||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
||||||
| GNU Affero General Public License for more details. |
|
|
||||||
| |
|
|
||||||
| "General Bots" is a registered trademark of pragmatismo.com.br. |
|
|
||||||
| The licensing of the program under the AGPLv3 does not imply a |
|
|
||||||
| trademark license. Therefore any rights, title and interest in |
|
|
||||||
| our trademarks remain entirely with us. |
|
|
||||||
| |
|
|
||||||
\*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @fileoverview General Bots server core.
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { GBLog, IGBInstallationDeployer, IGBInstance } from 'botlib';
|
|
||||||
import fs from 'fs/promises';
|
|
||||||
import { GBAdminService } from '../../../packages/admin.gbapp/services/GBAdminService.js';
|
|
||||||
import { GBConfigService } from '../../../packages/core.gbapp/services/GBConfigService.js';
|
|
||||||
import scanf from 'scanf';
|
|
||||||
import { AzureDeployerService } from '../services/AzureDeployerService.js';
|
|
||||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
|
||||||
import { GBUtil } from '../../../src/util.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles command-line dialog for getting info for Boot Bot.
|
|
||||||
*/
|
|
||||||
export class StartDialog {
|
|
||||||
public static async createBaseInstance (deployer, freeTier) {
|
|
||||||
// No .env so asks for cloud credentials to start a new farm.
|
|
||||||
|
|
||||||
if (!await GBUtil.exists(`.env`)) {
|
|
||||||
process.stdout.write(
|
|
||||||
'A empty enviroment is detected. To start automatic deploy, please enter some information:\n'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let botId: string;
|
|
||||||
while (botId === undefined) {
|
|
||||||
botId = this.retrieveBotId();
|
|
||||||
}
|
|
||||||
|
|
||||||
let username: string;
|
|
||||||
while (username === undefined) {
|
|
||||||
username = this.retrieveUsername();
|
|
||||||
}
|
|
||||||
|
|
||||||
let password: string;
|
|
||||||
while (password === undefined) {
|
|
||||||
password = this.retrievePassword();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connects to the cloud and retrieves subscriptions.
|
|
||||||
|
|
||||||
const credentials = await GBAdminService.getADALCredentialsFromUsername(username, password);
|
|
||||||
|
|
||||||
let subscriptionId: string;
|
|
||||||
while (subscriptionId === undefined) {
|
|
||||||
const list = await (new AzureDeployerService()).getSubscriptions(credentials);
|
|
||||||
subscriptionId = this.retrieveSubscriptionId(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
const installationDeployer = await AzureDeployerService.createInstanceWithADALCredentials(
|
|
||||||
deployer, freeTier, subscriptionId, credentials);
|
|
||||||
|
|
||||||
let location: string;
|
|
||||||
while (location === undefined) {
|
|
||||||
location = this.retrieveLocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
let appId: string;
|
|
||||||
while (appId === undefined) {
|
|
||||||
appId = this.retrieveAppId();
|
|
||||||
}
|
|
||||||
|
|
||||||
let appPassword: string;
|
|
||||||
while (appPassword === undefined) {
|
|
||||||
appPassword = this.retrieveAppPassword();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepares the first instance on bot farm.
|
|
||||||
|
|
||||||
const instance = <IGBInstance>{};
|
|
||||||
|
|
||||||
instance.botId = botId;
|
|
||||||
instance.state = 'active';
|
|
||||||
instance.cloudUsername = username;
|
|
||||||
instance.cloudPassword = password;
|
|
||||||
instance.cloudSubscriptionId = subscriptionId;
|
|
||||||
instance.cloudLocation = location;
|
|
||||||
instance.marketplaceId = appId;
|
|
||||||
instance.marketplacePassword = appPassword;
|
|
||||||
instance.adminPass = await GBUtil.hashPassword(GBAdminService.getRndPassword());
|
|
||||||
|
|
||||||
return { instance, credentials, subscriptionId , installationDeployer};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static retrieveUsername () {
|
|
||||||
let value = GBConfigService.get('CLOUD_USERNAME');
|
|
||||||
if (value === undefined) {
|
|
||||||
process.stdout.write(`${GBAdminService.GB_PROMPT}CLOUD_USERNAME:`);
|
|
||||||
value = scanf('%s').replace(/(\n|\r)+$/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static retrievePassword () {
|
|
||||||
let password = GBConfigService.get('CLOUD_PASSWORD');
|
|
||||||
if (password === undefined) {
|
|
||||||
process.stdout.write(`${GBAdminService.GB_PROMPT}CLOUD_PASSWORD:`);
|
|
||||||
password = scanf('%s').replace(/(\n|\r)+$/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static retrieveBotId () {
|
|
||||||
let botId = GBConfigService.get('BOT_ID');
|
|
||||||
if (botId === undefined) {
|
|
||||||
process.stdout.write(
|
|
||||||
`${GBAdminService.GB_PROMPT}Choose a unique bot Id containing lowercase letters, digits or
|
|
||||||
dashes (cannot use dash as the first two or last one characters),
|
|
||||||
cannot start or end with or contain consecutive dashes and having 4 to 42 characters long.\n`
|
|
||||||
);
|
|
||||||
process.stdout.write(`${GBAdminService.GB_PROMPT}BOT_ID:`);
|
|
||||||
botId = scanf('%s').replace(/(\n|\r)+$/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return botId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Update Manifest in Azure: "signInAudience": "AzureADandPersonalMicrosoftAccount" and "accessTokenAcceptedVersion": 2.
|
|
||||||
*/
|
|
||||||
private static retrieveAppId () {
|
|
||||||
let appId = GBConfigService.get('MARKETPLACE_ID');
|
|
||||||
if (appId === undefined) {
|
|
||||||
process.stdout.write(
|
|
||||||
`Sorry, this part cannot be automated yet due to Microsoft schedule,
|
|
||||||
please go to https://apps.dev.microsoft.com/portal/register-app to
|
|
||||||
generate manually an App ID and App Secret.\n`
|
|
||||||
);
|
|
||||||
|
|
||||||
process.stdout.write('Generated Application Id (MARKETPLACE_ID):');
|
|
||||||
appId = scanf('%s').replace(/(\n|\r)+$/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return appId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static retrieveAppPassword () {
|
|
||||||
let appPassword = GBConfigService.get('MARKETPLACE_SECRET');
|
|
||||||
if (appPassword === undefined) {
|
|
||||||
process.stdout.write('Generated Password (MARKETPLACE_SECRET):');
|
|
||||||
appPassword = scanf('%s').replace(/(\n|\r)+$/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return appPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static retrieveSubscriptionId (list) {
|
|
||||||
let subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
|
|
||||||
if (subscriptionId){
|
|
||||||
|
|
||||||
return subscriptionId;
|
|
||||||
}
|
|
||||||
const map = {};
|
|
||||||
let index = 1;
|
|
||||||
list.forEach(element => {
|
|
||||||
GBLogEx.info(0, `${index}: ${element.displayName} (${element.subscriptionId})`);
|
|
||||||
map[index++] = element;
|
|
||||||
});
|
|
||||||
let subscriptionIndex;
|
|
||||||
if (!subscriptionIndex && subscriptionId === undefined) {
|
|
||||||
process.stdout.write('CLOUD_SUBSCRIPTIONID (type a number):');
|
|
||||||
subscriptionIndex = scanf('%d');
|
|
||||||
subscriptionId = map[subscriptionIndex].subscriptionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return subscriptionId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static retrieveLocation () {
|
|
||||||
let location = GBConfigService.get('CLOUD_LOCATION');
|
|
||||||
if (location === undefined) {
|
|
||||||
process.stdout.write('CLOUD_LOCATION (eg. westus):');
|
|
||||||
location = scanf('%s');
|
|
||||||
}
|
|
||||||
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
/*****************************************************************************\
|
|
||||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
|
||||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
|
||||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
|
||||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
|
||||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
|
||||||
| |
|
|
||||||
| General Bots Copyright (c) pragmatismo.com.br. All rights reserved. |
|
|
||||||
| Licensed under the AGPL-3.0. |
|
|
||||||
| |
|
|
||||||
| According to our dual licensing model, this program can be used either |
|
|
||||||
| under the terms of the GNU Affero General Public License, version 3, |
|
|
||||||
| or under a proprietary license. |
|
|
||||||
| |
|
|
||||||
| The texts of the GNU Affero General Public License with an additional |
|
|
||||||
| permission and of our proprietary license can be found at and |
|
|
||||||
| in the LICENSE file you have received along with this program. |
|
|
||||||
| |
|
|
||||||
| This program is distributed in the hope that it will be useful, |
|
|
||||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
|
||||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
||||||
| GNU Affero General Public License for more details. |
|
|
||||||
| |
|
|
||||||
| "General Bots" is a registered trademark of pragmatismo.com.br. |
|
|
||||||
| The licensing of the program under the AGPLv3 does not imply a |
|
|
||||||
| trademark license. Therefore any rights, title and interest in |
|
|
||||||
| our trademarks remain entirely with us. |
|
|
||||||
| |
|
|
||||||
\*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @fileoverview General Bots server core.
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Package for Azure Deployer.
|
|
||||||
*/
|
|
||||||
export class GBAzureDeployerPackage implements IGBPackage {
|
|
||||||
public sysPackages: IGBPackage[];
|
|
||||||
public async getDialogs (min: GBMinInstance) {
|
|
||||||
GBLog.verbose(`getDialogs called.`);
|
|
||||||
}
|
|
||||||
public async loadPackage (core: IGBCoreService, sequelize: Sequelize): Promise<void> {
|
|
||||||
GBLog.verbose(`loadPackage called.`);
|
|
||||||
}
|
|
||||||
public async unloadPackage (core: IGBCoreService): Promise<void> {
|
|
||||||
GBLog.verbose(`unloadPackage called.`);
|
|
||||||
}
|
|
||||||
public async loadBot (min: GBMinInstance): Promise<void> {
|
|
||||||
GBLog.verbose(`loadBot called.`);
|
|
||||||
}
|
|
||||||
public async unloadBot (min: GBMinInstance): Promise<void> {
|
|
||||||
GBLog.verbose(`unloadBot called.`);
|
|
||||||
}
|
|
||||||
public async onNewSession (min: GBMinInstance, step: GBDialogStep): Promise<void> {
|
|
||||||
GBLog.verbose(`onNewSession called.`);
|
|
||||||
}
|
|
||||||
public async onExchangeData (min: GBMinInstance, kind: string, data: any) {
|
|
||||||
GBLog.verbose(`onExchangeData called.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +0,0 @@
|
||||||
export const Messages = {
|
|
||||||
'en-US': {
|
|
||||||
about_suggestions: 'Suggestions are welcomed and improve my quality...'
|
|
||||||
},
|
|
||||||
'pt-BR': {
|
|
||||||
about_suggestions: 'Sugestões melhoram muito minha qualidade...'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
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 Koa from 'koa';
|
import Koa from 'koa';
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBLog, GBMinInstance } from 'botlib';
|
import { GBLog, GBMinInstance } from 'botlib-legacy';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import SwaggerClient from 'swagger-client';
|
import SwaggerClient from 'swagger-client';
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { ActivityTypes } from 'botbuilder';
|
import { ActivityTypes } from 'botbuilder';
|
||||||
import { GBLog, GBMinInstance } from 'botlib';
|
import { GBLog, GBMinInstance } from 'botlib-legacy';
|
||||||
import * as df from 'date-diff';
|
import * as df from 'date-diff';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import libphonenumber from 'google-libphonenumber';
|
import libphonenumber from 'google-libphonenumber';
|
||||||
|
|
@ -39,9 +39,8 @@ import { Jimp } from 'jimp';
|
||||||
import jsQR from 'jsqr';
|
import jsQR from 'jsqr';
|
||||||
import mammoth from 'mammoth';
|
import mammoth from 'mammoth';
|
||||||
import mime from 'mime-types';
|
import mime from 'mime-types';
|
||||||
import tesseract from 'node-tesseract-ocr';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import puppeteer, { executablePath } from 'puppeteer';
|
import puppeteer, { executablePath } from 'puppeteer';
|
||||||
import qrcode from 'qrcode';
|
import qrcode from 'qrcode';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
|
|
@ -64,7 +63,6 @@ import { Client } from 'minio';
|
||||||
import nodemailer from 'nodemailer';
|
import nodemailer from 'nodemailer';
|
||||||
const { List, Buttons } = pkg;
|
const { List, Buttons } = pkg;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default check interval for user replay
|
* Default check interval for user replay
|
||||||
*/
|
*/
|
||||||
|
|
@ -82,9 +80,9 @@ export class DialogKeywords {
|
||||||
|
|
||||||
const llmPrompt = `
|
const llmPrompt = `
|
||||||
You are given the following data: ${JSON.stringify(data)}.
|
You are given the following data: ${JSON.stringify(data)}.
|
||||||
|
|
||||||
Based on this data, generate a configuration for a Billboard.js chart. The output should be valid JSON, following Billboard.js conventions. Ensure the JSON is returned without markdown formatting, explanations, or comments.
|
Based on this data, generate a configuration for a Billboard.js chart. The output should be valid JSON, following Billboard.js conventions. Ensure the JSON is returned without markdown formatting, explanations, or comments.
|
||||||
|
|
||||||
The chart should be ${prompt}. Return only the one-line only JSON configuration, nothing else.`;
|
The chart should be ${prompt}. Return only the one-line only JSON configuration, nothing else.`;
|
||||||
|
|
||||||
// Send the prompt to the LLM and get the response
|
// Send the prompt to the LLM and get the response
|
||||||
|
|
@ -96,9 +94,8 @@ export class DialogKeywords {
|
||||||
|
|
||||||
const browser = await puppeteer.launch({
|
const browser = await puppeteer.launch({
|
||||||
headless: process.env.CHROME_HEADLESS === 'true',
|
headless: process.env.CHROME_HEADLESS === 'true',
|
||||||
executablePath: process.env.CHROME_PATH ? process.env.CHROME_PATH : executablePath(),
|
executablePath: process.env.CHROME_PATH ? process.env.CHROME_PATH : executablePath()
|
||||||
}
|
});
|
||||||
);
|
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
|
|
||||||
// Load Billboard.js styles and scripts
|
// Load Billboard.js styles and scripts
|
||||||
|
|
@ -115,7 +112,7 @@ export class DialogKeywords {
|
||||||
const content = await page.$('.bb');
|
const content = await page.$('.bb');
|
||||||
const gbaiName = GBUtil.getGBAIPath(min.botId);
|
const gbaiName = GBUtil.getGBAIPath(min.botId);
|
||||||
const localName = path.join('work', gbaiName, 'cache', `chart${GBAdminService.getRndReadableIdentifier()}.jpg`);
|
const localName = path.join('work', gbaiName, 'cache', `chart${GBAdminService.getRndReadableIdentifier()}.jpg`);
|
||||||
await content.screenshot({ path: localName, omitBackground: true });
|
await content.screenshot({ path: localName, omitBackground: true } as any);
|
||||||
await browser.close();
|
await browser.close();
|
||||||
const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
||||||
GBLogEx.info(min, `Visualization: Chart generated at ${url}.`);
|
GBLogEx.info(min, `Visualization: Chart generated at ${url}.`);
|
||||||
|
|
@ -203,18 +200,7 @@ export class DialogKeywords {
|
||||||
* Returns the OCR of image file.
|
* Returns the OCR of image file.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public async getOCR({ pid, localFile }) {
|
public async getOCR({ pid, localFile }) {}
|
||||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
|
||||||
GBLogEx.info(min, `OCR processing on ${localFile}.`);
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
lang: 'eng',
|
|
||||||
oem: 1,
|
|
||||||
psm: 3
|
|
||||||
};
|
|
||||||
|
|
||||||
return await tesseract.recognize(localFile, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the today data filled in dd/mm/yyyy or mm/dd/yyyy.
|
* Returns the today data filled in dd/mm/yyyy or mm/dd/yyyy.
|
||||||
|
|
@ -258,28 +244,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) {
|
||||||
|
|
@ -587,18 +573,17 @@ export class DialogKeywords {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GBConfigService.get('GB_MODE') !== 'legacy') {
|
if (GBConfigService.get('GB_MODE') !== 'legacy') {
|
||||||
|
|
||||||
const transporter = nodemailer.createTransport({
|
const transporter = nodemailer.createTransport({
|
||||||
host: process.env.EMAIL_SERVER || 'localhost',
|
host: process.env.EMAIL_SERVER || 'localhost',
|
||||||
port: parseInt(process.env.EMAIL_PORT || '587', 10),
|
port: parseInt(process.env.EMAIL_PORT || '587', 10),
|
||||||
secure: false,
|
secure: false,
|
||||||
auth: {
|
auth: {
|
||||||
user: process.env.EMAIL_USER ,
|
user: process.env.EMAIL_USER,
|
||||||
pass: process.env.EMAIL_PASS ,
|
pass: process.env.EMAIL_PASS
|
||||||
},
|
},
|
||||||
tls: {
|
tls: {
|
||||||
rejectUnauthorized: (process.env.EMAIL_REJECT_UNAUTHORIZED === 'true'),
|
rejectUnauthorized: process.env.EMAIL_REJECT_UNAUTHORIZED === 'true'
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const mailOptions = {
|
const mailOptions = {
|
||||||
|
|
@ -606,16 +591,15 @@ export class DialogKeywords {
|
||||||
to: to,
|
to: to,
|
||||||
subject: subject,
|
subject: subject,
|
||||||
text: body,
|
text: body,
|
||||||
html: body,
|
html: body
|
||||||
// headers: {
|
// headers: {
|
||||||
// 'List-Unsubscribe': `<mailto:${config.unsubscribeEmail}?subject=Unsubscribe>`,
|
// 'List-Unsubscribe': `<mailto:${config.unsubscribeEmail}?subject=Unsubscribe>`,
|
||||||
// 'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click'
|
// 'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click'
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
await transporter.sendMail(mailOptions);
|
await transporter.sendMail(mailOptions);
|
||||||
GBLogEx.info(min, `E-mail ${to} (${subject}) sent via NodeMailer.`);
|
GBLogEx.info(min, `E-mail ${to} (${subject}) sent via NodeMailer.`);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let { client } = await GBDeployer.internalGetDriveClient(min);
|
let { client } = await GBDeployer.internalGetDriveClient(min);
|
||||||
|
|
||||||
|
|
@ -725,7 +709,7 @@ export class DialogKeywords {
|
||||||
proc.roles = role;
|
proc.roles = role;
|
||||||
|
|
||||||
// Checks access.
|
// Checks access.
|
||||||
|
|
||||||
const file = process.env.GB_MODE === 'legacy' ? 'People.xlsx' : 'people.csv';
|
const file = process.env.GB_MODE === 'legacy' ? 'People.xlsx' : 'people.csv';
|
||||||
const filters = [file, `${role}=x`, `id=${user.userSystemId}`];
|
const filters = [file, `${role}=x`, `id=${user.userSystemId}`];
|
||||||
const people = await sys.find({ pid, handle: null, args: filters });
|
const people = await sys.find({ pid, handle: null, args: filters });
|
||||||
|
|
@ -953,7 +937,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');
|
||||||
}
|
}
|
||||||
|
|
@ -1016,7 +1000,7 @@ export class DialogKeywords {
|
||||||
|
|
||||||
if (args.length > 3) {
|
if (args.length > 3) {
|
||||||
let section = { title: '', rows: [] };
|
let section = { title: '', rows: [] };
|
||||||
await CollectionUtil.asyncForEach(args, async arg => {
|
await GBUtil.asyncForEach(args, async arg => {
|
||||||
i++;
|
i++;
|
||||||
section.rows.push({ title: arg, id: `button${i}` });
|
section.rows.push({ title: arg, id: `button${i}` });
|
||||||
});
|
});
|
||||||
|
|
@ -1024,7 +1008,7 @@ export class DialogKeywords {
|
||||||
await this.talk({ pid: pid, text: list });
|
await this.talk({ pid: pid, text: list });
|
||||||
} else {
|
} else {
|
||||||
let buttons = [];
|
let buttons = [];
|
||||||
await CollectionUtil.asyncForEach(args, async arg => {
|
await GBUtil.asyncForEach(args, async arg => {
|
||||||
i++;
|
i++;
|
||||||
buttons.push({ body: arg, id: `button${i}` });
|
buttons.push({ body: arg, id: `button${i}` });
|
||||||
});
|
});
|
||||||
|
|
@ -1095,7 +1079,7 @@ export class DialogKeywords {
|
||||||
// Search the answer in one of valid list items loaded from sheeet.
|
// Search the answer in one of valid list items loaded from sheeet.
|
||||||
|
|
||||||
result = null;
|
result = null;
|
||||||
await CollectionUtil.asyncForEach(list, async item => {
|
await GBUtil.asyncForEach(list, async item => {
|
||||||
if (GBConversationalService.kmpSearch(answer, item) != -1) {
|
if (GBConversationalService.kmpSearch(answer, item) != -1) {
|
||||||
result = item;
|
result = item;
|
||||||
}
|
}
|
||||||
|
|
@ -1239,14 +1223,13 @@ export class DialogKeywords {
|
||||||
const imageData = {
|
const imageData = {
|
||||||
data: new Uint8ClampedArray(image.bitmap.data),
|
data: new Uint8ClampedArray(image.bitmap.data),
|
||||||
width: image.bitmap.width,
|
width: image.bitmap.width,
|
||||||
height: image.bitmap.height,
|
height: image.bitmap.height
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use jsQR to decode the QR code
|
// Use jsQR to decode the QR code
|
||||||
const decodedQR = jsQR(imageData.data, imageData.width, imageData.height);
|
const decodedQR = jsQR(imageData.data, imageData.width, imageData.height);
|
||||||
|
|
||||||
result = decodedQR.data;
|
result = decodedQR.data;
|
||||||
|
|
||||||
} else if (kind === 'zipcode') {
|
} else if (kind === 'zipcode') {
|
||||||
const extractEntity = (text: string) => {
|
const extractEntity = (text: string) => {
|
||||||
text = text.replace(/\-/gi, '');
|
text = text.replace(/\-/gi, '');
|
||||||
|
|
@ -1270,7 +1253,7 @@ export class DialogKeywords {
|
||||||
} else if (kind === 'menu') {
|
} else if (kind === 'menu') {
|
||||||
const list = args;
|
const list = args;
|
||||||
result = null;
|
result = null;
|
||||||
await CollectionUtil.asyncForEach(list, async item => {
|
await GBUtil.asyncForEach(list, async item => {
|
||||||
if (GBConversationalService.kmpSearch(answer, item) != -1) {
|
if (GBConversationalService.kmpSearch(answer, item) != -1) {
|
||||||
result = item;
|
result = item;
|
||||||
}
|
}
|
||||||
|
|
@ -1299,7 +1282,7 @@ export class DialogKeywords {
|
||||||
{ name: 'alemão', code: 'de' }
|
{ name: 'alemão', code: 'de' }
|
||||||
];
|
];
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(list, async item => {
|
await GBUtil.asyncForEach(list, async item => {
|
||||||
if (
|
if (
|
||||||
GBConversationalService.kmpSearch(answer.toLowerCase(), item.name.toLowerCase()) != -1 ||
|
GBConversationalService.kmpSearch(answer.toLowerCase(), item.name.toLowerCase()) != -1 ||
|
||||||
GBConversationalService.kmpSearch(answer.toLowerCase(), item.code.toLowerCase()) != -1
|
GBConversationalService.kmpSearch(answer.toLowerCase(), item.code.toLowerCase()) != -1
|
||||||
|
|
@ -1408,9 +1391,7 @@ export class DialogKeywords {
|
||||||
const conversation = min['apiConversations'][pid];
|
const conversation = min['apiConversations'][pid];
|
||||||
const client = await GBUtil.getDirectLineClient(min);
|
const client = await GBUtil.getDirectLineClient(min);
|
||||||
conversation.client = client;
|
conversation.client = client;
|
||||||
const response = await client.apis.Conversations.Conversations_StartConversation(
|
const response = await client.apis.Conversations.Conversations_StartConversation();
|
||||||
|
|
||||||
);
|
|
||||||
conversation.conversationId = response.obj.conversationId;
|
conversation.conversationId = response.obj.conversationId;
|
||||||
|
|
||||||
return await GBVMService.callVM('start', min, null, pid);
|
return await GBVMService.callVM('start', min, null, pid);
|
||||||
|
|
@ -1440,7 +1421,6 @@ export class DialogKeywords {
|
||||||
GBLogEx.info(min, `TALK '${text} step:${step}'.`);
|
GBLogEx.info(min, `TALK '${text} step:${step}'.`);
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
|
|
||||||
text = await min.conversationalService.translate(
|
text = await min.conversationalService.translate(
|
||||||
min,
|
min,
|
||||||
text,
|
text,
|
||||||
|
|
@ -1475,7 +1455,6 @@ export class DialogKeywords {
|
||||||
let localName;
|
let localName;
|
||||||
const gbaiName = GBUtil.getGBAIPath(min.botId);
|
const gbaiName = GBUtil.getGBAIPath(min.botId);
|
||||||
|
|
||||||
|
|
||||||
// Web automation.
|
// Web automation.
|
||||||
|
|
||||||
if (element) {
|
if (element) {
|
||||||
|
|
@ -1510,10 +1489,7 @@ export class DialogKeywords {
|
||||||
|
|
||||||
// .gbdrive direct sending.
|
// .gbdrive direct sending.
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
|
||||||
if (GBConfigService.get('GB_MODE') === 'legacy') {
|
if (GBConfigService.get('GB_MODE') === 'legacy') {
|
||||||
|
|
||||||
const ext = path.extname(filename);
|
const ext = path.extname(filename);
|
||||||
const gbaiName = GBUtil.getGBAIPath(min.botId);
|
const gbaiName = GBUtil.getGBAIPath(min.botId);
|
||||||
|
|
||||||
|
|
@ -1541,10 +1517,7 @@ export class DialogKeywords {
|
||||||
|
|
||||||
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
||||||
} else if (GBConfigService.get('GB_MODE') === 'gbcluster') {
|
} else if (GBConfigService.get('GB_MODE') === 'gbcluster') {
|
||||||
|
|
||||||
|
|
||||||
const ext = path.extname(filename);
|
const ext = path.extname(filename);
|
||||||
|
|
||||||
|
|
||||||
const fileUrl = urlJoin('/', `${min.botId}.gbdrive`, filename);
|
const fileUrl = urlJoin('/', `${min.botId}.gbdrive`, filename);
|
||||||
GBLogEx.info(min, `Direct send from .gbdrive: ${fileUrl} to ${mobile}.`);
|
GBLogEx.info(min, `Direct send from .gbdrive: ${fileUrl} to ${mobile}.`);
|
||||||
|
|
@ -1556,27 +1529,17 @@ export class DialogKeywords {
|
||||||
port: parseInt(process.env.DRIVE_PORT || '9000', 10),
|
port: parseInt(process.env.DRIVE_PORT || '9000', 10),
|
||||||
useSSL: process.env.DRIVE_USE_SSL === 'true',
|
useSSL: process.env.DRIVE_USE_SSL === 'true',
|
||||||
accessKey: process.env.DRIVE_ACCESSKEY,
|
accessKey: process.env.DRIVE_ACCESSKEY,
|
||||||
secretKey: process.env.DRIVE_SECRET,
|
secretKey: process.env.DRIVE_SECRET
|
||||||
});
|
});
|
||||||
|
|
||||||
const bucketName = (process.env.DRIVE_ORG_PREFIX + min.botId + '.gbai').toLowerCase();
|
const bucketName = (process.env.DRIVE_ORG_PREFIX + min.botId + '.gbai').toLowerCase();
|
||||||
localName = path.join(
|
localName = path.join('work', gbaiName, 'cache', `${GBAdminService.getNumberIdentifier()}-${fileOnly}`);
|
||||||
'work',
|
|
||||||
gbaiName,
|
|
||||||
'cache',
|
|
||||||
`${GBAdminService.getNumberIdentifier()}-${fileOnly}`
|
|
||||||
);
|
|
||||||
|
|
||||||
await minioClient.fGetObject(bucketName, fileUrl, localName);
|
await minioClient.fGetObject(bucketName, fileUrl, localName);
|
||||||
|
|
||||||
|
|
||||||
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
||||||
GBLogEx.info(min, `Exposing ${localName} to ${url}...`);
|
GBLogEx.info(min, `Exposing ${localName} to ${url}...`);
|
||||||
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
else {
|
|
||||||
const gbdriveName = GBUtil.getGBAIPath(min.botId, 'gbdrive');
|
const gbdriveName = GBUtil.getGBAIPath(min.botId, 'gbdrive');
|
||||||
localName = path.join(GBConfigService.get('STORAGE_LIBRARY'), gbdriveName, filename);
|
localName = path.join(GBConfigService.get('STORAGE_LIBRARY'), gbdriveName, filename);
|
||||||
}
|
}
|
||||||
|
|
@ -1585,7 +1548,7 @@ export class DialogKeywords {
|
||||||
GBLogEx.info(min, `Converting PDF to images...`);
|
GBLogEx.info(min, `Converting PDF to images...`);
|
||||||
const pngs = await GBUtil.pdfPageAsImage(min, localName, undefined);
|
const pngs = await GBUtil.pdfPageAsImage(min, localName, undefined);
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(pngs, async png => {
|
await GBUtil.asyncForEach(pngs, async png => {
|
||||||
await GBUtil.sleepRandom();
|
await GBUtil.sleepRandom();
|
||||||
// Prepare a cache to be referenced by Bot Framework.
|
// Prepare a cache to be referenced by Bot Framework.
|
||||||
|
|
||||||
|
|
@ -1600,9 +1563,6 @@ export class DialogKeywords {
|
||||||
contentUrl: url
|
contentUrl: url
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!isNaN(mobile)) {
|
if (!isNaN(mobile)) {
|
||||||
await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption, undefined, true, true);
|
await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption, undefined, true, true);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1612,7 +1572,6 @@ export class DialogKeywords {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!url) {
|
if (!url) {
|
||||||
|
|
@ -1625,7 +1584,6 @@ export class DialogKeywords {
|
||||||
const localName = path.join('work', gbaiName, 'cache', `tmp${GBAdminService.getRndReadableIdentifier()}.${ext}`);
|
const localName = path.join('work', gbaiName, 'cache', `tmp${GBAdminService.getRndReadableIdentifier()}.${ext}`);
|
||||||
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
||||||
|
|
||||||
|
|
||||||
await fs.writeFile(localName, new Uint8Array(buf), { encoding: null });
|
await fs.writeFile(localName, new Uint8Array(buf), { encoding: null });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,16 +30,15 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBMinInstance, GBService, IGBCoreService, GBLog } from 'botlib';
|
import { GBMinInstance, GBService, IGBCoreService, GBLog } from 'botlib-legacy';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import * as ji from 'just-indent';
|
import * as ji from 'just-indent';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
|
import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { ScheduleServices } from './ScheduleServices.js';
|
import { ScheduleServices } from './ScheduleServices.js';
|
||||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import { PostgresDialect } from '@sequelize/postgres';
|
|
||||||
import { NodeVM, VMScript } from 'vm2';
|
import { NodeVM, VMScript } from 'vm2';
|
||||||
import { createVm2Pool } from './vm2-process/index.js';
|
import { createVm2Pool } from './vm2-process/index.js';
|
||||||
import { watch } from 'fs';
|
import { watch } from 'fs';
|
||||||
|
|
@ -53,7 +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 { Sequelize, QueryTypes } from '@sequelize/core';
|
import { Sequelize, SequelizeOptions } from 'sequelize-typescript';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { zodToJsonSchema } from 'zod-to-json-schema';
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
||||||
import { GBUtil } from '../../../src/util.js';
|
import { GBUtil } from '../../../src/util.js';
|
||||||
|
|
@ -73,7 +72,7 @@ export class GBVMService extends GBService {
|
||||||
const ignore = path.join('work', GBUtil.getGBAIPath(min.botId, 'gbdialog'), 'node_modules');
|
const ignore = path.join('work', GBUtil.getGBAIPath(min.botId, 'gbdialog'), 'node_modules');
|
||||||
const files = await walkPromise(folder, { ignore: [ignore] });
|
const files = await walkPromise(folder, { ignore: [ignore] });
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(files, async file => {
|
await GBUtil.asyncForEach(files, async file => {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +204,7 @@ export class GBVMService extends GBService {
|
||||||
"author": "${min.botId} owner.",
|
"author": "${min.botId} owner.",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
||||||
"encoding": "0.1.13",
|
"encoding": "0.1.13",
|
||||||
"isomorphic-fetch": "3.0.0",
|
"isomorphic-fetch": "3.0.0",
|
||||||
"punycode": "2.1.1",
|
"punycode": "2.1.1",
|
||||||
|
|
@ -245,17 +244,16 @@ export class GBVMService extends GBService {
|
||||||
const logging: boolean | Function =
|
const logging: boolean | Function =
|
||||||
GBConfigService.get('STORAGE_LOGGING') === 'true'
|
GBConfigService.get('STORAGE_LOGGING') === 'true'
|
||||||
? (str: string): void => {
|
? (str: string): void => {
|
||||||
GBLogEx.info(min, str);
|
GBLogEx.info(min, str);
|
||||||
}
|
}
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
const encrypt: boolean = GBConfigService.get('STORAGE_ENCRYPT') === 'true';
|
const encrypt: boolean = GBConfigService.get('STORAGE_ENCRYPT') === 'true';
|
||||||
const acquire = parseInt(GBConfigService.get('STORAGE_ACQUIRE_TIMEOUT'));
|
const acquire = parseInt(GBConfigService.get('STORAGE_ACQUIRE_TIMEOUT'));
|
||||||
let sequelizeOptions;
|
let sequelizeOptions;
|
||||||
|
|
||||||
|
|
||||||
// Simple function to convert all object keys to lowercase
|
// Simple function to convert all object keys to lowercase
|
||||||
const toLowerCase = (obj) => {
|
const toLowerCase = obj => {
|
||||||
if (!obj) return obj;
|
if (!obj) return obj;
|
||||||
if (typeof obj !== 'object') return obj;
|
if (typeof obj !== 'object') return obj;
|
||||||
|
|
||||||
|
|
@ -263,10 +261,9 @@ export class GBVMService extends GBService {
|
||||||
acc[key.toLowerCase()] = obj[key];
|
acc[key.toLowerCase()] = obj[key];
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
};
|
||||||
|
|
||||||
if (dialect === 'postgres') {
|
if (dialect === 'postgres') {
|
||||||
|
|
||||||
sequelizeOptions = {
|
sequelizeOptions = {
|
||||||
host: host,
|
host: host,
|
||||||
port: port,
|
port: port,
|
||||||
|
|
@ -278,8 +275,7 @@ export class GBVMService extends GBService {
|
||||||
connectTimeout: 10000,
|
connectTimeout: 10000,
|
||||||
query_timeout: 10000,
|
query_timeout: 10000,
|
||||||
statement_timeout: 10000,
|
statement_timeout: 10000,
|
||||||
idle_in_transaction_session_timeout: 10000,
|
idle_in_transaction_session_timeout: 10000
|
||||||
|
|
||||||
},
|
},
|
||||||
pool: {
|
pool: {
|
||||||
max: 1,
|
max: 1,
|
||||||
|
|
@ -300,17 +296,17 @@ export class GBVMService extends GBService {
|
||||||
// Convert all table names to lowercase
|
// Convert all table names to lowercase
|
||||||
freezeTableName: true,
|
freezeTableName: true,
|
||||||
hooks: {
|
hooks: {
|
||||||
beforeSave: (options) => {
|
beforeSave: options => {
|
||||||
if (options.where) {
|
if (options.where) {
|
||||||
options.where = toLowerCase(options.where);
|
options.where = toLowerCase(options.where);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeDestroy: (options) => {
|
beforeDestroy: options => {
|
||||||
if (options.where) {
|
if (options.where) {
|
||||||
options.where = toLowerCase(options.where);
|
options.where = toLowerCase(options.where);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeFind: (options) => {
|
beforeFind: options => {
|
||||||
if (options.where) {
|
if (options.where) {
|
||||||
options.where = toLowerCase(options.where);
|
options.where = toLowerCase(options.where);
|
||||||
}
|
}
|
||||||
|
|
@ -324,7 +320,8 @@ export class GBVMService extends GBService {
|
||||||
options.tableName = options.tableName.toLowerCase();
|
options.tableName = options.tableName.toLowerCase();
|
||||||
} else {
|
} else {
|
||||||
options.tableName = options.modelName.toLowerCase();
|
options.tableName = options.modelName.toLowerCase();
|
||||||
} for (const attr in attributes) {
|
}
|
||||||
|
for (const attr in attributes) {
|
||||||
const lowered = attr.toLowerCase();
|
const lowered = attr.toLowerCase();
|
||||||
if (attr !== lowered) {
|
if (attr !== lowered) {
|
||||||
attributes[lowered] = attributes[attr];
|
attributes[lowered] = attributes[attr];
|
||||||
|
|
@ -333,14 +330,9 @@ export class GBVMService extends GBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
sequelizeOptions = {
|
sequelizeOptions = {
|
||||||
define: {
|
define: {
|
||||||
charset: 'utf8',
|
charset: 'utf8',
|
||||||
|
|
@ -463,7 +455,6 @@ export class GBVMService extends GBService {
|
||||||
if (!con) {
|
if (!con) {
|
||||||
GBLogEx.debug(min, `Invalid connection specified: ${min.bot} ${tableName} ${connectionName}.`);
|
GBLogEx.debug(min, `Invalid connection specified: ${min.bot} ${tableName} ${connectionName}.`);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Field checking, syncs if there is any difference.
|
// Field checking, syncs if there is any difference.
|
||||||
|
|
||||||
const seq = con ? con : minBoot.core.sequelize;
|
const seq = con ? con : minBoot.core.sequelize;
|
||||||
|
|
@ -471,7 +462,6 @@ export class GBVMService extends GBService {
|
||||||
if (seq) {
|
if (seq) {
|
||||||
const model = seq.models[tableName];
|
const model = seq.models[tableName];
|
||||||
if (model) {
|
if (model) {
|
||||||
|
|
||||||
// Except Id, checks if has same number of fields.
|
// Except Id, checks if has same number of fields.
|
||||||
|
|
||||||
let equals = 0;
|
let equals = 0;
|
||||||
|
|
@ -543,7 +533,6 @@ export class GBVMService extends GBService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async translateBASIC(mainName, filename: any, min: GBMinInstance) {
|
public async translateBASIC(mainName, filename: any, min: GBMinInstance) {
|
||||||
|
|
||||||
// Converts General Bots BASIC into regular VBS
|
// Converts General Bots BASIC into regular VBS
|
||||||
|
|
||||||
let basicCode: string = await fs.readFile(filename, 'utf8');
|
let basicCode: string = await fs.readFile(filename, 'utf8');
|
||||||
|
|
@ -557,7 +546,7 @@ export class GBVMService extends GBService {
|
||||||
await s.deleteScheduleIfAny(min, mainName);
|
await s.deleteScheduleIfAny(min, mainName);
|
||||||
|
|
||||||
let i = 1;
|
let i = 1;
|
||||||
await CollectionUtil.asyncForEach(schedules, async syntax => {
|
await GBUtil.asyncForEach(schedules, async syntax => {
|
||||||
if (s) {
|
if (s) {
|
||||||
await s.createOrUpdateSchedule(min, syntax, `${mainName};${i++}`);
|
await s.createOrUpdateSchedule(min, syntax, `${mainName};${i++}`);
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +599,6 @@ export class GBVMService extends GBService {
|
||||||
code = ji.default(code, ' ');
|
code = ji.default(code, ' ');
|
||||||
|
|
||||||
await fs.writeFile(jsfile, code);
|
await fs.writeFile(jsfile, code);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async executeTasks(min, tasks) {
|
private async executeTasks(min, tasks) {
|
||||||
|
|
@ -812,10 +800,9 @@ export class GBVMService extends GBService {
|
||||||
const oldLine = line;
|
const oldLine = line;
|
||||||
line = line.replace(keywords[j][0], keywords[j][1]);
|
line = line.replace(keywords[j][0], keywords[j][1]);
|
||||||
|
|
||||||
if(line != oldLine){
|
if (line != oldLine) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1009,7 +996,7 @@ export class GBVMService extends GBService {
|
||||||
const strFind = ' Client ID';
|
const strFind = ' Client ID';
|
||||||
const tokens = await min.core['findParam'](min.instance, strFind);
|
const tokens = await min.core['findParam'](min.instance, strFind);
|
||||||
let tokensList = [];
|
let tokensList = [];
|
||||||
await CollectionUtil.asyncForEach(tokens, async t => {
|
await GBUtil.asyncForEach(tokens, async t => {
|
||||||
const tokenName = t.replace(strFind, '');
|
const tokenName = t.replace(strFind, '');
|
||||||
tokensList.push(tokenName);
|
tokensList.push(tokenName);
|
||||||
});
|
});
|
||||||
|
|
@ -1036,10 +1023,10 @@ export class GBVMService extends GBService {
|
||||||
try {
|
try {
|
||||||
if (GBConfigService.get('GBVM') !== false) {
|
if (GBConfigService.get('GBVM') !== false) {
|
||||||
return await (async () => {
|
return await (async () => {
|
||||||
return await new Promise((resolve) => {
|
return await new Promise(resolve => {
|
||||||
sandbox['resolve'] = resolve;
|
sandbox['resolve'] = resolve;
|
||||||
// TODO: #411 sandbox['reject'] = reject;
|
// TODO: #411 sandbox['reject'] = reject;
|
||||||
sandbox['reject'] = () => { };
|
sandbox['reject'] = () => {};
|
||||||
|
|
||||||
const vm1 = new NodeVM({
|
const vm1 = new NodeVM({
|
||||||
allowAsync: true,
|
allowAsync: true,
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { GBLog, GBMinInstance } from 'botlib';
|
import { GBLog, GBMinInstance } from 'botlib-legacy';
|
||||||
import { DialogKeywords } from './DialogKeywords.js';
|
import { DialogKeywords } from './DialogKeywords.js';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
|
|
@ -71,7 +71,7 @@ export class ImageProcessingServices {
|
||||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||||
|
|
||||||
let paths = [];
|
let paths = [];
|
||||||
await CollectionUtil.asyncForEach(files, async file => {
|
await GBUtil.asyncForEach(files, async file => {
|
||||||
const gbfile = DialogKeywords.getFileByHandle(file);
|
const gbfile = DialogKeywords.getFileByHandle(file);
|
||||||
paths.push(gbfile.path);
|
paths.push(gbfile.path);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -30,14 +30,15 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBLog, GBMinInstance, GBService } from 'botlib';
|
import { GBLog, GBMinInstance, GBService } from 'botlib-legacy';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
||||||
import { GuaribasSchedule } from '../../core.gbapp/models/GBModel.js';
|
import { GuaribasSchedule } from '../../core.gbapp/models/GBModel.js';
|
||||||
|
|
||||||
import cron from 'node-cron';
|
import cron from 'node-cron';
|
||||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
||||||
|
import { GBUtil } from '../../../src/util.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview Schedule Services.
|
* @fileoverview Schedule Services.
|
||||||
|
|
@ -110,7 +111,7 @@ export class ScheduleServices extends GBService {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
let lastName = '';
|
let lastName = '';
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(schedules, async item => {
|
await GBUtil.asyncForEach(schedules, async item => {
|
||||||
if (item.name === lastName) {
|
if (item.name === lastName) {
|
||||||
item.name = item.name + ++i;
|
item.name = item.name + ++i;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -33,16 +33,14 @@ import ComputerVisionClient from '@azure/cognitiveservices-computervision';
|
||||||
import ApiKeyCredentials from '@azure/ms-rest-js';
|
import ApiKeyCredentials from '@azure/ms-rest-js';
|
||||||
import { BlobServiceClient, BlockBlobClient, StorageSharedKeyCredential } from '@azure/storage-blob';
|
import { BlobServiceClient, BlockBlobClient, StorageSharedKeyCredential } from '@azure/storage-blob';
|
||||||
import { DataTypes, Sequelize } from '@sequelize/core';
|
import { DataTypes, Sequelize } from '@sequelize/core';
|
||||||
import ai2html from 'ai2html';
|
|
||||||
import alasql from 'alasql';
|
import alasql from 'alasql';
|
||||||
import retry from 'async-retry';
|
import retry from 'async-retry';
|
||||||
import { GBLog } from 'botlib';
|
import { GBLog } from 'botlib-legacy';
|
||||||
import csvdb from 'csv-database';
|
import csvdb from 'csv-database';
|
||||||
import Docxtemplater from 'docxtemplater';
|
import Docxtemplater from 'docxtemplater';
|
||||||
import Excel from 'exceljs';
|
import Excel from 'exceljs';
|
||||||
import { Page } from 'facebook-nodejs-business-sdk';
|
import { Page } from 'facebook-nodejs-business-sdk';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { IgApiClient } from 'instagram-private-api';
|
|
||||||
import { BufferWindowMemory } from 'langchain/memory';
|
import { BufferWindowMemory } from 'langchain/memory';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import mime from 'mime-types';
|
import mime from 'mime-types';
|
||||||
|
|
@ -51,7 +49,7 @@ import path from 'path';
|
||||||
import { pdfToPng, PngPageOutput } from 'pdf-to-png-converter';
|
import { pdfToPng, PngPageOutput } from 'pdf-to-png-converter';
|
||||||
import PizZip from 'pizzip';
|
import PizZip from 'pizzip';
|
||||||
import pptxTemplaterModule from 'pptxtemplater';
|
import pptxTemplaterModule from 'pptxtemplater';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import { setFlagsFromString } from 'v8';
|
import { setFlagsFromString } from 'v8';
|
||||||
import { runInNewContext } from 'vm';
|
import { runInNewContext } from 'vm';
|
||||||
|
|
@ -442,7 +440,6 @@ export class SystemKeywords {
|
||||||
useSystemFonts: false,
|
useSystemFonts: false,
|
||||||
viewportScale: 2.0,
|
viewportScale: 2.0,
|
||||||
pagesToProcess: [1],
|
pagesToProcess: [1],
|
||||||
strictPagesToProcess: false,
|
|
||||||
verbosityLevel: 0
|
verbosityLevel: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1162,7 +1159,7 @@ export class SystemKeywords {
|
||||||
let filter;
|
let filter;
|
||||||
const operators = [/\<\=/, /\<\>/, /\>\=/, /\</, /\>/, /\blike\b/, /\bnot in\b/, /\bin\b/, /\=/];
|
const operators = [/\<\=/, /\<\>/, /\>\=/, /\</, /\>/, /\blike\b/, /\bnot in\b/, /\bin\b/, /\=/];
|
||||||
let done = false;
|
let done = false;
|
||||||
await CollectionUtil.asyncForEach(operators, async op => {
|
await GBUtil.asyncForEach(operators, async op => {
|
||||||
var re = new RegExp(op, 'gi');
|
var re = new RegExp(op, 'gi');
|
||||||
const parts = text.split(re);
|
const parts = text.split(re);
|
||||||
|
|
||||||
|
|
@ -1404,7 +1401,7 @@ export class SystemKeywords {
|
||||||
}
|
}
|
||||||
|
|
||||||
let filterIndex = 0;
|
let filterIndex = 0;
|
||||||
await CollectionUtil.asyncForEach(args, async arg => {
|
await GBUtil.asyncForEach(args, async arg => {
|
||||||
const filter = await SystemKeywords.getFilter(arg);
|
const filter = await SystemKeywords.getFilter(arg);
|
||||||
if (!filter) {
|
if (!filter) {
|
||||||
throw new Error(`FIND filter has an error: ${arg} check this and publish .gbdialog again.`);
|
throw new Error(`FIND filter has an error: ${arg} check this and publish .gbdialog again.`);
|
||||||
|
|
@ -1447,7 +1444,7 @@ export class SystemKeywords {
|
||||||
let rowCount = 0;
|
let rowCount = 0;
|
||||||
for (; foundIndex < rows.length; foundIndex++) {
|
for (; foundIndex < rows.length; foundIndex++) {
|
||||||
let filterAcceptCount = 0;
|
let filterAcceptCount = 0;
|
||||||
await CollectionUtil.asyncForEach(filters, async filter => {
|
await GBUtil.asyncForEach(filters, async filter => {
|
||||||
let result = rows[foundIndex][filter.columnIndex];
|
let result = rows[foundIndex][filter.columnIndex];
|
||||||
let wholeWord = true;
|
let wholeWord = true;
|
||||||
if (user && params && params.wholeWord) {
|
if (user && params && params.wholeWord) {
|
||||||
|
|
@ -1514,7 +1511,7 @@ export class SystemKeywords {
|
||||||
const hr = Number.parseInt(filter.value.split(':')[0]);
|
const hr = Number.parseInt(filter.value.split(':')[0]);
|
||||||
let lastHour = Number.parseInt(e[0]);
|
let lastHour = Number.parseInt(e[0]);
|
||||||
let found = false;
|
let found = false;
|
||||||
await CollectionUtil.asyncForEach(e, async hour => {
|
await GBUtil.asyncForEach(e, async hour => {
|
||||||
if (!found && lastHour <= hr && hr <= hour) {
|
if (!found && lastHour <= hr && hr <= hour) {
|
||||||
filterAcceptCount++;
|
filterAcceptCount++;
|
||||||
found = true;
|
found = true;
|
||||||
|
|
@ -1709,7 +1706,7 @@ export class SystemKeywords {
|
||||||
|
|
||||||
// Creates each subfolder.
|
// Creates each subfolder.
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(parts, async item => {
|
await GBUtil.asyncForEach(parts, async item => {
|
||||||
// Calls drive API.
|
// Calls drive API.
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
|
|
@ -2902,7 +2899,7 @@ export class SystemKeywords {
|
||||||
|
|
||||||
// Navigate files / directory to recurse.
|
// Navigate files / directory to recurse.
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(documents, async item => {
|
await GBUtil.asyncForEach(documents, async item => {
|
||||||
if (item.folder) {
|
if (item.folder) {
|
||||||
remotePath = urlJoin(remotePath, item.name);
|
remotePath = urlJoin(remotePath, item.name);
|
||||||
array = [...array, ...(await this.dirFolder({ pid, remotePath, baseUrl, client, array }))];
|
array = [...array, ...(await this.dirFolder({ pid, remotePath, baseUrl, client, array }))];
|
||||||
|
|
@ -3020,18 +3017,6 @@ export class SystemKeywords {
|
||||||
fs.unlink(tempFilePath);
|
fs.unlink(tempFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async postToInstagram({ pid, username, password, imagePath, caption }) {
|
|
||||||
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
|
||||||
|
|
||||||
const ig = new IgApiClient();
|
|
||||||
ig.state.generateDevice(username);
|
|
||||||
await ig.account.login(username, password);
|
|
||||||
const imageBuffer = await fs.readFile(imagePath);
|
|
||||||
const publishResult = await ig.publish.photo({ file: imageBuffer, caption });
|
|
||||||
|
|
||||||
GBLogEx.info(min, `Image posted on IG: ${publishResult}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async setAnswerMode({ pid, mode }) {
|
public async setAnswerMode({ pid, mode }) {
|
||||||
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||||
|
|
||||||
|
|
@ -3116,30 +3101,6 @@ export class SystemKeywords {
|
||||||
await this.setMemoryContext({ pid, erase: true });
|
await this.setMemoryContext({ pid, erase: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
public async convertAI2HTML(aiFilePath) {
|
|
||||||
// Convert the AI file to HTML and assets
|
|
||||||
const result = await ai2html.convertFile(aiFilePath, {
|
|
||||||
outputFormat: 'html',
|
|
||||||
outputWriteMethod: 'write-file',
|
|
||||||
outputPath: path.dirname(aiFilePath),
|
|
||||||
useDocumentSettings: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get the generated HTML file path
|
|
||||||
const htmlFilePath = result.outputFiles.find(file => file.endsWith('.html')).filePath;
|
|
||||||
|
|
||||||
// Read the HTML content
|
|
||||||
const htmlContent = await fs.readFile(htmlFilePath, 'utf8');
|
|
||||||
|
|
||||||
// Save the HTML and assets to a cache directory
|
|
||||||
const cacheDir = path.join('work', 'cache');
|
|
||||||
await fs.mkdir(cacheDir, { recursive: true });
|
|
||||||
const cacheFilePath = path.join(cacheDir, path.basename(htmlFilePath));
|
|
||||||
await fs.writeFile(cacheFilePath, htmlContent);
|
|
||||||
|
|
||||||
return cacheFilePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async refreshDataSourceCache({ pid, connectionName }) {
|
public async refreshDataSourceCache({ pid, connectionName }) {
|
||||||
const { min, user, params, step } = await DialogKeywords.getProcessInfo(pid);
|
const { min, user, params, step } = await DialogKeywords.getProcessInfo(pid);
|
||||||
|
|
||||||
|
|
@ -3153,8 +3114,8 @@ export class SystemKeywords {
|
||||||
|
|
||||||
// Step 2: Connect to SQLite (Local)
|
// Step 2: Connect to SQLite (Local)
|
||||||
const sqlite = new Sequelize({
|
const sqlite = new Sequelize({
|
||||||
dialect: 'sqlite',
|
dialect: 'sqlite3',
|
||||||
storage: sqliteFilePath
|
url: `file://${sqliteFilePath}`
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get the connection details from the min object
|
// Get the connection details from the min object
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import urlJoin from 'url-join';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import url from 'url';
|
import url from 'url';
|
||||||
import { GBLog } from 'botlib';
|
import { GBLog } from 'botlib-legacy';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
import { GBSSR } from '../../core.gbapp/services/GBSSR.js';
|
import { GBSSR } from '../../core.gbapp/services/GBSSR.js';
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,17 @@ import { spawn } from 'child_process';
|
||||||
import CDP from 'chrome-remote-interface';
|
import CDP from 'chrome-remote-interface';
|
||||||
import {} from 'child_process';
|
import {} from 'child_process';
|
||||||
import net from 'net';
|
import net from 'net';
|
||||||
import { GBLog } from 'botlib';
|
import { GBLog } from 'botlib-legacy';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { GBServer } from '../../../../src/app.js';
|
import { GBServer } from '../../../../src/app.js';
|
||||||
import { DebuggerService } from '../DebuggerService.js';
|
import { DebuggerService } from '../DebuggerService.js';
|
||||||
import finalStream from 'final-stream';
|
|
||||||
import { GBLogEx } from '../../../core.gbapp/services/GBLogEx.js';
|
import { GBLogEx } from '../../../core.gbapp/services/GBLogEx.js';
|
||||||
|
import { GBUtil } from '../../../../src/util.js';
|
||||||
|
|
||||||
|
let finalStream: any = null;
|
||||||
|
try {
|
||||||
|
finalStream = await import('final-stream');
|
||||||
|
} catch {}
|
||||||
|
|
||||||
const waitUntil = condition => {
|
const waitUntil = condition => {
|
||||||
if (condition()) {
|
if (condition()) {
|
||||||
|
|
@ -208,7 +213,7 @@ export const createVm2Pool = ({ min, max, ...limits }) => {
|
||||||
const variables = await Runtime.getProperties({ objectId: scopeObjectId });
|
const variables = await Runtime.getProperties({ objectId: scopeObjectId });
|
||||||
let variablesText = '';
|
let variablesText = '';
|
||||||
if (variables && variables.result) {
|
if (variables && variables.result) {
|
||||||
await CollectionUtil.asyncForEach(variables.result, async v => {
|
await GBUtil.asyncForEach(variables.result, async v => {
|
||||||
if (!systemVariables.filter(x => x === v.name)[0]) {
|
if (!systemVariables.filter(x => x === v.name)[0]) {
|
||||||
if (v.value.value) {
|
if (v.value.value) {
|
||||||
variablesText = `${variablesText} \n ${v.name}: ${v.value.value}`;
|
variablesText = `${variablesText} \n ${v.name}: ${v.value.value}`;
|
||||||
|
|
@ -229,7 +234,7 @@ export const createVm2Pool = ({ min, max, ...limits }) => {
|
||||||
GBLog.verbose(`Configuring breakpoints if any for ${limits.botId}...`);
|
GBLog.verbose(`Configuring breakpoints if any for ${limits.botId}...`);
|
||||||
// Waits for debugger and setup breakpoints.
|
// Waits for debugger and setup breakpoints.
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(GBServer.globals.debuggers[limits.botId].breaks, async brk => {
|
await GBUtil.asyncForEach(GBServer.globals.debuggers[limits.botId].breaks, async brk => {
|
||||||
try {
|
try {
|
||||||
const { breakpointId } = await client.Debugger.setBreakpoint({
|
const { breakpointId } = await client.Debugger.setBreakpoint({
|
||||||
location: {
|
location: {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { SecService } from '../../security.gbapp/services/SecService.js';
|
import { SecService } from '../../security.gbapp/services/SecService.js';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,13 @@
|
||||||
|
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { SecService } from '../../security.gbapp/services/SecService.js';
|
import { SecService } from '../../security.gbapp/services/SecService.js';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GBConversationalService } from '../services/GBConversationalService.js';
|
import { GBConversationalService } from '../services/GBConversationalService.js';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
import { GBUtil } from '../../../src/util.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog for the bot explains about itself.
|
* Dialog for the bot explains about itself.
|
||||||
*/
|
*/
|
||||||
|
|
@ -52,7 +53,7 @@ export class LanguageDialog extends IGBDialog {
|
||||||
* @param bot The bot adapter.
|
* @param bot The bot adapter.
|
||||||
* @param min The minimal bot instance data.
|
* @param min The minimal bot instance data.
|
||||||
*/
|
*/
|
||||||
public static setup (bot: BotAdapter, min: GBMinInstance) {
|
public static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||||
min.dialogs.add(
|
min.dialogs.add(
|
||||||
new WaterfallDialog('/language', [
|
new WaterfallDialog('/language', [
|
||||||
async step => {
|
async step => {
|
||||||
|
|
@ -69,7 +70,7 @@ export class LanguageDialog extends IGBDialog {
|
||||||
return await min.conversationalService.prompt(min, step, Messages[locale].which_language);
|
return await min.conversationalService.prompt(min, step, Messages[locale].which_language);
|
||||||
},
|
},
|
||||||
async step => {
|
async step => {
|
||||||
const locale = step.context.activity.locale;
|
const locale = step.context.activity.locale;
|
||||||
|
|
||||||
const list = [
|
const list = [
|
||||||
{ name: 'english', code: 'en' },
|
{ name: 'english', code: 'en' },
|
||||||
|
|
@ -90,7 +91,7 @@ export class LanguageDialog extends IGBDialog {
|
||||||
let translatorLocale = null;
|
let translatorLocale = null;
|
||||||
const text = step.context.activity['originalText'];
|
const text = step.context.activity['originalText'];
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(list, async item => {
|
await GBUtil.asyncForEach(list, async item => {
|
||||||
if (
|
if (
|
||||||
GBConversationalService.kmpSearch(text.toLowerCase(), item.name.toLowerCase()) != -1 ||
|
GBConversationalService.kmpSearch(text.toLowerCase(), item.name.toLowerCase()) != -1 ||
|
||||||
GBConversationalService.kmpSearch(text.toLowerCase(), item.code.toLowerCase()) != -1
|
GBConversationalService.kmpSearch(text.toLowerCase(), item.code.toLowerCase()) != -1
|
||||||
|
|
@ -100,7 +101,7 @@ export class LanguageDialog extends IGBDialog {
|
||||||
});
|
});
|
||||||
|
|
||||||
let sec = new SecService();
|
let sec = new SecService();
|
||||||
let user = await sec.getUserFromSystemId(step.context.activity.from.id);
|
let user = await sec.getUserFromSystemId(step.context.activity.from.id);
|
||||||
user = await sec.updateUserLocale(user.userId, translatorLocale);
|
user = await sec.updateUserLocale(user.userId, translatorLocale);
|
||||||
|
|
||||||
await min.conversationalService.sendText(min, step, Messages[locale].language_chosen);
|
await min.conversationalService.sendText(min, step, Messages[locale].language_chosen);
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { SecService } from '../../security.gbapp/services/SecService.js';
|
import { SecService } from '../../security.gbapp/services/SecService.js';
|
||||||
import { GBConversationalService } from '../services/GBConversationalService.js';
|
import { GBConversationalService } from '../services/GBConversationalService.js';
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { GBLogEx } from '../services/GBLogEx.js';
|
import { GBLogEx } from '../services/GBLogEx.js';
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { GBConversationalService } from '../services/GBConversationalService.js';
|
import { GBConversationalService } from '../services/GBConversationalService.js';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
/**
|
/**
|
||||||
|
|
@ -49,7 +49,7 @@ export class WhoAmIDialog extends IGBDialog {
|
||||||
* @param bot The bot adapter.
|
* @param bot The bot adapter.
|
||||||
* @param min The minimal bot instance data.
|
* @param min The minimal bot instance data.
|
||||||
*/
|
*/
|
||||||
public static setup (bot: BotAdapter, min: GBMinInstance) {
|
public static setup(bot: BotAdapter, min: GBMinInstance) {
|
||||||
min.dialogs.add(
|
min.dialogs.add(
|
||||||
new WaterfallDialog('/whoAmI', [
|
new WaterfallDialog('/whoAmI', [
|
||||||
async step => {
|
async step => {
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
import { BroadcastDialog } from './dialogs/BroadcastDialog.js';
|
import { BroadcastDialog } from './dialogs/BroadcastDialog.js';
|
||||||
import { LanguageDialog } from './dialogs/LanguageDialog.js';
|
import { LanguageDialog } from './dialogs/LanguageDialog.js';
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ import {
|
||||||
UpdatedAt
|
UpdatedAt
|
||||||
} from 'sequelize-typescript';
|
} from 'sequelize-typescript';
|
||||||
|
|
||||||
import { IGBInstance } from 'botlib';
|
import { IGBInstance } from 'botlib-legacy';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base instance data for a bot.
|
* Base instance data for a bot.
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBLog } from 'botlib';
|
import { GBLog } from 'botlib-legacy';
|
||||||
import * as en from 'dotenv-extended';
|
import * as en from 'dotenv-extended';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
import { MessageFactory, RecognizerResult, TurnContext } from 'botbuilder';
|
import { MessageFactory, RecognizerResult, TurnContext } from 'botbuilder';
|
||||||
import { LuisRecognizer } from 'botbuilder-ai';
|
import { LuisRecognizer } from 'botbuilder-ai';
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { Readable } from 'stream';
|
import { Readable } from 'stream';
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
|
|
@ -45,20 +45,16 @@ import { AnalyticsService } from '../../analytics.gblib/services/AnalyticsServic
|
||||||
import { MicrosoftAppCredentials } from 'botframework-connector';
|
import { MicrosoftAppCredentials } from 'botframework-connector';
|
||||||
import { DocxLoader } from '@langchain/community/document_loaders/fs/docx';
|
import { DocxLoader } from '@langchain/community/document_loaders/fs/docx';
|
||||||
import { GBConfigService } from './GBConfigService.js';
|
import { GBConfigService } from './GBConfigService.js';
|
||||||
import { CollectionUtil, AzureText } from 'pragmatismo-io-framework';
|
|
||||||
import { GuaribasUser } from '../../security.gbapp/models/index.js';
|
import { GuaribasUser } from '../../security.gbapp/models/index.js';
|
||||||
import { GBMinService } from './GBMinService.js';
|
import { GBMinService } from './GBMinService.js';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import { createWriteStream, createReadStream } from 'fs';
|
import { createWriteStream, createReadStream } from 'fs';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import twilio from 'twilio';
|
import twilio from 'twilio';
|
||||||
import Nexmo from 'nexmo';
|
|
||||||
import path, { join } from 'path';
|
import path, { join } from 'path';
|
||||||
import shell from 'any-shell-escape';
|
|
||||||
import { exec } from 'child_process';
|
import { exec } from 'child_process';
|
||||||
import prism from 'prism-media';
|
import prism from 'prism-media';
|
||||||
|
|
||||||
|
|
||||||
import SpeechToTextV1 from 'ibm-watson/speech-to-text/v1.js';
|
import SpeechToTextV1 from 'ibm-watson/speech-to-text/v1.js';
|
||||||
import TextToSpeechV1 from 'ibm-watson/text-to-speech/v1.js';
|
import TextToSpeechV1 from 'ibm-watson/text-to-speech/v1.js';
|
||||||
import { IamAuthenticator } from 'ibm-watson/auth/index.js';
|
import { IamAuthenticator } from 'ibm-watson/auth/index.js';
|
||||||
|
|
@ -67,6 +63,8 @@ import Translate from '@google-cloud/translate';
|
||||||
import { GBUtil } from '../../../src/util.js';
|
import { GBUtil } from '../../../src/util.js';
|
||||||
import { GBLogEx } from './GBLogEx.js';
|
import { GBLogEx } from './GBLogEx.js';
|
||||||
|
|
||||||
|
import shell from 'any-shell-escape';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides basic services for handling messages and dispatching to back-end
|
* Provides basic services for handling messages and dispatching to back-end
|
||||||
* services like NLP or Search.
|
* services like NLP or Search.
|
||||||
|
|
@ -401,25 +399,6 @@ export class GBConversationalService {
|
||||||
|
|
||||||
return Promise.reject(new Error(msg));
|
return Promise.reject(new Error(msg));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (min.instance.smsKey && min.instance.smsSecret) {
|
|
||||||
return new Promise((resolve: any, reject: any): any => {
|
|
||||||
const nexmo = new Nexmo({
|
|
||||||
apiKey: min.instance.smsKey,
|
|
||||||
apiSecret: min.instance.smsSecret
|
|
||||||
});
|
|
||||||
// tslint:disable-next-line:no-unsafe-any
|
|
||||||
nexmo.message.sendSms(min.instance.smsServiceNumber, mobile, text, {}, (err, data) => {
|
|
||||||
const message = data.messages ? data.messages[0] : {};
|
|
||||||
if (err || message['error-text']) {
|
|
||||||
GBLog.error(`error sending SMS to ${mobile}: ${message['error-text']}`);
|
|
||||||
reject(message['error-text']);
|
|
||||||
} else {
|
|
||||||
resolve(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -474,7 +453,7 @@ export class GBConversationalService {
|
||||||
return new Promise<string>(async (resolve, reject) => {
|
return new Promise<string>(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
const oggFile = new Readable();
|
const oggFile = new Readable();
|
||||||
oggFile._read = () => { }; // _read is required but you can noop it
|
oggFile._read = () => {}; // _read is required but you can noop it
|
||||||
oggFile.push(buffer);
|
oggFile.push(buffer);
|
||||||
oggFile.push(null);
|
oggFile.push(null);
|
||||||
|
|
||||||
|
|
@ -602,7 +581,7 @@ export class GBConversationalService {
|
||||||
renderer: renderer,
|
renderer: renderer,
|
||||||
gfm: true,
|
gfm: true,
|
||||||
breaks: false,
|
breaks: false,
|
||||||
pedantic: false,
|
pedantic: false
|
||||||
});
|
});
|
||||||
|
|
||||||
// MSFT Translator breaks markdown, so we need to manually fix it:
|
// MSFT Translator breaks markdown, so we need to manually fix it:
|
||||||
|
|
@ -944,7 +923,7 @@ export class GBConversationalService {
|
||||||
// FIX MSFT NLP issue.
|
// FIX MSFT NLP issue.
|
||||||
|
|
||||||
if (nlp.entities) {
|
if (nlp.entities) {
|
||||||
await CollectionUtil.asyncForEach(Object.keys(nlp.entities), async key => {
|
await GBUtil.asyncForEach(Object.keys(nlp.entities), async key => {
|
||||||
if (key !== '$instance') {
|
if (key !== '$instance') {
|
||||||
let entity = nlp.entities[key];
|
let entity = nlp.entities[key];
|
||||||
if (Array.isArray(entity[0])) {
|
if (Array.isArray(entity[0])) {
|
||||||
|
|
@ -964,31 +943,12 @@ export class GBConversationalService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getLanguage(min: GBMinInstance, text: string): Promise<string> {
|
public async getLanguage(min: GBMinInstance, text: string): Promise<string> {
|
||||||
const key = min.core.getParam<string>(min.instance, 'textAnalyticsKey', null);
|
// TODO: Azure removed.
|
||||||
if (!key) {
|
return process.env.DEFAULT_USER_LANGUAGE;
|
||||||
return process.env.DEFAULT_USER_LANGUAGE;
|
|
||||||
}
|
|
||||||
let language = await AzureText.getLocale(
|
|
||||||
key,
|
|
||||||
min.core.getParam<string>(min.instance, 'textAnalyticsEndpoint', null),
|
|
||||||
text
|
|
||||||
);
|
|
||||||
|
|
||||||
return language === '(Unknown)' ? 'en' : language;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async spellCheck(min: GBMinInstance, text: string): Promise<string> {
|
public async spellCheck(min: GBMinInstance, text: string): Promise<string> {
|
||||||
const key = min.core.getParam<string>(min.instance, 'spellcheckerKey', null);
|
// TODO: Azure removed.
|
||||||
|
|
||||||
if (key) {
|
|
||||||
text = text.charAt(0).toUpperCase() + text.slice(1);
|
|
||||||
const data = await AzureText.getSpelledText(key, text);
|
|
||||||
if (data !== text) {
|
|
||||||
GBLogEx.info(min, `Spelling>: ${data}`);
|
|
||||||
text = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1091,7 +1051,7 @@ export class GBConversationalService {
|
||||||
keepTextList = keepTextList.concat(keepText.split(';'));
|
keepTextList = keepTextList.concat(keepText.split(';'));
|
||||||
}
|
}
|
||||||
const replacements = [];
|
const replacements = [];
|
||||||
await CollectionUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
await GBUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
||||||
const result = await e.onExchangeData(min, 'getKeepText', {});
|
const result = await e.onExchangeData(min, 'getKeepText', {});
|
||||||
if (result) {
|
if (result) {
|
||||||
keepTextList = keepTextList.concat(result);
|
keepTextList = keepTextList.concat(result);
|
||||||
|
|
@ -1118,7 +1078,7 @@ export class GBConversationalService {
|
||||||
if (keepTextList) {
|
if (keepTextList) {
|
||||||
keepTextList = keepTextList.filter(p => p.trim() !== '');
|
keepTextList = keepTextList.filter(p => p.trim() !== '');
|
||||||
let i = 0;
|
let i = 0;
|
||||||
await CollectionUtil.asyncForEach(keepTextList, item => {
|
await GBUtil.asyncForEach(keepTextList, item => {
|
||||||
const it = GBConversationalService.removeDiacritics(item);
|
const it = GBConversationalService.removeDiacritics(item);
|
||||||
const noAccentText = GBConversationalService.removeDiacritics(textProcessed);
|
const noAccentText = GBConversationalService.removeDiacritics(textProcessed);
|
||||||
|
|
||||||
|
|
@ -1175,7 +1135,7 @@ export class GBConversationalService {
|
||||||
|
|
||||||
if (keepTextList) {
|
if (keepTextList) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
await CollectionUtil.asyncForEach(replacements, item => {
|
await GBUtil.asyncForEach(replacements, item => {
|
||||||
i++;
|
i++;
|
||||||
text = text.replace(new RegExp(`${item.replacementToken}`, 'gi'), item.text);
|
text = text.replace(new RegExp(`${item.replacementToken}`, 'gi'), item.text);
|
||||||
});
|
});
|
||||||
|
|
@ -1219,7 +1179,6 @@ export class GBConversationalService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async sendTextWithOptionsAndUser(min: GBMinInstance, user, step, text, translate, keepTextList) {
|
public async sendTextWithOptionsAndUser(min: GBMinInstance, user, step, text, translate, keepTextList) {
|
||||||
|
|
||||||
let replacements = [];
|
let replacements = [];
|
||||||
|
|
||||||
// To fix MSFT bug.
|
// To fix MSFT bug.
|
||||||
|
|
@ -1227,7 +1186,7 @@ export class GBConversationalService {
|
||||||
if (keepTextList) {
|
if (keepTextList) {
|
||||||
keepTextList = keepTextList.filter(p => p.trim() !== '');
|
keepTextList = keepTextList.filter(p => p.trim() !== '');
|
||||||
let i = 0;
|
let i = 0;
|
||||||
await CollectionUtil.asyncForEach(keepTextList, item => {
|
await GBUtil.asyncForEach(keepTextList, item => {
|
||||||
if (text.toLowerCase().indexOf(item.toLowerCase()) != -1) {
|
if (text.toLowerCase().indexOf(item.toLowerCase()) != -1) {
|
||||||
const replacementToken = GBAdminService['getNumberIdentifier']();
|
const replacementToken = GBAdminService['getNumberIdentifier']();
|
||||||
replacements[i] = { text: item, replacementToken: replacementToken };
|
replacements[i] = { text: item, replacementToken: replacementToken };
|
||||||
|
|
@ -1246,7 +1205,7 @@ export class GBConversationalService {
|
||||||
|
|
||||||
if (keepTextList) {
|
if (keepTextList) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
await CollectionUtil.asyncForEach(replacements, item => {
|
await GBUtil.asyncForEach(replacements, item => {
|
||||||
i++;
|
i++;
|
||||||
text = text.replace(new RegExp(`${item.replacementToken}`, 'gi'), item.text);
|
text = text.replace(new RegExp(`${item.replacementToken}`, 'gi'), item.text);
|
||||||
});
|
});
|
||||||
|
|
@ -1263,12 +1222,9 @@ export class GBConversationalService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNaN(user.userSystemId)) {
|
if (!isNaN(user.userSystemId)) {
|
||||||
|
|
||||||
await min.whatsAppDirectLine.sendToDevice(user.userSystemId, text);
|
await min.whatsAppDirectLine.sendToDevice(user.userSystemId, text);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
await step.context.sendActivity(text);
|
await step.context.sendActivity(text);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async broadcast(min: GBMinInstance, message: string) {
|
public async broadcast(min: GBMinInstance, message: string) {
|
||||||
|
|
@ -1276,7 +1232,7 @@ export class GBConversationalService {
|
||||||
|
|
||||||
const service = new SecService();
|
const service = new SecService();
|
||||||
const users = await service.getAllUsers(min.instance.instanceId);
|
const users = await service.getAllUsers(min.instance.instanceId);
|
||||||
await CollectionUtil.asyncForEach(users, async user => {
|
await GBUtil.asyncForEach(users, async user => {
|
||||||
if (user.conversationReference) {
|
if (user.conversationReference) {
|
||||||
await this.sendOnConversation(min, user, message);
|
await this.sendOnConversation(min, user, message);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1299,21 +1255,18 @@ export class GBConversationalService {
|
||||||
await t2.sendActivity(message);
|
await t2.sendActivity(message);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const ref = JSON.parse(user.conversationReference);
|
const ref = JSON.parse(user.conversationReference);
|
||||||
await min.bot['continueConversation'](ref, async (t1) => {
|
await min.bot['continueConversation'](ref, async t1 => {
|
||||||
const ref2 = TurnContext.getConversationReference(t1.activity);
|
const ref2 = TurnContext.getConversationReference(t1.activity);
|
||||||
await min.bot.continueConversation(ref2, async (t2) => {
|
await min.bot.continueConversation(ref2, async t2 => {
|
||||||
await t2.sendActivity(message);
|
await t2.sendActivity(message);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (message['buttons'] || message['sections']) {
|
if (message['buttons'] || message['sections']) {
|
||||||
await min['whatsAppDirectLine'].sendToDevice(user.userSystemId, message, user.conversationReference);
|
await min['whatsAppDirectLine'].sendToDevice(user.userSystemId, message, user.conversationReference);
|
||||||
}
|
} else if (user.conversationReference && user.conversationReference.startsWith('spaces')) {
|
||||||
else if (user.conversationReference && user.conversationReference.startsWith('spaces')) {
|
|
||||||
await min['googleDirectLine'].sendToDevice(user.userSystemId, null, user.conversationReference, message);
|
await min['googleDirectLine'].sendToDevice(user.userSystemId, null, user.conversationReference, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBLog, GBMinInstance, IGBCoreService, IGBInstallationDeployer, IGBInstance, IGBPackage } from 'botlib';
|
import { GBLog, GBMinInstance, IGBCoreService, IGBInstallationDeployer, IGBInstance, IGBPackage } from 'botlib-legacy';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { Sequelize, SequelizeOptions } from 'sequelize-typescript';
|
import { Sequelize, SequelizeOptions } from 'sequelize-typescript';
|
||||||
import { Op, Dialect } from 'sequelize';
|
import { Op, Dialect } from 'sequelize';
|
||||||
|
|
@ -42,7 +42,6 @@ import { GBServer } from '../../../src/app.js';
|
||||||
import { GBAdminPackage } from '../../admin.gbapp/index.js';
|
import { GBAdminPackage } from '../../admin.gbapp/index.js';
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
import { GBAnalyticsPackage } from '../../analytics.gblib/index.js';
|
import { GBAnalyticsPackage } from '../../analytics.gblib/index.js';
|
||||||
import { StartDialog } from '../../azuredeployer.gbapp/dialogs/StartDialog.js';
|
|
||||||
import { GBCorePackage } from '../../core.gbapp/index.js';
|
import { GBCorePackage } from '../../core.gbapp/index.js';
|
||||||
import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp/index.js';
|
import { GBCustomerSatisfactionPackage } from '../../customer-satisfaction.gbapp/index.js';
|
||||||
import { GBKBPackage } from '../../kb.gbapp/index.js';
|
import { GBKBPackage } from '../../kb.gbapp/index.js';
|
||||||
|
|
@ -52,14 +51,10 @@ import { GBWhatsappPackage } from '../../whatsapp.gblib/index.js';
|
||||||
import { GuaribasApplications, GuaribasInstance, GuaribasLog } from '../models/GBModel.js';
|
import { GuaribasApplications, GuaribasInstance, GuaribasLog } from '../models/GBModel.js';
|
||||||
import { GBConfigService } from './GBConfigService.js';
|
import { GBConfigService } from './GBConfigService.js';
|
||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
import { GBAzureDeployerPackage } from '../../azuredeployer.gbapp/index.js';
|
|
||||||
import { GBSharePointPackage } from '../../sharepoint.gblib/index.js';
|
import { GBSharePointPackage } from '../../sharepoint.gblib/index.js';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { GBBasicPackage } from '../../basic.gblib/index.js';
|
import { GBBasicPackage } from '../../basic.gblib/index.js';
|
||||||
import { GBGoogleChatPackage } from '../../google-chat.gblib/index.js';
|
import { GBGoogleChatPackage } from '../../google-chat.gblib/index.js';
|
||||||
import { GBHubSpotPackage } from '../../hubspot.gblib/index.js';
|
|
||||||
import open from 'open';
|
|
||||||
import ngrok from 'ngrok';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { GBUtil } from '../../../src/util.js';
|
import { GBUtil } from '../../../src/util.js';
|
||||||
import { GBLogEx } from './GBLogEx.js';
|
import { GBLogEx } from './GBLogEx.js';
|
||||||
|
|
@ -113,7 +108,7 @@ export class GBCoreService implements IGBCoreService {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.adminService = new GBAdminService(this);
|
this.adminService = new GBAdminService(this);
|
||||||
}
|
}
|
||||||
public async ensureInstances(instances: IGBInstance[], bootInstance: any, core: IGBCoreService) { }
|
public async ensureInstances(instances: IGBInstance[], bootInstance: any, core: IGBCoreService) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets database config and connect to storage. Currently two databases
|
* Gets database config and connect to storage. Currently two databases
|
||||||
|
|
@ -129,12 +124,10 @@ export class GBCoreService implements IGBCoreService {
|
||||||
let password: string | undefined;
|
let password: string | undefined;
|
||||||
let storage: string | undefined;
|
let storage: string | undefined;
|
||||||
|
|
||||||
|
|
||||||
if (!['mssql', 'postgres', 'sqlite'].includes(this.dialect)) {
|
if (!['mssql', 'postgres', 'sqlite'].includes(this.dialect)) {
|
||||||
throw new Error(`Unknown or unsupported dialect: ${this.dialect}.`);
|
throw new Error(`Unknown or unsupported dialect: ${this.dialect}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (this.dialect === 'mssql' || this.dialect === 'postgres') {
|
if (this.dialect === 'mssql' || this.dialect === 'postgres') {
|
||||||
host = GBConfigService.get('STORAGE_SERVER');
|
host = GBConfigService.get('STORAGE_SERVER');
|
||||||
database = GBConfigService.get('STORAGE_NAME');
|
database = GBConfigService.get('STORAGE_NAME');
|
||||||
|
|
@ -159,26 +152,22 @@ export class GBCoreService implements IGBCoreService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const logging: boolean | Function =
|
const logging: boolean | Function =
|
||||||
GBConfigService.get('STORAGE_LOGGING') === 'true'
|
GBConfigService.get('STORAGE_LOGGING') === 'true'
|
||||||
? (str: string): void => {
|
? (str: string): void => {
|
||||||
GBLogEx.info(0, str);
|
GBLogEx.info(0, str);
|
||||||
}
|
}
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
|
|
||||||
const encrypt: boolean = GBConfigService.get('STORAGE_ENCRYPT') === 'true';
|
const encrypt: boolean = GBConfigService.get('STORAGE_ENCRYPT') === 'true';
|
||||||
|
|
||||||
|
|
||||||
const acquireStr = GBConfigService.get('STORAGE_ACQUIRE_TIMEOUT');
|
const acquireStr = GBConfigService.get('STORAGE_ACQUIRE_TIMEOUT');
|
||||||
const acquire = acquireStr ? parseInt(acquireStr, 10) : 10000; // Valor padrão de 10 segundos
|
const acquire = acquireStr ? parseInt(acquireStr, 10) : 10000; // Valor padrão de 10 segundos
|
||||||
|
|
||||||
|
|
||||||
const sequelizeOptions: SequelizeOptions = {
|
const sequelizeOptions: SequelizeOptions = {
|
||||||
define: {
|
define: {
|
||||||
freezeTableName: true,
|
freezeTableName: true,
|
||||||
timestamps: false,
|
timestamps: false
|
||||||
},
|
},
|
||||||
host: host,
|
host: host,
|
||||||
port: port,
|
port: port,
|
||||||
|
|
@ -186,22 +175,24 @@ export class GBCoreService implements IGBCoreService {
|
||||||
dialect: this.dialect as Dialect,
|
dialect: this.dialect as Dialect,
|
||||||
storage: storage,
|
storage: storage,
|
||||||
quoteIdentifiers: this.dialect === 'postgres',
|
quoteIdentifiers: this.dialect === 'postgres',
|
||||||
dialectOptions: this.dialect === 'mssql' ? {
|
dialectOptions:
|
||||||
options: {
|
this.dialect === 'mssql'
|
||||||
trustServerCertificate: true,
|
? {
|
||||||
encrypt: encrypt,
|
options: {
|
||||||
},
|
trustServerCertificate: true,
|
||||||
} : {},
|
encrypt: encrypt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: {},
|
||||||
pool: {
|
pool: {
|
||||||
max: 5,
|
max: 5,
|
||||||
min: 0,
|
min: 0,
|
||||||
idle: 10000,
|
idle: 10000,
|
||||||
evict: 10000,
|
evict: 10000,
|
||||||
acquire: acquire,
|
acquire: acquire
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.sequelize = new Sequelize(database, username, password, sequelizeOptions);
|
this.sequelize = new Sequelize(database, username, password, sequelizeOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,7 +248,7 @@ export class GBCoreService implements IGBCoreService {
|
||||||
};
|
};
|
||||||
const list = await GuaribasLog.findAll(options);
|
const list = await GuaribasLog.findAll(options);
|
||||||
let out = 'General Bots Log\n';
|
let out = 'General Bots Log\n';
|
||||||
await CollectionUtil.asyncForEach(list, async e => {
|
await GBUtil.asyncForEach(list, async e => {
|
||||||
out = `${out}\n${e.createdAt} - ${e.message}`;
|
out = `${out}\n${e.createdAt} - ${e.message}`;
|
||||||
});
|
});
|
||||||
return out;
|
return out;
|
||||||
|
|
@ -270,7 +261,7 @@ export class GBCoreService implements IGBCoreService {
|
||||||
if (process.env.LOAD_ONLY) {
|
if (process.env.LOAD_ONLY) {
|
||||||
const bots = process.env.LOAD_ONLY.split(`;`);
|
const bots = process.env.LOAD_ONLY.split(`;`);
|
||||||
const and = [];
|
const and = [];
|
||||||
await CollectionUtil.asyncForEach(bots, async e => {
|
await GBUtil.asyncForEach(bots, async e => {
|
||||||
and.push({ botId: e });
|
and.push({ botId: e });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -282,9 +273,11 @@ export class GBCoreService implements IGBCoreService {
|
||||||
};
|
};
|
||||||
return await GuaribasInstance.findAll(options as any);
|
return await GuaribasInstance.findAll(options as any);
|
||||||
} else {
|
} else {
|
||||||
const options = { where: { state: 'active' } ,
|
const options = {
|
||||||
|
where: { state: 'active' },
|
||||||
order: [['instanceId', 'ASC']]};
|
|
||||||
|
order: [['instanceId', 'ASC']]
|
||||||
|
};
|
||||||
return await GuaribasInstance.findAll(options as any);
|
return await GuaribasInstance.findAll(options as any);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -343,31 +336,6 @@ ENDPOINT_UPDATE=true
|
||||||
await fs.writeFile('.env', env);
|
await fs.writeFile('.env', env);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Certifies that network servers will reach back the development machine
|
|
||||||
* when calling back from web services. This ensures that reverse proxy is
|
|
||||||
* established.
|
|
||||||
*/
|
|
||||||
public async ensureProxy(port): Promise<string> {
|
|
||||||
try {
|
|
||||||
if (
|
|
||||||
(await GBUtil.exists('node_modules/ngrok/bin/ngrok.exe')) ||
|
|
||||||
(await GBUtil.exists('node_modules/.bin/ngrok'))
|
|
||||||
) {
|
|
||||||
return await ngrok.connect({ port: port });
|
|
||||||
} else {
|
|
||||||
GBLog.warn('ngrok executable not found. Check installation or node_modules folder.');
|
|
||||||
|
|
||||||
return 'https://localhost';
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// There are false positive from ngrok regarding to no memory, but it's just
|
|
||||||
// lack of connection.
|
|
||||||
|
|
||||||
throw new Error(`Error connecting to remote ngrok server, please check network connection. ${error.msg}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup generic web hooks so .gbapps can expose application logic
|
* Setup generic web hooks so .gbapps can expose application logic
|
||||||
* and get called on demand.
|
* and get called on demand.
|
||||||
|
|
@ -439,7 +407,7 @@ ENDPOINT_UPDATE=true
|
||||||
const apps = await GuaribasApplications.findAll(options);
|
const apps = await GuaribasApplications.findAll(options);
|
||||||
|
|
||||||
let matchingAppPackages = [];
|
let matchingAppPackages = [];
|
||||||
await CollectionUtil.asyncForEach(appPackages, async appPackage => {
|
await GBUtil.asyncForEach(appPackages, async appPackage => {
|
||||||
const filenameOnly = path.basename(appPackage.name);
|
const filenameOnly = path.basename(appPackage.name);
|
||||||
const matchedApp = apps.find(app => app.name === filenameOnly);
|
const matchedApp = apps.find(app => app.name === filenameOnly);
|
||||||
if (matchedApp || filenameOnly.endsWith('.gblib')) {
|
if (matchedApp || filenameOnly.endsWith('.gblib')) {
|
||||||
|
|
@ -464,7 +432,7 @@ ENDPOINT_UPDATE=true
|
||||||
instances = await core.loadInstances();
|
instances = await core.loadInstances();
|
||||||
if (process.env.ENDPOINT_UPDATE === 'true') {
|
if (process.env.ENDPOINT_UPDATE === 'true') {
|
||||||
const group = GBConfigService.get('CLOUD_GROUP') ?? GBConfigService.get('BOT_ID');
|
const group = GBConfigService.get('CLOUD_GROUP') ?? GBConfigService.get('BOT_ID');
|
||||||
await CollectionUtil.asyncForEach(instances, async instance => {
|
await GBUtil.asyncForEach(instances, async instance => {
|
||||||
GBLogEx.info(instance.instanceId, `Updating bot endpoint for ${instance.botId}...`);
|
GBLogEx.info(instance.instanceId, `Updating bot endpoint for ${instance.botId}...`);
|
||||||
try {
|
try {
|
||||||
await installationDeployer.updateBotProxy(
|
await installationDeployer.updateBotProxy(
|
||||||
|
|
@ -517,7 +485,7 @@ ENDPOINT_UPDATE=true
|
||||||
// Loads all system packages.
|
// Loads all system packages.
|
||||||
const sysPackages: IGBPackage[] = [];
|
const sysPackages: IGBPackage[] = [];
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(
|
await GBUtil.asyncForEach(
|
||||||
[
|
[
|
||||||
GBAdminPackage,
|
GBAdminPackage,
|
||||||
GBCorePackage,
|
GBCorePackage,
|
||||||
|
|
@ -526,11 +494,9 @@ ENDPOINT_UPDATE=true
|
||||||
GBCustomerSatisfactionPackage,
|
GBCustomerSatisfactionPackage,
|
||||||
GBAnalyticsPackage,
|
GBAnalyticsPackage,
|
||||||
GBWhatsappPackage,
|
GBWhatsappPackage,
|
||||||
GBAzureDeployerPackage,
|
|
||||||
GBSharePointPackage,
|
GBSharePointPackage,
|
||||||
GBGoogleChatPackage,
|
GBGoogleChatPackage,
|
||||||
GBBasicPackage,
|
GBBasicPackage,
|
||||||
GBHubSpotPackage,
|
|
||||||
SaaSPackage
|
SaaSPackage
|
||||||
],
|
],
|
||||||
async e => {
|
async e => {
|
||||||
|
|
@ -550,88 +516,16 @@ ENDPOINT_UPDATE=true
|
||||||
* Verifies that an complex global password has been specified
|
* Verifies that an complex global password has been specified
|
||||||
* before starting the server.
|
* before starting the server.
|
||||||
*/
|
*/
|
||||||
public ensureAdminIsSecured() { }
|
public ensureAdminIsSecured() {}
|
||||||
|
|
||||||
public async createBootInstance(
|
public async createBootInstance(
|
||||||
core: GBCoreService,
|
core: GBCoreService,
|
||||||
installationDeployer: IGBInstallationDeployer,
|
installationDeployer: IGBInstallationDeployer,
|
||||||
proxyAddress: string
|
proxyAddress: string
|
||||||
) {
|
) {}
|
||||||
return await this.createBootInstanceEx(
|
|
||||||
core,
|
|
||||||
installationDeployer,
|
|
||||||
proxyAddress,
|
|
||||||
null,
|
|
||||||
GBConfigService.get('FREE_TIER')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Creates the first bot instance (boot instance) used to "boot" the server.
|
|
||||||
* At least one bot is required to perform conversational administrative tasks.
|
|
||||||
* So a base main bot is always deployed and will act as root bot for
|
|
||||||
* configuration tree with three levels: .env > root bot > all other bots.
|
|
||||||
*/
|
|
||||||
public async createBootInstanceEx(
|
|
||||||
core: GBCoreService,
|
|
||||||
installationDeployer: IGBInstallationDeployer,
|
|
||||||
proxyAddress: string,
|
|
||||||
deployer,
|
|
||||||
freeTier
|
|
||||||
) {
|
|
||||||
GBLogEx.info(0, `Deploying cognitive infrastructure (on the cloud / on premises)...`);
|
|
||||||
try {
|
|
||||||
const { instance, credentials, subscriptionId, installationDeployer } = await StartDialog.createBaseInstance(
|
|
||||||
deployer,
|
|
||||||
freeTier
|
|
||||||
);
|
|
||||||
installationDeployer['core'] = this;
|
|
||||||
const changedInstance = await installationDeployer['deployFarm2'](
|
|
||||||
proxyAddress,
|
|
||||||
instance,
|
|
||||||
credentials,
|
|
||||||
subscriptionId
|
|
||||||
);
|
|
||||||
await this.writeEnv(changedInstance);
|
|
||||||
GBConfigService.init();
|
|
||||||
|
|
||||||
GBLogEx.info(0, `File .env written. Preparing storage and search for the first time...`);
|
public async openBrowserInDevelopment() {}
|
||||||
await this.openStorageFrontier(installationDeployer);
|
|
||||||
await this.initStorage();
|
|
||||||
|
|
||||||
return [changedInstance, installationDeployer];
|
|
||||||
} catch (error) {
|
|
||||||
GBLog.warn(
|
|
||||||
`There is an error being thrown, so please cleanup any infrastructure objects
|
|
||||||
created during this procedure and .env before running again.`
|
|
||||||
);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper to get the web browser onpened in UI interfaces.
|
|
||||||
*/
|
|
||||||
public openBrowserInDevelopment() {
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
|
||||||
open('http://localhost:4242');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SQL:
|
|
||||||
*
|
|
||||||
* // let sql: string = '' +
|
|
||||||
* // 'IF OBJECT_ID(\'[UserGroup]\', \'U\') IS NULL' +
|
|
||||||
* // 'CREATE TABLE [UserGroup] (' +
|
|
||||||
* // ' [id] INTEGER NOT NULL IDENTITY(1,1),' +
|
|
||||||
* // ' [userId] INTEGER NULL,' +
|
|
||||||
* // ' [groupId] INTEGER NULL,' +
|
|
||||||
* // ' [instanceId] INTEGER NULL,' +
|
|
||||||
* // ' PRIMARY KEY ([id1], [id2]),' +
|
|
||||||
* // ' FOREIGN KEY ([userId1], [userId2], [userId3]) REFERENCES [User] ([userId1], [userId2], [userId3]) ON DELETE NO ACTION,' +
|
|
||||||
* // ' FOREIGN KEY ([groupId1], [groupId2]) REFERENCES [Group] ([groupId1], [groupId1]) ON DELETE NO ACTION,' +
|
|
||||||
* // ' FOREIGN KEY ([instanceId]) REFERENCES [Instance] ([instanceId]) ON DELETE NO ACTION)'
|
|
||||||
*/
|
|
||||||
private createTableQueryOverride(tableName, attributes, options): string {
|
private createTableQueryOverride(tableName, attributes, options): string {
|
||||||
let sql: string = this.createTableQuery.apply(this.queryGenerator, [tableName, attributes, options]);
|
let sql: string = this.createTableQuery.apply(this.queryGenerator, [tableName, attributes, options]);
|
||||||
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/;
|
const re1 = /CREATE\s+TABLE\s+\[([^\]]*)\]/;
|
||||||
|
|
@ -718,7 +612,9 @@ ENDPOINT_UPDATE=true
|
||||||
|
|
||||||
// Get the current rows in column A
|
// Get the current rows in column A
|
||||||
let results = await client
|
let results = await client
|
||||||
.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='A1:A${maxLines}')`)
|
.api(
|
||||||
|
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='A1:A${maxLines}')`
|
||||||
|
)
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
const rows = results.values;
|
const rows = results.values;
|
||||||
|
|
@ -748,11 +644,12 @@ ENDPOINT_UPDATE=true
|
||||||
|
|
||||||
// Update or add the new value in the found address
|
// Update or add the new value in the found address
|
||||||
await client
|
await client
|
||||||
.api(`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${address}')`)
|
.api(
|
||||||
|
`${baseUrl}/drive/items/${document.id}/workbook/worksheets('${sheets.value[0].name}')/range(address='${address}')`
|
||||||
|
)
|
||||||
.patch(body);
|
.patch(body);
|
||||||
}
|
} else if (GBConfigService.get('GB_MODE') === 'local') {
|
||||||
else if (GBConfigService.get('GB_MODE') === 'local') {
|
let packagePath = GBUtil.getGBAIPath(min.botId, `gbot`);
|
||||||
let packagePath = GBUtil.getGBAIPath(min.botId, `gbot`);
|
|
||||||
const config = path.join(GBConfigService.get('STORAGE_LIBRARY'), packagePath, 'config.csv');
|
const config = path.join(GBConfigService.get('STORAGE_LIBRARY'), packagePath, 'config.csv');
|
||||||
|
|
||||||
const db = await csvdb(config, ['name', 'value'], ',');
|
const db = await csvdb(config, ['name', 'value'], ',');
|
||||||
|
|
@ -862,6 +759,10 @@ ENDPOINT_UPDATE=true
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async ensureProxy(port: any): Promise<string> {
|
||||||
|
return '';
|
||||||
|
} // Azure removed.
|
||||||
|
|
||||||
public async ensureFolders(instances, deployer: GBDeployer) {
|
public async ensureFolders(instances, deployer: GBDeployer) {
|
||||||
const storageMode = process.env.GB_MODE;
|
const storageMode = process.env.GB_MODE;
|
||||||
let libraryPath = GBConfigService.get('STORAGE_LIBRARY');
|
let libraryPath = GBConfigService.get('STORAGE_LIBRARY');
|
||||||
|
|
@ -872,7 +773,7 @@ ENDPOINT_UPDATE=true
|
||||||
port: parseInt(process.env.DRIVE_PORT),
|
port: parseInt(process.env.DRIVE_PORT),
|
||||||
useSSL: process.env.DRIVE_USE_SSL === 'true',
|
useSSL: process.env.DRIVE_USE_SSL === 'true',
|
||||||
accessKey: process.env.DRIVE_ACCESSKEY,
|
accessKey: process.env.DRIVE_ACCESSKEY,
|
||||||
secretKey: process.env.DRIVE_SECRET,
|
secretKey: process.env.DRIVE_SECRET
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.syncBotStorage(instances, 'default', deployer, libraryPath);
|
await this.syncBotStorage(instances, 'default', deployer, libraryPath);
|
||||||
|
|
@ -881,10 +782,8 @@ ENDPOINT_UPDATE=true
|
||||||
|
|
||||||
for await (const bucket of bucketStream) {
|
for await (const bucket of bucketStream) {
|
||||||
if (bucket.name.endsWith('.gbai') && bucket.name.startsWith(process.env.DRIVE_ORG_PREFIX)) {
|
if (bucket.name.endsWith('.gbai') && bucket.name.startsWith(process.env.DRIVE_ORG_PREFIX)) {
|
||||||
|
|
||||||
const botId = bucket.name.replace('.gbai', '').replace(process.env.DRIVE_ORG_PREFIX, '');
|
const botId = bucket.name.replace('.gbai', '').replace(process.env.DRIVE_ORG_PREFIX, '');
|
||||||
await this.syncBotStorage(instances, botId, deployer, libraryPath);
|
await this.syncBotStorage(instances, botId, deployer, libraryPath);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -895,19 +794,16 @@ ENDPOINT_UPDATE=true
|
||||||
await this.syncBotStorage(instances, 'default', deployer, libraryPath);
|
await this.syncBotStorage(instances, 'default', deployer, libraryPath);
|
||||||
|
|
||||||
const files = await fs.readdir(libraryPath);
|
const files = await fs.readdir(libraryPath);
|
||||||
await CollectionUtil.asyncForEach(files, async (file) => {
|
await GBUtil.asyncForEach(files, async file => {
|
||||||
if (file.trim().toLowerCase() !== 'default.gbai' && file.charAt(0) !== '_') {
|
if (file.trim().toLowerCase() !== 'default.gbai' && file.charAt(0) !== '_') {
|
||||||
let botId = file.replace(/\.gbai/, '');
|
let botId = file.replace(/\.gbai/, '');
|
||||||
await this.syncBotStorage(instances, botId, deployer, libraryPath);
|
await this.syncBotStorage(instances, botId, deployer, libraryPath);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async syncBotStorage(instances: any, botId: any, deployer: GBDeployer, libraryPath: string) {
|
private async syncBotStorage(instances: any, botId: any, deployer: GBDeployer, libraryPath: string) {
|
||||||
|
|
||||||
|
|
||||||
let instance = instances.find(p => p.botId.toLowerCase().trim() === botId.toLowerCase().trim());
|
let instance = instances.find(p => p.botId.toLowerCase().trim() === botId.toLowerCase().trim());
|
||||||
|
|
||||||
if (process.env.GB_MODE === 'local') {
|
if (process.env.GB_MODE === 'local') {
|
||||||
|
|
|
||||||
|
|
@ -42,16 +42,14 @@ import urlJoin from 'url-join';
|
||||||
import { Client } from 'minio';
|
import { Client } from 'minio';
|
||||||
|
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { GBError, GBLog, GBMinInstance, IGBCoreService, IGBDeployer, IGBInstance, IGBPackage } from 'botlib';
|
import { GBError, GBLog, GBMinInstance, IGBCoreService, IGBDeployer, IGBInstance, IGBPackage } from 'botlib-legacy';
|
||||||
import { AzureSearch } from 'pragmatismo-io-framework';
|
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
||||||
import Excel from 'exceljs';
|
import Excel from 'exceljs';
|
||||||
import asyncPromise from 'async-promises';
|
import asyncPromise from 'async-promises';
|
||||||
import { GuaribasInstance, GuaribasPackage } from '../models/GBModel.js';
|
import { GuaribasInstance, GuaribasPackage } from '../models/GBModel.js';
|
||||||
import { GBAdminService } from './../../admin.gbapp/services/GBAdminService.js';
|
import { GBAdminService } from './../../admin.gbapp/services/GBAdminService.js';
|
||||||
import { AzureDeployerService } from './../../azuredeployer.gbapp/services/AzureDeployerService.js';
|
|
||||||
import { KBService } from './../../kb.gbapp/services/KBService.js';
|
import { KBService } from './../../kb.gbapp/services/KBService.js';
|
||||||
import { GBConfigService } from './GBConfigService.js';
|
import { GBConfigService } from './GBConfigService.js';
|
||||||
import { GBImporter } from './GBImporterService.js';
|
import { GBImporter } from './GBImporterService.js';
|
||||||
|
|
@ -60,7 +58,7 @@ import MicrosoftGraph from '@microsoft/microsoft-graph-client';
|
||||||
import { GBLogEx } from './GBLogEx.js';
|
import { GBLogEx } from './GBLogEx.js';
|
||||||
import { GBUtil } from '../../../src/util.js';
|
import { GBUtil } from '../../../src/util.js';
|
||||||
import { HNSWLib } from '@langchain/community/vectorstores/hnswlib';
|
import { HNSWLib } from '@langchain/community/vectorstores/hnswlib';
|
||||||
import { OpenAIEmbeddings } from '@langchain/openai';
|
import { AzureOpenAIEmbeddings, OpenAIEmbeddings } from '@langchain/openai';
|
||||||
import { GBMinService } from './GBMinService.js';
|
import { GBMinService } from './GBMinService.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -157,7 +155,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
const getDirectories = async source =>
|
const getDirectories = async source =>
|
||||||
(await fs.readdir(source)).map(name => path.join(source, name)).filter(isDirectory);
|
(await fs.readdir(source)).map(name => path.join(source, name)).filter(isDirectory);
|
||||||
const dirs = await getDirectories(directory);
|
const dirs = await getDirectories(directory);
|
||||||
await CollectionUtil.asyncForEach(dirs, async element => {
|
await GBUtil.asyncForEach(dirs, async element => {
|
||||||
// For each folder, checks its extensions looking for valid packages.
|
// For each folder, checks its extensions looking for valid packages.
|
||||||
|
|
||||||
if (element === '.') {
|
if (element === '.') {
|
||||||
|
|
@ -190,7 +188,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
// Start the process of searching.
|
// Start the process of searching.
|
||||||
|
|
||||||
GBLogEx.info(0, `Deploying Application packages...`);
|
GBLogEx.info(0, `Deploying Application packages...`);
|
||||||
await CollectionUtil.asyncForEach(paths, async e => {
|
await GBUtil.asyncForEach(paths, async e => {
|
||||||
GBLogEx.info(0, `Looking in: ${e}...`);
|
GBLogEx.info(0, `Looking in: ${e}...`);
|
||||||
await scanPackageDirectory(e);
|
await scanPackageDirectory(e);
|
||||||
});
|
});
|
||||||
|
|
@ -222,25 +220,6 @@ export class GBDeployer implements IGBDeployer {
|
||||||
const instance = await this.importer.createBotInstance(botId);
|
const instance = await this.importer.createBotInstance(botId);
|
||||||
const bootInstance = GBServer.globals.bootInstance;
|
const bootInstance = GBServer.globals.bootInstance;
|
||||||
|
|
||||||
if (GBConfigService.get('GB_MODE') === 'legacy') {
|
|
||||||
// Gets the access token to perform service operations.
|
|
||||||
|
|
||||||
const accessToken = await (GBServer.globals.minBoot.adminService as any)['acquireElevatedToken'](
|
|
||||||
bootInstance.instanceId,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
// Creates the MSFT application that will be associated to the bot.
|
|
||||||
|
|
||||||
const service = await AzureDeployerService.createInstance(this);
|
|
||||||
const application = await service.createApplication(accessToken, botId);
|
|
||||||
|
|
||||||
// Fills new instance base information and get App secret.
|
|
||||||
|
|
||||||
instance.marketplaceId = (application as any).appId;
|
|
||||||
instance.marketplacePassword = await service.createApplicationSecret(accessToken, (application as any).id);
|
|
||||||
}
|
|
||||||
|
|
||||||
instance.adminPass = await GBUtil.hashPassword(GBAdminService.getRndPassword());
|
instance.adminPass = await GBUtil.hashPassword(GBAdminService.getRndPassword());
|
||||||
instance.title = botId;
|
instance.title = botId;
|
||||||
instance.activationCode = instance.botId.substring(0, 15);
|
instance.activationCode = instance.botId.substring(0, 15);
|
||||||
|
|
@ -252,9 +231,6 @@ export class GBDeployer implements IGBDeployer {
|
||||||
// Saves bot information to the store.
|
// Saves bot information to the store.
|
||||||
|
|
||||||
await this.core.saveInstance(instance);
|
await this.core.saveInstance(instance);
|
||||||
if (GBConfigService.get('GB_MODE') === 'legacy') {
|
|
||||||
await this.deployBotOnAzure(instance, GBServer.globals.publicAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Makes available bot to the channels and .gbui interfaces.
|
// Makes available bot to the channels and .gbui interfaces.
|
||||||
|
|
||||||
|
|
@ -278,61 +254,10 @@ export class GBDeployer implements IGBDeployer {
|
||||||
where: where
|
where: where
|
||||||
})) !== null
|
})) !== null
|
||||||
);
|
);
|
||||||
} else {
|
return false;
|
||||||
const service = await AzureDeployerService.createInstance(this);
|
|
||||||
|
|
||||||
return await service.botExists(botId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs all tasks of deploying a new bot on the cloud.
|
|
||||||
*/
|
|
||||||
public async deployBotOnAzure(instance: IGBInstance, publicAddress: string): Promise<IGBInstance> {
|
|
||||||
// Reads base configuration from environent file.
|
|
||||||
|
|
||||||
const service = await AzureDeployerService.createInstance(this);
|
|
||||||
const username = GBConfigService.get('CLOUD_USERNAME');
|
|
||||||
const password = GBConfigService.get('CLOUD_PASSWORD');
|
|
||||||
const accessToken = await GBAdminService.getADALTokenFromUsername(username, password);
|
|
||||||
const group = GBConfigService.get('CLOUD_GROUP') ?? GBConfigService.get('BOT_ID');
|
|
||||||
const subscriptionId = GBConfigService.get('CLOUD_SUBSCRIPTIONID');
|
|
||||||
|
|
||||||
// If the bot already exists, just update the endpoint.
|
|
||||||
|
|
||||||
if (await service.botExists(instance.botId)) {
|
|
||||||
await service.updateBot(
|
|
||||||
instance.botId,
|
|
||||||
group,
|
|
||||||
instance.title,
|
|
||||||
instance.description,
|
|
||||||
`${publicAddress}/api/messages/${instance.botId}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// Internally create resources on cloud provider.
|
|
||||||
|
|
||||||
instance = await service.internalDeployBot(
|
|
||||||
instance,
|
|
||||||
accessToken,
|
|
||||||
instance.botId,
|
|
||||||
instance.title,
|
|
||||||
group,
|
|
||||||
instance.description,
|
|
||||||
`${publicAddress}/api/messages/${instance.botId}`,
|
|
||||||
'global',
|
|
||||||
instance.nlpAppId,
|
|
||||||
instance.nlpKey,
|
|
||||||
instance.marketplaceId,
|
|
||||||
instance.marketplacePassword,
|
|
||||||
subscriptionId
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Saves final instance object and returns it.
|
|
||||||
|
|
||||||
return await this.core.saveInstance(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async loadOrCreateEmptyVectorStore(min: GBMinInstance): Promise<HNSWLib> {
|
public async loadOrCreateEmptyVectorStore(min: GBMinInstance): Promise<HNSWLib> {
|
||||||
let vectorStore: HNSWLib;
|
let vectorStore: HNSWLib;
|
||||||
|
|
||||||
|
|
@ -390,7 +315,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
embedding = new OpenAIEmbeddings({
|
embedding = new AzureOpenAIEmbeddings({
|
||||||
maxConcurrency: 5,
|
maxConcurrency: 5,
|
||||||
azureOpenAIApiKey: azureOpenAIKey,
|
azureOpenAIApiKey: azureOpenAIKey,
|
||||||
azureOpenAIApiDeploymentName: azureOpenAIEmbeddingModel,
|
azureOpenAIApiDeploymentName: azureOpenAIEmbeddingModel,
|
||||||
|
|
@ -425,23 +350,14 @@ export class GBDeployer implements IGBDeployer {
|
||||||
* Performs the NLP publishing process on remote service.
|
* Performs the NLP publishing process on remote service.
|
||||||
*/
|
*/
|
||||||
public async publishNLP(instance: IGBInstance): Promise<void> {
|
public async publishNLP(instance: IGBInstance): Promise<void> {
|
||||||
const service = await AzureDeployerService.createInstance(this);
|
// TODO: Azure removed.
|
||||||
const res = await service.publishNLP(instance.cloudLocation, instance.nlpAppId, instance.nlpAuthoringKey);
|
|
||||||
if (res.status !== 200 && res.status !== 201) {
|
|
||||||
throw res.bodyAsText;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trains NLP on the remote service.
|
* Trains NLP on the remote service.
|
||||||
*/
|
*/
|
||||||
public async trainNLP(instance: IGBInstance): Promise<void> {
|
public async trainNLP(instance: IGBInstance): Promise<void> {
|
||||||
const service = await AzureDeployerService.createInstance(this);
|
// TODO: Azure removed.
|
||||||
const res = await service.trainNLP(instance.cloudLocation, instance.nlpAppId, instance.nlpAuthoringKey);
|
|
||||||
if (res.status !== 200 && res.status !== 202) {
|
|
||||||
throw res.bodyAsText;
|
|
||||||
}
|
|
||||||
GBUtil.sleep(5000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -465,27 +381,13 @@ export class GBDeployer implements IGBDeployer {
|
||||||
* Refreshes NLP entities on the remote service.
|
* Refreshes NLP entities on the remote service.
|
||||||
*/
|
*/
|
||||||
public async refreshNLPEntity(instance: IGBInstance, listName, listData): Promise<void> {
|
public async refreshNLPEntity(instance: IGBInstance, listName, listData): Promise<void> {
|
||||||
const service = await AzureDeployerService.createInstance(this);
|
// Azure removed.
|
||||||
const res = await service.refreshEntityList(
|
|
||||||
instance.cloudLocation,
|
|
||||||
instance.nlpAppId,
|
|
||||||
listName,
|
|
||||||
instance.nlpAuthoringKey,
|
|
||||||
listData
|
|
||||||
);
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw res.bodyAsText;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deploys a bot to the storage from a .gbot folder.
|
* Deploys a bot to the storage from a .gbot folder.
|
||||||
*/
|
*/
|
||||||
public async deployBotFromLocalPath(localPath: string, publicAddress: string): Promise<void> {
|
public async deployBotFromLocalPath(localPath: string, publicAddress: string): Promise<void> {}
|
||||||
const packageName = path.basename(localPath);
|
|
||||||
const instance = await this.importer.importIfNotExistsBotPackage(undefined, packageName, localPath);
|
|
||||||
await this.deployBotOnAzure(instance, publicAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all para from tabular file Config.xlsx.
|
* Loads all para from tabular file Config.xlsx.
|
||||||
|
|
@ -618,7 +520,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
await fs.mkdir(pathBase, { recursive: true });
|
await fs.mkdir(pathBase, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(parts, async item => {
|
await GBUtil.asyncForEach(parts, async item => {
|
||||||
pathBase = path.join(pathBase, item);
|
pathBase = path.join(pathBase, item);
|
||||||
if (!(await GBUtil.exists(pathBase))) {
|
if (!(await GBUtil.exists(pathBase))) {
|
||||||
await fs.mkdir(pathBase, { recursive: true });
|
await fs.mkdir(pathBase, { recursive: true });
|
||||||
|
|
@ -642,7 +544,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(documents, async item => {
|
await GBUtil.asyncForEach(documents, async item => {
|
||||||
const itemPath = path.join(localPath, remotePath, item.name);
|
const itemPath = path.join(localPath, remotePath, item.name);
|
||||||
|
|
||||||
if (item.folder) {
|
if (item.folder) {
|
||||||
|
|
@ -680,11 +582,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
public async undeployBot(botId: string, packageName: string): Promise<void> {
|
public async undeployBot(botId: string, packageName: string): Promise<void> {
|
||||||
// Deletes Bot registration on cloud.
|
// Deletes Bot registration on cloud.
|
||||||
|
|
||||||
const service = await AzureDeployerService.createInstance(this);
|
|
||||||
const group = GBConfigService.get('BOT_ID');
|
const group = GBConfigService.get('BOT_ID');
|
||||||
if (await service.botExists(botId)) {
|
|
||||||
await service.deleteBot(botId, group);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unbinds resources and listeners.
|
// Unbinds resources and listeners.
|
||||||
|
|
||||||
|
|
@ -742,7 +640,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
// Asks for each .gbapp if it will handle the package publishing.
|
// Asks for each .gbapp if it will handle the package publishing.
|
||||||
|
|
||||||
const _this = this;
|
const _this = this;
|
||||||
await CollectionUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
await GBUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
||||||
// If it will be handled, create a temporary service layer to be
|
// If it will be handled, create a temporary service layer to be
|
||||||
// called by .gbapp and manage the associated package row.
|
// called by .gbapp and manage the associated package row.
|
||||||
|
|
||||||
|
|
@ -785,7 +683,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
// Find all tokens in .gbot Config.
|
// Find all tokens in .gbot Config.
|
||||||
const strFind = ' Driver';
|
const strFind = ' Driver';
|
||||||
const conns = await min.core['findParam'](min.instance, strFind);
|
const conns = await min.core['findParam'](min.instance, strFind);
|
||||||
await CollectionUtil.asyncForEach(conns, async t => {
|
await GBUtil.asyncForEach(conns, async t => {
|
||||||
const connectionName = t.replace(strFind, '').trim();
|
const connectionName = t.replace(strFind, '').trim();
|
||||||
let con = {};
|
let con = {};
|
||||||
con['name'] = connectionName;
|
con['name'] = connectionName;
|
||||||
|
|
@ -942,61 +840,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
* Performs automation of the Indexer (Azure Search) and rebuild
|
* Performs automation of the Indexer (Azure Search) and rebuild
|
||||||
* its index based on .gbkb structure.
|
* its index based on .gbkb structure.
|
||||||
*/
|
*/
|
||||||
public async rebuildIndex(instance: IGBInstance, searchSchema: any) {
|
public async rebuildIndex(instance: IGBInstance, searchSchema: any) {}
|
||||||
const key = instance.searchKey ? instance.searchKey : GBServer.globals.minBoot.instance.searchKey;
|
|
||||||
GBLogEx.info(instance.instanceId, `rebuildIndex running...`);
|
|
||||||
|
|
||||||
if (!key) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const searchIndex = instance.searchIndex ? instance.searchIndex : GBServer.globals.minBoot.instance.searchIndex;
|
|
||||||
const searchIndexer = instance.searchIndexer
|
|
||||||
? instance.searchIndexer
|
|
||||||
: GBServer.globals.minBoot.instance.searchIndexer;
|
|
||||||
const host = instance.searchHost ? instance.searchHost : GBServer.globals.minBoot.instance.searchHost;
|
|
||||||
|
|
||||||
// Prepares search.
|
|
||||||
|
|
||||||
const search = new AzureSearch(key, host, searchIndex, searchIndexer);
|
|
||||||
const connectionString = GBDeployer.getConnectionStringFromInstance(GBServer.globals.minBoot.instance);
|
|
||||||
const dsName = 'gb';
|
|
||||||
|
|
||||||
// Removes any previous index.
|
|
||||||
|
|
||||||
try {
|
|
||||||
await search.deleteDataSource(dsName);
|
|
||||||
} catch (error) {
|
|
||||||
// If it is a 404 there is nothing to delete as it is the first creation.
|
|
||||||
|
|
||||||
if (error.code !== 404) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes the index.
|
|
||||||
|
|
||||||
try {
|
|
||||||
await search.deleteIndex();
|
|
||||||
} catch (error) {
|
|
||||||
// If it is a 404 there is nothing to delete as it is the first creation.
|
|
||||||
|
|
||||||
if (error.code !== 404 && error.code !== 'OperationNotAllowed') {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates the data source and index on the cloud.
|
|
||||||
|
|
||||||
try {
|
|
||||||
await search.createDataSource(dsName, dsName, 'GuaribasQuestion', 'azuresql', connectionString);
|
|
||||||
} catch (error) {
|
|
||||||
GBLog.error(error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
await search.createIndex(searchSchema, dsName);
|
|
||||||
|
|
||||||
GBLogEx.info(instance.instanceId, `Released rebuildIndex mutex.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a storage package by using package name.
|
* Finds a storage package by using package name.
|
||||||
|
|
@ -1175,7 +1019,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
// Loops through all ready to load .gbapp packages.
|
// Loops through all ready to load .gbapp packages.
|
||||||
|
|
||||||
let appPackagesProcessed = 0;
|
let appPackagesProcessed = 0;
|
||||||
await CollectionUtil.asyncForEach(gbappPackages, async e => {
|
await GBUtil.asyncForEach(gbappPackages, async e => {
|
||||||
const filenameOnly = path.basename(e);
|
const filenameOnly = path.basename(e);
|
||||||
|
|
||||||
// Skips .gbapp inside deploy folder.
|
// Skips .gbapp inside deploy folder.
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBMinInstance, IGBCoreService, IGBInstance } from 'botlib';
|
import { GBMinInstance, IGBCoreService, IGBInstance } from 'botlib-legacy';
|
||||||
import { CreateOptions } from 'sequelize/types';
|
import { CreateOptions } from 'sequelize/types';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBLog, IGBInstance } from 'botlib';
|
import { GBLog, IGBInstance } from 'botlib-legacy';
|
||||||
import { GuaribasLog } from '../models/GBModel.js';
|
import { GuaribasLog } from '../models/GBModel.js';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GBConfigService } from './GBConfigService.js';
|
import { GBConfigService } from './GBConfigService.js';
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ import {
|
||||||
IGBCoreService,
|
IGBCoreService,
|
||||||
IGBInstance,
|
IGBInstance,
|
||||||
IGBPackage
|
IGBPackage
|
||||||
} from 'botlib';
|
} from 'botlib-legacy';
|
||||||
import cliProgress from 'cli-progress';
|
import cliProgress from 'cli-progress';
|
||||||
import removeRoute from 'express-remove-route';
|
import removeRoute from 'express-remove-route';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
|
|
@ -76,7 +76,7 @@ import Koa from 'koa';
|
||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
import { NlpManager } from 'node-nlp';
|
import { NlpManager } from 'node-nlp';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import SwaggerClient from 'swagger-client';
|
import SwaggerClient from 'swagger-client';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import wash from 'washyourmouthoutwithsoap';
|
import wash from 'washyourmouthoutwithsoap';
|
||||||
|
|
@ -179,7 +179,7 @@ export class GBMinService {
|
||||||
let i = 1;
|
let i = 1;
|
||||||
const minInstances = [];
|
const minInstances = [];
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(
|
await GBUtil.asyncForEach(
|
||||||
instances,
|
instances,
|
||||||
(async instance => {
|
(async instance => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -222,7 +222,7 @@ export class GBMinService {
|
||||||
|
|
||||||
const steps = process.env.TEST_MESSAGE.split(';');
|
const steps = process.env.TEST_MESSAGE.split(';');
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(steps, async step => {
|
await GBUtil.asyncForEach(steps, async step => {
|
||||||
client.apis.Conversations.Conversations_PostActivity({
|
client.apis.Conversations.Conversations_PostActivity({
|
||||||
conversationId: conversationId,
|
conversationId: conversationId,
|
||||||
activity: {
|
activity: {
|
||||||
|
|
@ -829,10 +829,7 @@ export class GBMinService {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (GBConfigService.get('GB_MODE') !== 'legacy') {
|
if (GBConfigService.get('GB_MODE') !== 'legacy') {
|
||||||
const url =
|
const url = process.env.BOT_URL ? process.env.BOT_URL : `http://localhost:${GBConfigService.get('PORT')}`;
|
||||||
process.env.BOT_URL && !process.env.BOT_URL.includes('ngrok')
|
|
||||||
? process.env.BOT_URL
|
|
||||||
: `http://localhost:${GBConfigService.get('PORT')}`;
|
|
||||||
config['domain'] = urlJoin(url, 'directline', botId);
|
config['domain'] = urlJoin(url, 'directline', botId);
|
||||||
} else {
|
} else {
|
||||||
const webchatTokenContainer = await this.getWebchatToken(instance);
|
const webchatTokenContainer = await this.getWebchatToken(instance);
|
||||||
|
|
@ -991,7 +988,7 @@ export class GBMinService {
|
||||||
|
|
||||||
// Creates a hub of services available in .gbapps.
|
// Creates a hub of services available in .gbapps.
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
await GBUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
||||||
let services: ConcatArray<never>;
|
let services: ConcatArray<never>;
|
||||||
if ((services = await e.onExchangeData(min, 'getServices', null))) {
|
if ((services = await e.onExchangeData(min, 'getServices', null))) {
|
||||||
min.gbappServices = { ...min.gbappServices, ...services };
|
min.gbappServices = { ...min.gbappServices, ...services };
|
||||||
|
|
@ -1066,7 +1063,7 @@ export class GBMinService {
|
||||||
private async invokeLoadBot(appPackages: IGBPackage[], sysPackages: IGBPackage[], min: GBMinInstance) {
|
private async invokeLoadBot(appPackages: IGBPackage[], sysPackages: IGBPackage[], min: GBMinInstance) {
|
||||||
// Calls loadBot event in all .gbapp packages.
|
// Calls loadBot event in all .gbapp packages.
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(sysPackages, async p => {
|
await GBUtil.asyncForEach(sysPackages, async p => {
|
||||||
p.sysPackages = sysPackages;
|
p.sysPackages = sysPackages;
|
||||||
if (p.getDialogs !== undefined) {
|
if (p.getDialogs !== undefined) {
|
||||||
const dialogs = await p.getDialogs(min);
|
const dialogs = await p.getDialogs(min);
|
||||||
|
|
@ -1082,7 +1079,7 @@ export class GBMinService {
|
||||||
|
|
||||||
// Adds all dialogs from .gbapps into global dialo list for this minimal instance.
|
// Adds all dialogs from .gbapps into global dialo list for this minimal instance.
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(appPackages, async p => {
|
await GBUtil.asyncForEach(appPackages, async p => {
|
||||||
p.sysPackages = sysPackages;
|
p.sysPackages = sysPackages;
|
||||||
await p.loadBot(min);
|
await p.loadBot(min);
|
||||||
if (p.getDialogs !== undefined) {
|
if (p.getDialogs !== undefined) {
|
||||||
|
|
@ -1306,7 +1303,7 @@ export class GBMinService {
|
||||||
} else if (context.activity.type === 'conversationUpdate') {
|
} else if (context.activity.type === 'conversationUpdate') {
|
||||||
// Calls onNewSession event on each .gbapp package.
|
// Calls onNewSession event on each .gbapp package.
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(appPackages, async e => {
|
await GBUtil.asyncForEach(appPackages, async e => {
|
||||||
await e.onNewSession(min, step);
|
await e.onNewSession(min, step);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1572,7 +1569,7 @@ export class GBMinService {
|
||||||
context.activity.text = context.activity.text.replace(/\<at\>.*\<\/at\>\s/gi, '');
|
context.activity.text = context.activity.text.replace(/\<at\>.*\<\/at\>\s/gi, '');
|
||||||
|
|
||||||
let data = { query: context.activity.text };
|
let data = { query: context.activity.text };
|
||||||
await CollectionUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
await GBUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
||||||
await e.onExchangeData(min, 'handleRawInput', data);
|
await e.onExchangeData(min, 'handleRawInput', data);
|
||||||
});
|
});
|
||||||
context.activity.text = data.query;
|
context.activity.text = data.query;
|
||||||
|
|
@ -1784,7 +1781,7 @@ export class GBMinService {
|
||||||
message: message ? message['dataValues'] : null,
|
message: message ? message['dataValues'] : null,
|
||||||
user: user ? user.dataValues : null
|
user: user ? user.dataValues : null
|
||||||
};
|
};
|
||||||
await CollectionUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
await GBUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
||||||
if (!nextDialog) {
|
if (!nextDialog) {
|
||||||
nextDialog = await e.onExchangeData(min, 'handleAnswer', data);
|
nextDialog = await e.onExchangeData(min, 'handleAnswer', data);
|
||||||
}
|
}
|
||||||
|
|
@ -1826,10 +1823,10 @@ export class GBMinService {
|
||||||
await close();
|
await close();
|
||||||
|
|
||||||
let proxies = {};
|
let proxies = {};
|
||||||
await CollectionUtil.asyncForEach(mins, async min => {
|
await GBUtil.asyncForEach(mins, async min => {
|
||||||
let dialogs = {};
|
let dialogs = {};
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(Object.values(min.scriptMap), async script => {
|
await GBUtil.asyncForEach(Object.values(min.scriptMap), async script => {
|
||||||
const api = min.core.getParam(min.instance, 'Server API', null);
|
const api = min.core.getParam(min.instance, 'Server API', null);
|
||||||
if (api) {
|
if (api) {
|
||||||
dialogs[script] = async data => {
|
dialogs[script] = async data => {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ import path from 'path';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { NextFunction, Request, Response } from 'express';
|
import { NextFunction, Request, Response } from 'express';
|
||||||
import urljoin from 'url-join';
|
import urljoin from 'url-join';
|
||||||
import { GBMinInstance } from 'botlib';
|
import { GBMinInstance } from 'botlib-legacy';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GBLogEx } from './GBLogEx.js';
|
import { GBLogEx } from './GBLogEx.js';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
|
|
@ -125,11 +125,10 @@ export class GBSSR {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static async createBrowser(profilePath): Promise<any> {
|
public static async createBrowser(profilePath): Promise<any> {
|
||||||
const opts = await this.preparePuppeteer(profilePath);
|
const opts = await this.preparePuppeteer(profilePath);
|
||||||
puppeteer.use(hidden());
|
puppeteer.use(hidden());
|
||||||
puppeteer.use(require("puppeteer-extra-plugin-minmax")());
|
puppeteer.use(require('puppeteer-extra-plugin-minmax')());
|
||||||
const browser = await puppeteer.launch(opts);
|
const browser = await puppeteer.launch(opts);
|
||||||
return browser;
|
return browser;
|
||||||
}
|
}
|
||||||
|
|
@ -172,9 +171,6 @@ export class GBSSR {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await page.setExtraHTTPHeaders({
|
|
||||||
'ngrok-skip-browser-warning': '1'
|
|
||||||
});
|
|
||||||
const response = await page.goto(url, {
|
const response = await page.goto(url, {
|
||||||
timeout: 120000,
|
timeout: 120000,
|
||||||
waitUntil: 'networkidle0'
|
waitUntil: 'networkidle0'
|
||||||
|
|
@ -282,40 +278,35 @@ export class GBSSR {
|
||||||
let onlyChars: any = /\/([A-Za-z0-9\-\_]+)\/*/.exec(req.originalUrl);
|
let onlyChars: any = /\/([A-Za-z0-9\-\_]+)\/*/.exec(req.originalUrl);
|
||||||
onlyChars = onlyChars ? onlyChars[1] : minBoot.botId;
|
onlyChars = onlyChars ? onlyChars[1] : minBoot.botId;
|
||||||
|
|
||||||
let botId =
|
let botId = req.originalUrl && req.originalUrl === '/' ? minBoot.botId : onlyChars;
|
||||||
req.originalUrl && req.originalUrl === '/' ?
|
|
||||||
minBoot.botId :
|
|
||||||
onlyChars;
|
|
||||||
|
|
||||||
|
|
||||||
let min: GBMinInstance =
|
let min: GBMinInstance =
|
||||||
req.url === '/'
|
req.url === '/'
|
||||||
? minBoot
|
? minBoot
|
||||||
: GBServer.globals.minInstances.filter(p => p.instance.botId.toLowerCase() === botId.toLowerCase())[0];
|
: GBServer.globals.minInstances.filter(p => p.instance.botId.toLowerCase() === botId.toLowerCase())[0];
|
||||||
if (!min) {
|
if (!min) {
|
||||||
min = req.url === '/'
|
min =
|
||||||
? minBoot
|
req.url === '/'
|
||||||
: GBServer.globals.minInstances.filter(p =>
|
? minBoot
|
||||||
p.instance.activationCode ? p.instance.activationCode.toLowerCase() === botId.toLowerCase()
|
: GBServer.globals.minInstances.filter(p =>
|
||||||
: null)[0];
|
p.instance.activationCode ? p.instance.activationCode.toLowerCase() === botId.toLowerCase() : null
|
||||||
|
)[0];
|
||||||
}
|
}
|
||||||
if (!min) {
|
if (!min) {
|
||||||
botId = minBoot.botId;
|
botId = minBoot.botId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let packagePath = GBUtil.getGBAIPath(botId, `gbui`);
|
let packagePath = GBUtil.getGBAIPath(botId, `gbui`);
|
||||||
|
|
||||||
// Checks if the bot has an .gbui published or use default.gbui.
|
// Checks if the bot has an .gbui published or use default.gbui.
|
||||||
|
|
||||||
if (!await GBUtil.exists(packagePath)) {
|
if (!(await GBUtil.exists(packagePath))) {
|
||||||
packagePath = path.join(process.env.PWD, 'packages', `default.gbui`, 'build');
|
packagePath = path.join(process.env.PWD, 'packages', `default.gbui`, 'build');
|
||||||
}
|
}
|
||||||
let parts = req.url.replace(`/${botId}`, '').split('?');
|
let parts = req.url.replace(`/${botId}`, '').split('?');
|
||||||
let url = parts[0];
|
let url = parts[0];
|
||||||
|
|
||||||
if (min && req.originalUrl && prerender && exclude && await GBUtil.exists(packagePath)) {
|
if (min && req.originalUrl && prerender && exclude && (await GBUtil.exists(packagePath))) {
|
||||||
|
|
||||||
// Reads from static HTML when a bot is crawling.
|
// Reads from static HTML when a bot is crawling.
|
||||||
|
|
||||||
packagePath = path.join(process.env.PWD, 'work', packagePath, 'index.html');
|
packagePath = path.join(process.env.PWD, 'work', packagePath, 'index.html');
|
||||||
|
|
@ -323,7 +314,6 @@ export class GBSSR {
|
||||||
res.status(200).send(html);
|
res.status(200).send(html);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Servers default.gbui web application.
|
// Servers default.gbui web application.
|
||||||
|
|
||||||
packagePath = path.join(
|
packagePath = path.join(
|
||||||
|
|
@ -334,12 +324,12 @@ export class GBSSR {
|
||||||
url === '/' || url === '' ? `index.html` : url
|
url === '/' || url === '' ? `index.html` : url
|
||||||
);
|
);
|
||||||
if (GBServer.globals.wwwroot && url === '/') {
|
if (GBServer.globals.wwwroot && url === '/') {
|
||||||
packagePath = GBServer.globals.wwwroot + "/index.html"; // TODO.
|
packagePath = GBServer.globals.wwwroot + '/index.html'; // TODO.
|
||||||
}
|
}
|
||||||
if (!min && !url.startsWith("/images") && GBServer.globals.wwwroot) {
|
if (!min && !url.startsWith('/images') && GBServer.globals.wwwroot) {
|
||||||
packagePath = path.join(GBServer.globals.wwwroot, url);
|
packagePath = path.join(GBServer.globals.wwwroot, url);
|
||||||
}
|
}
|
||||||
if (!min && !url.startsWith("/static") && GBServer.globals.wwwroot) {
|
if (!min && !url.startsWith('/static') && GBServer.globals.wwwroot) {
|
||||||
packagePath = path.join(GBServer.globals.wwwroot, url);
|
packagePath = path.join(GBServer.globals.wwwroot, url);
|
||||||
}
|
}
|
||||||
if (await GBUtil.exists(packagePath)) {
|
if (await GBUtil.exists(packagePath)) {
|
||||||
|
|
@ -348,13 +338,11 @@ export class GBSSR {
|
||||||
html = html.replace(/\{p\}/gi, min.botId);
|
html = html.replace(/\{p\}/gi, min.botId);
|
||||||
html = html.replace(/\{botId\}/gi, min.botId);
|
html = html.replace(/\{botId\}/gi, min.botId);
|
||||||
|
|
||||||
const theme =
|
const theme = `theme-${await (min.core as any)['getParam'](min.instance, 'Theme Color', 'grey')}`;
|
||||||
`theme-${await (min.core as any)['getParam'](min.instance, 'Theme Color', 'grey')}`;
|
|
||||||
|
|
||||||
html = html.replace(/\{themeColor\}/gi, theme);
|
html = html.replace(/\{themeColor\}/gi, theme);
|
||||||
|
|
||||||
html = html.replace(/\{theme\}/gi, min.instance.theme ? min.instance.theme :
|
html = html.replace(/\{theme\}/gi, min.instance.theme ? min.instance.theme : 'default.gbtheme');
|
||||||
'default.gbtheme');
|
|
||||||
html = html.replace(/\{title\}/gi, min.instance.title);
|
html = html.replace(/\{title\}/gi, min.instance.title);
|
||||||
res.send(html).end();
|
res.send(html).end();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { GBMinService } from '../../core.gbapp/services/GBMinService.js';
|
import { GBMinService } from '../../core.gbapp/services/GBMinService.js';
|
||||||
import { AnalyticsService } from '../../analytics.gblib/services/AnalyticsService.js';
|
import { AnalyticsService } from '../../analytics.gblib/services/AnalyticsService.js';
|
||||||
import { SecService } from '../../security.gbapp/services/SecService.js';
|
import { SecService } from '../../security.gbapp/services/SecService.js';
|
||||||
|
|
@ -103,7 +103,6 @@ export class FeedbackDialog extends IGBDialog {
|
||||||
await min.userProfile.set(step.context, profile);
|
await min.userProfile.set(step.context, profile);
|
||||||
|
|
||||||
if (agentSystemId.indexOf('@') !== -1) {
|
if (agentSystemId.indexOf('@') !== -1) {
|
||||||
|
|
||||||
// Agent is from Teams or Google Chat.
|
// Agent is from Teams or Google Chat.
|
||||||
|
|
||||||
const agent = await sec.getUserFromSystemId(agentSystemId);
|
const agent = await sec.getUserFromSystemId(agentSystemId);
|
||||||
|
|
@ -168,8 +167,6 @@ export class FeedbackDialog extends IGBDialog {
|
||||||
|
|
||||||
await sec.updateHumanAgent(userSystemId, min.instance.instanceId, null);
|
await sec.updateHumanAgent(userSystemId, min.instance.instanceId, null);
|
||||||
await sec.updateHumanAgent(manualUser.userSystemId, min.instance.instanceId, null);
|
await sec.updateHumanAgent(manualUser.userSystemId, min.instance.instanceId, null);
|
||||||
|
|
||||||
|
|
||||||
} else if (user.agentMode === 'human') {
|
} else if (user.agentMode === 'human') {
|
||||||
const agent = await sec.getUserFromSystemId(user.agentSystemId);
|
const agent = await sec.getUserFromSystemId(user.agentSystemId);
|
||||||
|
|
||||||
|
|
@ -198,7 +195,6 @@ export class FeedbackDialog extends IGBDialog {
|
||||||
|
|
||||||
await sec.updateHumanAgent(user.userSystemId, min.instance.instanceId, null);
|
await sec.updateHumanAgent(user.userSystemId, min.instance.instanceId, null);
|
||||||
await sec.updateHumanAgent(agent.userSystemId, min.instance.instanceId, null);
|
await sec.updateHumanAgent(agent.userSystemId, min.instance.instanceId, null);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (user.userSystemId.charAt(2) === ':' || userSystemId.indexOf('@') > -1) {
|
if (user.userSystemId.charAt(2) === ':' || userSystemId.indexOf('@') > -1) {
|
||||||
// Agent is from Teams or Google Chat.
|
// Agent is from Teams or Google Chat.
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
|
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import { FeedbackDialog } from './dialogs/FeedbackDialog.js';
|
import { FeedbackDialog } from './dialogs/FeedbackDialog.js';
|
||||||
import { QualityDialog } from './dialogs/QualityDialog.js';
|
import { QualityDialog } from './dialogs/QualityDialog.js';
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
import { GoogleChatDirectLine } from './services/GoogleChatDirectLine.js';
|
import { GoogleChatDirectLine } from './services/GoogleChatDirectLine.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,8 @@
|
||||||
import Swagger from 'swagger-client';
|
import Swagger from 'swagger-client';
|
||||||
import { google } from 'googleapis';
|
import { google } from 'googleapis';
|
||||||
import { PubSub } from '@google-cloud/pubsub';
|
import { PubSub } from '@google-cloud/pubsub';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { GBLog, GBMinInstance, GBService } from 'botlib';
|
import { GBLog, GBMinInstance, GBService } from 'botlib-legacy';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { SecService } from '../../security.gbapp/services/SecService.js';
|
import { SecService } from '../../security.gbapp/services/SecService.js';
|
||||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
||||||
|
|
@ -57,7 +57,7 @@ export class GoogleChatDirectLine extends GBService {
|
||||||
GoogleClientPrivateKey: any;
|
GoogleClientPrivateKey: any;
|
||||||
GoogleProjectId: any;
|
GoogleProjectId: any;
|
||||||
|
|
||||||
constructor (
|
constructor(
|
||||||
min: GBMinInstance,
|
min: GBMinInstance,
|
||||||
botId,
|
botId,
|
||||||
directLineSecret,
|
directLineSecret,
|
||||||
|
|
@ -84,14 +84,14 @@ export class GoogleChatDirectLine extends GBService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async asyncForEach (array, callback) {
|
public static async asyncForEach(array, callback) {
|
||||||
for (let index = 0; index < array.length; index++) {
|
for (let index = 0; index < array.length; index++) {
|
||||||
await callback(array[index], index, array);
|
await callback(array[index], index, array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setup (setUrl) {
|
public async setup(setUrl) {
|
||||||
this.directLineClient = await GBUtil.getDirectLineClient(this.min);
|
this.directLineClient = await GBUtil.getDirectLineClient(this.min);
|
||||||
const client = await this.directLineClient;
|
const client = await this.directLineClient;
|
||||||
|
|
||||||
client.clientAuthorizations.add(
|
client.clientAuthorizations.add(
|
||||||
|
|
@ -109,15 +109,15 @@ export class GoogleChatDirectLine extends GBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async resetConversationId (key) {
|
public async resetConversationId(key) {
|
||||||
GoogleChatDirectLine.conversationIds[key] = undefined;
|
GoogleChatDirectLine.conversationIds[key] = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async check () {
|
public async check() {
|
||||||
GBLogEx.info(0, `GBGoogleChat: Checking server...`);
|
GBLogEx.info(0, `GBGoogleChat: Checking server...`);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async receiver (message) {
|
public async receiver(message) {
|
||||||
const event = JSON.parse(Buffer.from(message.data, 'binary').toString());
|
const event = JSON.parse(Buffer.from(message.data, 'binary').toString());
|
||||||
|
|
||||||
let from = '';
|
let from = '';
|
||||||
|
|
@ -158,7 +158,7 @@ export class GoogleChatDirectLine extends GBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public inputMessage (client, conversationId, threadName, text, from, fromName) {
|
public inputMessage(client, conversationId, threadName, text, from, fromName) {
|
||||||
return client.Conversations.Conversations_PostActivity({
|
return client.Conversations.Conversations_PostActivity({
|
||||||
conversationId: conversationId,
|
conversationId: conversationId,
|
||||||
activity: {
|
activity: {
|
||||||
|
|
@ -175,7 +175,7 @@ export class GoogleChatDirectLine extends GBService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public pollMessages (client, conversationId, threadName, from, fromName) {
|
public pollMessages(client, conversationId, threadName, from, fromName) {
|
||||||
GBLogEx.info(0, `GBGoogleChat: Starting message polling(${from}, ${conversationId}).`);
|
GBLogEx.info(0, `GBGoogleChat: Starting message polling(${from}, ${conversationId}).`);
|
||||||
|
|
||||||
let watermark: any;
|
let watermark: any;
|
||||||
|
|
@ -195,7 +195,7 @@ export class GoogleChatDirectLine extends GBService {
|
||||||
setInterval(worker, this.pollInterval);
|
setInterval(worker, this.pollInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async printMessages (activities, conversationId, threadName, from, fromName) {
|
public async printMessages(activities, conversationId, threadName, from, fromName) {
|
||||||
if (activities && activities.length) {
|
if (activities && activities.length) {
|
||||||
// Ignore own messages.
|
// Ignore own messages.
|
||||||
|
|
||||||
|
|
@ -211,7 +211,7 @@ export class GoogleChatDirectLine extends GBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async printMessage (activity, conversationId, threadName, from, fromName) {
|
public async printMessage(activity, conversationId, threadName, from, fromName) {
|
||||||
let output = '';
|
let output = '';
|
||||||
|
|
||||||
if (activity.text) {
|
if (activity.text) {
|
||||||
|
|
@ -235,14 +235,14 @@ export class GoogleChatDirectLine extends GBService {
|
||||||
await this.sendToDevice(from, conversationId, threadName, output);
|
await this.sendToDevice(from, conversationId, threadName, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async sendToDevice (from: string, conversationId: string, threadName, msg: string) {
|
public async sendToDevice(from: string, conversationId: string, threadName, msg: string) {
|
||||||
try {
|
try {
|
||||||
let threadParts = threadName.split('/');
|
let threadParts = threadName.split('/');
|
||||||
let spaces = threadParts[1];
|
let spaces = threadParts[1];
|
||||||
let threadKey = threadParts[3];
|
let threadKey = threadParts[3];
|
||||||
const scopes = ['https://www.googleapis.com/auth/chat.bot'];
|
const scopes = ['https://www.googleapis.com/auth/chat.bot'];
|
||||||
|
|
||||||
const jwtClient = new google.auth.JWT(this.GoogleClientEmail, null, this.GoogleClientPrivateKey, scopes, null);
|
const jwtClient = new google.auth.JWT(this.GoogleClientEmail);
|
||||||
await jwtClient.authorize();
|
await jwtClient.authorize();
|
||||||
const chat = google.chat({ version: 'v1', auth: jwtClient });
|
const chat = google.chat({ version: 'v1', auth: jwtClient });
|
||||||
|
|
||||||
|
|
@ -253,14 +253,14 @@ export class GoogleChatDirectLine extends GBService {
|
||||||
text: msg
|
text: msg
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
GBLogEx.info(0, `Message [${msg}] sent to ${from}: `);
|
GBLogEx.info(0, `Message [${msg}] sent to ${from}: `);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
GBLog.error(`Error sending message to GoogleChat provider ${error.message}`);
|
GBLog.error(`Error sending message to GoogleChat provider ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async sendToDeviceEx (to, conversationId, threadName, text, locale) {
|
public async sendToDeviceEx(to, conversationId, threadName, text, locale) {
|
||||||
const minBoot = GBServer.globals.minBoot as any;
|
const minBoot = GBServer.globals.minBoot as any;
|
||||||
|
|
||||||
text = await minBoot.conversationalService.translate(minBoot, text, locale);
|
text = await minBoot.conversationalService.translate(minBoot, text, locale);
|
||||||
|
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
/*****************************************************************************\
|
|
||||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
|
||||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
|
||||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
|
||||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
|
||||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
|
||||||
| |
|
|
||||||
| General Bots Copyright (c) pragmatismo.com.br. All rights reserved. |
|
|
||||||
| Licensed under the AGPL-3.0. |
|
|
||||||
| |
|
|
||||||
| According to our dual licensing model, this program can be used either |
|
|
||||||
| under the terms of the GNU Affero General Public License, version 3, |
|
|
||||||
| or under a proprietary license. |
|
|
||||||
| |
|
|
||||||
| The texts of the GNU Affero General Public License with an additional |
|
|
||||||
| permission and of our proprietary license can be found at and |
|
|
||||||
| in the LICENSE file you have received along with this program. |
|
|
||||||
| |
|
|
||||||
| This program is distributed in the hope that it will be useful, |
|
|
||||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
|
||||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
||||||
| GNU Affero General Public License for more details. |
|
|
||||||
| |
|
|
||||||
| "General Bots" is a registered trademark of pragmatismo.com.br. |
|
|
||||||
| The licensing of the program under the AGPLv3 does not imply a |
|
|
||||||
| trademark license. Therefore any rights, title and interest in |
|
|
||||||
| our trademarks remain entirely with us. |
|
|
||||||
| |
|
|
||||||
\*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @fileoverview General Bots server core.
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Package for GoogleChat.gblib
|
|
||||||
*/
|
|
||||||
export class GBHubSpotPackage implements IGBPackage {
|
|
||||||
public sysPackages: IGBPackage[];
|
|
||||||
|
|
||||||
public async loadBot(min: GBMinInstance): Promise<void> {
|
|
||||||
GBLog.verbose(`loadBot called.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getDialogs(min: GBMinInstance) {
|
|
||||||
GBLog.verbose(`getDialogs called.`);
|
|
||||||
}
|
|
||||||
public async loadPackage(core: IGBCoreService, sequelize: Sequelize): Promise<void> {
|
|
||||||
GBLog.verbose(`loadPackage called.`);
|
|
||||||
}
|
|
||||||
public async unloadPackage(core: IGBCoreService): Promise<void> {
|
|
||||||
GBLog.verbose(`unloadPackage called.`);
|
|
||||||
}
|
|
||||||
public async unloadBot(min: GBMinInstance): Promise<void> {
|
|
||||||
GBLog.verbose(`unloadBot called.`);
|
|
||||||
}
|
|
||||||
public async onNewSession(min: GBMinInstance, step: GBDialogStep): Promise<void> {
|
|
||||||
GBLog.verbose(`onNewSession called.`);
|
|
||||||
}
|
|
||||||
public async onExchangeData(min: GBMinInstance, kind: string, data: any) {
|
|
||||||
GBLog.verbose(`onExchangeData called.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
/*****************************************************************************\
|
|
||||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
|
||||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
|
||||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
|
||||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
|
||||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
|
||||||
| |
|
|
||||||
| General Bots Copyright (c) pragmatismo.com.br. All rights reserved. |
|
|
||||||
| Licensed under the AGPL-3.0. |
|
|
||||||
| |
|
|
||||||
| According to our dual licensing model, this program can be used either |
|
|
||||||
| under the terms of the GNU Affero General Public License, version 3, |
|
|
||||||
| or under a proprietary license. |
|
|
||||||
| |
|
|
||||||
| The texts of the GNU Affero General Public License with an additional |
|
|
||||||
| permission and of our proprietary license can be found at and |
|
|
||||||
| in the LICENSE file you have received along with this program. |
|
|
||||||
| |
|
|
||||||
| This program is distributed in the hope that it will be useful, |
|
|
||||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
|
||||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
||||||
| GNU Affero General Public License for more details. |
|
|
||||||
| |
|
|
||||||
| "General Bots" is a registered trademark of pragmatismo.com.br. |
|
|
||||||
| The licensing of the program under the AGPLv3 does not imply a |
|
|
||||||
| trademark license. Therefore any rights, title and interest in |
|
|
||||||
| our trademarks remain entirely with us. |
|
|
||||||
| |
|
|
||||||
\*****************************************************************************/
|
|
||||||
|
|
||||||
import { GBLog, GBMinInstance, GBService } from 'botlib';
|
|
||||||
import { promisify } from 'util';
|
|
||||||
import Swagger from 'swagger-client';
|
|
||||||
import * as hubspot from '@hubspot/api-client';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support for Hub Spot XRM.
|
|
||||||
*/
|
|
||||||
export class HubSpotServices extends GBService { }
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
export const Messages = {
|
|
||||||
'en-US': {},
|
|
||||||
'pt-BR': {}
|
|
||||||
};
|
|
||||||
|
|
@ -37,12 +37,12 @@
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBLog, GBMinInstance, IGBDialog, IGBPackage } from 'botlib';
|
import { GBLog, GBMinInstance, IGBDialog, IGBPackage } from 'botlib-legacy';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { KBService } from './../services/KBService.js';
|
import { KBService } from './../services/KBService.js';
|
||||||
import { GuaribasAnswer } from '../models/index.js';
|
import { GuaribasAnswer } from '../models/index.js';
|
||||||
import { SecService } from '../../security.gbapp/services/SecService.js';
|
import { SecService } from '../../security.gbapp/services/SecService.js';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
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';
|
||||||
|
|
@ -140,7 +140,7 @@ export class AskDialog extends IGBDialog {
|
||||||
message: text,
|
message: text,
|
||||||
user: user ? user['dataValues'] : null
|
user: user ? user['dataValues'] : null
|
||||||
};
|
};
|
||||||
await CollectionUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
await GBUtil.asyncForEach(min.appPackages, async (e: IGBPackage) => {
|
||||||
if ((nextDialog = await e.onExchangeData(min, 'handleAnswer', data))) {
|
if ((nextDialog = await e.onExchangeData(min, 'handleAnswer', data))) {
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
|
|
@ -174,10 +174,7 @@ export class AskDialog extends IGBDialog {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async step => {
|
async step => {
|
||||||
|
min = GBServer.globals.minInstances.find(p => p.botId === min.botId);
|
||||||
|
|
||||||
min = GBServer.globals.minInstances.find(p=> p.botId === min.botId);
|
|
||||||
|
|
||||||
|
|
||||||
let answer;
|
let answer;
|
||||||
const member = step.context.activity.from;
|
const member = step.context.activity.from;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
import { BotAdapter } from 'botbuilder';
|
import { BotAdapter } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { KBService } from './../services/KBService.js';
|
import { KBService } from './../services/KBService.js';
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ import urlJoin from 'url-join';
|
||||||
|
|
||||||
import { BotAdapter, CardFactory, MessageFactory } from 'botbuilder';
|
import { BotAdapter, CardFactory, MessageFactory } from 'botbuilder';
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBMinInstance, IGBDialog } from 'botlib';
|
import { GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
||||||
import { GuaribasSubject } from '../models/index.js';
|
import { GuaribasSubject } from '../models/index.js';
|
||||||
import { KBService } from '../services/KBService.js';
|
import { KBService } from '../services/KBService.js';
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
import { AskDialog } from './dialogs/AskDialog.js';
|
import { AskDialog } from './dialogs/AskDialog.js';
|
||||||
import { FaqDialog } from './dialogs/FaqDialog.js';
|
import { FaqDialog } from './dialogs/FaqDialog.js';
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ import { CSVLoader } from '@langchain/community/document_loaders/fs/csv';
|
||||||
import { DocxLoader } from '@langchain/community/document_loaders/fs/docx';
|
import { DocxLoader } from '@langchain/community/document_loaders/fs/docx';
|
||||||
import { EPubLoader } from '@langchain/community/document_loaders/fs/epub';
|
import { EPubLoader } from '@langchain/community/document_loaders/fs/epub';
|
||||||
import { PDFLoader } from '@langchain/community/document_loaders/fs/pdf';
|
import { PDFLoader } from '@langchain/community/document_loaders/fs/pdf';
|
||||||
import svg2img from 'svg2img';
|
|
||||||
import isICO from 'icojs';
|
import isICO from 'icojs';
|
||||||
import getColors from 'get-image-colors';
|
import getColors from 'get-image-colors';
|
||||||
import { Document } from 'langchain/document';
|
import { Document } from 'langchain/document';
|
||||||
|
|
@ -62,18 +62,15 @@ import {
|
||||||
IGBCoreService,
|
IGBCoreService,
|
||||||
IGBInstance,
|
IGBInstance,
|
||||||
IGBKBService
|
IGBKBService
|
||||||
} from 'botlib';
|
} from 'botlib-legacy';
|
||||||
import mammoth from 'mammoth';
|
import mammoth from 'mammoth';
|
||||||
import { parse } from 'node-html-parser';
|
import { parse } from 'node-html-parser';
|
||||||
import pdf from 'pdf-extraction';
|
import pdf from 'pdf-extraction';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { Op } from 'sequelize';
|
import { Op } from 'sequelize';
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
import textract from 'textract';
|
|
||||||
import { GBUtil } from '../../../src/util.js';
|
import { GBUtil } from '../../../src/util.js';
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
import { AzureDeployerService } from '../../azuredeployer.gbapp/services/AzureDeployerService.js';
|
|
||||||
import webp from 'webp-converter';
|
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
||||||
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
||||||
|
|
@ -88,6 +85,29 @@ import { GuaribasAnswer, GuaribasQuestion, GuaribasSubject } from '../models/ind
|
||||||
import { GBConfigService } from './../../core.gbapp/services/GBConfigService.js';
|
import { GBConfigService } from './../../core.gbapp/services/GBConfigService.js';
|
||||||
import { exec } from 'child_process';
|
import { exec } from 'child_process';
|
||||||
|
|
||||||
|
let webp: any = null;
|
||||||
|
try {
|
||||||
|
webp = await import('webp-converter');
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
let svg2img: any = null;
|
||||||
|
try {
|
||||||
|
const svg2imgModule = await import('svg2img');
|
||||||
|
svg2img = svg2imgModule.default || svg2imgModule;
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
let getColors: any = null;
|
||||||
|
try {
|
||||||
|
const getColorsModule = await import('get-image-colors');
|
||||||
|
getColors = getColorsModule.default || getColorsModule;
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
let textract: any = null;
|
||||||
|
try {
|
||||||
|
const textractModule = await import('textract');
|
||||||
|
textract = textractModule.default || textractModule;
|
||||||
|
} catch {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result for quey on KB data.
|
* Result for quey on KB data.
|
||||||
*/
|
*/
|
||||||
|
|
@ -624,7 +644,7 @@ export class KBService implements IGBKBService {
|
||||||
const answersCreated = await GuaribasAnswer.bulkCreate(answers);
|
const answersCreated = await GuaribasAnswer.bulkCreate(answers);
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
await CollectionUtil.asyncForEach(questions, async question => {
|
await GBUtil.asyncForEach(questions, async question => {
|
||||||
question.answerId = answersCreated[i++].answerId;
|
question.answerId = answersCreated[i++].answerId;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -656,22 +676,19 @@ export class KBService implements IGBKBService {
|
||||||
} else if (answer.endsWith('.ogg') && process.env.AUDIO_DISABLED !== 'true') {
|
} else if (answer.endsWith('.ogg') && process.env.AUDIO_DISABLED !== 'true') {
|
||||||
await this.playAudio(min, answer, channel, step, min.conversationalService);
|
await this.playAudio(min, answer, channel, step, min.conversationalService);
|
||||||
} else if (answer.startsWith('![')) {
|
} else if (answer.startsWith('![')) {
|
||||||
|
|
||||||
// Checks for text after the image markdown, after the element 4, there are text blocks.
|
// Checks for text after the image markdown, after the element 4, there are text blocks.
|
||||||
|
|
||||||
const removeMarkdownImages = (text: string) => {
|
const removeMarkdownImages = (text: string) => {
|
||||||
return text.replace(/!\[[^\]]*\](?:\([^)]*\)|\[[^\]]*\])/g, '').trim();
|
return text.replace(/!\[[^\]]*\](?:\([^)]*\)|\[[^\]]*\])/g, '').trim();
|
||||||
}
|
};
|
||||||
|
|
||||||
if (removeMarkdownImages(answer)) {
|
if (removeMarkdownImages(answer)) {
|
||||||
await min.conversationalService.sendText(min, step, answer);
|
await min.conversationalService.sendText(min, step, answer);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
const urlMatch = answer.match(/!?\[.*?\]\((.*?)\)/);
|
const urlMatch = answer.match(/!?\[.*?\]\((.*?)\)/);
|
||||||
const url = urlMatch ? urlMatch[1] : null;
|
const url = urlMatch ? urlMatch[1] : null;
|
||||||
await this.showImage(min, min.conversationalService, step, url, channel)
|
await this.showImage(min, min.conversationalService, step, url, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
await min.conversationalService.sendText(min, step, answer);
|
await min.conversationalService.sendText(min, step, answer);
|
||||||
}
|
}
|
||||||
|
|
@ -713,7 +730,6 @@ export class KBService implements IGBKBService {
|
||||||
packageStorage: GuaribasPackage,
|
packageStorage: GuaribasPackage,
|
||||||
instance: IGBInstance
|
instance: IGBInstance
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
|
|
||||||
// Imports subjects tree into database and return it.
|
// Imports subjects tree into database and return it.
|
||||||
|
|
||||||
const subjectFile = urlJoin(localPath, 'subjects.json');
|
const subjectFile = urlJoin(localPath, 'subjects.json');
|
||||||
|
|
@ -750,7 +766,7 @@ export class KBService implements IGBKBService {
|
||||||
const files = await walkPromise(urlJoin(localPath, 'articles'));
|
const files = await walkPromise(urlJoin(localPath, 'articles'));
|
||||||
const data = { questions: [], answers: [] };
|
const data = { questions: [], answers: [] };
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(files, async file => {
|
await GBUtil.asyncForEach(files, async file => {
|
||||||
if (file !== null && file.name.endsWith('.md')) {
|
if (file !== null && file.name.endsWith('.md')) {
|
||||||
let content = await this.getAnswerTextByMediaName(instance.instanceId, file.name);
|
let content = await this.getAnswerTextByMediaName(instance.instanceId, file.name);
|
||||||
|
|
||||||
|
|
@ -885,7 +901,7 @@ export class KBService implements IGBKBService {
|
||||||
|
|
||||||
const answersCreated = await GuaribasAnswer.bulkCreate(data.answers);
|
const answersCreated = await GuaribasAnswer.bulkCreate(data.answers);
|
||||||
let i = 0;
|
let i = 0;
|
||||||
await CollectionUtil.asyncForEach(data.questions, async question => {
|
await GBUtil.asyncForEach(data.questions, async question => {
|
||||||
question.answerId = answersCreated[i++].answerId;
|
question.answerId = answersCreated[i++].answerId;
|
||||||
});
|
});
|
||||||
return await GuaribasQuestion.bulkCreate(data.questions);
|
return await GuaribasQuestion.bulkCreate(data.questions);
|
||||||
|
|
@ -899,11 +915,12 @@ export class KBService implements IGBKBService {
|
||||||
depth: number,
|
depth: number,
|
||||||
maxDepth: number,
|
maxDepth: number,
|
||||||
page: Page,
|
page: Page,
|
||||||
websiteIgnoreUrls, maxDocuments: number
|
websiteIgnoreUrls,
|
||||||
|
maxDocuments: number
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
(maxDocuments < visited.size) ||
|
maxDocuments < visited.size ||
|
||||||
(depth > maxDepth && !url.endsWith('pdf')) ||
|
(depth > maxDepth && !url.endsWith('pdf')) ||
|
||||||
visited.has(url) ||
|
visited.has(url) ||
|
||||||
url.endsWith('.jpg') ||
|
url.endsWith('.jpg') ||
|
||||||
|
|
@ -970,8 +987,7 @@ export class KBService implements IGBKBService {
|
||||||
|
|
||||||
const childLinks = [];
|
const childLinks = [];
|
||||||
for (const link of filteredLinks) {
|
for (const link of filteredLinks) {
|
||||||
const links = await this.crawl(min, link,
|
const links = await this.crawl(min, link, visited, depth + 1, maxDepth, page, websiteIgnoreUrls, maxDocuments);
|
||||||
visited, depth + 1, maxDepth, page, websiteIgnoreUrls, maxDocuments);
|
|
||||||
if (links) {
|
if (links) {
|
||||||
childLinks.push(...links);
|
childLinks.push(...links);
|
||||||
}
|
}
|
||||||
|
|
@ -1037,7 +1053,6 @@ export class KBService implements IGBKBService {
|
||||||
executablePath: process.env.CHROME_PATH ? process.env.CHROME_PATH : executablePath(),
|
executablePath: process.env.CHROME_PATH ? process.env.CHROME_PATH : executablePath(),
|
||||||
args
|
args
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
try {
|
try {
|
||||||
|
|
@ -1068,7 +1083,10 @@ export class KBService implements IGBKBService {
|
||||||
const MAX_DOCUMENTS = 15;
|
const MAX_DOCUMENTS = 15;
|
||||||
const maxDocuments = min.core.getParam<number>(min.instance, 'Website Max Documents', MAX_DOCUMENTS);
|
const maxDocuments = min.core.getParam<number>(min.instance, 'Website Max Documents', MAX_DOCUMENTS);
|
||||||
const websiteIgnoreUrls = min.core.getParam<[]>(min.instance, 'Website Ignore URLs', null);
|
const websiteIgnoreUrls = min.core.getParam<[]>(min.instance, 'Website Ignore URLs', null);
|
||||||
GBLogEx.info(min, `Website: ${website}, Max Depth: ${maxDepth}, Website Max Documents: ${maxDocuments}, Ignore URLs: ${websiteIgnoreUrls}`);
|
GBLogEx.info(
|
||||||
|
min,
|
||||||
|
`Website: ${website}, Max Depth: ${maxDepth}, Website Max Documents: ${maxDocuments}, Ignore URLs: ${websiteIgnoreUrls}`
|
||||||
|
);
|
||||||
|
|
||||||
let shouldSave = false;
|
let shouldSave = false;
|
||||||
|
|
||||||
|
|
@ -1104,8 +1122,7 @@ export class KBService implements IGBKBService {
|
||||||
|
|
||||||
const baseUrl = page.url().split('/').slice(0, 3).join('/');
|
const baseUrl = page.url().split('/').slice(0, 3).join('/');
|
||||||
|
|
||||||
logo = logo.startsWith('//') ? 'https:' + logo : (
|
logo = logo.startsWith('//') ? 'https:' + logo : logo.startsWith('https') ? logo : urlJoin(baseUrl, logo);
|
||||||
logo.startsWith('https') ? logo : urlJoin(baseUrl, logo));
|
|
||||||
|
|
||||||
const logoBinary = await page.goto(logo);
|
const logoBinary = await page.goto(logo);
|
||||||
let buffer = await logoBinary.buffer();
|
let buffer = await logoBinary.buffer();
|
||||||
|
|
@ -1126,7 +1143,7 @@ export class KBService implements IGBKBService {
|
||||||
await fs.writeFile(tempAvif, buffer);
|
await fs.writeFile(tempAvif, buffer);
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
exec(`node_modules/ffmpeg-static/ffmpeg -i "${tempAvif}" "${tempPng}"`, (error) => {
|
exec(`node_modules/ffmpeg-static/ffmpeg -i "${tempAvif}" "${tempPng}"`, error => {
|
||||||
if (error) reject(error);
|
if (error) reject(error);
|
||||||
else resolve(null);
|
else resolve(null);
|
||||||
});
|
});
|
||||||
|
|
@ -1134,40 +1151,42 @@ export class KBService implements IGBKBService {
|
||||||
buffer = await fs.readFile(tempPng);
|
buffer = await fs.readFile(tempPng);
|
||||||
|
|
||||||
// Clean up temp files
|
// Clean up temp files
|
||||||
await fs.unlink(tempAvif).catch(() => { });
|
await fs.unlink(tempAvif).catch(() => {});
|
||||||
await fs.unlink(tempPng).catch(() => { });
|
await fs.unlink(tempPng).catch(() => {});
|
||||||
|
} else if (
|
||||||
} else if (buffer.slice(0, 4).toString('hex') === '52494646' &&
|
buffer.slice(0, 4).toString('hex') === '52494646' &&
|
||||||
buffer.slice(8, 12).toString('hex') === '57454250') {
|
buffer.slice(8, 12).toString('hex') === '57454250'
|
||||||
|
) {
|
||||||
// Convert WebP to PNG using temporary files
|
// Convert WebP to PNG using temporary files
|
||||||
const tempWebP = path.join(os.tmpdir(), `temp-${Date.now()}.webp`);
|
const tempWebP = path.join(os.tmpdir(), `temp-${Date.now()}.webp`);
|
||||||
const tempPNG = path.join(os.tmpdir(), `temp-${Date.now()}.png`);
|
const tempPNG = path.join(os.tmpdir(), `temp-${Date.now()}.png`);
|
||||||
|
|
||||||
await fs.writeFile(tempWebP, buffer);
|
await fs.writeFile(tempWebP, buffer);
|
||||||
await webp.dwebp(tempWebP, tempPNG, "-o");
|
await webp.dwebp(tempWebP, tempPNG, '-o');
|
||||||
|
|
||||||
buffer = await fs.readFile(tempPNG);
|
buffer = await fs.readFile(tempPNG);
|
||||||
|
|
||||||
} else if (buffer.toString().includes('<svg')) {
|
} else if (buffer.toString().includes('<svg')) {
|
||||||
|
|
||||||
// For SVG files, convert using svg2img
|
// For SVG files, convert using svg2img
|
||||||
|
|
||||||
buffer = await new Promise((resolve, reject) => {
|
buffer = await new Promise((resolve, reject) => {
|
||||||
svg2img(buffer, {
|
svg2img(
|
||||||
resvg: {
|
buffer,
|
||||||
fitTo: {
|
{
|
||||||
mode: 'width', // or height
|
resvg: {
|
||||||
value: 48,
|
fitTo: {
|
||||||
},
|
mode: 'width', // or height
|
||||||
|
value: 48
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error: any, buffer: Buffer) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
} else {
|
||||||
|
resolve(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, (error: any, buffer: Buffer) => {
|
);
|
||||||
if (error) {
|
|
||||||
reject(error);
|
|
||||||
} else {
|
|
||||||
resolve(buffer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1179,11 +1198,10 @@ export class KBService implements IGBKBService {
|
||||||
const logoPath = path.join(packagePath, 'cache', logoFilename);
|
const logoPath = path.join(packagePath, 'cache', logoFilename);
|
||||||
await (image as any).write(logoPath);
|
await (image as any).write(logoPath);
|
||||||
await min.core['setConfig'](min, 'Logo', logoFilename);
|
await min.core['setConfig'](min, 'Logo', logoFilename);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract dominant colors from the screenshot
|
// Extract dominant colors from the screenshot
|
||||||
page = await this.getFreshPage(browser, website);
|
page = await this.getFreshPage(browser, website);
|
||||||
|
|
||||||
await page.screenshot({ path: 'screenshot.png' });
|
await page.screenshot({ path: 'screenshot.png' });
|
||||||
const colors = await getColors('screenshot.png');
|
const colors = await getColors('screenshot.png');
|
||||||
|
|
@ -1208,25 +1226,22 @@ export class KBService implements IGBKBService {
|
||||||
page.setCacheEnabled(false);
|
page.setCacheEnabled(false);
|
||||||
|
|
||||||
const visited = new Set<string>();
|
const visited = new Set<string>();
|
||||||
page = await this.getFreshPage(browser, website);
|
page = await this.getFreshPage(browser, website);
|
||||||
|
|
||||||
files = files.concat(await this.crawl(min, website, visited, 0, maxDepth, page, websiteIgnoreUrls, maxDocuments));
|
files = files.concat(await this.crawl(min, website, visited, 0, maxDepth, page, websiteIgnoreUrls, maxDocuments));
|
||||||
|
|
||||||
await browser.close();
|
await browser.close();
|
||||||
|
|
||||||
|
|
||||||
GBLogEx.info(min, `Vectorizing ${files.length} file(s)...`);
|
GBLogEx.info(min, `Vectorizing ${files.length} file(s)...`);
|
||||||
|
|
||||||
if (await GBUtil.exists(min['vectorStorePath'])) {
|
if (await GBUtil.exists(min['vectorStorePath'])) {
|
||||||
|
GBLogEx.info(min, `Cleaning vector store: ${min['vectorStorePath']}...`);
|
||||||
GBLogEx.info(min, `Cleaning vector store: ${min['vectorStorePath']}...`)
|
|
||||||
const gbkbPath = GBUtil.getGBAIPath(min.botId, 'gbkb');
|
const gbkbPath = GBUtil.getGBAIPath(min.botId, 'gbkb');
|
||||||
min['vectorStorePath'] = path.join('work', gbkbPath, 'docs-vectorized');
|
min['vectorStorePath'] = path.join('work', gbkbPath, 'docs-vectorized');
|
||||||
min['vectorStore'] = await min.deployService['loadOrCreateEmptyVectorStore'](min);
|
min['vectorStore'] = await min.deployService['loadOrCreateEmptyVectorStore'](min);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(files, async file => {
|
await GBUtil.asyncForEach(files, async file => {
|
||||||
let content = null;
|
let content = null;
|
||||||
shouldSave = true;
|
shouldSave = true;
|
||||||
|
|
||||||
|
|
@ -1238,16 +1253,13 @@ export class KBService implements IGBKBService {
|
||||||
GBLogEx.info(min, `Ignore processing of ${file}. ${GBUtil.toYAML(error)}`);
|
GBLogEx.info(min, `Ignore processing of ${file}. ${GBUtil.toYAML(error)}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GBLogEx.info(min, `Added ${files.length} from site...`);
|
GBLogEx.info(min, `Added ${files.length} from site...`);
|
||||||
|
|
||||||
files = await walkPromise(urlJoin(localPath, 'docs'));
|
files = await walkPromise(urlJoin(localPath, 'docs'));
|
||||||
|
|
||||||
GBLogEx.info(min, `Add ${files.length} files being processed...`);
|
GBLogEx.info(min, `Add ${files.length} files being processed...`);
|
||||||
|
|
||||||
|
|
||||||
// const gbdrive = path.join(process.env.PWD, 'work', GBUtil.getGBAIPath(min.botId, 'gbdrive'));
|
// const gbdrive = path.join(process.env.PWD, 'work', GBUtil.getGBAIPath(min.botId, 'gbdrive'));
|
||||||
// files = files.concat(await walkPromise(gbdrive));
|
// files = files.concat(await walkPromise(gbdrive));
|
||||||
|
|
@ -1256,26 +1268,26 @@ export class KBService implements IGBKBService {
|
||||||
files = files.concat(await walkPromise(gbdata));
|
files = files.concat(await walkPromise(gbdata));
|
||||||
|
|
||||||
if (files[0]) {
|
if (files[0]) {
|
||||||
|
files = files.filter(p => {
|
||||||
files = files.filter(p => { return p });
|
return p;
|
||||||
|
});
|
||||||
shouldSave = true;
|
shouldSave = true;
|
||||||
GBLogEx.info(min, `Add embeddings from packages, ${files.length} files being processed...`);
|
GBLogEx.info(min, `Add embeddings from packages, ${files.length} files being processed...`);
|
||||||
await CollectionUtil.asyncForEach(files, async file => {
|
await GBUtil.asyncForEach(files, async file => {
|
||||||
|
|
||||||
let filePath = typeof file === 'string' ? file : path.join(file.root, file.name);
|
let filePath = typeof file === 'string' ? file : path.join(file.root, file.name);
|
||||||
|
|
||||||
if (filePath) {
|
|
||||||
|
|
||||||
|
if (filePath) {
|
||||||
let content = null;
|
let content = null;
|
||||||
let filePath = path.join(file.root, file.name);
|
let filePath = path.join(file.root, file.name);
|
||||||
try {
|
try {
|
||||||
|
if (
|
||||||
if (file.name.endsWith('.csv') || file.name.endsWith('.md')
|
file.name.endsWith('.csv') ||
|
||||||
|| file.name.endsWith('.pdf') || file.name.endsWith('.docx') ||
|
file.name.endsWith('.md') ||
|
||||||
file.name.endsWith('.epub') || file.name.endsWith('.txt')
|
file.name.endsWith('.pdf') ||
|
||||||
|
file.name.endsWith('.docx') ||
|
||||||
|
file.name.endsWith('.epub') ||
|
||||||
|
file.name.endsWith('.txt')
|
||||||
) {
|
) {
|
||||||
|
|
||||||
if (file.name.endsWith('.csv')) {
|
if (file.name.endsWith('.csv')) {
|
||||||
// Read first 1000 lines of CSV file
|
// Read first 1000 lines of CSV file
|
||||||
const csvContent = await fs.readFile(filePath, 'utf8');
|
const csvContent = await fs.readFile(filePath, 'utf8');
|
||||||
|
|
@ -1301,8 +1313,6 @@ export class KBService implements IGBKBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
defaultRecursiveCharacterTextSplitter = new RecursiveCharacterTextSplitter({
|
defaultRecursiveCharacterTextSplitter = new RecursiveCharacterTextSplitter({
|
||||||
chunkSize: 700,
|
chunkSize: 700,
|
||||||
chunkOverlap: 50
|
chunkOverlap: 50
|
||||||
|
|
@ -1363,7 +1373,7 @@ export class KBService implements IGBKBService {
|
||||||
public async importKbTabularDirectory(localPath: string, min: GBMinInstance, packageId: number): Promise<any> {
|
public async importKbTabularDirectory(localPath: string, min: GBMinInstance, packageId: number): Promise<any> {
|
||||||
const files = await walkPromise(localPath);
|
const files = await walkPromise(localPath);
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(files, async file => {
|
await GBUtil.asyncForEach(files, async file => {
|
||||||
if (file !== null && (file.name.endsWith('.xlsx') || file.name.endsWith('.csv'))) {
|
if (file !== null && (file.name.endsWith('.xlsx') || file.name.endsWith('.csv'))) {
|
||||||
return await this.importKbTabularFile(urlJoin(file.root, file.name), min, packageId);
|
return await this.importKbTabularFile(urlJoin(file.root, file.name), min, packageId);
|
||||||
}
|
}
|
||||||
|
|
@ -1494,7 +1504,7 @@ export class KBService implements IGBKBService {
|
||||||
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
||||||
);
|
);
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(questions, async question => {
|
await GBUtil.asyncForEach(questions, async question => {
|
||||||
const text = question.content;
|
const text = question.content;
|
||||||
|
|
||||||
const categoryReg = /.*\((.*)\).*/gi.exec(text);
|
const categoryReg = /.*\((.*)\).*/gi.exec(text);
|
||||||
|
|
@ -1529,11 +1539,6 @@ export class KBService implements IGBKBService {
|
||||||
await this.importKbPackage(min, localPath, p, instance);
|
await this.importKbPackage(min, localPath, p, instance);
|
||||||
GBDeployer.mountGBKBAssets(packageName, min.botId, localPath);
|
GBDeployer.mountGBKBAssets(packageName, min.botId, localPath);
|
||||||
|
|
||||||
if (GBConfigService.get('GB_MODE') === 'legacy') {
|
|
||||||
const service = await AzureDeployerService.createInstance(deployer);
|
|
||||||
const searchIndex = instance.searchIndex ? instance.searchIndex : GBServer.globals.minBoot.instance.searchIndex;
|
|
||||||
await deployer.rebuildIndex(instance, service.getKBSearchSchema(searchIndex));
|
|
||||||
}
|
|
||||||
min['groupCache'] = await KBService.getGroupReplies(instance.instanceId);
|
min['groupCache'] = await KBService.getGroupReplies(instance.instanceId);
|
||||||
await KBService.RefreshNER(min);
|
await KBService.RefreshNER(min);
|
||||||
|
|
||||||
|
|
@ -1669,7 +1674,6 @@ export class KBService implements IGBKBService {
|
||||||
|
|
||||||
return filePath; // Return the saved file path
|
return filePath; // Return the saved file path
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const parsedUrl = new URL(url);
|
const parsedUrl = new URL(url);
|
||||||
|
|
||||||
// Get the last part of the URL path or default to 'index' if empty
|
// Get the last part of the URL path or default to 'index' if empty
|
||||||
|
|
@ -1688,7 +1692,7 @@ export class KBService implements IGBKBService {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
request.abort().catch(() => {
|
request.abort().catch(() => {
|
||||||
// Ignore errors from requests that were already handled
|
// Ignore errors from requests that were already handled
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
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';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,15 +47,15 @@ import {
|
||||||
import { RunnableSequence } from '@langchain/core/runnables';
|
import { RunnableSequence } from '@langchain/core/runnables';
|
||||||
import { DynamicStructuredTool } from '@langchain/core/tools';
|
import { DynamicStructuredTool } from '@langchain/core/tools';
|
||||||
import { convertToOpenAITool } from '@langchain/core/utils/function_calling';
|
import { convertToOpenAITool } from '@langchain/core/utils/function_calling';
|
||||||
import { ChatOpenAI } from '@langchain/openai';
|
import { AzureOpenAI, ChatOpenAI } from '@langchain/openai';
|
||||||
import { SqlDatabase } from 'langchain/sql_db';
|
import { SqlDatabase } from 'langchain/sql_db';
|
||||||
import { DataSource } from 'typeorm';
|
import { DataSource } from 'typeorm';
|
||||||
import { GBMinInstance } from 'botlib';
|
import { GBMinInstance } from 'botlib-legacy';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import { BufferWindowMemory } from 'langchain/memory';
|
import { BufferWindowMemory } from 'langchain/memory';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { getDocument } from 'pdfjs-dist/legacy/build/pdf.mjs';
|
import { getDocument } from 'pdfjs-dist/legacy/build/pdf.mjs';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
||||||
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
||||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
||||||
|
|
@ -137,7 +137,7 @@ export class GBLLMOutputParser extends BaseLLMOutputParser<ExpectedOutput> {
|
||||||
if (!sources) {
|
if (!sources) {
|
||||||
GBLogEx.verbose(this.min, `LLM JSON output sources is NULL.`);
|
GBLogEx.verbose(this.min, `LLM JSON output sources is NULL.`);
|
||||||
} else {
|
} else {
|
||||||
await CollectionUtil.asyncForEach(sources, async source => {
|
await GBUtil.asyncForEach(sources, async source => {
|
||||||
let found = false;
|
let found = false;
|
||||||
|
|
||||||
if (securityEnabled) {
|
if (securityEnabled) {
|
||||||
|
|
@ -281,12 +281,6 @@ export class ChatServices {
|
||||||
model = new ChatOpenAI({
|
model = new ChatOpenAI({
|
||||||
model: process.env.LOCAL_LLM_MODEL,
|
model: process.env.LOCAL_LLM_MODEL,
|
||||||
apiKey: 'empty',
|
apiKey: 'empty',
|
||||||
azureOpenAIApiDeploymentName: 'v1',
|
|
||||||
azureOpenAIApiInstanceName: 'v1',
|
|
||||||
azureOpenAIApiKey: 'empty',
|
|
||||||
azureOpenAIApiVersion: 'empty',
|
|
||||||
azureOpenAIBasePath: process.env.LOCAL_LLM_ENDPOINT,
|
|
||||||
openAIApiKey: 'empty',
|
|
||||||
configuration: {
|
configuration: {
|
||||||
baseURL: process.env.LOCAL_LLM_ENDPOINT
|
baseURL: process.env.LOCAL_LLM_ENDPOINT
|
||||||
}
|
}
|
||||||
|
|
@ -298,7 +292,7 @@ export class ChatServices {
|
||||||
const azureOpenAIApiInstanceName = process.env.AZURE_OPEN_AI_INSTANCE;
|
const azureOpenAIApiInstanceName = process.env.AZURE_OPEN_AI_INSTANCE;
|
||||||
const azureOpenAIEndPoint = process.env.AZURE_OPEN_AI_ENDPOINT;
|
const azureOpenAIEndPoint = process.env.AZURE_OPEN_AI_ENDPOINT;
|
||||||
|
|
||||||
model = new ChatOpenAI({
|
model = new AzureOpenAI({
|
||||||
azureOpenAIApiKey: azureOpenAIKey,
|
azureOpenAIApiKey: azureOpenAIKey,
|
||||||
azureOpenAIApiInstanceName: azureOpenAIApiInstanceName,
|
azureOpenAIApiInstanceName: azureOpenAIApiInstanceName,
|
||||||
azureOpenAIApiDeploymentName: azureOpenAILLMModel,
|
azureOpenAIApiDeploymentName: azureOpenAILLMModel,
|
||||||
|
|
@ -756,7 +750,7 @@ export class ChatServices {
|
||||||
let functions = [];
|
let functions = [];
|
||||||
|
|
||||||
// Adds .gbdialog as functions if any to LLM Functions.
|
// Adds .gbdialog as functions if any to LLM Functions.
|
||||||
await CollectionUtil.asyncForEach(Object.keys(min.scriptMap), async script => {
|
await GBUtil.asyncForEach(Object.keys(min.scriptMap), async script => {
|
||||||
const packagePath = GBUtil.getGBAIPath(min.botId, 'gbdialog', null);
|
const packagePath = GBUtil.getGBAIPath(min.botId, 'gbdialog', null);
|
||||||
const jsonFile = path.join('work', packagePath, `${script}.json`);
|
const jsonFile = path.join('work', packagePath, `${script}.json`);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
// BotServer/packages/saas.gbapp/dialog/NewUserDialog.ts
|
// BotServer/packages/saas.gbapp/dialog/NewUserDialog.ts
|
||||||
import { IGBDialog, GBMinInstance } from 'botlib';
|
import { IGBDialog, GBMinInstance } from 'botlib-legacy';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { MainService } from '../service/MainService.js';
|
import { MainService } from '../service/MainService.js';
|
||||||
import { SaaSPackage } from '../index.js';
|
import { SaaSPackage } from '../index.js';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { GBOService } from '../service/GBOService.js';
|
import { GBOService } from '../service/GBOService.js';
|
||||||
|
import { GBUtil } from '../../../src/util.js';
|
||||||
|
|
||||||
export class NewUserDialog extends IGBDialog {
|
export class NewUserDialog extends IGBDialog {
|
||||||
static getPlanSelectionDialog(min: GBMinInstance) {
|
static getPlanSelectionDialog(min: GBMinInstance) {
|
||||||
|
|
@ -80,7 +81,7 @@ export class NewUserDialog extends IGBDialog {
|
||||||
const list = await gboService.listTemplates(min);
|
const list = await gboService.listTemplates(min);
|
||||||
|
|
||||||
let templateMessage = undefined;
|
let templateMessage = undefined;
|
||||||
await CollectionUtil.asyncForEach(list, async item => {
|
await GBUtil.asyncForEach(list, async item => {
|
||||||
if (item.name !== 'Shared.gbai') {
|
if (item.name !== 'Shared.gbai') {
|
||||||
templateMessage = templateMessage ? `${templateMessage}\n- ${item.name}` : `- ${item.name}`;
|
templateMessage = templateMessage ? `${templateMessage}\n- ${item.name}` : `- ${item.name}`;
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +95,7 @@ export class NewUserDialog extends IGBDialog {
|
||||||
const list = step.activeDialog.state.options.templateList;
|
const list = step.activeDialog.state.options.templateList;
|
||||||
let template = null;
|
let template = null;
|
||||||
let gboService = new GBOService();
|
let gboService = new GBOService();
|
||||||
await CollectionUtil.asyncForEach(list, async item => {
|
await GBUtil.asyncForEach(list, async item => {
|
||||||
if (gboService.kmpSearch(step.context.activity.originalText, item.name) != -1) {
|
if (gboService.kmpSearch(step.context.activity.originalText, item.name) != -1) {
|
||||||
template = item.name;
|
template = item.name;
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +106,7 @@ export class NewUserDialog extends IGBDialog {
|
||||||
return await step.replaceDialog('/welcome_saas_bottemplate', step.activeDialog.state.options);
|
return await step.replaceDialog('/welcome_saas_bottemplate', step.activeDialog.state.options);
|
||||||
} else {
|
} else {
|
||||||
step.activeDialog.state.options.templateName = template;
|
step.activeDialog.state.options.templateName = template;
|
||||||
|
|
||||||
const service = new MainService();
|
const service = new MainService();
|
||||||
const result: any = await service.startSubscriptionProcess(
|
const result: any = await service.startSubscriptionProcess(
|
||||||
min,
|
min,
|
||||||
|
|
@ -123,14 +124,10 @@ export class NewUserDialog extends IGBDialog {
|
||||||
} else {
|
} else {
|
||||||
await step.context.sendActivity(`Please complete your payment here: ${result.paymentUrl}`);
|
await step.context.sendActivity(`Please complete your payment here: ${result.paymentUrl}`);
|
||||||
await step.context.sendActivity('I will check for payment completion every few seconds...');
|
await step.context.sendActivity('I will check for payment completion every few seconds...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const finalResult = await service.waitForPaymentCompletion(
|
const finalResult = await service.waitForPaymentCompletion(min, result.subscriptionId, template);
|
||||||
min,
|
|
||||||
result.subscriptionId,
|
|
||||||
template
|
|
||||||
);
|
|
||||||
|
|
||||||
await step.context.sendActivity(`Payment verified and bot created successfully!`);
|
await step.context.sendActivity(`Payment verified and bot created successfully!`);
|
||||||
await step.context.sendActivity(`Access your bot here: ${finalResult.botUrl}`);
|
await step.context.sendActivity(`Access your bot here: ${finalResult.botUrl}`);
|
||||||
return await step.replaceDialog('/ask', { isReturning: true });
|
return await step.replaceDialog('/ask', { isReturning: true });
|
||||||
|
|
@ -182,4 +179,4 @@ export class NewUserDialog extends IGBDialog {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,29 +28,28 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
"use strict"
|
'use strict';
|
||||||
|
|
||||||
import { IGBPackage, GBMinInstance, IGBCoreService, GBLog, IGBAdminService, GBDialogStep } from 'botlib'
|
import { IGBPackage, GBMinInstance, IGBCoreService, GBLog, IGBAdminService, GBDialogStep } from 'botlib-legacy';
|
||||||
import { Sequelize } from 'sequelize-typescript'
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
import { GBOnlineSubscription } from './model/MainModel.js'
|
import { GBOnlineSubscription } from './model/MainModel.js';
|
||||||
|
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
import { NewUserDialog } from './dialog/NewUserDialog.js';
|
||||||
import { NewUserDialog } from './dialog/NewUserDialog.js'
|
import { GBOService } from './service/GBOService.js';
|
||||||
import { GBOService } from './service/GBOService.js'
|
|
||||||
|
|
||||||
export class SaaSPackage implements IGBPackage {
|
export class SaaSPackage implements IGBPackage {
|
||||||
sysPackages: IGBPackage[]
|
sysPackages: IGBPackage[];
|
||||||
adminService: IGBAdminService;
|
adminService: IGBAdminService;
|
||||||
public static welcomes = {};
|
public static welcomes = {};
|
||||||
instanceId: any
|
instanceId: any;
|
||||||
|
|
||||||
public getDialogs(min: GBMinInstance) {
|
public getDialogs(min: GBMinInstance) {
|
||||||
return [NewUserDialog.getDialog(min),
|
return [
|
||||||
NewUserDialog.getBotNameDialog(min),
|
NewUserDialog.getDialog(min),
|
||||||
NewUserDialog.getBotTemplateDialog(min),
|
NewUserDialog.getBotNameDialog(min),
|
||||||
|
NewUserDialog.getBotTemplateDialog(min),
|
||||||
NewUserDialog.getPlanSelectionDialog(min),
|
|
||||||
|
|
||||||
|
NewUserDialog.getPlanSelectionDialog(min)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,7 +58,6 @@ export class SaaSPackage implements IGBPackage {
|
||||||
if (process.env.DISABLE_SAAS_WELCOME !== 'true') {
|
if (process.env.DISABLE_SAAS_WELCOME !== 'true') {
|
||||||
core.setEntryPointDialog('/welcome_saas');
|
core.setEntryPointDialog('/welcome_saas');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -74,24 +72,17 @@ export class SaaSPackage implements IGBPackage {
|
||||||
|
|
||||||
this.adminService = min.adminService;
|
this.adminService = min.adminService;
|
||||||
this.instanceId = min.instanceId;
|
this.instanceId = min.instanceId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by scheduler to send notification message to phones.
|
* Called by scheduler to send notification message to phones.
|
||||||
* @param sendToDevice The function used to notify.
|
* @param sendToDevice The function used to notify.
|
||||||
*/
|
*/
|
||||||
private async notifyJob(sendToDevice) {
|
private async notifyJob(sendToDevice) {}
|
||||||
|
|
||||||
}
|
async unloadPackage(core: IGBCoreService): Promise<void> {}
|
||||||
|
|
||||||
|
|
||||||
async unloadPackage(core: IGBCoreService): Promise<void> {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadBot(min: GBMinInstance): Promise<void> {
|
async loadBot(min: GBMinInstance): Promise<void> {
|
||||||
|
|
||||||
let gboService = new GBOService();
|
let gboService = new GBOService();
|
||||||
|
|
||||||
// Gets the sendToDevice method of whatsapp.gblib and setups scheduler.
|
// Gets the sendToDevice method of whatsapp.gblib and setups scheduler.
|
||||||
|
|
@ -103,19 +94,13 @@ export class SaaSPackage implements IGBPackage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async unloadBot(min: GBMinInstance): Promise<void> {
|
async unloadBot(min: GBMinInstance): Promise<void> {}
|
||||||
|
|
||||||
}
|
async onNewSession(min: GBMinInstance, step: GBDialogStep): Promise<void> {}
|
||||||
|
|
||||||
async onNewSession(min: GBMinInstance, step: GBDialogStep): Promise<void> {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public async onExchangeData(min: GBMinInstance, kind: string, data: any) {
|
public async onExchangeData(min: GBMinInstance, kind: string, data: any) {
|
||||||
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case "whatsappMessage":
|
case 'whatsappMessage':
|
||||||
|
|
||||||
const from = data.from;
|
const from = data.from;
|
||||||
const fromName = data.fromName;
|
const fromName = data.fromName;
|
||||||
SaaSPackage.welcomes[from] = fromName;
|
SaaSPackage.welcomes[from] = fromName;
|
||||||
|
|
@ -126,5 +111,4 @@ export class SaaSPackage implements IGBPackage {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,26 @@
|
||||||
// General Bots Copyright (c) pragmatismo.com.br. All rights reserved. Licensed under the AGPL-3.0.
|
// General Bots Copyright (c) pragmatismo.com.br. All rights reserved. Licensed under the AGPL-3.0.
|
||||||
|
|
||||||
"use strict"
|
'use strict';
|
||||||
|
|
||||||
import { GBMinInstance, GBLog } from "botlib";
|
import { GBMinInstance, GBLog } from 'botlib-legacy';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import MicrosoftGraph from "@microsoft/microsoft-graph-client";
|
import MicrosoftGraph from '@microsoft/microsoft-graph-client';
|
||||||
|
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
|
|
||||||
import { GBConfigService } from "../../core.gbapp/services/GBConfigService.js";
|
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
||||||
import path from "path";
|
import path from 'path';
|
||||||
import { Client } from "minio";
|
import { Client } from 'minio';
|
||||||
|
import { GBUtil } from '../../../src/util.js';
|
||||||
|
|
||||||
export class GBOService {
|
export class GBOService {
|
||||||
|
|
||||||
public async listTemplates(min: GBMinInstance) {
|
public async listTemplates(min: GBMinInstance) {
|
||||||
if (GBConfigService.get('GB_MODE') === 'legacy') {
|
if (GBConfigService.get('GB_MODE') === 'legacy') {
|
||||||
let templateLibraryId = process.env.SAAS_TEMPLATE_LIBRARY;
|
let templateLibraryId = process.env.SAAS_TEMPLATE_LIBRARY;
|
||||||
let siteId = process.env.STORAGE_SITE_ID;
|
let siteId = process.env.STORAGE_SITE_ID;
|
||||||
|
|
||||||
let token =
|
let token = await (min.adminService as any).acquireElevatedToken(min.instance.instanceId, true);
|
||||||
await (min.adminService as any).acquireElevatedToken(min.instance.instanceId, true);
|
|
||||||
|
|
||||||
let client = MicrosoftGraph.Client.init({
|
let client = MicrosoftGraph.Client.init({
|
||||||
authProvider: done => {
|
authProvider: done => {
|
||||||
|
|
@ -29,14 +28,12 @@ export class GBOService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const packagePath = `/`;
|
const packagePath = `/`;
|
||||||
let res = await client.api(
|
let res = await client
|
||||||
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/root/children`)
|
.api(`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/root/children`)
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
return res.value;
|
return res.value;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
|
|
||||||
const templatesDir = path.join(process.env.PWD, 'templates');
|
const templatesDir = path.join(process.env.PWD, 'templates');
|
||||||
const gbaiDirectories = [];
|
const gbaiDirectories = [];
|
||||||
|
|
||||||
|
|
@ -52,7 +49,13 @@ export class GBOService {
|
||||||
return gbaiDirectories;
|
return gbaiDirectories;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async copyTemplates(min: GBMinInstance, gbaiDest: any, templateName: string, kind: string, botName: string): Promise<void> {
|
public async copyTemplates(
|
||||||
|
min: GBMinInstance,
|
||||||
|
gbaiDest: any,
|
||||||
|
templateName: string,
|
||||||
|
kind: string,
|
||||||
|
botName: string
|
||||||
|
): Promise<void> {
|
||||||
const storageMode = process.env.GB_MODE;
|
const storageMode = process.env.GB_MODE;
|
||||||
|
|
||||||
if (storageMode === 'legacy') {
|
if (storageMode === 'legacy') {
|
||||||
|
|
@ -63,7 +66,7 @@ export class GBOService {
|
||||||
const libraryId = process.env.STORAGE_LIBRARY;
|
const libraryId = process.env.STORAGE_LIBRARY;
|
||||||
|
|
||||||
const client = MicrosoftGraph.Client.init({
|
const client = MicrosoftGraph.Client.init({
|
||||||
authProvider: (done) => done(null, token)
|
authProvider: done => done(null, token)
|
||||||
});
|
});
|
||||||
|
|
||||||
const packageName = `${templateName.split('.')[0]}.${kind}`;
|
const packageName = `${templateName.split('.')[0]}.${kind}`;
|
||||||
|
|
@ -71,69 +74,70 @@ export class GBOService {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Try direct copy first
|
// Try direct copy first
|
||||||
const src = await client.api(
|
const src = await client
|
||||||
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/root:/${templateName}/${packageName}`
|
.api(
|
||||||
).get();
|
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/root:/${templateName}/${packageName}`
|
||||||
|
)
|
||||||
|
.get();
|
||||||
|
|
||||||
await client.api(
|
await client
|
||||||
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/items/${src.id}/copy`
|
.api(`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/items/${src.id}/copy`)
|
||||||
).post({
|
.post({
|
||||||
parentReference: {
|
parentReference: {
|
||||||
driveId: gbaiDest.parentReference.driveId,
|
driveId: gbaiDest.parentReference.driveId,
|
||||||
id: gbaiDest.id
|
id: gbaiDest.id
|
||||||
},
|
},
|
||||||
name: destinationName
|
name: destinationName
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error.code === "nameAlreadyExists") {
|
if (error.code === 'nameAlreadyExists') {
|
||||||
// Handle existing destination by copying contents individually
|
// Handle existing destination by copying contents individually
|
||||||
const srcItems = await client.api(
|
const srcItems = await client
|
||||||
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/root:/${templateName}/${packageName}:/children`
|
.api(
|
||||||
).get();
|
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/root:/${templateName}/${packageName}:/children`
|
||||||
|
)
|
||||||
|
.get();
|
||||||
|
|
||||||
const dstPath = `${botName}.gbai/${destinationName}`;
|
const dstPath = `${botName}.gbai/${destinationName}`;
|
||||||
const dst = await client.api(
|
const dst = await client
|
||||||
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/root:/${dstPath}`
|
.api(`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/root:/${dstPath}`)
|
||||||
).get();
|
.get();
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(srcItems.value, async (item) => {
|
await GBUtil.asyncForEach(srcItems.value, async item => {
|
||||||
await client.api(
|
await client
|
||||||
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/items/${item.id}/copy`
|
.api(
|
||||||
).post({
|
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/items/${item.id}/copy`
|
||||||
parentReference: {
|
)
|
||||||
driveId: dst.parentReference.driveId,
|
.post({
|
||||||
id: dst.id
|
parentReference: {
|
||||||
}
|
driveId: dst.parentReference.driveId,
|
||||||
});
|
id: dst.id
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
GBLog.error(`Failed to copy templates: ${error.message}`);
|
GBLog.error(`Failed to copy templates: ${error.message}`);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (storageMode === 'gbcluster') {
|
||||||
else if (storageMode === 'gbcluster') {
|
|
||||||
|
|
||||||
// MinIO Implementation
|
// MinIO Implementation
|
||||||
const minioClient = new Client({
|
const minioClient = new Client({
|
||||||
endPoint: process.env.DRIVE_SERVER,
|
endPoint: process.env.DRIVE_SERVER,
|
||||||
port: parseInt(process.env.DRIVE_PORT),
|
port: parseInt(process.env.DRIVE_PORT),
|
||||||
useSSL: process.env.DRIVE_USE_SSL === 'true',
|
useSSL: process.env.DRIVE_USE_SSL === 'true',
|
||||||
accessKey: process.env.DRIVE_ACCESSKEY,
|
accessKey: process.env.DRIVE_ACCESSKEY,
|
||||||
secretKey: process.env.DRIVE_SECRET,
|
secretKey: process.env.DRIVE_SECRET
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const bucketName = `${process.env.DRIVE_ORG_PREFIX}${botName}.gbai`.toLowerCase();
|
const bucketName = `${process.env.DRIVE_ORG_PREFIX}${botName}.gbai`.toLowerCase();
|
||||||
const packageName = `${templateName.split('.')[0]}.${kind}`;
|
const packageName = `${templateName.split('.')[0]}.${kind}`;
|
||||||
const localTemplatePath = path.join(process.env.PWD, 'templates', templateName, packageName);
|
const localTemplatePath = path.join(process.env.PWD, 'templates', templateName, packageName);
|
||||||
const minioDestinationPath = `${botName}.${kind}`;
|
const minioDestinationPath = `${botName}.${kind}`;
|
||||||
|
|
||||||
const uploadDirectory = async (localPath: string, minioPath: string = '') => {
|
const uploadDirectory = async (localPath: string, minioPath: string = '') => {
|
||||||
|
|
||||||
// Ensure the bucket exists in local file system
|
// Ensure the bucket exists in local file system
|
||||||
if (existsSync(localPath)) {
|
if (existsSync(localPath)) {
|
||||||
|
|
||||||
const entries = await fs.readdir(localPath, { withFileTypes: true });
|
const entries = await fs.readdir(localPath, { withFileTypes: true });
|
||||||
|
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
|
|
@ -148,8 +152,7 @@ export class GBOService {
|
||||||
GBLog.info(`Uploaded ${objectName} to MinIO bucket ${bucketName}`);
|
GBLog.info(`Uploaded ${objectName} to MinIO bucket ${bucketName}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
GBLog.verbose(`Package ${localPath} does not exist on templates.`);
|
GBLog.verbose(`Package ${localPath} does not exist on templates.`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -159,9 +162,7 @@ export class GBOService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createExcelFile(min: GBMinInstance, destinationFolder: any, name: string) {
|
public async createExcelFile(min: GBMinInstance, destinationFolder: any, name: string) {
|
||||||
|
let token = await (min.adminService.acquireElevatedToken as any)(min.instance.instanceId, true);
|
||||||
let token =
|
|
||||||
await (min.adminService.acquireElevatedToken as any)(min.instance.instanceId, true);
|
|
||||||
|
|
||||||
let siteId = process.env.STORAGE_SITE_ID;
|
let siteId = process.env.STORAGE_SITE_ID;
|
||||||
let templateLibraryId = process.env.SAAS_TEMPLATE_LIBRARY;
|
let templateLibraryId = process.env.SAAS_TEMPLATE_LIBRARY;
|
||||||
|
|
@ -172,107 +173,97 @@ export class GBOService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const body =
|
const body = {
|
||||||
{
|
parentReference: { driveId: destinationFolder.parentReference.driveId, id: destinationFolder.id },
|
||||||
"parentReference": { driveId: destinationFolder.parentReference.driveId, id: destinationFolder.id },
|
name: name
|
||||||
"name": name
|
};
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const src = await client.api(
|
const src = await client
|
||||||
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/root:/System.gbdata/blank.xlsx`)
|
.api(
|
||||||
|
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/root:/System.gbdata/blank.xlsx`
|
||||||
|
)
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
return await client.api(
|
return await client
|
||||||
`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/items/${src.id}/copy`)
|
.api(`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${templateLibraryId}/drive/items/${src.id}/copy`)
|
||||||
.post(body);
|
.post(body);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
GBLog.error(error);
|
GBLog.error(error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async shareWithEmail(bucketName, folder, expiresInHours = 24 * 365) {
|
public async shareWithEmail(bucketName, folder, expiresInHours = 24 * 365) {
|
||||||
const minioClient = new Client({
|
const minioClient = new Client({
|
||||||
endPoint: process.env.DRIVE_SERVER || 'localhost',
|
endPoint: process.env.DRIVE_SERVER || 'localhost',
|
||||||
port: parseInt(process.env.DRIVE_PORT || '9000', 10),
|
port: parseInt(process.env.DRIVE_PORT || '9000', 10),
|
||||||
useSSL: process.env.DRIVE_USE_SSL === 'true',
|
useSSL: process.env.DRIVE_USE_SSL === 'true',
|
||||||
accessKey: process.env.DRIVE_ACCESSKEY,
|
accessKey: process.env.DRIVE_ACCESSKEY,
|
||||||
secretKey: process.env.DRIVE_SECRET,
|
secretKey: process.env.DRIVE_SECRET
|
||||||
});
|
});
|
||||||
|
|
||||||
// Generate a time-limited access link (default: 24 hours)
|
// Generate a time-limited access link (default: 24 hours)
|
||||||
const presignedUrl = await minioClient.presignedGetObject(
|
const presignedUrl = await minioClient.presignedGetObject(
|
||||||
bucketName,
|
bucketName,
|
||||||
folder,
|
folder,
|
||||||
expiresInHours * 60 * 60 // Convert hours to seconds
|
expiresInHours * 60 * 60 // Convert hours to seconds
|
||||||
);
|
);
|
||||||
return presignedUrl;
|
return presignedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async shareFolder(token: string, driveId: string, itemId: string, email: string) {
|
public async shareFolder(token: string, driveId: string, itemId: string, email: string) {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
return new Promise<string>((resolve, reject) => {
|
let client = MicrosoftGraph.Client.init({
|
||||||
let client = MicrosoftGraph.Client.init({
|
authProvider: done => {
|
||||||
authProvider: done => {
|
done(null, token);
|
||||||
done(null, token);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const body =
|
|
||||||
{
|
|
||||||
"recipients": [
|
|
||||||
{
|
|
||||||
"email": email
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"message": "General Bots Online - Packages folder",
|
|
||||||
"requireSignIn": true,
|
|
||||||
"sendInvitation": true,
|
|
||||||
"roles": ["write"]
|
|
||||||
};
|
|
||||||
|
|
||||||
client.api(`https://graph.microsoft.com/v1.0/drives/${driveId}/items/${itemId}/invite`)
|
|
||||||
.post(body, (err, res) => {
|
|
||||||
if (err) {
|
|
||||||
GBLog.error('Sharing: ' + err);
|
|
||||||
reject(err)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(res);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
recipients: [
|
||||||
|
{
|
||||||
|
email: email
|
||||||
|
}
|
||||||
|
],
|
||||||
|
message: 'General Bots Online - Packages folder',
|
||||||
|
requireSignIn: true,
|
||||||
|
sendInvitation: true,
|
||||||
|
roles: ['write']
|
||||||
|
};
|
||||||
|
|
||||||
|
client.api(`https://graph.microsoft.com/v1.0/drives/${driveId}/items/${itemId}/invite`).post(body, (err, res) => {
|
||||||
|
if (err) {
|
||||||
|
GBLog.error('Sharing: ' + err);
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public kmpSearch(pattern, text) {
|
public kmpSearch(pattern, text) {
|
||||||
pattern = pattern.toLowerCase();
|
pattern = pattern.toLowerCase();
|
||||||
text = text.toLowerCase();
|
text = text.toLowerCase();
|
||||||
if (pattern.length == 0)
|
if (pattern.length == 0) return 0; // Immediate match
|
||||||
return 0; // Immediate match
|
|
||||||
|
|
||||||
// Compute longest suffix-prefix table
|
// Compute longest suffix-prefix table
|
||||||
var lsp = [0]; // Base case
|
var lsp = [0]; // Base case
|
||||||
for (var i = 1; i < pattern.length; i++) {
|
for (var i = 1; i < pattern.length; i++) {
|
||||||
var j = lsp[i - 1]; // Start by assuming we're extending the previous LSP
|
var j = lsp[i - 1]; // Start by assuming we're extending the previous LSP
|
||||||
while (j > 0 && pattern.charAt(i) != pattern.charAt(j))
|
while (j > 0 && pattern.charAt(i) != pattern.charAt(j)) j = lsp[j - 1];
|
||||||
j = lsp[j - 1];
|
if (pattern.charAt(i) == pattern.charAt(j)) j++;
|
||||||
if (pattern.charAt(i) == pattern.charAt(j))
|
|
||||||
j++;
|
|
||||||
lsp.push(j);
|
lsp.push(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk through text string
|
// Walk through text string
|
||||||
var j = 0; // Number of chars matched in pattern
|
var j = 0; // Number of chars matched in pattern
|
||||||
for (var i = 0; i < text.length; i++) {
|
for (var i = 0; i < text.length; i++) {
|
||||||
while (j > 0 && text.charAt(i) != pattern.charAt(j))
|
while (j > 0 && text.charAt(i) != pattern.charAt(j)) j = lsp[j - 1]; // Fall back in the pattern
|
||||||
j = lsp[j - 1]; // Fall back in the pattern
|
|
||||||
if (text.charAt(i) == pattern.charAt(j)) {
|
if (text.charAt(i) == pattern.charAt(j)) {
|
||||||
j++; // Next char matched, increment position
|
j++; // Next char matched, increment position
|
||||||
if (j == pattern.length)
|
if (j == pattern.length) return i - (j - 1);
|
||||||
return i - (j - 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1; // Not found
|
return -1; // Not found
|
||||||
|
|
@ -303,9 +294,7 @@ export class GBOService {
|
||||||
* Retrives a document from the drive, given a path and filename.
|
* Retrives a document from the drive, given a path and filename.
|
||||||
*/
|
*/
|
||||||
private async internalGetDocument(client: any, baseUrl: any, path: string, file: string) {
|
private async internalGetDocument(client: any, baseUrl: any, path: string, file: string) {
|
||||||
let res = await client
|
let res = await client.api(`${baseUrl}/drive/root:${path}:/children`).get();
|
||||||
.api(`${baseUrl}/drive/root:${path}:/children`)
|
|
||||||
.get();
|
|
||||||
|
|
||||||
let documents = res.value.filter(m => {
|
let documents = res.value.filter(m => {
|
||||||
return m.name.toLowerCase() === file.toLowerCase();
|
return m.name.toLowerCase() === file.toLowerCase();
|
||||||
|
|
@ -318,8 +307,7 @@ export class GBOService {
|
||||||
return documents[0];
|
return documents[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createRootFolder(token: string, name: string,
|
public async createRootFolder(token: string, name: string, siteId: string, libraryId: string) {
|
||||||
siteId: string, libraryId: string) {
|
|
||||||
const storageMode = process.env.GB_MODE;
|
const storageMode = process.env.GB_MODE;
|
||||||
|
|
||||||
if (storageMode === 'gbcluster') {
|
if (storageMode === 'gbcluster') {
|
||||||
|
|
@ -329,10 +317,9 @@ export class GBOService {
|
||||||
port: parseInt(process.env.DRIVE_PORT),
|
port: parseInt(process.env.DRIVE_PORT),
|
||||||
useSSL: process.env.DRIVE_USE_SSL === 'true',
|
useSSL: process.env.DRIVE_USE_SSL === 'true',
|
||||||
accessKey: process.env.DRIVE_ACCESSKEY,
|
accessKey: process.env.DRIVE_ACCESSKEY,
|
||||||
secretKey: process.env.DRIVE_SECRET,
|
secretKey: process.env.DRIVE_SECRET
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Ensure bucket exists
|
// Ensure bucket exists
|
||||||
|
|
||||||
name = `${process.env.DRIVE_ORG_PREFIX}${name}`.toLowerCase();
|
name = `${process.env.DRIVE_ORG_PREFIX}${name}`.toLowerCase();
|
||||||
|
|
@ -341,7 +328,6 @@ export class GBOService {
|
||||||
await minioClient.makeBucket(name);
|
await minioClient.makeBucket(name);
|
||||||
}
|
}
|
||||||
return { name: name, folder: {} }; // Return similar structure to MS Graph
|
return { name: name, folder: {} }; // Return similar structure to MS Graph
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Original MS Graph implementation
|
// Original MS Graph implementation
|
||||||
return new Promise<any>((resolve, reject) => {
|
return new Promise<any>((resolve, reject) => {
|
||||||
|
|
@ -351,22 +337,20 @@ export class GBOService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const body = {
|
const body = {
|
||||||
"name": name,
|
name: name,
|
||||||
"folder": {},
|
folder: {},
|
||||||
"@microsoft.graph.conflictBehavior": "rename"
|
'@microsoft.graph.conflictBehavior': 'rename'
|
||||||
}
|
};
|
||||||
client.api(`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/root/children`)
|
client
|
||||||
|
.api(`https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${libraryId}/drive/root/children`)
|
||||||
.post(body, (err, res) => {
|
.post(body, (err, res) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err)
|
reject(err);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
resolve(res);
|
resolve(res);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// BotServer/packages/saas.gbapp/service/MainService.ts
|
// BotServer/packages/saas.gbapp/service/MainService.ts
|
||||||
import { GBOnlineSubscription } from '../model/MainModel.js';
|
import { GBOnlineSubscription } from '../model/MainModel.js';
|
||||||
import { GBMinInstance, GBLog } from 'botlib';
|
import { GBMinInstance, GBLog } from 'botlib-legacy';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import { GBOService } from './GBOService.js';
|
import { GBOService } from './GBOService.js';
|
||||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { TokenResponse } from 'botbuilder';
|
import { TokenResponse } from 'botbuilder';
|
||||||
import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
|
import { GBLog, GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
|
import { GBLog, GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import libphonenumber from 'google-libphonenumber';
|
import libphonenumber from 'google-libphonenumber';
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { TokenResponse } from 'botbuilder';
|
import { TokenResponse } from 'botbuilder';
|
||||||
import { GBLog, GBMinInstance, IGBDialog } from 'botlib';
|
import { GBLog, GBMinInstance, IGBDialog } from 'botlib-legacy';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
import { SecService } from '../services/SecService.js';
|
import { SecService } from '../services/SecService.js';
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
import { OAuthDialog } from './dialogs/OAuthDialog.js';
|
import { OAuthDialog } from './dialogs/OAuthDialog.js';
|
||||||
import { ProfileDialog } from './dialogs/ProfileDialog.js';
|
import { ProfileDialog } from './dialogs/ProfileDialog.js';
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
import { ConversationReference } from 'botbuilder';
|
import { ConversationReference } from 'botbuilder';
|
||||||
import { GBLog, GBMinInstance, GBService, IGBInstance } from 'botlib';
|
import { GBLog, GBMinInstance, GBService, IGBInstance } from 'botlib-legacy';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { GuaribasUser } from '../models/index.js';
|
import { GuaribasUser } from '../models/index.js';
|
||||||
import { FindOptions } from 'sequelize';
|
import { FindOptions } from 'sequelize';
|
||||||
import { DialogKeywords } from '../../../packages/basic.gblib/services/DialogKeywords.js';
|
import { DialogKeywords } from '../../../packages/basic.gblib/services/DialogKeywords.js';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GBUtil } from '../../../src/util.js';
|
import { GBUtil } from '../../../src/util.js';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Security service layer.
|
* Security service layer.
|
||||||
*/
|
*/
|
||||||
|
|
@ -25,11 +24,10 @@ export class SecService extends GBService {
|
||||||
displayName: string,
|
displayName: string,
|
||||||
email: string
|
email: string
|
||||||
): Promise<GuaribasUser> {
|
): Promise<GuaribasUser> {
|
||||||
|
|
||||||
const gbaiPath = GBUtil.getGBAIPath(min.botId);
|
const gbaiPath = GBUtil.getGBAIPath(min.botId);
|
||||||
const dir = urlJoin ('work',gbaiPath, 'users', userSystemId);
|
const dir = urlJoin('work', gbaiPath, 'users', userSystemId);
|
||||||
|
|
||||||
if (!await GBUtil.exists(dir)) {
|
if (!(await GBUtil.exists(dir))) {
|
||||||
mkdirp.sync(dir);
|
mkdirp.sync(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,7 +43,7 @@ export class SecService extends GBService {
|
||||||
|
|
||||||
const systemPromptFile = urlJoin(dir, 'systemPrompt.txt');
|
const systemPromptFile = urlJoin(dir, 'systemPrompt.txt');
|
||||||
if (await GBUtil.exists(systemPromptFile)) {
|
if (await GBUtil.exists(systemPromptFile)) {
|
||||||
user[ 'systemPrompt'] = await fs.readFile(systemPromptFile);
|
user['systemPrompt'] = await fs.readFile(systemPromptFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
user.instanceId = min.instance.instanceId;
|
user.instanceId = min.instance.instanceId;
|
||||||
|
|
@ -54,8 +52,8 @@ export class SecService extends GBService {
|
||||||
user.displayName = displayName;
|
user.displayName = displayName;
|
||||||
user.email = email;
|
user.email = email;
|
||||||
user.defaultChannel = channelName;
|
user.defaultChannel = channelName;
|
||||||
GBServer.globals.users [user.userId] = user;
|
GBServer.globals.users[user.userId] = user;
|
||||||
if(user.changed()){
|
if (user.changed()) {
|
||||||
await user.save();
|
await user.save();
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
|
|
@ -79,7 +77,7 @@ export class SecService extends GBService {
|
||||||
const user = await GuaribasUser.findOne(options);
|
const user = await GuaribasUser.findOne(options);
|
||||||
|
|
||||||
user.conversationReference = conversationReference;
|
user.conversationReference = conversationReference;
|
||||||
GBServer.globals.users [user.userId] = user;
|
GBServer.globals.users[user.userId] = user;
|
||||||
return await user.save();
|
return await user.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,7 +86,7 @@ export class SecService extends GBService {
|
||||||
const user = await GuaribasUser.findOne(options);
|
const user = await GuaribasUser.findOne(options);
|
||||||
|
|
||||||
user.conversationReference = conversationReference;
|
user.conversationReference = conversationReference;
|
||||||
GBServer.globals.users [user.userId] = user;
|
GBServer.globals.users[user.userId] = user;
|
||||||
return await user.save();
|
return await user.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,7 +97,7 @@ export class SecService extends GBService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
user.locale = locale;
|
user.locale = locale;
|
||||||
GBServer.globals.users [user.userId] = user;
|
GBServer.globals.users[user.userId] = user;
|
||||||
return await user.save();
|
return await user.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +108,7 @@ export class SecService extends GBService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
user.hearOnDialog = dialogName;
|
user.hearOnDialog = dialogName;
|
||||||
GBServer.globals.users [user.userId] = user;
|
GBServer.globals.users[user.userId] = user;
|
||||||
return await user.save();
|
return await user.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,7 +119,7 @@ export class SecService extends GBService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
user.instanceId = instanceId;
|
user.instanceId = instanceId;
|
||||||
GBServer.globals.users [user.userId] = user;
|
GBServer.globals.users[user.userId] = user;
|
||||||
return await user.save();
|
return await user.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,11 +165,11 @@ export class SecService extends GBService {
|
||||||
agent.instanceId = user.instanceId;
|
agent.instanceId = user.instanceId;
|
||||||
agent.agentMode = 'self';
|
agent.agentMode = 'self';
|
||||||
agent.agentSystemId = null;
|
agent.agentSystemId = null;
|
||||||
GBServer.globals.users [agent.userId] = user;
|
GBServer.globals.users[agent.userId] = user;
|
||||||
await agent.save();
|
await agent.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
GBServer.globals.users [user.userId] = user;
|
GBServer.globals.users[user.userId] = user;
|
||||||
await user.save();
|
await user.save();
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
|
|
@ -203,13 +201,8 @@ export class SecService extends GBService {
|
||||||
list = list.split(';');
|
list = list.split(';');
|
||||||
}
|
}
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(list, async item => {
|
await GBUtil.asyncForEach(list, async item => {
|
||||||
if (
|
if (item !== undefined && !agentSystemId && item !== userSystemId && !(await this.isAgentSystemId(item))) {
|
||||||
item !== undefined &&
|
|
||||||
!agentSystemId &&
|
|
||||||
item !== userSystemId &&
|
|
||||||
!(await this.isAgentSystemId(item))
|
|
||||||
) {
|
|
||||||
agentSystemId = item;
|
agentSystemId = item;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -263,7 +256,6 @@ export class SecService extends GBService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a dynamic param from user. Dynamic params are defined in .gbdialog SET
|
* Get a dynamic param from user. Dynamic params are defined in .gbdialog SET
|
||||||
* variables and other semantics during conversation.
|
* variables and other semantics during conversation.
|
||||||
|
|
@ -315,7 +307,7 @@ export class SecService extends GBService {
|
||||||
}
|
}
|
||||||
obj[name] = value;
|
obj[name] = value;
|
||||||
user.params = JSON.stringify(obj);
|
user.params = JSON.stringify(obj);
|
||||||
GBServer.globals.users [userId] = user;
|
GBServer.globals.users[userId] = user;
|
||||||
return await user.save();
|
return await user.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
| |
|
| |
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
import { GBService } from 'botlib';
|
import { GBService } from 'botlib-legacy';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import AdmZip from 'adm-zip';
|
import AdmZip from 'adm-zip';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib';
|
import { GBDialogStep, GBLog, GBMinInstance, IGBCoreService, IGBPackage } from 'botlib-legacy';
|
||||||
import { Sequelize } from 'sequelize-typescript';
|
import { Sequelize } from 'sequelize-typescript';
|
||||||
import { WhatsappDirectLine } from './services/WhatsappDirectLine.js';
|
import { WhatsappDirectLine } from './services/WhatsappDirectLine.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ import urlJoin from 'url-join';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import Fs from 'fs';
|
import Fs from 'fs';
|
||||||
import { GBLog, GBMinInstance, GBService, IGBPackage } from 'botlib';
|
import { GBLog, GBMinInstance, GBService, IGBPackage } from 'botlib-legacy';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
||||||
import { SecService } from '../../security.gbapp/services/SecService.js';
|
import { SecService } from '../../security.gbapp/services/SecService.js';
|
||||||
|
|
@ -220,7 +220,7 @@ export class WhatsappDirectLine extends GBService {
|
||||||
// TODO: await client.pupPage['minimize']();
|
// TODO: await client.pupPage['minimize']();
|
||||||
// Keeps the chat list cleaned.
|
// Keeps the chat list cleaned.
|
||||||
const chats = await client.getChats();
|
const chats = await client.getChats();
|
||||||
await CollectionUtil.asyncForEach(chats, async chat => {
|
await GBUtil.asyncForEach(chats, async chat => {
|
||||||
const wait = Math.floor(Math.random() * 5000) + 1000;
|
const wait = Math.floor(Math.random() * 5000) + 1000;
|
||||||
await GBUtil.sleep(wait);
|
await GBUtil.sleep(wait);
|
||||||
if (chat.isGroup) {
|
if (chat.isGroup) {
|
||||||
|
|
@ -442,7 +442,7 @@ export class WhatsappDirectLine extends GBService {
|
||||||
|
|
||||||
// Processes .gbapp message interception.
|
// Processes .gbapp message interception.
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(this.min.appPackages, async (e: IGBPackage) => {
|
await GBUtil.asyncForEach(this.min.appPackages, async (e: IGBPackage) => {
|
||||||
await e.onExchangeData(this.min, 'whatsappMessage', { from, fromName });
|
await e.onExchangeData(this.min, 'whatsappMessage', { from, fromName });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -692,7 +692,7 @@ export class WhatsappDirectLine extends GBService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activity.attachments) {
|
if (activity.attachments) {
|
||||||
await CollectionUtil.asyncForEach(activity.attachments, async attachment => {
|
await GBUtil.asyncForEach(activity.attachments, async attachment => {
|
||||||
switch (attachment.contentType) {
|
switch (attachment.contentType) {
|
||||||
case 'application/vnd.microsoft.card.hero':
|
case 'application/vnd.microsoft.card.hero':
|
||||||
output += `\n${this.renderHeroCard(attachment)}`;
|
output += `\n${this.renderHeroCard(attachment)}`;
|
||||||
|
|
@ -1003,7 +1003,7 @@ export class WhatsappDirectLine extends GBService {
|
||||||
} else {
|
} else {
|
||||||
messages = msg.match(/(.|[\r\n]){1,4096}/g);
|
messages = msg.match(/(.|[\r\n]){1,4096}/g);
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(messages, async msg => {
|
await GBUtil.asyncForEach(messages, async msg => {
|
||||||
|
|
||||||
await this.sendTextMessage(to, msg);
|
await this.sendTextMessage(to, msg);
|
||||||
|
|
||||||
|
|
@ -1021,7 +1021,7 @@ export class WhatsappDirectLine extends GBService {
|
||||||
|
|
||||||
messages = msg.match(/(.|[\r\n]){1,1000}/g);
|
messages = msg.match(/(.|[\r\n]){1,1000}/g);
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(messages, async msg => {
|
await GBUtil.asyncForEach(messages, async msg => {
|
||||||
await GBUtil.sleep(3000);
|
await GBUtil.sleep(3000);
|
||||||
await this.customClient.messages.create({
|
await this.customClient.messages.create({
|
||||||
body: msg,
|
body: msg,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
* @fileoverview General Bots server core.
|
* @fileoverview General Bots server core.
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
import { GBMinInstance, IGBInstance } from 'botlib';
|
import { GBMinInstance, IGBInstance } from 'botlib-legacy';
|
||||||
import { GBMinService } from '../packages/core.gbapp/services/GBMinService.js';
|
import { GBMinService } from '../packages/core.gbapp/services/GBMinService.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
39
src/app.ts
39
src/app.ts
|
|
@ -37,7 +37,7 @@
|
||||||
import { Mutex } from 'async-mutex';
|
import { Mutex } from 'async-mutex';
|
||||||
import auth from 'basic-auth';
|
import auth from 'basic-auth';
|
||||||
import bodyParser from 'body-parser';
|
import bodyParser from 'body-parser';
|
||||||
import { GBLog, GBMinInstance, IGBCoreService, IGBInstance } from 'botlib';
|
import { GBLog, GBMinInstance, IGBCoreService, IGBInstance } from 'botlib-legacy';
|
||||||
import child_process from 'child_process';
|
import child_process from 'child_process';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
|
|
@ -48,7 +48,6 @@ import mkdirp from 'mkdirp';
|
||||||
import { default as Path, default as path } from 'path';
|
import { default as Path, default as path } from 'path';
|
||||||
import swaggerUI from 'swagger-ui-dist';
|
import swaggerUI from 'swagger-ui-dist';
|
||||||
import { GBAdminService } from '../packages/admin.gbapp/services/GBAdminService.js';
|
import { GBAdminService } from '../packages/admin.gbapp/services/GBAdminService.js';
|
||||||
import { AzureDeployerService } from '../packages/azuredeployer.gbapp/services/AzureDeployerService.js';
|
|
||||||
import { GBConfigService } from '../packages/core.gbapp/services/GBConfigService.js';
|
import { GBConfigService } from '../packages/core.gbapp/services/GBConfigService.js';
|
||||||
import { GBConversationalService } from '../packages/core.gbapp/services/GBConversationalService.js';
|
import { GBConversationalService } from '../packages/core.gbapp/services/GBConversationalService.js';
|
||||||
import { GBCoreService } from '../packages/core.gbapp/services/GBCoreService.js';
|
import { GBCoreService } from '../packages/core.gbapp/services/GBCoreService.js';
|
||||||
|
|
@ -165,7 +164,6 @@ export class GBServer {
|
||||||
const core: IGBCoreService = new GBCoreService();
|
const core: IGBCoreService = new GBCoreService();
|
||||||
const importer: GBImporter = new GBImporter(core);
|
const importer: GBImporter = new GBImporter(core);
|
||||||
const deployer: GBDeployer = new GBDeployer(core, importer);
|
const deployer: GBDeployer = new GBDeployer(core, importer);
|
||||||
let azureDeployer: AzureDeployerService;
|
|
||||||
|
|
||||||
// Ensure that local proxy is setup.
|
// Ensure that local proxy is setup.
|
||||||
|
|
||||||
|
|
@ -186,27 +184,14 @@ export class GBServer {
|
||||||
|
|
||||||
// Creates a boot instance or load it from storage.
|
// Creates a boot instance or load it from storage.
|
||||||
|
|
||||||
if (GBConfigService.get('GB_MODE') === 'legacy') {
|
await core.initStorage();
|
||||||
await core.initStorage();
|
|
||||||
// [GBServer.globals.bootInstance, azureDeployer] = await core['createBootInstanceEx'](
|
|
||||||
// core,
|
|
||||||
// null,
|
|
||||||
// GBServer.globals.publicAddress,
|
|
||||||
// deployer,
|
|
||||||
// GBConfigService.get('FREE_TIER')
|
|
||||||
// );
|
|
||||||
// await core.saveInstance(GBServer.globals.bootInstance);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
await core.initStorage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deploys system and user packages.
|
// Deploys system and user packages.
|
||||||
|
|
||||||
GBLogEx.info(0, `Deploying System packages...`);
|
GBLogEx.info(0, `Deploying System packages...`);
|
||||||
GBServer.globals.sysPackages = await core.loadSysPackages(core);
|
GBServer.globals.sysPackages = await core.loadSysPackages(core);
|
||||||
GBLogEx.info(0, `Connecting to Bot Storage...`);
|
GBLogEx.info(0, `Connecting to Bot Storage...`);
|
||||||
await core.checkStorage(azureDeployer);
|
await core.checkStorage(null);
|
||||||
await deployer.deployPackages(core, server, GBServer.globals.appPackages);
|
await deployer.deployPackages(core, server, GBServer.globals.appPackages);
|
||||||
await core.syncDatabaseStructure();
|
await core.syncDatabaseStructure();
|
||||||
|
|
||||||
|
|
@ -217,11 +202,7 @@ export class GBServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
GBLogEx.info(0, `Publishing instances...`);
|
GBLogEx.info(0, `Publishing instances...`);
|
||||||
const instances: IGBInstance[] = await core.loadAllInstances(
|
const instances: IGBInstance[] = await core.loadAllInstances(core, null, GBServer.globals.publicAddress);
|
||||||
core,
|
|
||||||
azureDeployer,
|
|
||||||
GBServer.globals.publicAddress
|
|
||||||
);
|
|
||||||
|
|
||||||
if (instances.length === 0) {
|
if (instances.length === 0) {
|
||||||
if (GBConfigService.get('GB_MODE') === 'legacy') {
|
if (GBConfigService.get('GB_MODE') === 'legacy') {
|
||||||
|
|
@ -235,11 +216,6 @@ export class GBServer {
|
||||||
instances.push(instance);
|
instances.push(instance);
|
||||||
GBServer.globals.minBoot.instance = instances[0];
|
GBServer.globals.minBoot.instance = instances[0];
|
||||||
GBServer.globals.bootInstance = instances[0];
|
GBServer.globals.bootInstance = instances[0];
|
||||||
await deployer.deployBotOnAzure(instance, GBServer.globals.publicAddress);
|
|
||||||
|
|
||||||
// Runs the search even with empty content to create structure.
|
|
||||||
|
|
||||||
await azureDeployer['runSearch'](instance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,8 +226,7 @@ export class GBServer {
|
||||||
|
|
||||||
// Just sync if not using LOAD_ONLY.
|
// Just sync if not using LOAD_ONLY.
|
||||||
|
|
||||||
if (GBConfigService.get('GB_MODE') !== 'legacy'
|
if (GBConfigService.get('GB_MODE') !== 'legacy' && !process.env.LOAD_ONLY) {
|
||||||
&& !process.env.LOAD_ONLY) {
|
|
||||||
await core['ensureFolders'](instances, deployer);
|
await core['ensureFolders'](instances, deployer);
|
||||||
}
|
}
|
||||||
GBServer.globals.bootInstance = instances[0];
|
GBServer.globals.bootInstance = instances[0];
|
||||||
|
|
@ -289,7 +264,6 @@ export class GBServer {
|
||||||
return proxy.web(req, res, { target: 'http://localhost:1111' }); // Express server
|
return proxy.web(req, res, { target: 'http://localhost:1111' }); // Express server
|
||||||
} else if (host === process.env.ROUTER_1) {
|
} else if (host === process.env.ROUTER_1) {
|
||||||
return proxy.web(req, res, { target: `http://localhost:${process.env.ROUTER_1_PORT}` });
|
return proxy.web(req, res, { target: `http://localhost:${process.env.ROUTER_1_PORT}` });
|
||||||
|
|
||||||
} else if (host === process.env.ROUTER_2) {
|
} else if (host === process.env.ROUTER_2) {
|
||||||
return proxy.web(req, res, { target: `http://localhost:${process.env.ROUTER_2_PORT}` });
|
return proxy.web(req, res, { target: `http://localhost:${process.env.ROUTER_2_PORT}` });
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -378,10 +352,7 @@ export class GBServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
function shutdown() {
|
function shutdown() {
|
||||||
|
|
||||||
GBLogEx.info(0, 'General Bots server is now shutdown.');
|
GBLogEx.info(0, 'General Bots server is now shutdown.');
|
||||||
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
66
src/util.ts
66
src/util.ts
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fileoverview General Bots local utility.
|
* @fileoverview General Bots local utility.
|
||||||
* This file contains utility functions used across the General Bots project.
|
* This file contains utility functions used across the General Bots project.
|
||||||
|
|
@ -29,8 +28,6 @@ import { QueryTypes } from '@sequelize/core';
|
||||||
* Utility class containing various helper functions for the General Bots project.
|
* Utility class containing various helper functions for the General Bots project.
|
||||||
*/
|
*/
|
||||||
export class GBUtil {
|
export class GBUtil {
|
||||||
|
|
||||||
|
|
||||||
// When creating/updating a user (hashing before saving to DB)
|
// When creating/updating a user (hashing before saving to DB)
|
||||||
public static async hashPassword(password) {
|
public static async hashPassword(password) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -42,6 +39,12 @@ export class GBUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async asyncForEach(array, callback) {
|
||||||
|
for (let index = 0; index < array.length; index++) {
|
||||||
|
await callback(array[index], index, array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// When comparing passwords (like during login)
|
// When comparing passwords (like during login)
|
||||||
public static async comparePassword(inputPassword, hashedPassword) {
|
public static async comparePassword(inputPassword, hashedPassword) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -116,8 +119,7 @@ export class GBUtil {
|
||||||
};
|
};
|
||||||
config.spec['host'] = `127.0.0.1:${GBConfigService.getServerPort()}`;
|
config.spec['host'] = `127.0.0.1:${GBConfigService.getServerPort()}`;
|
||||||
config.spec['basePath'] = `/api/messages/${min.botId}`;
|
config.spec['basePath'] = `/api/messages/${min.botId}`;
|
||||||
config.spec['schemes'] = ["http"];
|
config.spec['schemes'] = ['http'];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
config = {
|
config = {
|
||||||
spec: JSON.parse(await fs.readFile('directline-v2.json', 'utf8')),
|
spec: JSON.parse(await fs.readFile('directline-v2.json', 'utf8')),
|
||||||
|
|
@ -150,10 +152,8 @@ export class GBUtil {
|
||||||
styles: { '!!null': 'canonical' } // Optional: Customize null display
|
styles: { '!!null': 'canonical' } // Optional: Customize null display
|
||||||
} as any);
|
} as any);
|
||||||
|
|
||||||
|
|
||||||
//yamlString = yamlString.slice(0, 256); // Truncate to 1024 bytes
|
//yamlString = yamlString.slice(0, 256); // Truncate to 1024 bytes
|
||||||
|
|
||||||
|
|
||||||
return yamlString;
|
return yamlString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,20 +242,33 @@ export class GBUtil {
|
||||||
const destEntry = path.join(dest, entry);
|
const destEntry = path.join(dest, entry);
|
||||||
|
|
||||||
// Recursively copy each entry
|
// Recursively copy each entry
|
||||||
await this.copyIfNewerRecursive(srcEntry, destEntry ,onlyTextFiles);
|
await this.copyIfNewerRecursive(srcEntry, destEntry, onlyTextFiles);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
let skip = false;
|
let skip = false;
|
||||||
|
|
||||||
if (onlyTextFiles && !(
|
if (
|
||||||
src.endsWith('.txt') || src.endsWith('.json')
|
onlyTextFiles &&
|
||||||
|| src.endsWith('.csv') || src.endsWith('.xlsx') || src.endsWith('.xls')
|
!(
|
||||||
|| src.endsWith('.xlsm') || src.endsWith('.xlsb') || src.endsWith('.xml')
|
src.endsWith('.txt') ||
|
||||||
|| src.endsWith('.html') || src.endsWith('.htm') || src.endsWith('.md')
|
src.endsWith('.json') ||
|
||||||
|| src.endsWith('.docx') || src.endsWith('.pdf')
|
src.endsWith('.csv') ||
|
||||||
|| src.endsWith('.doc') || src.endsWith('.pptx') || src.endsWith('.ppt'))) {
|
src.endsWith('.xlsx') ||
|
||||||
skip = true;
|
src.endsWith('.xls') ||
|
||||||
|
src.endsWith('.xlsm') ||
|
||||||
|
src.endsWith('.xlsb') ||
|
||||||
|
src.endsWith('.xml') ||
|
||||||
|
src.endsWith('.html') ||
|
||||||
|
src.endsWith('.htm') ||
|
||||||
|
src.endsWith('.md') ||
|
||||||
|
src.endsWith('.docx') ||
|
||||||
|
src.endsWith('.pdf') ||
|
||||||
|
src.endsWith('.doc') ||
|
||||||
|
src.endsWith('.pptx') ||
|
||||||
|
src.endsWith('.ppt')
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
skip = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
|
|
@ -272,7 +285,6 @@ export class GBUtil {
|
||||||
await fs.cp(src, dest, { force: true });
|
await fs.cp(src, dest, { force: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,10 +415,7 @@ export class GBUtil {
|
||||||
|
|
||||||
public static isContentPage(text: string): boolean {
|
public static isContentPage(text: string): boolean {
|
||||||
// Common patterns that indicate non-content pages
|
// Common patterns that indicate non-content pages
|
||||||
const nonContentPatterns = [
|
const nonContentPatterns = [/^index$/i, /^table of contents$/i];
|
||||||
/^index$/i,
|
|
||||||
/^table of contents$/i,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Check if page is mostly dots, numbers or blank
|
// Check if page is mostly dots, numbers or blank
|
||||||
const isDotLeaderPage = text.replace(/\s+/g, '').match(/\.{10,}/);
|
const isDotLeaderPage = text.replace(/\s+/g, '').match(/\.{10,}/);
|
||||||
|
|
@ -418,21 +427,12 @@ export class GBUtil {
|
||||||
const hasMinimalContent = wordCount > 10;
|
const hasMinimalContent = wordCount > 10;
|
||||||
|
|
||||||
// Check if page matches any non-content patterns
|
// Check if page matches any non-content patterns
|
||||||
const isNonContent = nonContentPatterns.some(pattern =>
|
const isNonContent = nonContentPatterns.some(pattern => pattern.test(text.trim()));
|
||||||
pattern.test(text.trim())
|
|
||||||
);
|
|
||||||
|
|
||||||
// Page is valid content if:
|
// Page is valid content if:
|
||||||
// - Not mostly dots/numbers/blank
|
// - Not mostly dots/numbers/blank
|
||||||
// - Has minimal word count
|
// - Has minimal word count
|
||||||
// - Doesn't match non-content patterns
|
// - Doesn't match non-content patterns
|
||||||
return !isDotLeaderPage &&
|
return !isDotLeaderPage && !isNumbersPage && !isBlankPage && hasMinimalContent && !isNonContent;
|
||||||
!isNumbersPage &&
|
|
||||||
!isBlankPage &&
|
|
||||||
hasMinimalContent &&
|
|
||||||
!isNonContent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import { GBConfigService } from '../packages/core.gbapp/services/GBConfigService.js';
|
|
||||||
const {app} = (await import('electron')).default;
|
|
||||||
|
|
||||||
import path from 'path';
|
|
||||||
import url from 'url';
|
|
||||||
|
|
||||||
export function runUI() {
|
|
||||||
// Create the browser window.
|
|
||||||
const win = null;// new BrowserWindow({ width: 800, height: 600, title: 'General Bots Studio' });
|
|
||||||
|
|
||||||
import('./app.js').then(gb => {
|
|
||||||
gb.GBServer.run();
|
|
||||||
// and load the index.html of the app.
|
|
||||||
win.loadURL(
|
|
||||||
url.format({
|
|
||||||
pathname: path.join(__dirname, `http://localhost:${GBConfigService.get('PORT')}`),
|
|
||||||
protocol: 'file:',
|
|
||||||
slashes: true
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export class GBUI {
|
|
||||||
static run() {
|
|
||||||
app.on('ready', runUI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"noImplicitAny": false,
|
||||||
"rootDir": "./",
|
"rootDir": "./",
|
||||||
"strict": false,
|
"strict": false,
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
|
|
@ -17,36 +18,15 @@
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"paths": {
|
"paths": {
|
||||||
"*": [
|
"*": ["types/*"],
|
||||||
"types/*"
|
"botlib/*": ["node_modules/botlib/*"],
|
||||||
],
|
"pragmatismo-io-framework/*": ["node_modules/pragmatismo-io-framework/*"]
|
||||||
"botlib/*": [
|
|
||||||
"node_modules/botlib/*"
|
|
||||||
],
|
|
||||||
"pragmatismo-io-framework/*": [
|
|
||||||
"node_modules/pragmatismo-io-framework/*"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"types": [
|
"types": ["node", "lodash", "node-fetch"],
|
||||||
"node",
|
|
||||||
"lodash",
|
|
||||||
"node-fetch"
|
|
||||||
],
|
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"typeRoots": [
|
"typeRoots": ["node_modules/@types"]
|
||||||
"node_modules/@types"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["src/**/*", "packages/*.gbapp/**/*", "packages/*.gblib/**/*", "packages/*.gbtheme/**/*"],
|
||||||
"src/**/*",
|
"exclude": ["dist", "node_modules", "**/*.test.ts"]
|
||||||
"packages/*.gbapp/**/*",
|
}
|
||||||
"packages/*.gblib/**/*",
|
|
||||||
"packages/*.gbtheme/**/*"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"dist",
|
|
||||||
"node_modules",
|
|
||||||
"**/*.test.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
npm --save install \
|
npm install \
|
||||||
c3-chart-maker@0.2.8 \
|
c3-chart-maker@0.2.8 \
|
||||||
|
ms-rest-azure@3.0.2 \
|
||||||
open-docxtemplater-image-module@1.0.3 \
|
open-docxtemplater-image-module@1.0.3 \
|
||||||
svg2img@1.0.0-beta.2 \
|
svg2img@1.0.0-beta.2 \
|
||||||
get-image-colors@4.0.1 \
|
get-image-colors@4.0.1 \
|
||||||
|
textract \
|
||||||
pragmatismo-framework \
|
webp-converter \
|
||||||
botlib \
|
final-stream
|
||||||
Loading…
Add table
Reference in a new issue