new(basic.gblib): SEND FILE pdf as temporary images.

This commit is contained in:
me@rodrigorodriguez.com 2024-10-03 19:36:18 -03:00
parent 4656e1d57d
commit 8590607aa9
2 changed files with 86 additions and 47 deletions

View file

@ -1460,9 +1460,9 @@ export class DialogKeywords {
const pdf = path.join(GBConfigService.get('STORAGE_LIBRARY'), gbdriveName, filename); const pdf = path.join(GBConfigService.get('STORAGE_LIBRARY'), gbdriveName, filename);
const pngs = await GBUtil.pdfPageAsImage(min, pdf, undefined); const pngs = await GBUtil.pdfPageAsImage(min, pdf, undefined);
await CollectionUtil.asyncForEach(pngs, async png => { await CollectionUtil.asyncForEach(pngs, async png => {
await GBUtil.sleep(500);
// Prepare a cache to be referenced by Bot Framework. // Prepare a cache to be referenced by Bot Framework.
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(png.localName)); url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(png.localName));
@ -1476,8 +1476,8 @@ export class DialogKeywords {
contentUrl: url contentUrl: url
}); });
if (channel === 'omnichannel' || !user) { if (channel === 'omnichannel' || channel === 'whatsapp' || !user) {
await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption); await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption, undefined, true);
} else { } else {
await min.conversationalService['sendOnConversation'](min, user, reply); await min.conversationalService['sendOnConversation'](min, user, reply);
} }

View file

@ -32,6 +32,7 @@ import mime from 'mime-types';
import urlJoin from 'url-join'; 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 { GBLog, GBMinInstance, GBService, IGBPackage } from 'botlib'; import { GBLog, GBMinInstance, GBService, IGBPackage } from 'botlib';
import { CollectionUtil } from 'pragmatismo-io-framework'; import { CollectionUtil } from 'pragmatismo-io-framework';
import { GBServer } from '../../../src/app.js'; import { GBServer } from '../../../src/app.js';
@ -281,38 +282,36 @@ export class WhatsappDirectLine extends GBService {
switch (provider) { switch (provider) {
case 'meta': case 'meta':
if (req.body.entry[0].changes[0].value.messages[0].text) { if (req.body.entry[0].changes[0].value.messages[0].text) {
text = req.body.entry[0].changes[0].value.messages[0].text.body; text = req.body.entry[0].changes[0].value.messages[0].text.body;
} else if (req.body.entry[0].changes[0].value.messages[0].button) { } else if (req.body.entry[0].changes[0].value.messages[0].button) {
text = req.body.entry[0].changes[0].value.messages[0].button.text; 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;
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;
// Check for media in the 'meta' case // Check for media in the 'meta' case
if (req.body.entry[0].changes[0].value.messages[0].hasMedia) { if (req.body.entry[0].changes[0].value.messages[0].type === 'image') {
const base64Image = await req.body.entry[0].changes[0].value.messages[0].downloadMedia(); // Ensure this method exists const gbaiName = GBUtil.getGBAIPath(this.min.botId);
const localName = path.join(
let buf = Buffer.from(base64Image.data, 'base64'); 'work',
const gbaiName = GBUtil.getGBAIPath(this.min.botId); gbaiName,
const localName = path.join( 'cache',
'work', `tmp${GBAdminService.getRndReadableIdentifier()}`
gbaiName, );
'cache', const image = req.body.entry[0].changes[0].value.messages[0].image;
`tmp${GBAdminService.getRndReadableIdentifier()}` // No extension await this.downloadImage(image.id, localName);
); const url = urlJoin(GBServer.globals.publicAddress, this.min.botId, 'cache', path.basename(localName));
await fs.writeFile(localName, buf, { encoding: null });
const url = urlJoin(GBServer.globals.publicAddress, this.min.botId, 'cache', path.basename(localName)); attachments = [{
name: path.basename(localName),
attachments = [{ noName: true,
name: `${new Date().toISOString().replace(/:/g, '')}`, // No extension contentType: image.mime_type,
noName: true, contentUrl: url
contentType: base64Image.mimetype, }];
contentUrl: url
}];
} }
break; break;
case 'official': case 'official':
message = req.body; message = req.body;
@ -365,8 +364,8 @@ export class WhatsappDirectLine extends GBService {
break; break;
} }
text = text.replace(/\@\d+ /gi, ''); text = text ? text.replace(/\@\d+ /gi, '') : null;
GBLogEx.info(0, `GBWhatsapp: RCV ${from}(${fromName}): ${text})`); GBLogEx.info(0, `GBWhatsapp: RCV ${from}(${fromName}): ${text ? text : 'binary'})`);
let botGroupID = WhatsappDirectLine.botGroups[this.min.botId]; let botGroupID = WhatsappDirectLine.botGroups[this.min.botId];
let botShortcuts = this.min.core.getParam<string>(this.min.instance, 'WhatsApp Group Shortcuts', null); let botShortcuts = this.min.core.getParam<string>(this.min.instance, 'WhatsApp Group Shortcuts', null);
@ -725,10 +724,10 @@ export class WhatsappDirectLine extends GBService {
whatsappServiceNumber = GBServer.globals.minBoot.instance.whatsappServiceNumber; whatsappServiceNumber = GBServer.globals.minBoot.instance.whatsappServiceNumber;
whatsappServiceKey = GBServer.globals.minBoot.instance.whatsappServiceKey; whatsappServiceKey = GBServer.globals.minBoot.instance.whatsappServiceKey;
} }
if (viewOnce){ if (viewOnce) {
this.sendImageViewOnce(to, url, caption); await this.sendImageViewOnce(to, url, caption);
} }
else{ else {
const driver = createBot(whatsappServiceNumber, whatsappServiceKey); const driver = createBot(whatsappServiceNumber, whatsappServiceKey);
await driver.sendImage(to, url, { caption: caption }); await driver.sendImage(to, url, { caption: caption });
} }
@ -793,7 +792,7 @@ export class WhatsappDirectLine extends GBService {
const accessToken = this.whatsappServiceKey; const accessToken = this.whatsappServiceKey;
const sendMessageEndpoint = `${baseUrl}/${this.whatsappBusinessManagerId}/messages`; const sendMessageEndpoint = `${baseUrl}/${this.whatsappServiceNumber}/messages`;
const messageData = { const messageData = {
messaging_product: 'whatsapp', messaging_product: 'whatsapp',
@ -802,9 +801,9 @@ export class WhatsappDirectLine extends GBService {
type: 'image', type: 'image',
image: { image: {
link: imageUrl, link: imageUrl,
caption: caption caption: caption,
view_once: true
}, },
view_once: true
}; };
const response = await fetch(sendMessageEndpoint, { const response = await fetch(sendMessageEndpoint, {
@ -1039,11 +1038,6 @@ export class WhatsappDirectLine extends GBService {
text = req.body.entry[0].changes[0].value.messages[0].text.body; text = req.body.entry[0].changes[0].value.messages[0].text.body;
} else if (req.body.entry[0].changes[0].value.messages[0].button) { } else if (req.body.entry[0].changes[0].value.messages[0].button) {
text = req.body.entry[0].changes[0].value.messages[0].button.text; text = req.body.entry[0].changes[0].value.messages[0].button.text;
} else {
res.status(200);
res.end();
return;
} }
id = req.body.entry[0].changes[0].value.messages[0].from; id = req.body.entry[0].changes[0].value.messages[0].from;
senderName = req.body.entry[0].changes[0].value.contacts[0].profile.name; senderName = req.body.entry[0].changes[0].value.contacts[0].profile.name;
@ -1076,12 +1070,15 @@ export class WhatsappDirectLine extends GBService {
} }
const sec = new SecService(); const sec = new SecService();
let toSwitchMin;
// Tries to find if user wants to switch bots. // Tries to find if user wants to switch bots.
let toSwitchMin = GBServer.globals.minInstances.filter( if (text) {
p => p.instance.botId.toLowerCase() === text.toLowerCase() toSwitchMin = GBServer.globals.minInstances.filter(
)[0]; 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}.`); GBLogEx.info(this.min, `A WhatsApp mobile requested instance for: ${botId}.`);
@ -1139,7 +1136,7 @@ export class WhatsappDirectLine extends GBService {
// Processes group behaviour. // Processes group behaviour.
text = text.replace(/\@\d+ /gi, ''); text = text ? text.replace(/\@\d+ /gi, '') : null;
let group; let group;
if (provider === 'GeneralBots') { if (provider === 'GeneralBots') {
@ -1184,7 +1181,7 @@ export class WhatsappDirectLine extends GBService {
return; return;
} }
if (!toSwitchMin) { if (!toSwitchMin && text) {
toSwitchMin = GBServer.globals.minInstances.filter(p => toSwitchMin = GBServer.globals.minInstances.filter(p =>
p.instance.activationCode ? p.instance.activationCode.toLowerCase() === text.toLowerCase() : false p.instance.activationCode ? p.instance.activationCode.toLowerCase() === text.toLowerCase() : false
)[0]; )[0];
@ -1355,4 +1352,46 @@ export class WhatsappDirectLine extends GBService {
console.error('Error during file upload:', error); console.error('Error during file upload:', error);
} }
} }
public async downloadImage(mediaId, outputPath) {
const userAccessToken = this.whatsappServiceKey;
let imageUrl;
try {
// Step 1: Fetch the media metadata
const metadataResponse = await fetch(
`https://graph.facebook.com/v20.0/${mediaId}`, {
headers: {
Authorization: `Bearer ${userAccessToken}`,
}
}
);
const metadataData = await metadataResponse.json();
if (!metadataResponse.ok) {
throw new Error(metadataData.error.message);
}
imageUrl = metadataData.url; // Assuming the API returns the image URL in this field
console.log('Image URL retrieved:', imageUrl);
// Step 2: Download the image
const imageResponse = await fetch(imageUrl, {
headers: {
Authorization: `Bearer ${userAccessToken}`,
'User-Agent': 'gb/5.0.0'
}
});
if (!imageResponse.ok) {
throw new Error('Failed to download image: ' + imageResponse.statusText);
}
// Step 3: Save the image to the specified output path
const fileStream = Fs.createWriteStream(outputPath);
imageResponse.body.pipe(fileStream);
} catch (error) {
console.error('Error during image download:', error.message);
}
}
} }