From fc00916345ef771f6fd8778fdf12506d0b825370 Mon Sep 17 00:00:00 2001
From: Willian Coqueiro <wil_kokero@hotmail.com>
Date: Mon, 19 May 2025 23:05:11 +0000
Subject: [PATCH 1/5] fix: Corrige o erro Unable to fit integer value
 '1747658857155' into an INT4 (32-bit signed integer.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

## Solução
Após analise dos valores recebidos e seguindo a logica em outras partes também, se confirma que o valor de entrada é de timestamp em ms.
---
 .../integrations/channel/whatsapp/whatsapp.baileys.service.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
index aa8f245c09..5a180df412 100644
--- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
+++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
@@ -1173,8 +1173,8 @@ export class BaileysStartupService extends ChannelStartupService {
             const oldMessage = await this.getMessage(editedMessage.key, true);
             if ((oldMessage as any)?.id) {
               const editedMessageTimestamp = Long.isLong(editedMessage?.timestampMs)
-                ? editedMessage.timestampMs?.toNumber()
-                : (editedMessage.timestampMs as number);
+                ? Math.floor(editedMessage.timestampMs.toNumber() / 1000) // Convert to int32 by dividing by 1000 to get seconds
+                : Math.floor((editedMessage.timestampMs as number) / 1000); // Convert to int32 by dividing by 1000 to get seconds
 
               await this.prismaRepository.message.update({
                 where: { id: (oldMessage as any).id },

From 348a4ff25161df02cd8239989a32f69829d7e840 Mon Sep 17 00:00:00 2001
From: Willian Coqueiro <wil_kokero@hotmail.com>
Date: Mon, 19 May 2025 23:14:57 +0000
Subject: [PATCH 2/5] fix: Corrige problemas com deadlocks

## Erros:
- code: "40P01", message: "deadlock detected".
- Argument status is missing.
---
 .../whatsapp/whatsapp.baileys.service.ts      | 110 ++++++++++--------
 1 file changed, 62 insertions(+), 48 deletions(-)

diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
index 5a180df412..9fba987840 100644
--- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
+++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
@@ -1173,8 +1173,8 @@ export class BaileysStartupService extends ChannelStartupService {
             const oldMessage = await this.getMessage(editedMessage.key, true);
             if ((oldMessage as any)?.id) {
               const editedMessageTimestamp = Long.isLong(editedMessage?.timestampMs)
-                ? Math.floor(editedMessage.timestampMs.toNumber() / 1000) // Convert to int32 by dividing by 1000 to get seconds
-                : Math.floor((editedMessage.timestampMs as number) / 1000); // Convert to int32 by dividing by 1000 to get seconds
+                ? Math.floor(editedMessage.timestampMs.toNumber() / 1000)
+                : Math.floor((editedMessage.timestampMs as number) / 1000);
 
               await this.prismaRepository.message.update({
                 where: { id: (oldMessage as any).id },
@@ -1205,7 +1205,7 @@ export class BaileysStartupService extends ChannelStartupService {
             continue;
           }
 
-          await this.baileysCache.set(messageKey, true, 30 * 60);
+          await this.baileysCache.set(messageKey, true, 5 * 60);
 
           if (
             (type !== 'notify' && type !== 'append') ||
@@ -1311,21 +1311,31 @@ export class BaileysStartupService extends ChannelStartupService {
               data: messageRaw,
             });
 
-            if (received.key.fromMe === false) {
-              if (msg.status === status[3]) {
-                this.logger.log(`Update not read messages ${received.key.remoteJid}`);
-
-                await this.updateChatUnreadMessages(received.key.remoteJid);
-              } else if (msg.status === status[4]) {
-                this.logger.log(`Update readed messages ${received.key.remoteJid} - ${msg.messageTimestamp}`);
-
-                await this.updateMessagesReadedByTimestamp(received.key.remoteJid, msg.messageTimestamp);
+            const remoteJid = received.key.remoteJid;
+            const timestamp = msg.messageTimestamp;
+            const fromMe = received.key.fromMe.toString();
+            const messageKey = `${remoteJid}_${timestamp}_${fromMe}`;
+
+            const cachedTimestamp = await this.baileysCache.get(messageKey);
+
+            if (!cachedTimestamp) {
+              if (!received.key.fromMe) {
+                if (msg.status === status[3]) {
+                  this.logger.log(`Update not read messages ${remoteJid}`);
+                  await this.updateChatUnreadMessages(remoteJid);
+                } else if (msg.status === status[4]) {
+                  this.logger.log(`Update readed messages ${remoteJid} - ${timestamp}`);
+                  await this.updateMessagesReadedByTimestamp(remoteJid, timestamp);
+                }
+              } else {
+                // is send message by me
+                this.logger.log(`Update readed messages ${remoteJid} - ${timestamp}`);
+                await this.updateMessagesReadedByTimestamp(remoteJid, timestamp);
               }
-            } else {
-              // is send message by me
-              this.logger.log(`Update readed messages ${received.key.remoteJid} - ${msg.messageTimestamp}`);
 
-              await this.updateMessagesReadedByTimestamp(received.key.remoteJid, msg.messageTimestamp);
+              await this.baileysCache.set(messageKey, true, 5 * 60);
+            } else {
+              this.logger.info(`Update readed messages duplicated ignored [avoid deadlock]: ${messageKey}`);
             }
 
             if (isMedia) {
@@ -1481,7 +1491,7 @@ export class BaileysStartupService extends ChannelStartupService {
         const cached = await this.baileysCache.get(updateKey);
 
         if (cached) {
-          this.logger.info(`Message duplicated ignored: ${key.id}`);
+          this.logger.info(`Message duplicated ignored [avoid deadlock]: ${updateKey}`);
           continue;
         }
 
@@ -1497,7 +1507,7 @@ export class BaileysStartupService extends ChannelStartupService {
           }
         }
 
-        if (key.remoteJid !== 'status@broadcast') {
+        if (key.remoteJid !== 'status@broadcast' && key.id !== undefined) {
           let pollUpdates: any;
 
           if (update.pollUpdates) {
@@ -1525,19 +1535,20 @@ export class BaileysStartupService extends ChannelStartupService {
             continue;
           }
 
+          const message: any = {
+            messageId: findMessage.id,
+            keyId: key.id,
+            remoteJid: key?.remoteJid,
+            fromMe: key.fromMe,
+            participant: key?.remoteJid,
+            status: status[update.status] ?? 'DELETED',
+            pollUpdates,
+            instanceId: this.instanceId,
+          };
+
           if (update.message === null && update.status === undefined) {
             this.sendDataWebhook(Events.MESSAGES_DELETE, key);
 
-            const message: any = {
-              messageId: findMessage.id,
-              keyId: key.id,
-              remoteJid: key.remoteJid,
-              fromMe: key.fromMe,
-              participant: key?.remoteJid,
-              status: 'DELETED',
-              instanceId: this.instanceId,
-            };
-
             if (this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE)
               await this.prismaRepository.messageUpdate.create({
                 data: message,
@@ -1556,29 +1567,32 @@ export class BaileysStartupService extends ChannelStartupService {
             if (!key.fromMe && key.remoteJid) {
               readChatToUpdate[key.remoteJid] = true;
 
-              if (status[update.status] === status[4]) {
-                this.logger.log(`Update as read ${key.remoteJid} - ${findMessage.messageTimestamp}`);
-                this.updateMessagesReadedByTimestamp(key.remoteJid, findMessage.messageTimestamp);
+              const remoteJid = key.remoteJid;
+              const timestamp = findMessage.messageTimestamp;
+              const fromMe = key.fromMe.toString();
+              const messageKey = `${remoteJid}_${timestamp}_${fromMe}`;
+
+              const cachedTimestamp = await this.baileysCache.get(messageKey);
+
+              if (!cachedTimestamp) {
+                if (status[update.status] === status[4]) {
+                  this.logger.log(`Update as read in message.update ${remoteJid} - ${timestamp}`);
+                  await this.updateMessagesReadedByTimestamp(remoteJid, timestamp);
+                  await this.baileysCache.set(messageKey, true, 5 * 60);
+                }
+
+                await this.prismaRepository.message.update({
+                  where: { id: findMessage.id },
+                  data: { status: status[update.status] },
+                });
+              } else {
+                this.logger.info(
+                  `Update readed messages duplicated ignored in message.update [avoid deadlock]: ${messageKey}`,
+                );
               }
             }
-
-            await this.prismaRepository.message.update({
-              where: { id: findMessage.id },
-              data: { status: status[update.status] },
-            });
           }
 
-          const message: any = {
-            messageId: findMessage.id,
-            keyId: key.id,
-            remoteJid: key.remoteJid,
-            fromMe: key.fromMe,
-            participant: key?.remoteJid,
-            status: status[update.status],
-            pollUpdates,
-            instanceId: this.instanceId,
-          };
-
           this.sendDataWebhook(Events.MESSAGES_UPDATE, message);
 
           if (this.configService.get<Database>('DATABASE').SAVE_DATA.MESSAGE_UPDATE)
@@ -3745,7 +3759,7 @@ export class BaileysStartupService extends ChannelStartupService {
           break;
         }
       }
-
+      
       if (!mediaMessage) {
         throw 'The message is not of the media type';
       }

From 9c530c69cf78fe23a3c3a3feee3b12d7a5cf62c1 Mon Sep 17 00:00:00 2001
From: Willian Coqueiro <wil_kokero@hotmail.com>
Date: Mon, 19 May 2025 23:18:23 +0000
Subject: [PATCH 3/5] fix: Evita tentar processar media messageContextInfo e
 disparar um erro generico.

---
 .../channel/whatsapp/whatsapp.baileys.service.ts          | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
index 9fba987840..2090a96a10 100644
--- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
+++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
@@ -3749,6 +3749,10 @@ export class BaileysStartupService extends ChannelStartupService {
         }
       }
 
+      if ('messageContextInfo' in msg.message && Object.keys(msg.message).length === 1) {
+        throw 'The message is messageContextInfo';
+      }
+
       let mediaMessage: any;
       let mediaType: string;
 
@@ -3824,8 +3828,8 @@ export class BaileysStartupService extends ChannelStartupService {
         buffer: getBuffer ? buffer : null,
       };
     } catch (error) {
-      this.logger.error('Error processing media message:');
-      this.logger.error(error);
+      this.logger.info('Error processing media message:');
+      this.logger.info(error);
       throw new BadRequestException(error.toString());
     }
   }

From a2d8642e1cf6400a1b3876d05f42bdca24a914f3 Mon Sep 17 00:00:00 2001
From: Willian Coqueiro <wil_kokero@hotmail.com>
Date: Mon, 19 May 2025 23:21:01 +0000
Subject: [PATCH 4/5] fix: Corrige processamento de documentos sem filename.

## Erros:
- Cannot read properties of null (reading 'fileName')
---
 .../chatwoot/utils/chatwoot-import-helper.ts  | 34 +++++++++++--------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/src/api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper.ts b/src/api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper.ts
index 52453f59cc..faa9308eaf 100644
--- a/src/api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper.ts
+++ b/src/api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper.ts
@@ -499,25 +499,29 @@ class ChatwootImport {
       stickerMessage: msg.message.stickerMessage,
       templateMessage: msg.message.templateMessage?.hydratedTemplate?.hydratedContentText,
     };
-    const typeKey = Object.keys(types).find((key) => types[key] !== undefined);
 
+    const typeKey = Object.keys(types).find(
+      (key) => types[key] !== undefined && types[key] !== null
+    );
     switch (typeKey) {
-      case 'documentMessage':
-        return `_<File: ${msg.message.documentMessage.fileName}${
-          msg.message.documentMessage.caption ? ` ${msg.message.documentMessage.caption}` : ''
-        }>_`;
-
-      case 'documentWithCaptionMessage':
-        return `_<File: ${msg.message.documentWithCaptionMessage.message.documentMessage.fileName}${
-          msg.message.documentWithCaptionMessage.message.documentMessage.caption
-            ? ` ${msg.message.documentWithCaptionMessage.message.documentMessage.caption}`
-            : ''
-        }>_`;
+      case 'documentMessage': {
+        const doc = msg.message.documentMessage;
+        const fileName = doc?.fileName || 'document';
+        const caption = doc?.caption ? ` ${doc.caption}` : '';
+        return `_<File: ${fileName}${caption}>_`;
+      }
+
+      case 'documentWithCaptionMessage': {
+        const doc = msg.message.documentWithCaptionMessage?.message?.documentMessage;
+        const fileName = doc?.fileName || 'document';
+        const caption = doc?.caption ? ` ${doc.caption}` : '';
+        return `_<File: ${fileName}${caption}>_`;
+      }
 
       case 'templateMessage':
-        return msg.message.templateMessage.hydratedTemplate.hydratedTitleText
-          ? `*${msg.message.templateMessage.hydratedTemplate.hydratedTitleText}*\\n`
-          : '' + msg.message.templateMessage.hydratedTemplate.hydratedContentText;
+        const template = msg.message.templateMessage?.hydratedTemplate;
+        return (template?.hydratedTitleText ? `*${template.hydratedTitleText}*\n` : '') +
+              (template?.hydratedContentText || '');
 
       case 'imageMessage':
         return '_<Image Message>_';

From c53a96e7574035e5e07474dd046ab35f1ef65a41 Mon Sep 17 00:00:00 2001
From: Willian Coqueiro <wil_kokero@hotmail.com>
Date: Tue, 20 May 2025 13:07:28 +0000
Subject: [PATCH 5/5] Fix suggestions

---
 .../channel/whatsapp/whatsapp.baileys.service.ts          | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
index 2090a96a10..2b00fa2df2 100644
--- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
+++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
@@ -1311,7 +1311,7 @@ export class BaileysStartupService extends ChannelStartupService {
               data: messageRaw,
             });
 
-            const remoteJid = received.key.remoteJid;
+            const {remoteJid} = received.key;
             const timestamp = msg.messageTimestamp;
             const fromMe = received.key.fromMe.toString();
             const messageKey = `${remoteJid}_${timestamp}_${fromMe}`;
@@ -1567,7 +1567,7 @@ export class BaileysStartupService extends ChannelStartupService {
             if (!key.fromMe && key.remoteJid) {
               readChatToUpdate[key.remoteJid] = true;
 
-              const remoteJid = key.remoteJid;
+              const {remoteJid} = key; 
               const timestamp = findMessage.messageTimestamp;
               const fromMe = key.fromMe.toString();
               const messageKey = `${remoteJid}_${timestamp}_${fromMe}`;
@@ -3828,8 +3828,8 @@ export class BaileysStartupService extends ChannelStartupService {
         buffer: getBuffer ? buffer : null,
       };
     } catch (error) {
-      this.logger.info('Error processing media message:');
-      this.logger.info(error);
+      this.logger.error('Error processing media message:');  
+      this.logger.error(error);
       throw new BadRequestException(error.toString());
     }
   }
