fix(all): fetch calls replaces request packages.

This commit is contained in:
rodrigorodriguez 2022-11-30 09:40:09 -03:00
parent e4fc246b25
commit ea6c721cb5
11 changed files with 1668 additions and 162 deletions

1547
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -14,7 +14,7 @@
"Dário Vieira <dario.junior3@gmail.com>" "Dário Vieira <dario.junior3@gmail.com>"
], ],
"engines": { "engines": {
"node": "=19.1.0" "node": "=19.2.0"
}, },
"license": "AGPL-3.0", "license": "AGPL-3.0",
"preferGlobal": true, "preferGlobal": true,
@ -143,6 +143,7 @@
"swagger-client": "^3.18.5", "swagger-client": "^3.18.5",
"tabulator-tables": "5.4.2", "tabulator-tables": "5.4.2",
"tedious": "15.1.2", "tedious": "15.1.2",
"textract": "^2.5.0",
"twitter-api-v2": "1.12.9", "twitter-api-v2": "1.12.9",
"typescript": "4.9.3", "typescript": "4.9.3",
"typescript-rest-rpc": "^1.0.7", "typescript-rest-rpc": "^1.0.7",

View file

@ -94,7 +94,7 @@ export class GuaribasConversation extends Model<GuaribasConversation> {
@CreatedAt @CreatedAt
@Column(DataType.DATE) @Column(DataType.DATE)
createdAt: Date; declare createdAt: Date;
@Column(DataType.STRING(255)) @Column(DataType.STRING(255))
text: string; text: string;
@ -126,11 +126,11 @@ export class GuaribasConversationMessage extends Model<GuaribasConversationMessa
@Column(DataType.DATE) @Column(DataType.DATE)
@CreatedAt @CreatedAt
createdAt: Date; declare createdAt: Date;
@Column(DataType.DATE) @Column(DataType.DATE)
@UpdatedAt @UpdatedAt
updatedAt: Date; declare updatedAt: Date;
//tslint:disable-next-line:no-use-before-declare //tslint:disable-next-line:no-use-before-declare
@ForeignKey(() => GuaribasConversation) @ForeignKey(() => GuaribasConversation)

View file

@ -69,9 +69,9 @@ export class GuaribasSchedule extends Model<GuaribasSchedule> {
@Column(DataType.DATE) @Column(DataType.DATE)
@CreatedAt @CreatedAt
createdAt: Date; declare createdAt: Date;
@Column(DataType.DATE) @Column(DataType.DATE)
@UpdatedAt @UpdatedAt
updatedAt: Date; declare updatedAt: Date;
} }

View file

@ -383,11 +383,8 @@ export class SystemKeywords {
* Retrives stock inforation for a given symbol. * Retrives stock inforation for a given symbol.
*/ */
public async getStock ({ symbol }) { public async getStock ({ symbol }) {
var options = { const url = `http://live-nse.herokuapp.com/?symbol=${symbol}`;
uri: `http://live-nse.herokuapp.com/?symbol=${symbol}` let data = await fetch(url);
};
let data = await request.get(options);
return data; return data;
} }
@ -716,8 +713,8 @@ export class SystemKeywords {
const gbaiName = `${this.min.botId}.gbai`; const gbaiName = `${this.min.botId}.gbai`;
const localName = Path.join('work', gbaiName, 'cache', `csv${GBAdminService.getRndReadableIdentifier()}.csv`); const localName = Path.join('work', gbaiName, 'cache', `csv${GBAdminService.getRndReadableIdentifier()}.csv`);
const url = file['@microsoft.graph.downloadUrl']; const url = file['@microsoft.graph.downloadUrl'];
const response = await request({ uri: url, encoding: null }); const response = await fetch(url);
Fs.writeFileSync(localName, response, { encoding: null }); Fs.writeFileSync(localName, Buffer.from(await response.arrayBuffer()), { encoding: null });
var workbook = new Excel.Workbook(); var workbook = new Excel.Workbook();
const worksheet = await workbook.csv.readFile(localName); const worksheet = await workbook.csv.readFile(localName);
@ -1282,7 +1279,7 @@ export class SystemKeywords {
* *
*/ */
public async getByHttp ({ url, headers, username, ps, qs, streaming }) { public async getByHttp ({ url, headers, username, ps, qs, streaming }) {
let options = { url: url }; let options = { };
if (headers) { if (headers) {
options['headers'] = headers; options['headers'] = headers;
} }
@ -1295,14 +1292,14 @@ export class SystemKeywords {
if (qs) { if (qs) {
options['qs'] = qs; options['qs'] = qs;
} }
if (streaming) { if (streaming) { // TODO: Do it with fetch.
options['responseType'] = 'stream'; options['responseType'] = 'stream';
options['encoding'] = null; options['encoding'] = null;
} }
let result = await request.get(options); let result = await fetch(url, options);
try { try {
return JSON.parse(result); return JSON.parse(await result.text());
} catch (error) { } catch (error) {
GBLog.info(`[GET]: OK.`); GBLog.info(`[GET]: OK.`);
@ -1321,12 +1318,11 @@ export class SystemKeywords {
*/ */
public async putByHttp ({ url, data, headers }) { public async putByHttp ({ url, data, headers }) {
const options = { const options = {
uri: url,
json: data, json: data,
headers: headers headers: headers
}; };
let result = await request.put(options); let result = await fetch(url, options);
GBLog.info(`[PUT]: ${url} (${data}): ${result}`); GBLog.info(`[PUT]: ${url} (${data}): ${result}`);
return typeof result === 'object' ? result : JSON.parse(result); return typeof result === 'object' ? result : JSON.parse(result);
} }
@ -1342,12 +1338,11 @@ export class SystemKeywords {
*/ */
public async postByHttp ({ url, data, headers }) { public async postByHttp ({ url, data, headers }) {
const options = { const options = {
uri: url,
json: data, json: data,
headers: headers headers: headers
}; };
let result = await request.post(options); let result = await fetch(url, options);
GBLog.info(`[POST]: ${url} (${data}): ${result}`); GBLog.info(`[POST]: ${url} (${data}): ${result}`);
return result ? (typeof result === 'object' ? result : JSON.parse(result)) : true; return result ? (typeof result === 'object' ? result : JSON.parse(result)) : true;
@ -1375,8 +1370,8 @@ export class SystemKeywords {
let template = await this.internalGetDocument(client, baseUrl, path, templateName); let template = await this.internalGetDocument(client, baseUrl, path, templateName);
const url = template['@microsoft.graph.downloadUrl']; const url = template['@microsoft.graph.downloadUrl'];
const localName = Path.join('work', gbaiName, 'cache', ``); const localName = Path.join('work', gbaiName, 'cache', ``);
const response = await request({ uri: url, encoding: null }); const response = await fetch( url);
Fs.writeFileSync(localName, response, { encoding: null }); Fs.writeFileSync(localName, Buffer.from(await response.arrayBuffer()), { encoding: null });
// Loads the file as binary content. // Loads the file as binary content.

View file

@ -57,7 +57,7 @@ import { join } from 'path';
import shell from 'any-shell-escape'; 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 request from 'request-promise-native';
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';
@ -355,27 +355,26 @@ export class GBConversationalService {
GBLog.info(`Sending SMS to ${mobile} with text: '${text}'.`); GBLog.info(`Sending SMS to ${mobile} with text: '${text}'.`);
if (!min.instance.smsKey && min.instance.smsSecret) { if (!min.instance.smsKey && min.instance.smsSecret) {
const url = 'http://sms-api.megaconecta.com.br/mt';
let options = { let options = {
method: 'POST', method: 'POST',
url: 'http://sms-api.megaconecta.com.br/mt',
headers: { headers: {
'content-type': 'application/json', 'content-type': 'application/json',
authorization: `Bearer ${min.instance.smsSecret}` authorization: `Bearer ${min.instance.smsSecret}`
}, },
body: [ body:
{ JSON.stringify({
numero: `${mobile}`, numero: `${mobile}`,
servico: 'short', servico: 'short',
mensagem: text, mensagem: text,
parceiro_id: '', parceiro_id: '',
codificacao: '0' codificacao: '0'
} })
],
json: true
}; };
try { try {
const results = await request(options); const results = await fetch(url, options);
return results; return results;
} catch (error) { } catch (error) {
@ -961,30 +960,24 @@ export class GBConversationalService {
return Promise.reject(new Error(msg)); return Promise.reject(new Error(msg));
} }
} else { } else {
const url = urlJoin(endPoint, 'translate', new URLSearchParams({
'api-version': '3.0',
to: language
}).toString());
let options = { let options = {
method: 'POST', method: 'POST',
baseUrl: endPoint,
url: 'translate',
qs: {
'api-version': '3.0',
to: [language]
},
headers: { headers: {
'Ocp-Apim-Subscription-Key': key, 'Ocp-Apim-Subscription-Key': key,
'Ocp-Apim-Subscription-Region': 'westeurope', 'Ocp-Apim-Subscription-Region': 'westeurope',
'Content-type': 'application/json', 'Content-type': 'application/json',
'X-ClientTraceId': GBAdminService.generateUuid() 'X-ClientTraceId': GBAdminService.generateUuid()
}, },
body: [ body:text,
{
text: text
}
],
json: true json: true
}; };
try { try {
const results = await request(options); const results = await fetch(url, options);
return results[0].translations[0].text; return results[0].translations[0].text;
} catch (error) { } catch (error) {

View file

@ -40,7 +40,7 @@ import Path from 'path';
import express from 'express'; import express from 'express';
import child_process from 'child_process'; import child_process from 'child_process';
import rimraf from 'rimraf'; import rimraf from 'rimraf';
import request from 'request-promise-native';
import vhost from 'vhost'; import vhost from 'vhost';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
import Fs from 'fs'; import Fs from 'fs';
@ -522,8 +522,8 @@ export class GBDeployer implements IGBDeployer {
GBLog.info(`Downloading ${itemPath}...`); GBLog.info(`Downloading ${itemPath}...`);
const url = item['@microsoft.graph.downloadUrl']; const url = item['@microsoft.graph.downloadUrl'];
const response = await request({ uri: url, encoding: null }); const response = await fetch(url);
Fs.writeFileSync(itemPath, response, { encoding: null }); Fs.writeFileSync(itemPath, Buffer.from(await response.arrayBuffer()), { encoding: null });
Fs.utimesSync(itemPath, new Date(), new Date(item.lastModifiedDateTime)); Fs.utimesSync(itemPath, new Date(), new Date(item.lastModifiedDateTime));
} else { } else {
GBLog.info(`Local is up to date: ${itemPath}...`); GBLog.info(`Local is up to date: ${itemPath}...`);

View file

@ -39,9 +39,9 @@ import cliProgress from 'cli-progress';
import { DialogSet, TextPrompt } from 'botbuilder-dialogs'; import { DialogSet, TextPrompt } from 'botbuilder-dialogs';
import express from 'express'; import express from 'express';
import Swagger from 'swagger-client'; import Swagger from 'swagger-client';
import request from 'request-promise-native';
import removeRoute from 'express-remove-route'; import removeRoute from 'express-remove-route';
import AuthenticationContext from '@azure/msal-node'; import AuthenticationContext from 'adal-node';
import wash from 'washyourmouthoutwithsoap'; import wash from 'washyourmouthoutwithsoap';
import { FacebookAdapter } from 'botbuilder-adapter-facebook'; import { FacebookAdapter } from 'botbuilder-adapter-facebook';
import path from 'path'; import path from 'path';
@ -574,8 +574,8 @@ export class GBMinService {
* Gets Webchat token from Bot Service. * Gets Webchat token from Bot Service.
*/ */
private async getWebchatToken (instance: any) { private async getWebchatToken (instance: any) {
const url = 'https://directline.botframework.com/v3/directline/tokens/generate';
const options = { const options = {
url: 'https://directline.botframework.com/v3/directline/tokens/generate',
method: 'POST', method: 'POST',
headers: { headers: {
Authorization: `Bearer ${instance.webchatKey}` Authorization: `Bearer ${instance.webchatKey}`
@ -583,9 +583,9 @@ export class GBMinService {
}; };
try { try {
const json = await request(options); const res = await fetch(url, options);
return JSON.parse(json); return await res.json();
} catch (error) { } catch (error) {
const msg = `[botId:${instance.botId}] Error calling Direct Line to generate a token for Web control: ${error}.`; const msg = `[botId:${instance.botId}] Error calling Direct Line to generate a token for Web control: ${error}.`;
@ -598,7 +598,6 @@ export class GBMinService {
*/ */
private async getSTSToken (instance: any) { private async getSTSToken (instance: any) {
const options = { const options = {
url: instance.speechEndpoint,
method: 'POST', method: 'POST',
headers: { headers: {
'Ocp-Apim-Subscription-Key': instance.speechKey 'Ocp-Apim-Subscription-Key': instance.speechKey
@ -606,7 +605,7 @@ export class GBMinService {
}; };
try { try {
return await request(options); return await fetch(instance.speechEndpoint, options);
} catch (error) { } catch (error) {
const msg = `Error calling Speech to Text client. Error is: ${error}.`; const msg = `Error calling Speech to Text client. Error is: ${error}.`;

View file

@ -153,11 +153,11 @@ export class GuaribasQuestion extends Model<GuaribasQuestion> {
@Column(DataType.DATE) @Column(DataType.DATE)
@CreatedAt @CreatedAt
createdAt: Date; declare createdAt: Date;
@Column(DataType.DATE) @Column(DataType.DATE)
@UpdatedAt @UpdatedAt
updatedAt: Date; declare updatedAt: Date;
//tslint:disable-next-line:no-use-before-declare //tslint:disable-next-line:no-use-before-declare
@ForeignKey(() => GuaribasAnswer) @ForeignKey(() => GuaribasAnswer)

View file

@ -62,7 +62,6 @@ import { GBDeployer } from '../../core.gbapp/services/GBDeployer.js';
import { CSService } from '../../customer-satisfaction.gbapp/services/CSService.js'; import { CSService } from '../../customer-satisfaction.gbapp/services/CSService.js';
import { GuaribasAnswer, GuaribasQuestion, GuaribasSubject } from '../models/index.js'; import { GuaribasAnswer, GuaribasQuestion, GuaribasSubject } from '../models/index.js';
import { GBConfigService } from './../../core.gbapp/services/GBConfigService.js'; import { GBConfigService } from './../../core.gbapp/services/GBConfigService.js';
import request from 'request-promise-native';
import textract from 'textract'; import textract from 'textract';
import pdf from 'pdf-extraction'; import pdf from 'pdf-extraction';
@ -80,11 +79,11 @@ export class KBServiceSearchResults {
export class KBService implements IGBKBService { export class KBService implements IGBKBService {
public sequelize: Sequelize; public sequelize: Sequelize;
constructor (sequelize: Sequelize) { constructor(sequelize: Sequelize) {
this.sequelize = sequelize; this.sequelize = sequelize;
} }
public static getFormattedSubjectItems (subjects: GuaribasSubject[]) { public static getFormattedSubjectItems(subjects: GuaribasSubject[]) {
if (subjects === null) { if (subjects === null) {
return ''; return '';
} }
@ -96,7 +95,7 @@ export class KBService implements IGBKBService {
return out.join(', '); return out.join(', ');
} }
public static getSubjectItemsSeparatedBySpaces (subjects: GuaribasSubject[]) { public static getSubjectItemsSeparatedBySpaces(subjects: GuaribasSubject[]) {
const out = []; const out = [];
if (subjects === undefined) { if (subjects === undefined) {
return ''; return '';
@ -108,7 +107,7 @@ export class KBService implements IGBKBService {
return out.join(' '); return out.join(' ');
} }
public async getAnswerTextByMediaName (instanceId: number, answerMediaName: string): Promise<string> { public async getAnswerTextByMediaName(instanceId: number, answerMediaName: string): Promise<string> {
const answer = await GuaribasAnswer.findOne({ const answer = await GuaribasAnswer.findOne({
where: { where: {
instanceId: instanceId, instanceId: instanceId,
@ -119,7 +118,7 @@ export class KBService implements IGBKBService {
return answer != undefined ? answer.content : null; return answer != undefined ? answer.content : null;
} }
public async getQuestionById (instanceId: number, questionId: number): Promise<GuaribasQuestion> { public async getQuestionById(instanceId: number, questionId: number): Promise<GuaribasQuestion> {
return GuaribasQuestion.findOne({ return GuaribasQuestion.findOne({
where: { where: {
instanceId: instanceId, instanceId: instanceId,
@ -128,7 +127,7 @@ export class KBService implements IGBKBService {
}); });
} }
public async getAnswerById (instanceId: number, answerId: number): Promise<GuaribasAnswer> { public async getAnswerById(instanceId: number, answerId: number): Promise<GuaribasAnswer> {
return GuaribasAnswer.findOne({ return GuaribasAnswer.findOne({
where: { where: {
instanceId: instanceId, instanceId: instanceId,
@ -140,7 +139,7 @@ export class KBService implements IGBKBService {
/** /**
* Returns a question object given a SEO friendly URL. * Returns a question object given a SEO friendly URL.
*/ */
public async getQuestionIdFromURL (core: IGBCoreService, url: string) { public async getQuestionIdFromURL(core: IGBCoreService, url: string) {
// Extracts questionId from URL. // Extracts questionId from URL.
const id = url.substr(url.lastIndexOf('-') + 1); const id = url.substr(url.lastIndexOf('-') + 1);
@ -164,7 +163,7 @@ export class KBService implements IGBKBService {
return question; return question;
} }
public static async getQuestionsNER (instanceId: number) { public static async getQuestionsNER(instanceId: number) {
const where = { const where = {
instanceId: instanceId, instanceId: instanceId,
content: { [Op.like]: `%(%` } content: { [Op.like]: `%(%` }
@ -177,7 +176,7 @@ export class KBService implements IGBKBService {
return questions; return questions;
} }
public async getQuestionsSEO (instanceId: number) { public async getQuestionsSEO(instanceId: number) {
const questions = await GuaribasQuestion.findAll({ const questions = await GuaribasQuestion.findAll({
where: { where: {
instanceId: instanceId instanceId: instanceId
@ -195,7 +194,7 @@ export class KBService implements IGBKBService {
return output; return output;
} }
public async getDocs (instanceId: number) { public async getDocs(instanceId: number) {
return await GuaribasAnswer.findAll({ return await GuaribasAnswer.findAll({
where: { where: {
instanceId: instanceId, instanceId: instanceId,
@ -204,7 +203,7 @@ export class KBService implements IGBKBService {
}); });
} }
public async getAnswerByText (instanceId: number, text: string, from: string = null): Promise<any> { public async getAnswerByText(instanceId: number, text: string, from: string = null): Promise<any> {
text = text.trim(); text = text.trim();
const service = new CSService(); const service = new CSService();
@ -247,11 +246,11 @@ export class KBService implements IGBKBService {
return undefined; return undefined;
} }
public async addAnswer (obj: GuaribasAnswer): Promise<GuaribasAnswer> { public async addAnswer(obj: GuaribasAnswer): Promise<GuaribasAnswer> {
return await GuaribasAnswer.create(obj); return await GuaribasAnswer.create(obj);
} }
public async ask ( public async ask(
instance: IGBInstance, instance: IGBInstance,
query: string, query: string,
searchScore: number, searchScore: number,
@ -350,7 +349,7 @@ export class KBService implements IGBKBService {
} }
} }
public async getSubjectItems (instanceId: number, parentId: number): Promise<GuaribasSubject[]> { public async getSubjectItems(instanceId: number, parentId: number): Promise<GuaribasSubject[]> {
const where = { parentSubjectId: parentId, instanceId: instanceId }; const where = { parentSubjectId: parentId, instanceId: instanceId };
return GuaribasSubject.findAll({ return GuaribasSubject.findAll({
@ -358,7 +357,7 @@ export class KBService implements IGBKBService {
}); });
} }
public async getFaqBySubjectArray (instanceId: number, from: string, subjects: any): Promise<GuaribasQuestion[]> { public async getFaqBySubjectArray(instanceId: number, from: string, subjects: any): Promise<GuaribasQuestion[]> {
if (subjects) { if (subjects) {
const where = { const where = {
from: from, from: from,
@ -400,13 +399,13 @@ export class KBService implements IGBKBService {
} }
} }
public static async getGroupReplies (instanceId: number): Promise<GuaribasQuestion[]> { public static async getGroupReplies(instanceId: number): Promise<GuaribasQuestion[]> {
return await GuaribasQuestion.findAll({ return await GuaribasQuestion.findAll({
where: { from: 'group', instanceId: instanceId } where: { from: 'group', instanceId: instanceId }
}); });
} }
public async importKbTabularFile ( public async importKbTabularFile(
filePath: string, filePath: string,
instanceId: number, instanceId: number,
packageId: number packageId: number
@ -572,7 +571,7 @@ export class KBService implements IGBKBService {
return await GuaribasQuestion.bulkCreate(questions); return await GuaribasQuestion.bulkCreate(questions);
} }
public async sendAnswer (min: GBMinInstance, channel: string, step: GBDialogStep, answer: GuaribasAnswer) { public async sendAnswer(min: GBMinInstance, channel: string, step: GBDialogStep, answer: GuaribasAnswer) {
if (answer.content.endsWith('.mp4')) { if (answer.content.endsWith('.mp4')) {
await this.playVideo(min, min.conversationalService, step, answer, channel); await this.playVideo(min, min.conversationalService, step, answer, channel);
} else if ( } else if (
@ -606,7 +605,7 @@ export class KBService implements IGBKBService {
} }
} }
public async importKbPackage ( public async importKbPackage(
min: GBMinInstance, min: GBMinInstance,
localPath: string, localPath: string,
packageStorage: GuaribasPackage, packageStorage: GuaribasPackage,
@ -636,7 +635,7 @@ export class KBService implements IGBKBService {
/** /**
* Import all .md files in articles folder that has not been referenced by tabular files. * Import all .md files in articles folder that has not been referenced by tabular files.
*/ */
public async importRemainingArticles (localPath: string, instance: IGBInstance, packageId: number): Promise<any> { public async importRemainingArticles(localPath: string, instance: IGBInstance, packageId: number): Promise<any> {
const files = await walkPromise(urlJoin(localPath, 'articles')); const files = await walkPromise(urlJoin(localPath, 'articles'));
await CollectionUtil.asyncForEach(files, async file => { await CollectionUtil.asyncForEach(files, async file => {
@ -663,7 +662,7 @@ export class KBService implements IGBKBService {
/** /**
* Import all .docx files in reading comprehension folder. * Import all .docx files in reading comprehension folder.
*/ */
public async importDocs ( public async importDocs(
min: GBMinInstance, min: GBMinInstance,
localPath: string, localPath: string,
instance: IGBInstance, instance: IGBInstance,
@ -701,7 +700,7 @@ export class KBService implements IGBKBService {
} }
} }
public async importKbTabularDirectory (localPath: string, instance: IGBInstance, packageId: number): Promise<any> { public async importKbTabularDirectory(localPath: string, instance: IGBInstance, packageId: number): Promise<any> {
const files = await walkPromise(localPath); const files = await walkPromise(localPath);
await CollectionUtil.asyncForEach(files, async file => { await CollectionUtil.asyncForEach(files, async file => {
@ -711,7 +710,7 @@ export class KBService implements IGBKBService {
}); });
} }
public async importSubjectFile (packageId: number, filename: string, instance: IGBInstance): Promise<any> { public async importSubjectFile(packageId: number, filename: string, instance: IGBInstance): Promise<any> {
const subjectsLoaded = JSON.parse(Fs.readFileSync(filename, 'utf8')); const subjectsLoaded = JSON.parse(Fs.readFileSync(filename, 'utf8'));
const doIt = async (subjects: GuaribasSubject[], parentSubjectId: number) => { const doIt = async (subjects: GuaribasSubject[], parentSubjectId: number) => {
@ -738,7 +737,7 @@ export class KBService implements IGBKBService {
return doIt(subjectsLoaded.children, undefined); return doIt(subjectsLoaded.children, undefined);
} }
public async undeployKbFromStorage (instance: IGBInstance, deployer: GBDeployer, packageId: number) { public async undeployKbFromStorage(instance: IGBInstance, deployer: GBDeployer, packageId: number) {
await GuaribasQuestion.destroy({ await GuaribasQuestion.destroy({
where: { instanceId: instance.instanceId, packageId: packageId } where: { instanceId: instance.instanceId, packageId: packageId }
}); });
@ -751,7 +750,7 @@ export class KBService implements IGBKBService {
await this.undeployPackageFromStorage(instance, packageId); await this.undeployPackageFromStorage(instance, packageId);
} }
public static async RefreshNER (min: GBMinInstance) { public static async RefreshNER(min: GBMinInstance) {
const questions = await KBService.getQuestionsNER(min.instance.instanceId); const questions = await KBService.getQuestionsNER(min.instance.instanceId);
const contentLocale = min.core.getParam<string>( const contentLocale = min.core.getParam<string>(
min.instance, min.instance,
@ -778,7 +777,7 @@ export class KBService implements IGBKBService {
* *
* @param localPath Path to the .gbkb folder. * @param localPath Path to the .gbkb folder.
*/ */
public async deployKb (core: IGBCoreService, deployer: GBDeployer, localPath: string, min: GBMinInstance) { public async deployKb(core: IGBCoreService, deployer: GBDeployer, localPath: string, min: GBMinInstance) {
const packageName = Path.basename(localPath); const packageName = Path.basename(localPath);
GBLog.info(`[GBDeployer] Opening package: ${localPath}`); GBLog.info(`[GBDeployer] Opening package: ${localPath}`);
@ -796,7 +795,7 @@ export class KBService implements IGBKBService {
GBLog.info(`[GBDeployer] Finished import of ${localPath}`); GBLog.info(`[GBDeployer] Finished import of ${localPath}`);
} }
private async playAudio ( private async playAudio(
min: GBMinInstance, min: GBMinInstance,
answer: GuaribasAnswer, answer: GuaribasAnswer,
channel: string, channel: string,
@ -806,7 +805,7 @@ export class KBService implements IGBKBService {
conversationalService.sendAudio(min, step, answer.content); conversationalService.sendAudio(min, step, answer.content);
} }
private async playUrl ( private async playUrl(
min, min,
conversationalService: IGBConversationalService, conversationalService: IGBConversationalService,
step: GBDialogStep, step: GBDialogStep,
@ -823,7 +822,7 @@ export class KBService implements IGBKBService {
} }
} }
private async playVideo ( private async playVideo(
min, min,
conversationalService: IGBConversationalService, conversationalService: IGBConversationalService,
step: GBDialogStep, step: GBDialogStep,
@ -840,25 +839,26 @@ export class KBService implements IGBKBService {
} }
} }
private async undeployPackageFromStorage (instance: any, packageId: number) { private async undeployPackageFromStorage(instance: any, packageId: number) {
await GuaribasPackage.destroy({ await GuaribasPackage.destroy({
where: { instanceId: instance.instanceId, packageId: packageId } where: { instanceId: instance.instanceId, packageId: packageId }
}); });
} }
public async readComprehension (instanceId: number, doc: string, question: string) { public async readComprehension(instanceId: number, doc: string, question: string) {
const url =
`http://${process.env.GBMODELS_SERVER}/reading-comprehension` +
new URLSearchParams({ question: question, key: process.env.GBMODELS_KEY });
const form = new FormData();
form.append('content', doc);
const options = { const options = {
timeout: 60000 * 5, body: form
uri: `http://${process.env.GBMODELS_SERVER}/reading-comprehension`,
form: { content: doc },
qs: { question: question, key: process.env.GBMODELS_KEY }
}; };
GBLog.info(`[General Bots Models]: ReadComprehension for ${question}.`); GBLog.info(`[General Bots Models]: ReadComprehension for ${question}.`);
return await request.post(options); return await fetch(url, options);
} }
private async getTextFromFile (filename: string) { private async getTextFromFile(filename: string) {
return new Promise<string>(async (resolve, reject) => { return new Promise<string>(async (resolve, reject) => {
textract.fromFileWithPath(filename, { preserveLineBreaks: true }, (error, text) => { textract.fromFileWithPath(filename, { preserveLineBreaks: true }, (error, text) => {
if (error) { if (error) {

View file

@ -79,7 +79,7 @@ export class WhatsappDirectLine extends GBService {
private browserWSEndpoint; private browserWSEndpoint;
private groupId; private groupId;
constructor ( constructor(
min: GBMinInstance, min: GBMinInstance,
botId, botId,
directLineSecret, directLineSecret,
@ -105,13 +105,13 @@ export class WhatsappDirectLine extends GBService {
this.groupId = groupId; this.groupId = groupId;
} }
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 = new Swagger({ this.directLineClient = new Swagger({
spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')), spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')),
usePromise: true usePromise: true
@ -192,17 +192,22 @@ export class WhatsappDirectLine extends GBService {
const s = new DialogKeywords(this.min, null, null); const s = new DialogKeywords(this.min, null, null);
const qrBuf = await s.getQRCode(qr); const qrBuf = await s.getQRCode(qr);
const gbaiName = `${this.min.botId}.gbai`; const gbaiName = `${this.min.botId}.gbai`;
const localName = Path.join('work', gbaiName, 'cache', `qr${GBAdminService.getRndReadableIdentifier()}.png`); const localName = Path.join(
Fs.writeFileSync(localName, qrBuf); 'work',
const url = urlJoin( gbaiName,
GBServer.globals.publicAddress,
this.min.botId,
'cache', 'cache',
Path.basename(localName) `qr${GBAdminService.getRndReadableIdentifier()}.png`
);
Fs.writeFileSync(localName, qrBuf);
const url = urlJoin(GBServer.globals.publicAddress, this.min.botId, 'cache', Path.basename(localName));
GBServer.globals.minBoot.whatsAppDirectLine.sendFileToDevice(
adminNumber,
url,
Path.basename(localName),
msg
); );
GBServer.globals.minBoot.whatsAppDirectLine.sendFileToDevice(adminNumber, url, Path.basename(localName), msg);
s.sendEmail({to:adminEmail, subject:`Check your WhatsApp for bot ${this.botId}`, body:msg); s.sendEmail({ to: adminEmail, subject: `Check your WhatsApp for bot ${this.botId}`, body: msg });
}).bind(this) }).bind(this)
); );
@ -250,7 +255,7 @@ export class WhatsappDirectLine extends GBService {
break; break;
case 'chatapi': case 'chatapi':
url = urlJoin(this.whatsappServiceUrl, 'webhook') url = urlJoin(this.whatsappServiceUrl, 'webhook');
options = { options = {
method: 'POST', method: 'POST',
url: url, url: url,
@ -270,7 +275,7 @@ export class WhatsappDirectLine extends GBService {
let phoneId = this.whatsappServiceNumber.split(';')[0]; let phoneId = this.whatsappServiceNumber.split(';')[0];
let productId = this.whatsappServiceNumber.split(';')[1]; let productId = this.whatsappServiceNumber.split(';')[1];
url = `${this.INSTANCE_URL}/${productId}/${phoneId}/config`; url = `${this.INSTANCE_URL}/${productId}/${phoneId}/config`;
body= { body = {
webhook: `${GBServer.globals.publicAddress}/webhooks/whatsapp/${this.botId}`, webhook: `${GBServer.globals.publicAddress}/webhooks/whatsapp/${this.botId}`,
ack_delivery: false ack_delivery: false
}; };
@ -279,7 +284,7 @@ export class WhatsappDirectLine extends GBService {
options = { options = {
url: url, url: url,
method: 'POST', method: 'POST',
body:body, body: body,
headers: { headers: {
'x-maytapi-key': this.whatsappServiceKey, 'x-maytapi-key': this.whatsappServiceKey,
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@ -294,9 +299,7 @@ export class WhatsappDirectLine extends GBService {
if (options) { if (options) {
try { try {
const response: Response = await fetch(url, options);
const response: Response = await fetch(url,options);
} catch (error) { } catch (error) {
GBLog.error(`Error initializing 3rd party Whatsapp provider(1) ${error.message}`); GBLog.error(`Error initializing 3rd party Whatsapp provider(1) ${error.message}`);
} }
@ -304,33 +307,33 @@ export class WhatsappDirectLine extends GBService {
} }
} }
public async resetConversationId (botId, number, group = '') { public async resetConversationId(botId, number, group = '') {
WhatsappDirectLine.conversationIds[botId + number + group] = undefined; WhatsappDirectLine.conversationIds[botId + number + group] = undefined;
} }
public async check () { public async check() {
switch (this.provider) { switch (this.provider) {
case 'GeneralBots': case 'GeneralBots':
return true; return true;
default: default:
GBLog.verbose(`GBWhatsapp: Checking server...`); GBLog.verbose(`GBWhatsapp: Checking server...`);
let url = urlJoin(this.whatsappServiceUrl, 'status') + `?token=${this.min.instance.whatsappServiceKey}`;
const options = { const options = {
url: urlJoin(this.whatsappServiceUrl, 'status') + `?token=${this.min.instance.whatsappServiceKey}`, url: url,
method: 'GET' method: 'GET'
}; };
const res = await request(options); const res = await fetch(url, options);
const json = JSON.parse(res); const json = (await res.json());
return json ['accountStatus'] === 'authenticated';
return json.accountStatus === 'authenticated';
} }
} }
public static providerFromRequest (req) { public static providerFromRequest(req) {
return req.body.messages ? 'chatapi' : req.body.message ? 'maytapi' : 'GeneralBots'; return req.body.messages ? 'chatapi' : req.body.message ? 'maytapi' : 'GeneralBots';
} }
public async received (req, res) { public async received(req, res) {
const provider = WhatsappDirectLine.providerFromRequest(req); const provider = WhatsappDirectLine.providerFromRequest(req);
let message, from, fromName, text; let message, from, fromName, text;
@ -484,15 +487,16 @@ export class WhatsappDirectLine extends GBService {
} }
if (message.type === 'ptt') { if (message.type === 'ptt') {
let url = provider ? message.body : message.text;
if (process.env.AUDIO_DISABLED !== 'true') { if (process.env.AUDIO_DISABLED !== 'true') {
const options = { const options = {
url: provider ? message.body : message.text, url: url,
method: 'GET', method: 'GET',
encoding: 'binary' encoding: 'binary'
}; };
const res = await request(options); const res = await fetch(url, options);
const buf = Buffer.from(res, 'binary'); const buf = Buffer.from(await res.arrayBuffer());
text = await GBConversationalService.getTextFromAudioBuffer( text = await GBConversationalService.getTextFromAudioBuffer(
this.min.instance.speechKey, this.min.instance.speechKey,
this.min.instance.cloudLocation, this.min.instance.cloudLocation,
@ -620,7 +624,7 @@ export class WhatsappDirectLine extends GBService {
} }
} }
private async endTransfer (id: any, locale: string, user: GuaribasUser, agent: GuaribasUser, sec: SecService) { private async endTransfer(id: any, locale: string, user: GuaribasUser, agent: GuaribasUser, sec: SecService) {
await this.sendToDeviceEx(id, Messages[this.locale].notify_end_transfer(this.min.instance.botId), locale, null); await this.sendToDeviceEx(id, Messages[this.locale].notify_end_transfer(this.min.instance.botId), locale, null);
if (user.agentSystemId.charAt(2) === ':') { if (user.agentSystemId.charAt(2) === ':') {
@ -642,7 +646,7 @@ export class WhatsappDirectLine extends GBService {
await sec.updateHumanAgent(id, this.min.instance.instanceId, null); await sec.updateHumanAgent(id, this.min.instance.instanceId, null);
} }
public inputMessage (client, conversationId, text, from, fromName, group, attachments) { public inputMessage(client, conversationId, text, from, fromName, group, attachments) {
return client.Conversations.Conversations_PostActivity({ return client.Conversations.Conversations_PostActivity({
conversationId: conversationId, conversationId: conversationId,
activity: { activity: {
@ -661,7 +665,7 @@ export class WhatsappDirectLine extends GBService {
}); });
} }
public pollMessages (client, conversationId, from, fromName) { public pollMessages(client, conversationId, from, fromName) {
GBLog.info(`GBWhatsapp: Starting message polling(${from}, ${conversationId}).`); GBLog.info(`GBWhatsapp: Starting message polling(${from}, ${conversationId}).`);
let watermark: any; let watermark: any;
@ -685,7 +689,7 @@ export class WhatsappDirectLine extends GBService {
setInterval(worker, this.pollInterval); setInterval(worker, this.pollInterval);
} }
public async printMessages (activities, conversationId, from, fromName) { public async printMessages(activities, conversationId, from, fromName) {
if (activities && activities.length) { if (activities && activities.length) {
// Ignore own messages. // Ignore own messages.
@ -701,7 +705,7 @@ export class WhatsappDirectLine extends GBService {
} }
} }
public async printMessage (activity, conversationId, from, fromName) { public async printMessage(activity, conversationId, from, fromName) {
let output = ''; let output = '';
if (activity.text) { if (activity.text) {
@ -729,11 +733,11 @@ export class WhatsappDirectLine extends GBService {
await this.sendToDevice(from, output, conversationId); await this.sendToDevice(from, output, conversationId);
} }
public renderHeroCard (attachment) { public renderHeroCard(attachment) {
return `${attachment.content.title} - ${attachment.content.text}`; return `${attachment.content.title} - ${attachment.content.text}`;
} }
public async sendFileToDevice (to, url, filename, caption, chatId) { public async sendFileToDevice(to, url, filename, caption, chatId) {
let options; let options;
switch (this.provider) { switch (this.provider) {
case 'GeneralBots': case 'GeneralBots':
@ -797,7 +801,7 @@ export class WhatsappDirectLine extends GBService {
if (options) { if (options) {
try { try {
// tslint:disable-next-line: await-promise // tslint:disable-next-line: await-promise
const result = await request.post(options); const result = await fetch(url, options);
GBLog.info(`File ${url} sent to ${to}: ${result}`); GBLog.info(`File ${url} sent to ${to}: ${result}`);
} catch (error) { } catch (error) {
GBLog.error(`Error sending file to Whatsapp provider ${error.message}`); GBLog.error(`Error sending file to Whatsapp provider ${error.message}`);
@ -805,7 +809,7 @@ export class WhatsappDirectLine extends GBService {
} }
} }
public async sendAudioToDevice (to, url, chatId) { public async sendAudioToDevice(to, url, chatId) {
let options; let options;
switch (this.provider) { switch (this.provider) {
case 'GeneralBots': case 'GeneralBots':
@ -838,7 +842,7 @@ export class WhatsappDirectLine extends GBService {
if (options) { if (options) {
try { try {
const result = await request.post(options); const result = await fetch(url, options);
GBLog.info(`Audio ${url} sent to ${to}: ${result}`); GBLog.info(`Audio ${url} sent to ${to}: ${result}`);
} catch (error) { } catch (error) {
GBLog.error(`Error sending audio message to Whatsapp provider ${error.message}`); GBLog.error(`Error sending audio message to Whatsapp provider ${error.message}`);
@ -846,15 +850,15 @@ export class WhatsappDirectLine extends GBService {
} }
} }
public async sendTextAsAudioToDevice (to, msg, chatId) { public async sendTextAsAudioToDevice(to, msg, chatId) {
const url = await GBConversationalService.getAudioBufferFromText(msg); const url = await GBConversationalService.getAudioBufferFromText(msg);
await this.sendFileToDevice(to, url, 'Audio', msg, chatId); await this.sendFileToDevice(to, url, 'Audio', msg, chatId);
} }
public async sendToDevice (to: string, msg: string, conversationId) { public async sendToDevice(to: string, msg: string, conversationId) {
const cmd = '/audio '; const cmd = '/audio ';
let url;
let chatId = WhatsappDirectLine.chatIds[conversationId]; let chatId = WhatsappDirectLine.chatIds[conversationId];
if (typeof msg !== 'object' && msg.startsWith(cmd)) { if (typeof msg !== 'object' && msg.startsWith(cmd)) {
@ -895,10 +899,9 @@ export class WhatsappDirectLine extends GBService {
case 'maytapi': case 'maytapi':
let phoneId = this.whatsappServiceNumber.split(';')[0]; let phoneId = this.whatsappServiceNumber.split(';')[0];
let productId = this.whatsappServiceNumber.split(';')[1]; let productId = this.whatsappServiceNumber.split(';')[1];
let url = `${this.INSTANCE_URL}/${productId}/${phoneId}/sendMessage`; url = `${this.INSTANCE_URL}/${productId}/${phoneId}/sendMessage`;
options = { options = {
url: url,
method: 'post', method: 'post',
json: true, json: true,
body: { type: 'text', message: msg, to_number: to }, body: { type: 'text', message: msg, to_number: to },
@ -913,7 +916,7 @@ export class WhatsappDirectLine extends GBService {
if (options) { if (options) {
try { try {
GBLog.info(`Message [${msg}] is being sent to ${to}...`); GBLog.info(`Message [${msg}] is being sent to ${to}...`);
await request.post(options); await fetch(url, options);
} catch (error) { } catch (error) {
GBLog.error(`Error sending message to Whatsapp provider ${error.message}`); GBLog.error(`Error sending message to Whatsapp provider ${error.message}`);
@ -923,12 +926,12 @@ export class WhatsappDirectLine extends GBService {
} }
} }
public async sendToDeviceEx (to, text, locale, conversationId) { public async sendToDeviceEx(to, text, locale, conversationId) {
text = await this.min.conversationalService.translate(this.min, text, locale); text = await this.min.conversationalService.translate(this.min, text, locale);
await this.sendToDevice(to, text, conversationId); await this.sendToDevice(to, text, conversationId);
} }
private async WhatsAppCallback (req, res) { private async WhatsAppCallback(req, res) {
try { try {
if (req.body && req.body.webhook) { if (req.body && req.body.webhook) {
res.status(200); res.status(200);
@ -1030,7 +1033,7 @@ export class WhatsappDirectLine extends GBService {
if (group) { if (group) {
GBLog.info(`Group: ${group}`); GBLog.info(`Group: ${group}`);
function getKeyByValue (object, value) { function getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value); return Object.keys(object).find(key => object[key] === value);
} }
const botId = getKeyByValue(WhatsappDirectLine.botGroups, group); const botId = getKeyByValue(WhatsappDirectLine.botGroups, group);
@ -1090,9 +1093,7 @@ export class WhatsappDirectLine extends GBService {
} else { } else {
await (activeMin as any).whatsAppDirectLine.sendToDevice( await (activeMin as any).whatsAppDirectLine.sendToDevice(
id, id,
`Olá! Seja bem-vinda(o)!\nMe chamo ${ `Olá! Seja bem-vinda(o)!\nMe chamo ${activeMin.instance.title}. Como posso ajudar? Pode me falar que eu te ouço, me manda um aúdio.`,
activeMin.instance.title
}. Como posso ajudar? Pode me falar que eu te ouço, me manda um aúdio.`,
null null
); );
if (res) { if (res) {
@ -1138,9 +1139,7 @@ export class WhatsappDirectLine extends GBService {
activeMin = GBServer.globals.minBoot; activeMin = GBServer.globals.minBoot;
await (activeMin as any).whatsAppDirectLine.sendToDevice( await (activeMin as any).whatsAppDirectLine.sendToDevice(
id, id,
`O outro Bot que você estava falando(${ `O outro Bot que você estava falando(${user.instanceId}), não está mais disponível. Agora você está falando comigo, ${activeMin.instance.title}...`
user.instanceId
}), não está mais disponível. Agora você está falando comigo, ${activeMin.instance.title}...`
); );
} }
await (activeMin as any).whatsAppDirectLine.received(req, res); await (activeMin as any).whatsAppDirectLine.received(req, res);