Merge branch 'main' of https://github.com/GeneralBots/BotServer
This commit is contained in:
commit
4c813ce02d
5 changed files with 133 additions and 153 deletions
|
@ -133,7 +133,7 @@
|
||||||
"prism-media": "1.3.4",
|
"prism-media": "1.3.4",
|
||||||
"public-ip": "6.0.1",
|
"public-ip": "6.0.1",
|
||||||
"punycode": "2.1.1",
|
"punycode": "2.1.1",
|
||||||
"puppeteer": "19.2.2",
|
"puppeteer": "19.6.3",
|
||||||
"puppeteer-extra": "3.3.4",
|
"puppeteer-extra": "3.3.4",
|
||||||
"puppeteer-extra-plugin-stealth": "2.11.1",
|
"puppeteer-extra-plugin-stealth": "2.11.1",
|
||||||
"qrcode": "1.5.1",
|
"qrcode": "1.5.1",
|
||||||
|
@ -165,7 +165,7 @@
|
||||||
"vm2-process": "2.1.1",
|
"vm2-process": "2.1.1",
|
||||||
"walk-promise": "0.2.0",
|
"walk-promise": "0.2.0",
|
||||||
"washyourmouthoutwithsoap": "1.0.2",
|
"washyourmouthoutwithsoap": "1.0.2",
|
||||||
"whatsapp-web.js": "1.18.3",
|
"whatsapp-web.js": "github:pedroslopez/whatsapp-web.js#fix-buttons-list",
|
||||||
"winston": "3.8.2",
|
"winston": "3.8.2",
|
||||||
"winston-logs-display": "1.0.0",
|
"winston-logs-display": "1.0.0",
|
||||||
"yarn": "1.22.19"
|
"yarn": "1.22.19"
|
||||||
|
|
|
@ -60,7 +60,7 @@ export class GBBasicPackage implements IGBPackage {
|
||||||
|
|
||||||
public async loadPackage (core: IGBCoreService, sequelize: Sequelize): Promise<void> {
|
public async loadPackage (core: IGBCoreService, sequelize: Sequelize): Promise<void> {
|
||||||
core.sequelize.addModels([GuaribasSchedule]);
|
core.sequelize.addModels([GuaribasSchedule]);
|
||||||
app.use(koaBody.koaBody({ multipart: true, }));
|
//app.use(koaBody.koaBody({ multipart: true, }));
|
||||||
|
|
||||||
app.listen(1111);
|
app.listen(1111);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1050,9 +1050,9 @@ export class DialogKeywords {
|
||||||
public static async getProcessInfo(pid: number) {
|
public static async getProcessInfo(pid: number) {
|
||||||
const proc = GBServer.globals.processes[pid];
|
const proc = GBServer.globals.processes[pid];
|
||||||
|
|
||||||
const min = GBServer.globals.minInstances.filter(p => p.instance.instanceId == proc.instanceId)[0];
|
const min = GBServer.globals.minInstances[0];//.filter(p => p.instance.instanceId == proc.instanceId)[0];
|
||||||
const sec = new SecService();
|
const sec = new SecService();
|
||||||
const user = await sec.getUserFromId(min.instance.instanceId, proc.userId);
|
const user = await sec.getUserFromId(min.instance.instanceId, "1");
|
||||||
const params = JSON.parse(user.params);
|
const params = JSON.parse(user.params);
|
||||||
return {
|
return {
|
||||||
min,
|
min,
|
||||||
|
@ -1064,13 +1064,15 @@ export class DialogKeywords {
|
||||||
/**
|
/**
|
||||||
* Talks to the user by using the specified text.
|
* Talks to the user by using the specified text.
|
||||||
*/
|
*/
|
||||||
public async talk({ pid, text }) {
|
public async talk(x) {
|
||||||
|
const text="",pid=0
|
||||||
GBLog.info(`BASIC: TALK '${text}'.`);
|
GBLog.info(`BASIC: TALK '${text}'.`);
|
||||||
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
const { min, user } = await DialogKeywords.getProcessInfo(pid);
|
||||||
|
await min.whatsAppDirectLine.sendButton();
|
||||||
if (user) {
|
if (user) {
|
||||||
// TODO: const translate = this.user ? this.user.basicOptions.translatorOn : false;
|
// TODO: const translate = this.user ? this.user.basicOptions.translatorOn : false;
|
||||||
|
|
||||||
await min.conversationalService['sendOnConversation'](min, user, text);
|
// await min.conversationalService['sendOnConversation'](min, user, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,12 +43,13 @@ import { Messages } from '../strings.js';
|
||||||
import { GuaribasUser } from '../../security.gbapp/models/index.js';
|
import { GuaribasUser } from '../../security.gbapp/models/index.js';
|
||||||
import { GBMinService } from '../../core.gbapp/services/GBMinService.js';
|
import { GBMinService } from '../../core.gbapp/services/GBMinService.js';
|
||||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
||||||
import * as wpp from 'whatsapp-web.js';
|
|
||||||
import qrcode from 'qrcode-terminal';
|
import qrcode from 'qrcode-terminal';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
||||||
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
import { method } from 'lodash';
|
import { method } from 'lodash';
|
||||||
|
import pkg from 'whatsapp-web.js';
|
||||||
|
const { Buttons, Client, MessageMedia } = pkg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for Whatsapp.
|
* Support for Whatsapp.
|
||||||
|
@ -114,6 +115,14 @@ export class WhatsappDirectLine extends GBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async sendButton() {
|
||||||
|
let url = 'https://wwebjs.dev/logo.png';
|
||||||
|
const media = await MessageMedia.fromUrl(url);
|
||||||
|
media.mimetype = 'image/png';
|
||||||
|
media.filename = 'hello.png';
|
||||||
|
let btnClickableMenu = new Buttons(media as any, [{ id: 'customId', body: 'button1' }, { body: 'button2' }]);
|
||||||
|
await this.sendToDevice("5521996049063",btnClickableMenu as any,null)
|
||||||
|
}
|
||||||
public async setup(setUrl: boolean) {
|
public async setup(setUrl: boolean) {
|
||||||
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')),
|
||||||
|
@ -123,115 +132,72 @@ export class WhatsappDirectLine extends GBService {
|
||||||
let url: string;
|
let url: string;
|
||||||
let body: any;
|
let body: any;
|
||||||
|
|
||||||
client.clientAuthorizations.add(
|
/*client.clientAuthorizations.add(
|
||||||
'AuthorizationBotConnector',
|
'AuthorizationBotConnector',
|
||||||
new Swagger.ApiKeyAuthorization('Authorization', `Bearer ${this.directLineSecret}`, 'header')
|
new Swagger.ApiKeyAuthorization('Authorization', `Bearer ${this.directLineSecret}`, 'header')
|
||||||
);
|
);*/
|
||||||
let options: any;
|
let options: any;
|
||||||
const phoneId = this.whatsappServiceNumber.split(';')[0];
|
const phoneId = this.whatsappServiceNumber.split(';')[0];
|
||||||
|
|
||||||
switch (this.provider) {
|
switch (this.provider) {
|
||||||
case 'GeneralBots':
|
case 'GeneralBots':
|
||||||
const minBoot = GBServer.globals.minBoot as any;
|
const minBoot = GBServer.globals.minBoot;
|
||||||
|
// TODO: REMOVE THIS.
|
||||||
|
if (!setUrl) {
|
||||||
|
this.customClient = minBoot.whatsAppDirectLine.customClient;
|
||||||
|
} else {
|
||||||
// Initialize the browser using a local profile for each bot.
|
// Initialize the browser using a local profile for each bot.
|
||||||
|
|
||||||
const gbaiName = `${this.min.botId}.gbai`;
|
const gbaiName = `${this.min.botId}.gbai`;
|
||||||
const localName = Path.join('work', gbaiName, 'profile');
|
const localName = Path.join('work', gbaiName, 'profile');
|
||||||
|
|
||||||
const createClient = async browserWSEndpoint => {
|
const createClient = async browserWSEndpoint => {
|
||||||
let puppeteer: any = {
|
let puppeteer = { headless: false, args: ['--no-sandbox', '--disable-dev-shm-usage'] };
|
||||||
headless: false,
|
|
||||||
args: [
|
|
||||||
'--no-sandbox',
|
|
||||||
'--disable-setuid-sandbox',
|
|
||||||
'--disable-dev-shm-usage',
|
|
||||||
'--disable-accelerated-2d-canvas',
|
|
||||||
'--no-first-run',
|
|
||||||
'--no-zygote',
|
|
||||||
'--single-process',
|
|
||||||
'--disable-gpu',
|
|
||||||
'--disable-infobars',
|
|
||||||
'--disable-features=site-per-process',
|
|
||||||
`--user-data-dir=${localName}`
|
|
||||||
]
|
|
||||||
};
|
|
||||||
if (browserWSEndpoint) {
|
if (browserWSEndpoint) {
|
||||||
puppeteer = { browserWSEndpoint: browserWSEndpoint };
|
// puppeteer.browserWSEndpoint = browserWSEndpoint ;
|
||||||
}
|
}
|
||||||
|
const client = (this.customClient = new Client({
|
||||||
const client = (this.customClient = new wpp.Client({
|
|
||||||
authStrategy: new wpp.LocalAuth({
|
|
||||||
clientId: this.min.botId,
|
|
||||||
dataPath: localName
|
|
||||||
}),
|
|
||||||
puppeteer: puppeteer
|
puppeteer: puppeteer
|
||||||
}));
|
}));
|
||||||
|
|
||||||
client.on(
|
client.on(
|
||||||
'message',
|
'message',
|
||||||
(async (message: string) => {
|
(async message => {
|
||||||
await this.WhatsAppCallback(message, null);
|
await this.WhatsAppCallback(message, null);
|
||||||
}).bind(this)
|
}).bind(this)
|
||||||
);
|
);
|
||||||
|
|
||||||
client.on(
|
client.on(
|
||||||
'qr',
|
'qr',
|
||||||
(async qr => {
|
(async qr => {
|
||||||
const adminNumber = this.min.core.getParam(this.min.instance, 'Bot Admin Number', null);
|
const adminNumber = this.min.core.getParam(this.min.instance, 'Bot Admin Number', null);
|
||||||
const adminEmail = this.min.core.getParam(this.min.instance, 'Bot Admin E-mail', null);
|
const adminEmail = this.min.core.getParam(this.min.instance, 'Bot Admin E-mail', null);
|
||||||
|
|
||||||
// Sends QR Code to boot bot admin.
|
// Sends QR Code to boot bot admin.
|
||||||
|
|
||||||
const msg = `Please, scan QR Code with for bot ${this.botId}.`;
|
const msg = `Please, scan QR Code with for bot ${this.botId}.`;
|
||||||
GBLog.info(msg);
|
GBLog.info(msg);
|
||||||
qrcode.generate(qr, { small: true, scale: 0.5 });
|
qrcode.generate(qr, { small: true, scale: 0.5 });
|
||||||
|
|
||||||
// While handling other bots uses boot instance of this class to send QR Codes.
|
// While handling other bots uses boot instance of this class to send QR Codes.
|
||||||
|
// const s = new DialogKeywords(min., null, 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,
|
||||||
'cache',
|
// this.min.botId,
|
||||||
`qr${GBAdminService.getRndReadableIdentifier()}.png`
|
// 'cache',
|
||||||
);
|
// Path.basename(localName)
|
||||||
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(
|
// s.sendEmail(adminEmail, `Check your WhatsApp for bot ${this.botId}`, msg);
|
||||||
adminNumber,
|
|
||||||
url,
|
|
||||||
Path.basename(localName),
|
|
||||||
msg
|
|
||||||
);
|
|
||||||
|
|
||||||
s.sendEmail({ pid: 0, to: adminEmail, subject: `Check your WhatsApp for bot ${this.botId}`, body: msg });
|
|
||||||
}).bind(this)
|
}).bind(this)
|
||||||
);
|
);
|
||||||
|
|
||||||
client.on('authenticated', async () => {
|
client.on('authenticated', async () => {
|
||||||
this.browserWSEndpoint = client.pupBrowser.wsEndpoint();
|
this.browserWSEndpoint = client.pupBrowser.wsEndpoint();
|
||||||
GBLog.verbose(`GBWhatsApp: QR Code authenticated for ${this.botId}.`);
|
GBLog.verbose(`GBWhatsApp: QR Code authenticated for ${this.botId}.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('ready', async () => {
|
client.on('ready', async () => {
|
||||||
client.pupBrowser.on(
|
|
||||||
'disconnected',
|
|
||||||
(async () => {
|
|
||||||
GBLog.info(`Browser terminated. Restarting ${this.min.botId} WhatsApp native provider.`);
|
|
||||||
await createClient.bind(this)(null);
|
|
||||||
}).bind(this)
|
|
||||||
);
|
|
||||||
|
|
||||||
GBLog.verbose(`GBWhatsApp: Emptying chat list for ${this.botId}...`);
|
GBLog.verbose(`GBWhatsApp: Emptying chat list for ${this.botId}...`);
|
||||||
|
|
||||||
// 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 CollectionUtil.asyncForEach(chats, async chat => {
|
||||||
const sleep = (ms: number) => {
|
const sleep = ms => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
setTimeout(resolve, ms);
|
setTimeout(resolve, ms);
|
||||||
});
|
});
|
||||||
|
@ -245,13 +211,26 @@ export class WhatsappDirectLine extends GBService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
client.initialize();
|
client.initialize();
|
||||||
};
|
};
|
||||||
await createClient.bind(this)(this.browserWSEndpoint);
|
await createClient.bind(this)(this.browserWSEndpoint);
|
||||||
|
|
||||||
setUrl = false;
|
setUrl = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'chatapi':
|
||||||
|
options = {
|
||||||
|
method: 'POST',
|
||||||
|
url: urlJoin(this.whatsappServiceUrl, 'webhook'),
|
||||||
|
timeout: 10000,
|
||||||
|
qs: {
|
||||||
|
token: this.whatsappServiceKey,
|
||||||
|
webhookUrl: `${GBServer.globals.publicAddress}/webhooks/whatsapp/${this.botId}`,
|
||||||
|
set: true
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
'cache-control': 'no-cache'
|
||||||
|
}
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case 'chatapi':
|
case 'chatapi':
|
||||||
url = urlJoin(this.whatsappServiceUrl, 'webhook');
|
url = urlJoin(this.whatsappServiceUrl, 'webhook');
|
||||||
|
@ -742,7 +721,7 @@ export class WhatsappDirectLine extends GBService {
|
||||||
let options;
|
let options;
|
||||||
switch (this.provider) {
|
switch (this.provider) {
|
||||||
case 'GeneralBots':
|
case 'GeneralBots':
|
||||||
const attachment = await wpp.MessageMedia.fromUrl(url);
|
const attachment = await MessageMedia.fromUrl(url);
|
||||||
if (to.indexOf('@') == -1) {
|
if (to.indexOf('@') == -1) {
|
||||||
if (to.length == 18) {
|
if (to.length == 18) {
|
||||||
to = to + '@g.us';
|
to = to + '@g.us';
|
||||||
|
@ -800,20 +779,20 @@ export class WhatsappDirectLine extends GBService {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'graphapi':
|
case 'graphapi':
|
||||||
url = `https://graph.facebook.com/v15.0/${phoneId}/messages`
|
url = `https://graph.facebook.com/v15.0/${phoneId}/messages`;
|
||||||
options = {
|
options = {
|
||||||
method:'POST',
|
method: 'POST',
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
headers: {
|
headers: {
|
||||||
token: `Bearer `,
|
token: `Bearer `,
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
body:{
|
body: {
|
||||||
messaging_product: 'whatsapp',
|
messaging_product: 'whatsapp',
|
||||||
recipient_type: 'individual',
|
recipient_type: 'individual',
|
||||||
to: phoneId,
|
to: phoneId
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options) {
|
if (options) {
|
||||||
|
@ -831,7 +810,7 @@ export class WhatsappDirectLine extends GBService {
|
||||||
let options;
|
let options;
|
||||||
switch (this.provider) {
|
switch (this.provider) {
|
||||||
case 'GeneralBots':
|
case 'GeneralBots':
|
||||||
const attachment = wpp.MessageMedia.fromUrl(url);
|
const attachment = MessageMedia.fromUrl(url);
|
||||||
await this.customClient.sendMessage(to, attachment);
|
await this.customClient.sendMessage(to, attachment);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -928,7 +907,6 @@ export class WhatsappDirectLine extends GBService {
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'graphapi':
|
case 'graphapi':
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options) {
|
if (options) {
|
||||||
|
|
10
swagger.json
10
swagger.json
|
@ -13,7 +13,7 @@
|
||||||
"status": "Production"
|
"status": "Production"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"host": "",
|
"host": "f993e4828c0d50.lhr.life",
|
||||||
"basePath": "/",
|
"basePath": "/",
|
||||||
"schemes": [
|
"schemes": [
|
||||||
"https"
|
"https"
|
||||||
|
@ -21,11 +21,11 @@
|
||||||
"consumes": [],
|
"consumes": [],
|
||||||
"produces": [],
|
"produces": [],
|
||||||
"paths": {
|
"paths": {
|
||||||
"/api/v2//dialog/talk": {
|
"/api/v2/dev-perdomo/dialog/talk": {
|
||||||
"post": {
|
"post": {
|
||||||
"requestBody":{
|
"consumes":[
|
||||||
"content": "text/plain"
|
"text/plain; charset=utf-8"
|
||||||
},
|
],
|
||||||
"summary": "Talk to the user.",
|
"summary": "Talk to the user.",
|
||||||
"description": "Talk to the user.",
|
"description": "Talk to the user.",
|
||||||
"x-ms-no-generic-test": true,
|
"x-ms-no-generic-test": true,
|
||||||
|
|
Loading…
Add table
Reference in a new issue