Skip to content

Commit fbfa364

Browse files
committed
Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop
2 parents 624b37e + fcde1f9 commit fbfa364

File tree

3 files changed

+98
-68
lines changed

3 files changed

+98
-68
lines changed

src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,8 +1173,8 @@ export class BaileysStartupService extends ChannelStartupService {
11731173
const oldMessage = await this.getMessage(editedMessage.key, true);
11741174
if ((oldMessage as any)?.id) {
11751175
const editedMessageTimestamp = Long.isLong(editedMessage?.timestampMs)
1176-
? editedMessage.timestampMs?.toNumber()
1177-
: (editedMessage.timestampMs as number);
1176+
? Math.floor(editedMessage.timestampMs.toNumber() / 1000)
1177+
: Math.floor((editedMessage.timestampMs as number) / 1000);
11781178

11791179
await this.prismaRepository.message.update({
11801180
where: { id: (oldMessage as any).id },
@@ -1205,7 +1205,7 @@ export class BaileysStartupService extends ChannelStartupService {
12051205
continue;
12061206
}
12071207

1208-
await this.baileysCache.set(messageKey, true, 30 * 60);
1208+
await this.baileysCache.set(messageKey, true, 5 * 60);
12091209

12101210
if (
12111211
(type !== 'notify' && type !== 'append') ||
@@ -1311,21 +1311,31 @@ export class BaileysStartupService extends ChannelStartupService {
13111311
data: messageRaw,
13121312
});
13131313

1314-
if (received.key.fromMe === false) {
1315-
if (msg.status === status[3]) {
1316-
this.logger.log(`Update not read messages ${received.key.remoteJid}`);
1317-
1318-
await this.updateChatUnreadMessages(received.key.remoteJid);
1319-
} else if (msg.status === status[4]) {
1320-
this.logger.log(`Update readed messages ${received.key.remoteJid} - ${msg.messageTimestamp}`);
1321-
1322-
await this.updateMessagesReadedByTimestamp(received.key.remoteJid, msg.messageTimestamp);
1314+
const {remoteJid} = received.key;
1315+
const timestamp = msg.messageTimestamp;
1316+
const fromMe = received.key.fromMe.toString();
1317+
const messageKey = `${remoteJid}_${timestamp}_${fromMe}`;
1318+
1319+
const cachedTimestamp = await this.baileysCache.get(messageKey);
1320+
1321+
if (!cachedTimestamp) {
1322+
if (!received.key.fromMe) {
1323+
if (msg.status === status[3]) {
1324+
this.logger.log(`Update not read messages ${remoteJid}`);
1325+
await this.updateChatUnreadMessages(remoteJid);
1326+
} else if (msg.status === status[4]) {
1327+
this.logger.log(`Update readed messages ${remoteJid} - ${timestamp}`);
1328+
await this.updateMessagesReadedByTimestamp(remoteJid, timestamp);
1329+
}
1330+
} else {
1331+
// is send message by me
1332+
this.logger.log(`Update readed messages ${remoteJid} - ${timestamp}`);
1333+
await this.updateMessagesReadedByTimestamp(remoteJid, timestamp);
13231334
}
1324-
} else {
1325-
// is send message by me
1326-
this.logger.log(`Update readed messages ${received.key.remoteJid} - ${msg.messageTimestamp}`);
13271335

1328-
await this.updateMessagesReadedByTimestamp(received.key.remoteJid, msg.messageTimestamp);
1336+
await this.baileysCache.set(messageKey, true, 5 * 60);
1337+
} else {
1338+
this.logger.info(`Update readed messages duplicated ignored [avoid deadlock]: ${messageKey}`);
13291339
}
13301340

13311341
if (isMedia) {
@@ -1498,7 +1508,7 @@ export class BaileysStartupService extends ChannelStartupService {
14981508
const cached = await this.baileysCache.get(updateKey);
14991509

15001510
if (cached) {
1501-
this.logger.info(`Message duplicated ignored: ${key.id}`);
1511+
this.logger.info(`Message duplicated ignored [avoid deadlock]: ${updateKey}`);
15021512
continue;
15031513
}
15041514

@@ -1514,7 +1524,7 @@ export class BaileysStartupService extends ChannelStartupService {
15141524
}
15151525
}
15161526

1517-
if (key.remoteJid !== 'status@broadcast') {
1527+
if (key.remoteJid !== 'status@broadcast' && key.id !== undefined) {
15181528
let pollUpdates: any;
15191529

15201530
if (update.pollUpdates) {
@@ -1542,19 +1552,20 @@ export class BaileysStartupService extends ChannelStartupService {
15421552
continue;
15431553
}
15441554

1555+
const message: any = {
1556+
messageId: findMessage.id,
1557+
keyId: key.id,
1558+
remoteJid: key?.remoteJid,
1559+
fromMe: key.fromMe,
1560+
participant: key?.remoteJid,
1561+
status: status[update.status] ?? 'DELETED',
1562+
pollUpdates,
1563+
instanceId: this.instanceId,
1564+
};
1565+
15451566
if (update.message === null && update.status === undefined) {
15461567
this.sendDataWebhook(Events.MESSAGES_DELETE, key);
15471568

1548-
const message: any = {
1549-
messageId: findMessage.id,
1550-
keyId: key.id,
1551-
remoteJid: key.remoteJid,
1552-
fromMe: key.fromMe,
1553-
participant: key?.remoteJid,
1554-
status: 'DELETED',
1555-
instanceId: this.instanceId,
1556-
};
1557-
15581569
if (this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE)
15591570
await this.prismaRepository.messageUpdate.create({
15601571
data: message,
@@ -1573,29 +1584,32 @@ export class BaileysStartupService extends ChannelStartupService {
15731584
if (!key.fromMe && key.remoteJid) {
15741585
readChatToUpdate[key.remoteJid] = true;
15751586

1576-
if (status[update.status] === status[4]) {
1577-
this.logger.log(`Update as read ${key.remoteJid} - ${findMessage.messageTimestamp}`);
1578-
this.updateMessagesReadedByTimestamp(key.remoteJid, findMessage.messageTimestamp);
1587+
const {remoteJid} = key;
1588+
const timestamp = findMessage.messageTimestamp;
1589+
const fromMe = key.fromMe.toString();
1590+
const messageKey = `${remoteJid}_${timestamp}_${fromMe}`;
1591+
1592+
const cachedTimestamp = await this.baileysCache.get(messageKey);
1593+
1594+
if (!cachedTimestamp) {
1595+
if (status[update.status] === status[4]) {
1596+
this.logger.log(`Update as read in message.update ${remoteJid} - ${timestamp}`);
1597+
await this.updateMessagesReadedByTimestamp(remoteJid, timestamp);
1598+
await this.baileysCache.set(messageKey, true, 5 * 60);
1599+
}
1600+
1601+
await this.prismaRepository.message.update({
1602+
where: { id: findMessage.id },
1603+
data: { status: status[update.status] },
1604+
});
1605+
} else {
1606+
this.logger.info(
1607+
`Update readed messages duplicated ignored in message.update [avoid deadlock]: ${messageKey}`,
1608+
);
15791609
}
15801610
}
1581-
1582-
await this.prismaRepository.message.update({
1583-
where: { id: findMessage.id },
1584-
data: { status: status[update.status] },
1585-
});
15861611
}
15871612

1588-
const message: any = {
1589-
messageId: findMessage.id,
1590-
keyId: key.id,
1591-
remoteJid: key.remoteJid,
1592-
fromMe: key.fromMe,
1593-
participant: key?.remoteJid,
1594-
status: status[update.status],
1595-
pollUpdates,
1596-
instanceId: this.instanceId,
1597-
};
1598-
15991613
this.sendDataWebhook(Events.MESSAGES_UPDATE, message);
16001614

16011615
if (this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE)
@@ -3769,6 +3783,10 @@ export class BaileysStartupService extends ChannelStartupService {
37693783
}
37703784
}
37713785

3786+
if ('messageContextInfo' in msg.message && Object.keys(msg.message).length === 1) {
3787+
throw 'The message is messageContextInfo';
3788+
}
3789+
37723790
let mediaMessage: any;
37733791
let mediaType: string;
37743792

@@ -3779,7 +3797,7 @@ export class BaileysStartupService extends ChannelStartupService {
37793797
break;
37803798
}
37813799
}
3782-
3800+
37833801
if (!mediaMessage) {
37843802
throw 'The message is not of the media type';
37853803
}
@@ -3844,7 +3862,7 @@ export class BaileysStartupService extends ChannelStartupService {
38443862
buffer: getBuffer ? buffer : null,
38453863
};
38463864
} catch (error) {
3847-
this.logger.error('Error processing media message:');
3865+
this.logger.error('Error processing media message:');
38483866
this.logger.error(error);
38493867
throw new BadRequestException(error.toString());
38503868
}

src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ export class ChatwootService {
930930
quotedMsg?: MessageModel,
931931
) {
932932
if (sourceId && this.isImportHistoryAvailable()) {
933-
const messageAlreadySaved = await chatwootImport.getExistingSourceIds([sourceId]);
933+
const messageAlreadySaved = await chatwootImport.getExistingSourceIds([sourceId], conversationId);
934934
if (messageAlreadySaved) {
935935
if (messageAlreadySaved.size > 0) {
936936
this.logger.warn('Message already saved on chatwoot');

src/api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper.ts

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ class ChatwootImport {
169169
}
170170
}
171171

172-
public async getExistingSourceIds(sourceIds: string[]): Promise<Set<string>> {
172+
public async getExistingSourceIds(sourceIds: string[], conversationId?: number): Promise<Set<string>> {
173173
try {
174174
const existingSourceIdsSet = new Set<string>();
175175

@@ -178,9 +178,17 @@ class ChatwootImport {
178178
}
179179

180180
const formattedSourceIds = sourceIds.map((sourceId) => `WAID:${sourceId.replace('WAID:', '')}`); // Make sure the sourceId is always formatted as WAID:1234567890
181-
const query = 'SELECT source_id FROM messages WHERE source_id = ANY($1)';
181+
let query: string;
182+
if (conversationId) {
183+
query = 'SELECT source_id FROM messages WHERE source_id = ANY($1)';
184+
}
185+
186+
if(!conversationId) {
187+
query = 'SELECT source_id FROM messages WHERE source_id = ANY($1) AND conversation_id = $2';
188+
}
189+
182190
const pgClient = postgresClient.getChatwootConnection();
183-
const result = await pgClient.query(query, [formattedSourceIds]);
191+
const result = await pgClient.query(query, [formattedSourceIds, conversationId]);
184192

185193
for (const row of result.rows) {
186194
existingSourceIdsSet.add(row.source_id);
@@ -499,25 +507,29 @@ class ChatwootImport {
499507
stickerMessage: msg.message.stickerMessage,
500508
templateMessage: msg.message.templateMessage?.hydratedTemplate?.hydratedContentText,
501509
};
502-
const typeKey = Object.keys(types).find((key) => types[key] !== undefined);
503510

511+
const typeKey = Object.keys(types).find(
512+
(key) => types[key] !== undefined && types[key] !== null
513+
);
504514
switch (typeKey) {
505-
case 'documentMessage':
506-
return `_<File: ${msg.message.documentMessage.fileName}${
507-
msg.message.documentMessage.caption ? ` ${msg.message.documentMessage.caption}` : ''
508-
}>_`;
509-
510-
case 'documentWithCaptionMessage':
511-
return `_<File: ${msg.message.documentWithCaptionMessage.message.documentMessage.fileName}${
512-
msg.message.documentWithCaptionMessage.message.documentMessage.caption
513-
? ` ${msg.message.documentWithCaptionMessage.message.documentMessage.caption}`
514-
: ''
515-
}>_`;
515+
case 'documentMessage': {
516+
const doc = msg.message.documentMessage;
517+
const fileName = doc?.fileName || 'document';
518+
const caption = doc?.caption ? ` ${doc.caption}` : '';
519+
return `_<File: ${fileName}${caption}>_`;
520+
}
521+
522+
case 'documentWithCaptionMessage': {
523+
const doc = msg.message.documentWithCaptionMessage?.message?.documentMessage;
524+
const fileName = doc?.fileName || 'document';
525+
const caption = doc?.caption ? ` ${doc.caption}` : '';
526+
return `_<File: ${fileName}${caption}>_`;
527+
}
516528

517529
case 'templateMessage':
518-
return msg.message.templateMessage.hydratedTemplate.hydratedTitleText
519-
? `*${msg.message.templateMessage.hydratedTemplate.hydratedTitleText}*\\n`
520-
: '' + msg.message.templateMessage.hydratedTemplate.hydratedContentText;
530+
const template = msg.message.templateMessage?.hydratedTemplate;
531+
return (template?.hydratedTitleText ? `*${template.hydratedTitleText}*\n` : '') +
532+
(template?.hydratedContentText || '');
521533

522534
case 'imageMessage':
523535
return '_<Image Message>_';

0 commit comments

Comments
 (0)