mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-12-11 02:49:36 -06:00
chore: update Baileys dependency to version 7.0.0-rc.3 and improve message key handling in WhatsApp service
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
Some checks failed
Build Docker image / Build and Deploy (push) Has been cancelled
This commit is contained in:
parent
bfe7030fab
commit
486645fb08
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
|
|
||||||
* Baileys Updates: v7.0.0-rc.2 ([Link](https://github.com/WhiskeySockets/Baileys/releases/tag/v7.0.0-rc.2))
|
* Baileys Updates: v7.0.0-rc.3 ([Link](https://github.com/WhiskeySockets/Baileys/releases/tag/v7.0.0-rc.3))
|
||||||
|
|
||||||
# 2.3.2 (2025-09-02)
|
# 2.3.2 (2025-09-02)
|
||||||
|
|
||||||
|
|||||||
4142
package-lock.json
generated
4142
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -60,7 +60,7 @@
|
|||||||
"amqplib": "^0.10.5",
|
"amqplib": "^0.10.5",
|
||||||
"audio-decode": "^2.2.3",
|
"audio-decode": "^2.2.3",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"baileys": "github:WhiskeySockets/Baileys",
|
"baileys": "^7.0.0-rc.3",
|
||||||
"class-validator": "^0.14.1",
|
"class-validator": "^0.14.1",
|
||||||
"compression": "^1.7.5",
|
"compression": "^1.7.5",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
@ -125,7 +125,7 @@
|
|||||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.4.2",
|
||||||
"tsconfig-paths": "^4.2.0",
|
"tsconfig-paths": "^4.2.0",
|
||||||
"tsx": "^4.20.3",
|
"tsx": "^4.20.5",
|
||||||
"typescript": "^5.7.2"
|
"typescript": "^5.7.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -151,6 +151,19 @@ import { v4 } from 'uuid';
|
|||||||
import { BaileysMessageProcessor } from './baileysMessage.processor';
|
import { BaileysMessageProcessor } from './baileysMessage.processor';
|
||||||
import { useVoiceCallsBaileys } from './voiceCalls/useVoiceCallsBaileys';
|
import { useVoiceCallsBaileys } from './voiceCalls/useVoiceCallsBaileys';
|
||||||
|
|
||||||
|
export interface ExtendedMessageKey extends WAMessageKey {
|
||||||
|
senderPn?: string;
|
||||||
|
previousRemoteJid?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExtendedIMessageKey extends proto.IMessageKey {
|
||||||
|
senderPn?: string;
|
||||||
|
remoteJidAlt?: string;
|
||||||
|
participantAlt?: string;
|
||||||
|
server_id?: string;
|
||||||
|
isViewOnce?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
const groupMetadataCache = new CacheService(new CacheEngine(configService, 'groups').getEngine());
|
const groupMetadataCache = new CacheService(new CacheEngine(configService, 'groups').getEngine());
|
||||||
|
|
||||||
// Adicione a função getVideoDuration no início do arquivo
|
// Adicione a função getVideoDuration no início do arquivo
|
||||||
@ -986,8 +999,8 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m.key.remoteJid?.includes('@lid') && m.key.remoteJidAlt) {
|
if (m.key.remoteJid?.includes('@lid') && (m.key as ExtendedIMessageKey).senderPn) {
|
||||||
m.key.remoteJid = m.key.remoteJidAlt;
|
m.key.remoteJid = (m.key as ExtendedIMessageKey).senderPn;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Long.isLong(m?.messageTimestamp)) {
|
if (Long.isLong(m?.messageTimestamp)) {
|
||||||
@ -1052,9 +1065,9 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
for (const received of messages) {
|
for (const received of messages) {
|
||||||
if (received.key.remoteJid?.includes('@lid') && received.key.remoteJidAlt) {
|
if (received.key.remoteJid?.includes('@lid') && (received.key as ExtendedMessageKey).senderPn) {
|
||||||
(received.key as { previousRemoteJid?: string | null }).previousRemoteJid = received.key.remoteJid;
|
(received.key as ExtendedMessageKey).previousRemoteJid = received.key.remoteJid;
|
||||||
received.key.remoteJid = received.key.remoteJidAlt;
|
received.key.remoteJid = (received.key as ExtendedMessageKey).senderPn;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
received?.messageStubParameters?.some?.((param) =>
|
received?.messageStubParameters?.some?.((param) =>
|
||||||
@ -4308,47 +4321,30 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
throw new Error('Method not available in the Baileys service');
|
throw new Error('Method not available in the Baileys service');
|
||||||
}
|
}
|
||||||
|
|
||||||
private sanitizeMessageContent(messageContent: any): any {
|
private convertLongToNumber(obj: any): any {
|
||||||
if (!messageContent) return messageContent;
|
if (obj === null || obj === undefined) {
|
||||||
|
return obj;
|
||||||
// Deep clone and sanitize to avoid modifying original
|
|
||||||
return JSON.parse(
|
|
||||||
JSON.stringify(messageContent, (key, value) => {
|
|
||||||
// Convert Long objects to numbers
|
|
||||||
if (Long.isLong(value)) {
|
|
||||||
return value.toNumber();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert Uint8Array to regular arrays
|
if (Long.isLong(obj)) {
|
||||||
if (value instanceof Uint8Array) {
|
return obj.toNumber();
|
||||||
return Array.from(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove functions and other non-serializable objects
|
if (Array.isArray(obj)) {
|
||||||
if (typeof value === 'function') {
|
return obj.map((item) => this.convertLongToNumber(item));
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle objects with toJSON method
|
if (typeof obj === 'object') {
|
||||||
if (value && typeof value === 'object' && typeof value.toJSON === 'function') {
|
const converted: any = {};
|
||||||
return value.toJSON();
|
for (const key in obj) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||||
|
converted[key] = this.convertLongToNumber(obj[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return converted;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle special objects that might not serialize properly
|
return obj;
|
||||||
if (value && typeof value === 'object') {
|
|
||||||
// Check if it's a plain object or has prototype issues
|
|
||||||
try {
|
|
||||||
JSON.stringify(value);
|
|
||||||
return value;
|
|
||||||
} catch (e) {
|
|
||||||
// If it can't be stringified, return a safe representation
|
|
||||||
return '[Non-serializable object]';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private prepareMessage(message: proto.IWebMessageInfo): any {
|
private prepareMessage(message: proto.IWebMessageInfo): any {
|
||||||
@ -4363,11 +4359,11 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
? 'Você'
|
? 'Você'
|
||||||
: message?.participant || (message.key?.participant ? message.key.participant.split('@')[0] : null)),
|
: message?.participant || (message.key?.participant ? message.key.participant.split('@')[0] : null)),
|
||||||
status: status[message.status],
|
status: status[message.status],
|
||||||
message: this.sanitizeMessageContent({ ...message.message }),
|
message: this.convertLongToNumber({ ...message.message }),
|
||||||
contextInfo: this.sanitizeMessageContent(contentMsg?.contextInfo),
|
contextInfo: this.convertLongToNumber(contentMsg?.contextInfo),
|
||||||
messageType: contentType || 'unknown',
|
messageType: contentType || 'unknown',
|
||||||
messageTimestamp: Long.isLong(message.messageTimestamp)
|
messageTimestamp: Long.isLong(message.messageTimestamp)
|
||||||
? (message.messageTimestamp as Long).toNumber()
|
? message.messageTimestamp.toNumber()
|
||||||
: (message.messageTimestamp as number),
|
: (message.messageTimestamp as number),
|
||||||
instanceId: this.instanceId,
|
instanceId: this.instanceId,
|
||||||
source: getDevice(message.key.id),
|
source: getDevice(message.key.id),
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { InstanceDto } from '@api/dto/instance.dto';
|
import { InstanceDto } from '@api/dto/instance.dto';
|
||||||
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '@api/dto/sendMessage.dto';
|
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '@api/dto/sendMessage.dto';
|
||||||
|
import { ExtendedMessageKey } from '@api/integrations/channel/whatsapp/whatsapp.baileys.service';
|
||||||
import { ChatwootDto } from '@api/integrations/chatbot/chatwoot/dto/chatwoot.dto';
|
import { ChatwootDto } from '@api/integrations/chatbot/chatwoot/dto/chatwoot.dto';
|
||||||
import { postgresClient } from '@api/integrations/chatbot/chatwoot/libs/postgres.client';
|
import { postgresClient } from '@api/integrations/chatbot/chatwoot/libs/postgres.client';
|
||||||
import { chatwootImport } from '@api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper';
|
import { chatwootImport } from '@api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper';
|
||||||
@ -1284,12 +1285,7 @@ export class ChatwootService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (message) {
|
if (message) {
|
||||||
const key = message.key as {
|
const key = message.key as ExtendedMessageKey;
|
||||||
id: string;
|
|
||||||
remoteJid: string;
|
|
||||||
fromMe: boolean;
|
|
||||||
participant: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
await waInstance?.client.sendMessage(key.remoteJid, { delete: key });
|
await waInstance?.client.sendMessage(key.remoteJid, { delete: key });
|
||||||
|
|
||||||
@ -1487,12 +1483,7 @@ export class ChatwootService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (lastMessage && !lastMessage.chatwootIsRead) {
|
if (lastMessage && !lastMessage.chatwootIsRead) {
|
||||||
const key = lastMessage.key as {
|
const key = lastMessage.key as ExtendedMessageKey;
|
||||||
id: string;
|
|
||||||
fromMe: boolean;
|
|
||||||
remoteJid: string;
|
|
||||||
participant?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
waInstance?.markMessageAsRead({
|
waInstance?.markMessageAsRead({
|
||||||
readMessages: [
|
readMessages: [
|
||||||
@ -1550,12 +1541,7 @@ export class ChatwootService {
|
|||||||
chatwootMessageIds: ChatwootMessage,
|
chatwootMessageIds: ChatwootMessage,
|
||||||
instance: InstanceDto,
|
instance: InstanceDto,
|
||||||
) {
|
) {
|
||||||
const key = message.key as {
|
const key = message.key as ExtendedMessageKey;
|
||||||
id: string;
|
|
||||||
fromMe: boolean;
|
|
||||||
remoteJid: string;
|
|
||||||
participant?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!chatwootMessageIds.messageId || !key?.id) {
|
if (!chatwootMessageIds.messageId || !key?.id) {
|
||||||
return;
|
return;
|
||||||
@ -1623,12 +1609,7 @@ export class ChatwootService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const key = message?.key as {
|
const key = message?.key as ExtendedMessageKey;
|
||||||
id: string;
|
|
||||||
fromMe: boolean;
|
|
||||||
remoteJid: string;
|
|
||||||
participant?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (message && key?.id) {
|
if (message && key?.id) {
|
||||||
return {
|
return {
|
||||||
@ -2258,12 +2239,13 @@ export class ChatwootService {
|
|||||||
body?.editedMessage?.conversation || body?.editedMessage?.extendedTextMessage?.text
|
body?.editedMessage?.conversation || body?.editedMessage?.extendedTextMessage?.text
|
||||||
}\n\n_\`${i18next.t('cw.message.edited')}.\`_`;
|
}\n\n_\`${i18next.t('cw.message.edited')}.\`_`;
|
||||||
const message = await this.getMessageByKeyId(instance, body?.key?.id);
|
const message = await this.getMessageByKeyId(instance, body?.key?.id);
|
||||||
const key = message.key as {
|
|
||||||
id: string;
|
if (!message) {
|
||||||
fromMe: boolean;
|
this.logger.warn('Message not found for edit event');
|
||||||
remoteJid: string;
|
return;
|
||||||
participant?: string;
|
}
|
||||||
};
|
|
||||||
|
const key = message.key as ExtendedMessageKey;
|
||||||
|
|
||||||
const messageType = key?.fromMe ? 'outgoing' : 'incoming';
|
const messageType = key?.fromMe ? 'outgoing' : 'incoming';
|
||||||
|
|
||||||
@ -2541,7 +2523,7 @@ export class ChatwootService {
|
|||||||
const savedMessages = await this.prismaRepository.message.findMany({
|
const savedMessages = await this.prismaRepository.message.findMany({
|
||||||
where: {
|
where: {
|
||||||
Instance: { name: instance.instanceName },
|
Instance: { name: instance.instanceName },
|
||||||
messageTimestamp: { gte: dayjs().subtract(6, 'hours').unix() },
|
messageTimestamp: { gte: Number(dayjs().subtract(6, 'hours').unix()) },
|
||||||
AND: ids.map((id) => ({ key: { path: ['id'], not: id } })),
|
AND: ids.map((id) => ({ key: { path: ['id'], not: id } })),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -29,6 +29,8 @@ export class WAMonitoringService {
|
|||||||
|
|
||||||
Object.assign(this.db, configService.get<Database>('DATABASE'));
|
Object.assign(this.db, configService.get<Database>('DATABASE'));
|
||||||
Object.assign(this.redis, configService.get<CacheConf>('CACHE'));
|
Object.assign(this.redis, configService.get<CacheConf>('CACHE'));
|
||||||
|
|
||||||
|
(this as any).providerSession = Object.freeze(configService.get<ProviderSession>('PROVIDER'));
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly db: Partial<Database> = {};
|
private readonly db: Partial<Database> = {};
|
||||||
@ -37,7 +39,7 @@ export class WAMonitoringService {
|
|||||||
private readonly logger = new Logger('WAMonitoringService');
|
private readonly logger = new Logger('WAMonitoringService');
|
||||||
public readonly waInstances: Record<string, any> = {};
|
public readonly waInstances: Record<string, any> = {};
|
||||||
|
|
||||||
private readonly providerSession = Object.freeze(this.configService.get<ProviderSession>('PROVIDER'));
|
private readonly providerSession: ProviderSession;
|
||||||
|
|
||||||
public delInstanceTime(instance: string) {
|
public delInstanceTime(instance: string) {
|
||||||
const time = this.configService.get<DelInstance>('DEL_INSTANCE');
|
const time = this.configService.get<DelInstance>('DEL_INSTANCE');
|
||||||
|
|||||||
@ -3,6 +3,8 @@ import fs from 'fs';
|
|||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
|
const __dirname = path.resolve(process.cwd(), 'src', 'utils');
|
||||||
|
|
||||||
const languages = ['en', 'pt-BR', 'es'];
|
const languages = ['en', 'pt-BR', 'es'];
|
||||||
const translationsPath = path.join(__dirname, 'translations');
|
const translationsPath = path.join(__dirname, 'translations');
|
||||||
const configService: ConfigService = new ConfigService();
|
const configService: ConfigService = new ConfigService();
|
||||||
@ -12,8 +14,9 @@ const resources: any = {};
|
|||||||
languages.forEach((language) => {
|
languages.forEach((language) => {
|
||||||
const languagePath = path.join(translationsPath, `${language}.json`);
|
const languagePath = path.join(translationsPath, `${language}.json`);
|
||||||
if (fs.existsSync(languagePath)) {
|
if (fs.existsSync(languagePath)) {
|
||||||
|
const translationContent = fs.readFileSync(languagePath, 'utf8');
|
||||||
resources[language] = {
|
resources[language] = {
|
||||||
translation: require(languagePath),
|
translation: JSON.parse(translationContent),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user