new(whatsapp.gblib): New WhatsApp provider: Meta.
This commit is contained in:
parent
37d9028f98
commit
bac90cbff8
3 changed files with 130 additions and 40 deletions
|
@ -63,6 +63,8 @@ import * as marked from 'marked';
|
|||
import Translate from '@google-cloud/translate';
|
||||
import { GBUtil } from '../../../src/util.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
|
||||
|
@ -320,7 +322,7 @@ export class GBConversationalService {
|
|||
const filename = url.substring(url.lastIndexOf('/') + 1);
|
||||
await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption);
|
||||
} else {
|
||||
GBLogEx.info(min,
|
||||
GBLogEx.info(min,
|
||||
`Sending ${url} as file attachment not available in this channel ${step.context.activity['mobile']}...`
|
||||
);
|
||||
await min.conversationalService.sendText(min, step, url);
|
||||
|
@ -339,9 +341,9 @@ export class GBConversationalService {
|
|||
}
|
||||
|
||||
public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise<any> {
|
||||
if ( step.context.activity.channelId !== 'msteams' &&
|
||||
step.context.activity.channelId !== 'omnichannel') {
|
||||
GBLogEx.info(min,
|
||||
if (step.context.activity.channelId !== 'msteams' &&
|
||||
step.context.activity.channelId !== 'omnichannel') {
|
||||
GBLogEx.info(min,
|
||||
`Sending event ${name}:${typeof value === 'object' ? JSON.stringify(value) : value ? value : ''} to client...`
|
||||
);
|
||||
const msg = MessageFactory.text('');
|
||||
|
@ -355,7 +357,7 @@ export class GBConversationalService {
|
|||
|
||||
// tslint:disable:no-unsafe-any due to Nexmo.
|
||||
public async sendSms(min: GBMinInstance, mobile: string, text: string): Promise<any> {
|
||||
|
||||
|
||||
let botNumber = min.core.getParam<string>(min.instance, 'Bot Number', null);
|
||||
if (botNumber) {
|
||||
|
||||
|
@ -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}...`);
|
||||
return min.whatsAppDirectLine ? await min.whatsAppDirectLine.sendToDevice(mobile, message, conversationId) :
|
||||
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
|
||||
|
||||
public async sendMarkdownToMobile(min: GBMinInstance, step: GBDialogStep, mobile: string, text: string) {
|
||||
|
@ -888,7 +931,7 @@ export class GBConversationalService {
|
|||
return false;
|
||||
}
|
||||
|
||||
GBLogEx.info(min,
|
||||
GBLogEx.info(min,
|
||||
`NLP called: ${intent}, entities: ${nlp.entities.length}, score: ${score} > required (nlpScore): ${instanceScore}`
|
||||
);
|
||||
|
||||
|
|
|
@ -743,6 +743,26 @@ export class KBService implements IGBKBService {
|
|||
});
|
||||
}
|
||||
} 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 localName = Path.join('work', path, 'articles', file.name);
|
||||
const buffer = Fs.readFileSync(localName, { encoding: null });
|
||||
|
|
|
@ -104,7 +104,7 @@ export class WhatsappDirectLine extends GBService {
|
|||
this.whatsappServiceNumber = whatsappServiceNumber;
|
||||
this.whatsappServiceUrl = whatsappServiceUrl;
|
||||
this.provider = whatsappServiceKey === 'internal'
|
||||
? 'GeneralBots' : 'meta';
|
||||
? 'GeneralBots' : 'meta';
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
|
@ -137,13 +137,15 @@ export class WhatsappDirectLine extends GBService {
|
|||
const minBoot = GBServer.globals.minBoot;
|
||||
// Initialize the browser using a local profile for each bot.
|
||||
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 createClient = () => {
|
||||
const client = (this.customClient = new Client({
|
||||
puppeteer: GBSSR.preparePuppeteer(localName)
|
||||
, webVersionCache: { type: 'remote',
|
||||
remotePath: `https://raw.githubusercontent.com/wppconnect-team/wa-version/main/html/${webVersion}.html` }
|
||||
, webVersionCache: {
|
||||
type: 'remote',
|
||||
remotePath: `https://raw.githubusercontent.com/wppconnect-team/wa-version/main/html/${webVersion}.html`
|
||||
}
|
||||
}));
|
||||
client.on(
|
||||
'message',
|
||||
|
@ -157,14 +159,14 @@ export class WhatsappDirectLine extends GBService {
|
|||
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 pid = GBVMService.createProcessInfo(null, this.min, 'wppboot', null);
|
||||
|
||||
|
||||
// Sends QR Code to boot bot admin.
|
||||
|
||||
|
||||
const msg = `Please, scan QR Code with for bot ${this.botId}.`;
|
||||
qrcode.generate(qr, { small: true, scale: 0.5 });
|
||||
|
||||
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`);
|
||||
Fs.writeFileSync(localName, qrBuf.data);
|
||||
const url = urlJoin(
|
||||
|
@ -173,13 +175,14 @@ export class WhatsappDirectLine extends GBService {
|
|||
'cache',
|
||||
Path.basename(localName)
|
||||
);
|
||||
|
||||
if (adminNumber){
|
||||
|
||||
if (adminNumber) {
|
||||
await GBServer.globals.minBoot.whatsAppDirectLine.sendFileToDevice(adminNumber, url, Path.basename(localName), msg);
|
||||
}
|
||||
|
||||
if (adminEmail){
|
||||
await s.sendEmail({pid, to: adminEmail, subject: `Check your WhatsApp for bot ${this.min.botId}`,
|
||||
|
||||
if (adminEmail) {
|
||||
await s.sendEmail({
|
||||
pid, to: adminEmail, subject: `Check your WhatsApp for bot ${this.min.botId}`,
|
||||
body: msg
|
||||
});
|
||||
}
|
||||
|
@ -262,11 +265,17 @@ export class WhatsappDirectLine extends GBService {
|
|||
|
||||
switch (provider) {
|
||||
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;
|
||||
text = req.body.entry[0].changes[0].value.messages[0].text.body
|
||||
to = this.min.core.getParam<string>(this.min.instance, 'Bot Number', null);
|
||||
fromName = req.body.entry[0].changes[0].value.contacts[0].profile.name;
|
||||
|
||||
|
||||
break;
|
||||
case 'official':
|
||||
message = req.body;
|
||||
|
@ -595,7 +604,7 @@ export class WhatsappDirectLine extends GBService {
|
|||
await this.printMessages(response.obj.activities, conversationId, from, fromName);
|
||||
} catch (err) {
|
||||
GBLog.error(
|
||||
`Error calling printMessages on Whatsapp channel ${err.data === undefined ?
|
||||
`Error calling printMessages on Whatsapp channel ${err.data === undefined ?
|
||||
err : err.data} ${err.errObj ? err.errObj.message : ''
|
||||
}`
|
||||
);
|
||||
|
@ -710,7 +719,7 @@ export class WhatsappDirectLine extends GBService {
|
|||
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 ';
|
||||
let url;
|
||||
let chatId = WhatsappDirectLine.chatIds[conversationId];
|
||||
|
@ -725,14 +734,23 @@ export class WhatsappDirectLine extends GBService {
|
|||
|
||||
switch (this.provider) {
|
||||
case 'meta':
|
||||
const bot = createBot(this.min.instance.whatsappServiceNumber,
|
||||
this.min.instance.whatsappServiceKey);
|
||||
messages = msg.match(/(.|[\r\n]){1,4096}/g)
|
||||
const driver = createBot(this.min.instance.whatsappServiceNumber,
|
||||
this.min.instance.whatsappServiceKey);
|
||||
|
||||
await CollectionUtil.asyncForEach(messages, async msg => {
|
||||
await GBUtil.sleep(3000);
|
||||
await bot.sendText(to, msg);
|
||||
});
|
||||
if (msg['name']) {
|
||||
const res = await driver.sendTemplate(to, msg['name'], 'pt_br', msg['components']);
|
||||
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;
|
||||
case 'official':
|
||||
|
@ -740,7 +758,7 @@ export class WhatsappDirectLine extends GBService {
|
|||
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 GBUtil.sleep(3000);
|
||||
|
@ -753,8 +771,8 @@ export class WhatsappDirectLine extends GBService {
|
|||
});
|
||||
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
case 'GeneralBots':
|
||||
to = to.replace('+', '');
|
||||
|
@ -806,14 +824,23 @@ export class WhatsappDirectLine extends GBService {
|
|||
switch (provider) {
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
text = req.body.entry[0].changes[0].value.messages[0].text.body
|
||||
senderName = req.body.entry[0].changes[0].value.contacts[0].profile.name;
|
||||
|
||||
botId = this.botId;
|
||||
|
||||
break;
|
||||
|
@ -838,7 +865,7 @@ export class WhatsappDirectLine extends GBService {
|
|||
id = req.from.split('@')[0];
|
||||
senderName = req._data.notifyName;
|
||||
text = req.body;
|
||||
botId=botId?? this.botId;
|
||||
botId = botId ?? this.botId;
|
||||
break;
|
||||
|
||||
}
|
||||
|
@ -850,11 +877,11 @@ export class WhatsappDirectLine extends GBService {
|
|||
let toSwitchMin = GBServer.globals.minInstances.filter(
|
||||
p => p.instance.botId.toLowerCase() === text.toLowerCase()
|
||||
)[0];
|
||||
|
||||
|
||||
botId = botId??GBServer.globals.minBoot.botId;
|
||||
|
||||
botId = botId ?? GBServer.globals.minBoot.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];
|
||||
// Detects user typed language and updates their locale profile if applies.
|
||||
let min = urlMin;
|
||||
|
|
Loading…
Add table
Reference in a new issue