WhiskeySockets / Baileys

Lightweight full-featured typescript/javascript WhatsApp Web API
https://baileys.whiskeysockets.io/
MIT License
3.68k stars 1.24k forks source link

The messages.upsert event is called twice consecutively #962

Open ecatugy opened 1 month ago

ecatugy commented 1 month ago

Whenever I receive a message and it triggers the 'messages.upsert' event, it is fired twice consecutively. Is there a way to know if it's an already processed message, or is there a configuration to trigger it only once?

  event.on('messages.upsert', async ({ messages, type }) => {

      const m = messages[0];
      if (m && m.key.fromMe) return;

      console.log('enter twice')

  );
hacxk commented 1 month ago

check your whole code there is a another messages.upsert event?

ecatugy commented 1 month ago

check your whole code there is a another messages.upsert event?

Yes, I only subscribe to the event once, but I've noticed that when there are two or more sockets instantiated with different numbers, the call always gets duplicated in messages.upsert . There's no parameter indicating whether it's already been processed or not, and it happens instantaneously, within fractions of a second.

hacxk commented 1 month ago

Possible Solutions

  1. Message Deduplication:

    • Maintain a Cache: Create a client-side cache to store recently processed message IDs. When the messages.upsert event fires, check if the message ID exists in the cache. If it does, ignore it.
    • Timeout Mechanism: Consider adding a short timeout (e.g., a few seconds) to the cache entries. This prevents the cache from growing indefinitely and ensures that messages are re-processed if needed after a certain time.

    Example

    const processedMessages = new Set();
    
    event.on('messages.upsert', async ({ messages, type }) => {
       const m = messages[0];
       if (m && m.key.fromMe) return; // Ignore self-sent messages
    
       if (processedMessages.has(m.key.id)) {
           return; // Skip duplicate message
       }
    
       processedMessages.add(m.key.id);
       setTimeout(() => processedMessages.delete(m.key.id), 5000); // Remove from cache after 5 seconds
    
       // Process the message...
    });