Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0

This commit is contained in:
Felipe Medeiros 2024-09-23 20:54:31 -03:00 committed by GitHub
commit 59fac8bc4a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 595 additions and 289 deletions

View File

@ -1,4 +1,4 @@
# 2.1.1 (develop)
# 2.1.1 (2024-09-22 10:31)
### Features
@ -6,6 +6,8 @@
* Save is on whatsapp on the database
* Add headers to the instance's webhook registration
* Debounce message break is now "\n" instead of white space
* Single view messages are now supported in chatwoot
* Chatbots can now send any type of media
### Fixed
@ -19,6 +21,11 @@
* It is now possible to send images via the Evolution Channel
* Removed "version" from docker-compose as it is obsolete (https://dev.to/ajeetraina/do-we-still-use-version-in-compose-3inp)
* Fixed typebot ignoreJids being used only from default settings
* Fixed Chatwoot inbox creation on save
* Changed axios timeout for manager requests for 30s
* Update in Baileys version that fixes timeout when updating profile picture
* Fixed issue when sending links in markdown by chatbots like Dify
* Fixed issue with chatbots not respecting settings
# 2.1.0 (2024-08-26 15:33)

View File

@ -3,7 +3,7 @@ FROM node:20-alpine AS builder
RUN apk update && \
apk add git ffmpeg wget curl bash
LABEL version="2.1.0" description="Api to control whatsapp features through http requests."
LABEL version="2.1.1" description="Api to control whatsapp features through http requests."
LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes"
LABEL contact="contato@atendai.com"

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,7 @@
<link rel="icon" type="image/png" href="/assets/images/evolution-logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Evolution Manager</title>
<script type="module" crossorigin src="/assets/index-DOHK1pp9.js"></script>
<script type="module" crossorigin src="/assets/index-Do1bGWiz.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DNOCacL_.css">
</head>
<body>

View File

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

View File

@ -333,10 +333,10 @@ export class BusinessStartupService extends ChannelStartupService {
const mediaType = message.messages[0].document
? 'document'
: message.messages[0].image
? 'image'
: message.messages[0].audio
? 'audio'
: 'video';
? 'image'
: message.messages[0].audio
? 'audio'
: 'video';
const mimetype = result.headers['content-type'];

View File

@ -736,19 +736,24 @@ export class BaileysStartupService extends ChannelStartupService {
},
});
const instance = { instanceName: this.instance.name, instanceId: this.instance.id };
if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {
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) {
return;
if (!findParticipant) {
return;
}
this.chatwootService.updateContact(instance, findParticipant.id, {
name: contact.pushName,
avatar_url: contact.profilePicUrl,
});
}
this.chatwootService.updateContact(instance, findParticipant.id, {
name: contact.pushName,
avatar_url: contact.profilePicUrl,
});
return update;
}),
);

View File

@ -310,7 +310,7 @@ export class ChatwootService {
avatar_url: avatar_url,
};
if (jid.includes('@')) {
if ((jid && jid.includes('@')) || !jid) {
data['phone_number'] = `+${phoneNumber}`;
}
} else {
@ -369,6 +369,10 @@ export class ChatwootService {
public async addLabelToContact(nameInbox: string, contactId: number) {
try {
const uri = this.configService.get<Chatwoot>('CHATWOOT').IMPORT.DATABASE.CONNECTION.URI;
if (!uri) return false;
const sqlTags = `SELECT id FROM tags WHERE name = '${nameInbox}' LIMIT 1`;
const tagData = (await this.pgClient.query(sqlTags))?.rows[0];
@ -1138,7 +1142,8 @@ export class ChatwootService {
return { message: 'bot' };
}
const chatId = body.conversation.meta.sender?.identifier;
const chatId =
body.conversation.meta.sender?.identifier || body.conversation.meta.sender?.phone_number.replace('+', '');
// Chatwoot to Whatsapp
const messageReceived = body.content
? body.content
@ -1527,6 +1532,7 @@ export class ChatwootService {
'audioMessage',
'videoMessage',
'stickerMessage',
'viewOnceMessageV2'
];
const messageKeys = Object.keys(message);
@ -1580,6 +1586,8 @@ export class ChatwootService {
liveLocationMessage: msg.liveLocationMessage,
listMessage: msg.listMessage,
listResponseMessage: msg.listResponseMessage,
viewOnceMessageV2: msg?.message?.viewOnceMessageV2?.message?.imageMessage?.url || msg?.message?.viewOnceMessageV2?.message?.videoMessage?.url || msg?.message?.viewOnceMessageV2?.message?.audioMessage?.url,
};
return types;

View File

@ -736,17 +736,25 @@ export class DifyController extends ChatbotController implements ChatbotControll
if (!findBot) return;
let listeningFromMe = findBot.listeningFromMe;
let stopBotFromMe = findBot.stopBotFromMe;
let debounceTime = findBot.debounceTime;
let expire = findBot?.expire;
let keywordFinish = findBot?.keywordFinish;
let delayMessage = findBot?.delayMessage;
let unknownMessage = findBot?.unknownMessage;
let listeningFromMe = findBot?.listeningFromMe;
let stopBotFromMe = findBot?.stopBotFromMe;
let keepOpen = findBot?.keepOpen;
let debounceTime = findBot?.debounceTime;
let ignoreJids = findBot?.ignoreJids;
if (!listeningFromMe || !stopBotFromMe || !debounceTime) {
if (!listeningFromMe) listeningFromMe = settings.listeningFromMe;
if (!stopBotFromMe) stopBotFromMe = settings.stopBotFromMe;
if (!debounceTime) debounceTime = settings.debounceTime;
}
if (!expire) expire = settings.expire;
if (!keywordFinish) keywordFinish = settings.keywordFinish;
if (!delayMessage) delayMessage = settings.delayMessage;
if (!unknownMessage) unknownMessage = settings.unknownMessage;
if (!listeningFromMe) listeningFromMe = settings.listeningFromMe;
if (!stopBotFromMe) stopBotFromMe = settings.stopBotFromMe;
if (!keepOpen) keepOpen = settings.keepOpen;
if (!debounceTime) debounceTime = settings.debounceTime;
if (!ignoreJids) ignoreJids = settings.ignoreJids;
const key = msg.key as {
id: string;
@ -782,7 +790,18 @@ export class DifyController extends ChatbotController implements ChatbotControll
remoteJid,
findBot,
session,
settings,
{
...settings,
expire,
keywordFinish,
delayMessage,
unknownMessage,
listeningFromMe,
stopBotFromMe,
keepOpen,
debounceTime,
ignoreJids,
},
debouncedContent,
msg?.pushName,
);
@ -793,7 +812,18 @@ export class DifyController extends ChatbotController implements ChatbotControll
remoteJid,
findBot,
session,
settings,
{
...settings,
expire,
keywordFinish,
delayMessage,
unknownMessage,
listeningFromMe,
stopBotFromMe,
keepOpen,
debounceTime,
ignoreJids,
},
content,
msg?.pushName,
);

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { InstanceDto } from '@api/dto/instance.dto';
import { PrismaRepository } from '@api/repository/repository.service';
import { WAMonitoringService } from '@api/services/monitor.service';
@ -238,14 +239,14 @@ export class DifyService {
if (data.trim() === '' || !data.startsWith('{')) {
return;
}
try {
const events = data.split('\n').filter((line) => line.trim() !== '');
for (const eventString of events) {
if (eventString.trim().startsWith('{')) {
const event = JSON.parse(eventString);
if (event?.event === 'agent_message') {
console.log('event:', event);
conversationId = conversationId ?? event?.conversation_id;
@ -350,50 +351,91 @@ export class DifyService {
}
private async sendMessageWhatsApp(instance: any, remoteJid: string, message: string, settings: DifySetting) {
const regex = /!?\[(.*?)\]\((.*?)\)/g;
const linkRegex = /(!?)\[(.*?)\]\((.*?)\)/g;
const result = [];
let textBuffer = '';
let lastIndex = 0;
let match;
while ((match = regex.exec(message)) !== null) {
if (match.index > lastIndex) {
result.push({ text: message.slice(lastIndex, match.index).trim() });
let match: RegExpExecArray | null;
const getMediaType = (url: string): string | null => {
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()) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: textBuffer.trim(),
},
false,
);
textBuffer = '';
}
lastIndex = regex.lastIndex;
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) {
result.push({ text: message.slice(lastIndex).trim() });
const remainingText = message.slice(lastIndex);
if (remainingText.trim()) {
textBuffer += remainingText;
}
}
for (const item of result) {
if (item.text) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: item.text,
},
false,
);
}
if (item.url) {
await instance.mediaMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
mediatype: 'image',
media: item.url,
caption: item.caption,
},
false,
);
}
if (textBuffer.trim()) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: textBuffer.trim(),
},
false,
);
}
sendTelemetry('/message/sendText');

View File

@ -708,17 +708,25 @@ export class EvolutionBotController extends ChatbotController implements Chatbot
if (!findBot) return;
let listeningFromMe = findBot.listeningFromMe;
let stopBotFromMe = findBot.stopBotFromMe;
let debounceTime = findBot.debounceTime;
let expire = findBot?.expire;
let keywordFinish = findBot?.keywordFinish;
let delayMessage = findBot?.delayMessage;
let unknownMessage = findBot?.unknownMessage;
let listeningFromMe = findBot?.listeningFromMe;
let stopBotFromMe = findBot?.stopBotFromMe;
let keepOpen = findBot?.keepOpen;
let debounceTime = findBot?.debounceTime;
let ignoreJids = findBot?.ignoreJids;
if (!listeningFromMe || !stopBotFromMe || !debounceTime) {
if (!listeningFromMe) listeningFromMe = settings.listeningFromMe;
if (!stopBotFromMe) stopBotFromMe = settings.stopBotFromMe;
if (!debounceTime) debounceTime = settings.debounceTime;
}
if (!expire) expire = settings.expire;
if (!keywordFinish) keywordFinish = settings.keywordFinish;
if (!delayMessage) delayMessage = settings.delayMessage;
if (!unknownMessage) unknownMessage = settings.unknownMessage;
if (!listeningFromMe) listeningFromMe = settings.listeningFromMe;
if (!stopBotFromMe) stopBotFromMe = settings.stopBotFromMe;
if (!keepOpen) keepOpen = settings.keepOpen;
if (!debounceTime) debounceTime = settings.debounceTime;
if (!ignoreJids) ignoreJids = settings.ignoreJids;
const key = msg.key as {
id: string;
@ -754,7 +762,18 @@ export class EvolutionBotController extends ChatbotController implements Chatbot
remoteJid,
findBot,
session,
settings,
{
...settings,
expire,
keywordFinish,
delayMessage,
unknownMessage,
listeningFromMe,
stopBotFromMe,
keepOpen,
debounceTime,
ignoreJids,
},
debouncedContent,
msg?.pushName,
);
@ -765,7 +784,18 @@ export class EvolutionBotController extends ChatbotController implements Chatbot
remoteJid,
findBot,
session,
settings,
{
...settings,
expire,
keywordFinish,
delayMessage,
unknownMessage,
listeningFromMe,
stopBotFromMe,
keepOpen,
debounceTime,
ignoreJids,
},
content,
msg?.pushName,
);

View File

@ -13,7 +13,7 @@ export class EvolutionBotService {
private readonly waMonitor: WAMonitoringService,
private readonly configService: ConfigService,
private readonly prismaRepository: PrismaRepository,
) {}
) { }
private readonly logger = new Logger('EvolutionBotService');
@ -112,52 +112,97 @@ export class EvolutionBotService {
settings: EvolutionBotSetting,
message: string,
) {
const regex = /!?\[(.*?)\]\((.*?)\)/g;
const linkRegex = /(!?)\[(.*?)\]\((.*?)\)/g;
const result = [];
let textBuffer = '';
let lastIndex = 0;
let match;
while ((match = regex.exec(message)) !== null) {
if (match.index > lastIndex) {
result.push({ text: message.slice(lastIndex, match.index).trim() });
let match: RegExpExecArray | null;
const getMediaType = (url: string): string | null => {
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()) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: textBuffer.trim(),
},
false
);
textBuffer = '';
}
lastIndex = regex.lastIndex;
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) {
result.push({ text: message.slice(lastIndex).trim() });
}
for (const item of result) {
if (item.text) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: item.text,
},
false,
);
}
if (item.url) {
await instance.mediaMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
mediatype: 'image',
media: item.url,
caption: item.caption,
},
false,
);
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({
where: {
id: session.id,
@ -167,12 +212,9 @@ export class EvolutionBotService {
awaitUser: true,
},
});
sendTelemetry('/message/sendText');
return;
}
private async initNewSession(
instance: any,
remoteJid: string,

View File

@ -708,17 +708,25 @@ export class FlowiseController extends ChatbotController implements ChatbotContr
if (!findBot) return;
let listeningFromMe = findBot.listeningFromMe;
let stopBotFromMe = findBot.stopBotFromMe;
let debounceTime = findBot.debounceTime;
let expire = findBot?.expire;
let keywordFinish = findBot?.keywordFinish;
let delayMessage = findBot?.delayMessage;
let unknownMessage = findBot?.unknownMessage;
let listeningFromMe = findBot?.listeningFromMe;
let stopBotFromMe = findBot?.stopBotFromMe;
let keepOpen = findBot?.keepOpen;
let debounceTime = findBot?.debounceTime;
let ignoreJids = findBot?.ignoreJids;
if (!listeningFromMe || !stopBotFromMe || !debounceTime) {
if (!listeningFromMe) listeningFromMe = settings.listeningFromMe;
if (!stopBotFromMe) stopBotFromMe = settings.stopBotFromMe;
if (!debounceTime) debounceTime = settings.debounceTime;
}
if (!expire) expire = settings.expire;
if (!keywordFinish) keywordFinish = settings.keywordFinish;
if (!delayMessage) delayMessage = settings.delayMessage;
if (!unknownMessage) unknownMessage = settings.unknownMessage;
if (!listeningFromMe) listeningFromMe = settings.listeningFromMe;
if (!stopBotFromMe) stopBotFromMe = settings.stopBotFromMe;
if (!keepOpen) keepOpen = settings.keepOpen;
if (!debounceTime) debounceTime = settings.debounceTime;
if (!ignoreJids) ignoreJids = settings.ignoreJids;
const key = msg.key as {
id: string;
@ -754,7 +762,18 @@ export class FlowiseController extends ChatbotController implements ChatbotContr
remoteJid,
findBot,
session,
settings,
{
...settings,
expire,
keywordFinish,
delayMessage,
unknownMessage,
listeningFromMe,
stopBotFromMe,
keepOpen,
debounceTime,
ignoreJids,
},
debouncedContent,
msg?.pushName,
);
@ -765,7 +784,18 @@ export class FlowiseController extends ChatbotController implements ChatbotContr
remoteJid,
findBot,
session,
settings,
{
...settings,
expire,
keywordFinish,
delayMessage,
unknownMessage,
listeningFromMe,
stopBotFromMe,
keepOpen,
debounceTime,
ignoreJids,
},
content,
msg?.pushName,
);

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { InstanceDto } from '@api/dto/instance.dto';
import { PrismaRepository } from '@api/repository/repository.service';
import { WAMonitoringService } from '@api/services/monitor.service';
@ -111,52 +112,95 @@ export class FlowiseService {
settings: FlowiseSetting,
message: string,
) {
const regex = /!?\[(.*?)\]\((.*?)\)/g;
const linkRegex = /(!?)\[(.*?)\]\((.*?)\)/g;
const result = [];
let textBuffer = '';
let lastIndex = 0;
let match;
while ((match = regex.exec(message)) !== null) {
if (match.index > lastIndex) {
result.push({ text: message.slice(lastIndex, match.index).trim() });
let match: RegExpExecArray | null;
const getMediaType = (url: string): string | null => {
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()) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: textBuffer.trim(),
},
false,
);
textBuffer = '';
}
lastIndex = regex.lastIndex;
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) {
result.push({ text: message.slice(lastIndex).trim() });
}
for (const item of result) {
if (item.text) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: item.text,
},
false,
);
}
if (item.url) {
await instance.mediaMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
mediatype: 'image',
media: item.url,
caption: item.caption,
},
false,
);
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({
where: {
id: session.id,
@ -167,8 +211,6 @@ export class FlowiseService {
},
});
sendTelemetry('/message/sendText');
return;
}

View File

@ -945,18 +945,25 @@ export class OpenaiController extends ChatbotController implements ChatbotContro
if (!findBot) return;
// verify default settings
let listeningFromMe = findBot.listeningFromMe;
let stopBotFromMe = findBot.stopBotFromMe;
let debounceTime = findBot.debounceTime;
let expire = findBot?.expire;
let keywordFinish = findBot?.keywordFinish;
let delayMessage = findBot?.delayMessage;
let unknownMessage = findBot?.unknownMessage;
let listeningFromMe = findBot?.listeningFromMe;
let stopBotFromMe = findBot?.stopBotFromMe;
let keepOpen = findBot?.keepOpen;
let debounceTime = findBot?.debounceTime;
let ignoreJids = findBot?.ignoreJids;
if (!listeningFromMe || !stopBotFromMe || !debounceTime) {
if (!listeningFromMe) listeningFromMe = settings.listeningFromMe;
if (!stopBotFromMe) stopBotFromMe = settings.stopBotFromMe;
if (!debounceTime) debounceTime = settings.debounceTime;
}
if (!expire) expire = settings.expire;
if (!keywordFinish) keywordFinish = settings.keywordFinish;
if (!delayMessage) delayMessage = settings.delayMessage;
if (!unknownMessage) unknownMessage = settings.unknownMessage;
if (!listeningFromMe) listeningFromMe = settings.listeningFromMe;
if (!stopBotFromMe) stopBotFromMe = settings.stopBotFromMe;
if (!keepOpen) keepOpen = settings.keepOpen;
if (!debounceTime) debounceTime = settings.debounceTime;
if (!ignoreJids) ignoreJids = settings.ignoreJids;
const key = msg.key as {
id: string;
@ -994,7 +1001,18 @@ export class OpenaiController extends ChatbotController implements ChatbotContro
key.fromMe,
findBot,
session,
settings,
{
...settings,
expire,
keywordFinish,
delayMessage,
unknownMessage,
listeningFromMe,
stopBotFromMe,
keepOpen,
debounceTime,
ignoreJids,
},
debouncedContent,
);
}
@ -1006,7 +1024,18 @@ export class OpenaiController extends ChatbotController implements ChatbotContro
pushName,
findBot,
session,
settings,
{
...settings,
expire,
keywordFinish,
delayMessage,
unknownMessage,
listeningFromMe,
stopBotFromMe,
keepOpen,
debounceTime,
ignoreJids,
},
debouncedContent,
);
}

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { InstanceDto } from '@api/dto/instance.dto';
import { PrismaRepository } from '@api/repository/repository.service';
import { WAMonitoringService } from '@api/services/monitor.service';
@ -156,52 +157,95 @@ export class OpenaiService {
settings: OpenaiSetting,
message: string,
) {
const regex = /!?\[(.*?)\]\((.*?)\)/g;
const linkRegex = /(!?)\[(.*?)\]\((.*?)\)/g;
const result = [];
let textBuffer = '';
let lastIndex = 0;
let match;
while ((match = regex.exec(message)) !== null) {
if (match.index > lastIndex) {
result.push({ text: message.slice(lastIndex, match.index).trim() });
let match: RegExpExecArray | null;
const getMediaType = (url: string): string | null => {
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()) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: textBuffer.trim(),
},
false,
);
textBuffer = '';
}
lastIndex = regex.lastIndex;
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) {
result.push({ text: message.slice(lastIndex).trim() });
}
for (const item of result) {
if (item.text) {
await instance.textMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
text: item.text,
},
false,
);
}
if (item.url) {
await instance.mediaMessage(
{
number: remoteJid.split('@')[0],
delay: settings?.delayMessage || 1000,
mediatype: 'image',
media: item.url,
caption: item.caption,
},
false,
);
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({
where: {
id: session.id,
@ -211,8 +255,6 @@ export class OpenaiService {
awaitUser: true,
},
});
sendTelemetry('/message/sendText');
}
public async createAssistantNewSession(instance: InstanceDto, data: any) {