new(whatsapp.gblib): New WhatsApp provider: Meta.

This commit is contained in:
Rodrigo Rodriguez 2024-04-28 16:17:00 -03:00
parent 37d9028f98
commit bac90cbff8
3 changed files with 130 additions and 40 deletions

View file

@ -63,6 +63,8 @@ import * as marked from 'marked';
import Translate from '@google-cloud/translate'; 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 { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
/** /**
* Provides basic services for handling messages and dispatching to back-end * Provides basic services for handling messages and dispatching to back-end
@ -339,8 +341,8 @@ export class GBConversationalService {
} }
public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise<any> { public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise<any> {
if ( step.context.activity.channelId !== 'msteams' && if (step.context.activity.channelId !== 'msteams' &&
step.context.activity.channelId !== 'omnichannel') { step.context.activity.channelId !== 'omnichannel') {
GBLogEx.info(min, GBLogEx.info(min,
`Sending event ${name}:${typeof value === 'object' ? JSON.stringify(value) : value ? value : ''} to client...` `Sending event ${name}:${typeof value === 'object' ? JSON.stringify(value) : value ? value : ''} to client...`
); );
@ -425,7 +427,7 @@ export class GBConversationalService {
} }
} }
public async sendToMobile(min: GBMinInstance, mobile: string, message: string, conversationId) { public async sendToMobile(min: GBMinInstance, mobile: string, message: any, conversationId) {
GBLogEx.info(min, `Sending message ${message} to ${mobile}...`); GBLogEx.info(min, `Sending message ${message} to ${mobile}...`);
return min.whatsAppDirectLine ? await min.whatsAppDirectLine.sendToDevice(mobile, message, conversationId) : return min.whatsAppDirectLine ? await min.whatsAppDirectLine.sendToDevice(mobile, message, conversationId) :
await this.sendSms(min, mobile, message); await this.sendSms(min, mobile, message);
@ -646,6 +648,47 @@ export class GBConversationalService {
}); });
} }
public async fillAndBroadcastTemplate(min: GBMinInstance, step: GBDialogStep, mobile: string, text) {
let image = /(.*)\n/gmi.exec(text)[0].trim();
const gbaiName = DialogKeywords.getGBAIPath(min.botId);
const fileUrl = urlJoin(process.env.BOT_URL,'kb', gbaiName, `${min.botId}.gbkb`, 'images', image);
let urlImage = image.startsWith('http')
? image
: fileUrl;
text = text.substring(image.length).trim();
let data = {
name: 'broadcast', components: [
{
type: "header",
parameters: [
{
type: "image",
image: {
link: urlImage,
},
},
],
},
{
type: "body",
parameters: [
{
type: "text",
text: text,
}
]
}
]
};
GBLogEx.info(min, `Sending answer file to mobile: ${mobile}.`);
await this.sendToMobile(min, mobile, data, null);
}
// tslint:enable:no-unsafe-any // tslint:enable:no-unsafe-any
public async sendMarkdownToMobile(min: GBMinInstance, step: GBDialogStep, mobile: string, text: string) { public async sendMarkdownToMobile(min: GBMinInstance, step: GBDialogStep, mobile: string, text: string) {

View file

@ -743,6 +743,26 @@ export class KBService implements IGBKBService {
}); });
} }
} else if (file !== null && file.name.endsWith('.docx')) { } else if (file !== null && file.name.endsWith('.docx')) {
const path = DialogKeywords.getGBAIPath(instance.botId, `gbkb`);
const localName = Path.join('work', path, 'articles', file.name);
let loader = new DocxLoader(localName);
let doc = await loader.load();
const answer = {
instanceId: instance.instanceId,
content: doc[0].pageContent,
format: '.md',
media: file.name,
packageId: packageId,
prevId: 0
};
data.answers.push(answer);
} else if (file !== null && file.name.endsWith('.toc.docx')) {
const path = DialogKeywords.getGBAIPath(instance.botId, `gbkb`); const path = DialogKeywords.getGBAIPath(instance.botId, `gbkb`);
const localName = Path.join('work', path, 'articles', file.name); const localName = Path.join('work', path, 'articles', file.name);
const buffer = Fs.readFileSync(localName, { encoding: null }); const buffer = Fs.readFileSync(localName, { encoding: null });

View file

@ -104,7 +104,7 @@ export class WhatsappDirectLine extends GBService {
this.whatsappServiceNumber = whatsappServiceNumber; this.whatsappServiceNumber = whatsappServiceNumber;
this.whatsappServiceUrl = whatsappServiceUrl; this.whatsappServiceUrl = whatsappServiceUrl;
this.provider = whatsappServiceKey === 'internal' this.provider = whatsappServiceKey === 'internal'
? 'GeneralBots' : 'meta'; ? 'GeneralBots' : 'meta';
this.groupId = groupId; this.groupId = groupId;
} }
@ -137,13 +137,15 @@ export class WhatsappDirectLine extends GBService {
const minBoot = GBServer.globals.minBoot; const minBoot = GBServer.globals.minBoot;
// Initialize the browser using a local profile for each bot. // Initialize the browser using a local profile for each bot.
const gbaiPath = DialogKeywords.getGBAIPath(this.min.botId); const gbaiPath = DialogKeywords.getGBAIPath(this.min.botId);
const webVersion = '2.2411.2'; const webVersion = '2.2411.2';
const localName = Path.join('work', gbaiPath, 'profile'); const localName = Path.join('work', gbaiPath, 'profile');
const createClient = () => { const createClient = () => {
const client = (this.customClient = new Client({ const client = (this.customClient = new Client({
puppeteer: GBSSR.preparePuppeteer(localName) puppeteer: GBSSR.preparePuppeteer(localName)
, webVersionCache: { type: 'remote', , webVersionCache: {
remotePath: `https://raw.githubusercontent.com/wppconnect-team/wa-version/main/html/${webVersion}.html` } type: 'remote',
remotePath: `https://raw.githubusercontent.com/wppconnect-team/wa-version/main/html/${webVersion}.html`
}
})); }));
client.on( client.on(
'message', 'message',
@ -164,7 +166,7 @@ export class WhatsappDirectLine extends GBService {
qrcode.generate(qr, { small: true, scale: 0.5 }); qrcode.generate(qr, { small: true, scale: 0.5 });
const s = new DialogKeywords(); const s = new DialogKeywords();
const qrBuf = await s.getQRCode({pid, text: qr}); const qrBuf = await s.getQRCode({ pid, text: qr });
const localName = Path.join('work', gbaiPath, 'cache', `qr${GBAdminService.getRndReadableIdentifier()}.png`); const localName = Path.join('work', gbaiPath, 'cache', `qr${GBAdminService.getRndReadableIdentifier()}.png`);
Fs.writeFileSync(localName, qrBuf.data); Fs.writeFileSync(localName, qrBuf.data);
const url = urlJoin( const url = urlJoin(
@ -174,12 +176,13 @@ export class WhatsappDirectLine extends GBService {
Path.basename(localName) Path.basename(localName)
); );
if (adminNumber){ if (adminNumber) {
await GBServer.globals.minBoot.whatsAppDirectLine.sendFileToDevice(adminNumber, url, Path.basename(localName), msg); await GBServer.globals.minBoot.whatsAppDirectLine.sendFileToDevice(adminNumber, url, Path.basename(localName), msg);
} }
if (adminEmail){ if (adminEmail) {
await s.sendEmail({pid, to: adminEmail, subject: `Check your WhatsApp for bot ${this.min.botId}`, await s.sendEmail({
pid, to: adminEmail, subject: `Check your WhatsApp for bot ${this.min.botId}`,
body: msg body: msg
}); });
} }
@ -262,8 +265,14 @@ export class WhatsappDirectLine extends GBService {
switch (provider) { switch (provider) {
case 'meta': case 'meta':
if (req.body.entry[0].changes[0].value.messages[0].text) {
text = req.body.entry[0].changes[0].value.messages[0].text.body;
}
else {
text = req.body.entry[0].changes[0].value.messages[0].button.text;
}
from = req.body.entry[0].changes[0].value.messages[0].from; from = req.body.entry[0].changes[0].value.messages[0].from;
text = req.body.entry[0].changes[0].value.messages[0].text.body
to = this.min.core.getParam<string>(this.min.instance, 'Bot Number', null); to = this.min.core.getParam<string>(this.min.instance, 'Bot Number', null);
fromName = req.body.entry[0].changes[0].value.contacts[0].profile.name; fromName = req.body.entry[0].changes[0].value.contacts[0].profile.name;
@ -710,7 +719,7 @@ export class WhatsappDirectLine extends GBService {
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: any, msg: string, conversationId) {
const cmd = '/audio '; const cmd = '/audio ';
let url; let url;
let chatId = WhatsappDirectLine.chatIds[conversationId]; let chatId = WhatsappDirectLine.chatIds[conversationId];
@ -725,14 +734,23 @@ export class WhatsappDirectLine extends GBService {
switch (this.provider) { switch (this.provider) {
case 'meta': case 'meta':
const bot = createBot(this.min.instance.whatsappServiceNumber, const driver = createBot(this.min.instance.whatsappServiceNumber,
this.min.instance.whatsappServiceKey); this.min.instance.whatsappServiceKey);
messages = msg.match(/(.|[\r\n]){1,4096}/g)
await CollectionUtil.asyncForEach(messages, async msg => { if (msg['name']) {
await GBUtil.sleep(3000); const res = await driver.sendTemplate(to, msg['name'], 'pt_br', msg['components']);
await bot.sendText(to, msg); console.log(JSON.stringify(res));
}); }
else {
messages = msg.match(/(.|[\r\n]){1,4096}/g)
await CollectionUtil.asyncForEach(messages, async msg => {
await GBUtil.sleep(3000);
const res =await driver.sendText(to, msg);
console.log(JSON.stringify(res));
});
}
break; break;
case 'official': case 'official':
@ -740,7 +758,7 @@ export class WhatsappDirectLine extends GBService {
to = `+${to}` to = `+${to}`
} }
messages = msg.match(/(.|[\r\n]){1,1000}/g) messages = msg.match(/(.|[\r\n]){1,1000}/g)
await CollectionUtil.asyncForEach(messages, async msg => { await CollectionUtil.asyncForEach(messages, async msg => {
await GBUtil.sleep(3000); await GBUtil.sleep(3000);
@ -754,7 +772,7 @@ export class WhatsappDirectLine extends GBService {
}); });
break; break;
case 'GeneralBots': case 'GeneralBots':
to = to.replace('+', ''); to = to.replace('+', '');
@ -806,14 +824,23 @@ export class WhatsappDirectLine extends GBService {
switch (provider) { switch (provider) {
case 'meta': case 'meta':
if (req.body.entry[0].changes[0].value.statuses){
GBLogEx.info(this.min, `WhatsApp: ${req.body.entry[0].changes[0].value.statuses[0].status}.`); if (req.body.entry[0].changes[0].value.statuses) {
GBLogEx.info(this.min, `WhatsApp:${id} ${senderName} ${req.body.entry[0].changes[0].value.statuses[0].status}.`);
res.status(200);
res.end();
return; return;
} }
if (req.body.entry[0].changes[0].value.messages[0].text) {
text = req.body.entry[0].changes[0].value.messages[0].text.body;
}
else {
text = req.body.entry[0].changes[0].value.messages[0].button.text;
}
id = req.body.entry[0].changes[0].value.messages[0].from; id = req.body.entry[0].changes[0].value.messages[0].from;
text = req.body.entry[0].changes[0].value.messages[0].text.body
senderName = req.body.entry[0].changes[0].value.contacts[0].profile.name; senderName = req.body.entry[0].changes[0].value.contacts[0].profile.name;
botId = this.botId; botId = this.botId;
break; break;
@ -838,7 +865,7 @@ export class WhatsappDirectLine extends GBService {
id = req.from.split('@')[0]; id = req.from.split('@')[0];
senderName = req._data.notifyName; senderName = req._data.notifyName;
text = req.body; text = req.body;
botId=botId?? this.botId; botId = botId ?? this.botId;
break; break;
} }
@ -852,7 +879,7 @@ export class WhatsappDirectLine extends GBService {
)[0]; )[0];
botId = botId??GBServer.globals.minBoot.botId; botId = botId ?? GBServer.globals.minBoot.botId;
GBLogEx.info(this.min, `A WhatsApp mobile requested instance for: ${botId}.`); GBLogEx.info(this.min, `A WhatsApp mobile requested instance for: ${botId}.`);
let urlMin: any = GBServer.globals.minInstances.filter(p => p.instance.botId === botId)[0]; let urlMin: any = GBServer.globals.minInstances.filter(p => p.instance.botId === botId)[0];