fix: chatbot integrations send media and links

This commit is contained in:
Davidson Gomes 2024-09-22 08:53:10 -03:00
parent 3527e662e1
commit 5ebebbf211
6 changed files with 334 additions and 156 deletions

View File

@ -63,7 +63,6 @@
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"eventemitter2": "^6.4.9", "eventemitter2": "^6.4.9",
"evolution-manager-v2": "^0.0.2",
"exiftool-vendored": "^22.0.0", "exiftool-vendored": "^22.0.0",
"express": "^4.18.2", "express": "^4.18.2",
"express-async-errors": "^3.1.1", "express-async-errors": "^3.1.1",

View File

@ -739,9 +739,13 @@ export class BaileysStartupService extends ChannelStartupService {
}, },
}); });
if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {
const instance = { instanceName: this.instance.name, instanceId: this.instance.id }; const instance = { instanceName: this.instance.name, instanceId: this.instance.id };
const findParticipant = await this.chatwootService.findContact(instance, contact.remoteJid.split('@')[0]); const findParticipant = await this.chatwootService.findContact(
instance,
contact.remoteJid.split('@')[0],
);
if (!findParticipant) { if (!findParticipant) {
return; return;
@ -751,6 +755,7 @@ export class BaileysStartupService extends ChannelStartupService {
name: contact.pushName, name: contact.pushName,
avatar_url: contact.profilePicUrl, avatar_url: contact.profilePicUrl,
}); });
}
return update; return update;
}), }),

View File

@ -349,51 +349,99 @@ export class DifyService {
} }
} }
private async sendMessageWhatsApp(instance: any, remoteJid: string, message: string, settings: DifySetting) { private async sendMessageWhatsApp(
const regex = /!?\[(.*?)\]\((.*?)\)/g; instance: any,
remoteJid: string,
message: string,
settings: DifySetting
) {
const linkRegex = /(!?)\[(.*?)\]\((.*?)\)/g;
const result = []; let textBuffer = '';
let lastIndex = 0; let lastIndex = 0;
let match; let match: RegExpExecArray | null;
while ((match = regex.exec(message)) !== null) {
if (match.index > lastIndex) { const getMediaType = (url: string): string | null => {
result.push({ text: message.slice(lastIndex, match.index).trim() }); const extension = url.split('.').pop()?.toLowerCase();
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
const audioExtensions = ['mp3', 'wav', 'aac', 'ogg'];
const videoExtensions = ['mp4', 'avi', 'mkv', 'mov'];
const documentExtensions = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'];
if (imageExtensions.includes(extension || '')) return 'image';
if (audioExtensions.includes(extension || '')) return 'audio';
if (videoExtensions.includes(extension || '')) return 'video';
if (documentExtensions.includes(extension || '')) return 'document';
return null;
};
while ((match = linkRegex.exec(message)) !== null) {
const [fullMatch, exclMark, altText, url] = match;
const mediaType = getMediaType(url);
const beforeText = message.slice(lastIndex, match.index);
if (beforeText) {
textBuffer += beforeText;
} }
result.push({ caption: match[1], url: match[2] }); if (mediaType) {
if (textBuffer.trim()) {
lastIndex = regex.lastIndex;
}
if (lastIndex < message.length) {
result.push({ text: message.slice(lastIndex).trim() });
}
for (const item of result) {
if (item.text) {
await instance.textMessage( await instance.textMessage(
{ {
number: remoteJid.split('@')[0], number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000, delay: settings?.delayMessage || 1000,
text: item.text, text: textBuffer.trim(),
}, },
false, false
); );
textBuffer = '';
} }
if (item.url) { if (mediaType === 'audio') {
await instance.audioWhatsapp(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
audio: url,
caption: altText,
}
);
} else {
await instance.mediaMessage( await instance.mediaMessage(
{ {
number: remoteJid.split('@')[0], number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000, delay: settings?.delayMessage || 1000,
mediatype: 'image', mediatype: mediaType,
media: item.url, media: url,
caption: item.caption, caption: altText,
}, },
false, false
); );
} }
} else {
textBuffer += `[${altText}](${url})`;
}
lastIndex = linkRegex.lastIndex;
}
if (lastIndex < message.length) {
const remainingText = message.slice(lastIndex);
if (remainingText.trim()) {
textBuffer += remainingText;
}
}
if (textBuffer.trim()) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: textBuffer.trim(),
},
false
);
} }
sendTelemetry('/message/sendText'); sendTelemetry('/message/sendText');

View File

@ -112,52 +112,97 @@ export class EvolutionBotService {
settings: EvolutionBotSetting, settings: EvolutionBotSetting,
message: string, message: string,
) { ) {
const regex = /!?\[(.*?)\]\((.*?)\)/g; const linkRegex = /(!?)\[(.*?)\]\((.*?)\)/g;
const result = []; let textBuffer = '';
let lastIndex = 0; let lastIndex = 0;
let match; let match: RegExpExecArray | null;
while ((match = regex.exec(message)) !== null) {
if (match.index > lastIndex) { const getMediaType = (url: string): string | null => {
result.push({ text: message.slice(lastIndex, match.index).trim() }); const extension = url.split('.').pop()?.toLowerCase();
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
const audioExtensions = ['mp3', 'wav', 'aac', 'ogg'];
const videoExtensions = ['mp4', 'avi', 'mkv', 'mov'];
const documentExtensions = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'];
if (imageExtensions.includes(extension || '')) return 'image';
if (audioExtensions.includes(extension || '')) return 'audio';
if (videoExtensions.includes(extension || '')) return 'video';
if (documentExtensions.includes(extension || '')) return 'document';
return null;
};
while ((match = linkRegex.exec(message)) !== null) {
const [fullMatch, exclMark, altText, url] = match;
const mediaType = getMediaType(url);
const beforeText = message.slice(lastIndex, match.index);
if (beforeText) {
textBuffer += beforeText;
} }
result.push({ caption: match[1], url: match[2] }); if (mediaType) {
if (textBuffer.trim()) {
lastIndex = regex.lastIndex;
}
if (lastIndex < message.length) {
result.push({ text: message.slice(lastIndex).trim() });
}
for (const item of result) {
if (item.text) {
await instance.textMessage( await instance.textMessage(
{ {
number: remoteJid.split('@')[0], number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000, delay: settings?.delayMessage || 1000,
text: item.text, text: textBuffer.trim(),
}, },
false, false
); );
textBuffer = '';
} }
if (item.url) { if (mediaType === 'audio') {
await instance.audioWhatsapp(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
audio: url,
caption: altText,
}
);
} else {
await instance.mediaMessage( await instance.mediaMessage(
{ {
number: remoteJid.split('@')[0], number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000, delay: settings?.delayMessage || 1000,
mediatype: 'image', mediatype: mediaType,
media: item.url, media: url,
caption: item.caption, caption: altText,
}, },
false, false
); );
} }
} else {
textBuffer += `[${altText}](${url})`;
} }
lastIndex = linkRegex.lastIndex;
}
if (lastIndex < message.length) {
const remainingText = message.slice(lastIndex);
if (remainingText.trim()) {
textBuffer += remainingText;
}
}
if (textBuffer.trim()) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: textBuffer.trim(),
},
false
);
}
sendTelemetry('/message/sendText');
await this.prismaRepository.integrationSession.update({ await this.prismaRepository.integrationSession.update({
where: { where: {
id: session.id, id: session.id,
@ -167,12 +212,9 @@ export class EvolutionBotService {
awaitUser: true, awaitUser: true,
}, },
}); });
sendTelemetry('/message/sendText');
return;
} }
private async initNewSession( private async initNewSession(
instance: any, instance: any,
remoteJid: string, remoteJid: string,

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { InstanceDto } from '@api/dto/instance.dto'; import { InstanceDto } from '@api/dto/instance.dto';
import { PrismaRepository } from '@api/repository/repository.service'; import { PrismaRepository } from '@api/repository/repository.service';
import { WAMonitoringService } from '@api/services/monitor.service'; import { WAMonitoringService } from '@api/services/monitor.service';
@ -111,51 +112,94 @@ export class FlowiseService {
settings: FlowiseSetting, settings: FlowiseSetting,
message: string, message: string,
) { ) {
const regex = /!?\[(.*?)\]\((.*?)\)/g; const linkRegex = /(!?)\[(.*?)\]\((.*?)\)/g;
const result = []; let textBuffer = '';
let lastIndex = 0; let lastIndex = 0;
let match; let match: RegExpExecArray | null;
while ((match = regex.exec(message)) !== null) {
if (match.index > lastIndex) { const getMediaType = (url: string): string | null => {
result.push({ text: message.slice(lastIndex, match.index).trim() }); const extension = url.split('.').pop()?.toLowerCase();
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
const audioExtensions = ['mp3', 'wav', 'aac', 'ogg'];
const videoExtensions = ['mp4', 'avi', 'mkv', 'mov'];
const documentExtensions = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'];
if (imageExtensions.includes(extension || '')) return 'image';
if (audioExtensions.includes(extension || '')) return 'audio';
if (videoExtensions.includes(extension || '')) return 'video';
if (documentExtensions.includes(extension || '')) return 'document';
return null;
};
while ((match = linkRegex.exec(message)) !== null) {
const [fullMatch, exclMark, altText, url] = match;
const mediaType = getMediaType(url);
const beforeText = message.slice(lastIndex, match.index);
if (beforeText) {
textBuffer += beforeText;
} }
result.push({ caption: match[1], url: match[2] }); if (mediaType) {
if (textBuffer.trim()) {
lastIndex = regex.lastIndex;
}
if (lastIndex < message.length) {
result.push({ text: message.slice(lastIndex).trim() });
}
for (const item of result) {
if (item.text) {
await instance.textMessage( await instance.textMessage(
{ {
number: remoteJid.split('@')[0], number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000, delay: settings?.delayMessage || 1000,
text: item.text, text: textBuffer.trim(),
},
false,
);
textBuffer = '';
}
if (mediaType === 'audio') {
await instance.audioWhatsapp({
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
audio: url,
caption: altText,
});
} else {
await instance.mediaMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
mediatype: mediaType,
media: url,
caption: altText,
},
false,
);
}
} else {
textBuffer += `[${altText}](${url})`;
}
lastIndex = linkRegex.lastIndex;
}
if (lastIndex < message.length) {
const remainingText = message.slice(lastIndex);
if (remainingText.trim()) {
textBuffer += remainingText;
}
}
if (textBuffer.trim()) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: textBuffer.trim(),
}, },
false, false,
); );
} }
if (item.url) { sendTelemetry('/message/sendText');
await instance.mediaMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
mediatype: 'image',
media: item.url,
caption: item.caption,
},
false,
);
}
}
await this.prismaRepository.integrationSession.update({ await this.prismaRepository.integrationSession.update({
where: { where: {
@ -167,8 +211,6 @@ export class FlowiseService {
}, },
}); });
sendTelemetry('/message/sendText');
return; return;
} }

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { InstanceDto } from '@api/dto/instance.dto'; import { InstanceDto } from '@api/dto/instance.dto';
import { PrismaRepository } from '@api/repository/repository.service'; import { PrismaRepository } from '@api/repository/repository.service';
import { WAMonitoringService } from '@api/services/monitor.service'; import { WAMonitoringService } from '@api/services/monitor.service';
@ -156,51 +157,94 @@ export class OpenaiService {
settings: OpenaiSetting, settings: OpenaiSetting,
message: string, message: string,
) { ) {
const regex = /!?\[(.*?)\]\((.*?)\)/g; const linkRegex = /(!?)\[(.*?)\]\((.*?)\)/g;
const result = []; let textBuffer = '';
let lastIndex = 0; let lastIndex = 0;
let match; let match: RegExpExecArray | null;
while ((match = regex.exec(message)) !== null) {
if (match.index > lastIndex) { const getMediaType = (url: string): string | null => {
result.push({ text: message.slice(lastIndex, match.index).trim() }); const extension = url.split('.').pop()?.toLowerCase();
const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
const audioExtensions = ['mp3', 'wav', 'aac', 'ogg'];
const videoExtensions = ['mp4', 'avi', 'mkv', 'mov'];
const documentExtensions = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'];
if (imageExtensions.includes(extension || '')) return 'image';
if (audioExtensions.includes(extension || '')) return 'audio';
if (videoExtensions.includes(extension || '')) return 'video';
if (documentExtensions.includes(extension || '')) return 'document';
return null;
};
while ((match = linkRegex.exec(message)) !== null) {
const [fullMatch, exclMark, altText, url] = match;
const mediaType = getMediaType(url);
const beforeText = message.slice(lastIndex, match.index);
if (beforeText) {
textBuffer += beforeText;
} }
result.push({ caption: match[1], url: match[2] }); if (mediaType) {
if (textBuffer.trim()) {
lastIndex = regex.lastIndex;
}
if (lastIndex < message.length) {
result.push({ text: message.slice(lastIndex).trim() });
}
for (const item of result) {
if (item.text) {
await instance.textMessage( await instance.textMessage(
{ {
number: remoteJid.split('@')[0], number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000, delay: settings?.delayMessage || 1000,
text: item.text, text: textBuffer.trim(),
},
false,
);
textBuffer = '';
}
if (mediaType === 'audio') {
await instance.audioWhatsapp({
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
audio: url,
caption: altText,
});
} else {
await instance.mediaMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
mediatype: mediaType,
media: url,
caption: altText,
},
false,
);
}
} else {
textBuffer += `[${altText}](${url})`;
}
lastIndex = linkRegex.lastIndex;
}
if (lastIndex < message.length) {
const remainingText = message.slice(lastIndex);
if (remainingText.trim()) {
textBuffer += remainingText;
}
}
if (textBuffer.trim()) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: textBuffer.trim(),
}, },
false, false,
); );
} }
if (item.url) { sendTelemetry('/message/sendText');
await instance.mediaMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
mediatype: 'image',
media: item.url,
caption: item.caption,
},
false,
);
}
}
await this.prismaRepository.integrationSession.update({ await this.prismaRepository.integrationSession.update({
where: { where: {
@ -211,8 +255,6 @@ export class OpenaiService {
awaitUser: true, awaitUser: true,
}, },
}); });
sendTelemetry('/message/sendText');
} }
public async createAssistantNewSession(instance: InstanceDto, data: any) { public async createAssistantNewSession(instance: InstanceDto, data: any) {