open-wa / wa-automate-nodejs

💬 🤖 The most reliable tool for chatbots with advanced features. Be sure to 🌟 this repository for updates!
https://docs.openwa.dev/
Other
3.14k stars 601 forks source link

client.forwardMessages doesn't always return the boolean | messageId #2560

Closed linconrezende closed 2 years ago

linconrezende commented 2 years ago

Are you using the latest version of the library?

What type of session are you experiencing this issue on?

Multi-device and I have set multiDevice to true in my config OR am using the --multi-device flag

What type of host account are you experiencing this issue on?

Tested and experienced on both

Mode

My own code

Current Behavior

When I call client.forwardMessages passing the chat ID (as string) and a list of messages id (as string), the function sometimes return a array with the message id as true_ but ONLY the first message is actually sent. It instantly returns a array with one single message id and if I call the function again after a while, forwarding ANOTHER MESSAGE, it returns a array with the previous messages ids that were sent.

Apparently, it can only forward a single message to the same chat and the other messages seems to be waiting for a delay or something like that.

I've tested forwarding 5 messages to 10 different groups, it instantly send the first message to all groups but then.. after a while it sends the second message to every group, then a few seconds later the third, and so on. BUT THE PROBLEM is that, the forwardMessages function already returned a result. There is no way I can possibly know if those messages were in fact forwarded or not.

Expected Behavior

I think the client.forwardMessages should allways return a valid array with the all the messages ids (true or false). Not empty array., not array missing messages ids (sometimes it returns only one message id when It actually has 5).

Steps To Reproduce

  1. Initialize the client
  2. Authenticate with QR Code
  3. Set onMessage listener
  4. send a message to the logged in number
  5. use the client.forwardMessages('XXXXXXXXXXXX@c.us', [message]) and then wait for the result with await or with then(result =>...

create() code

wa.create({
      sessionId: "OPEN_WA_BOT",
      safeMode: false,
      multiDevice: true, //required to enable multiDevice support
      authTimeout: 120,
      blockCrashLogs: true,
      disableSpins: false,
      headless: true,
      hostNotificationLang: 'PT_BR',
      logConsole: true,
      popup: false,
      qrTimeout: 0, //0 means it will wait forever for you to scan the qr code
    }).then(c => {
        // Store the client object to use it later
        client = c
    }).catch(error => {
      console.error(error)
    });

DEBUG INFO

Debug Info {
  WA_VERSION: '2.2208.7',
  PAGE_UA: 'WhatsApp/2.2147.16 Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36',
  WA_AUTOMATE_VERSION: '4.32.2 UPDATE AVAILABLE: 4.32.5',
  BROWSER_VERSION: 'HeadlessChrome/99.0.4844.51',
  OS: 'Windows 10',
  START_TS: 1647140615170
}

Environment

- OS: Windows (I am also debuging on Ubuntu Server 18.04)
- Node: 14.17.6 (and also tried on 16.14)
- npm: 6.14.15

Screenshots/Logs

EXAMPLE 1: I forwarded 5 messages to a group: image

1 minute later, I forwarded one single message to the same group: (as you can see, it returned 4 messages ids, and none of those were actually from this one that I just forwarded, it was the 4 missing from the previous forward) image

My code bellow: image

console.log(`Forwarding messages`)
        lstMsg.forEach(msg => {
          console.log(`Message id: ${msg.id}`)
        });
        let r = await client.forwardMessages(chat.id, lstMsg)
        console.log(`${lstMsg.length} messages forwarded to chat [${chat.id}]`)
        console.log('The result of the forwardMessages fonction is:')
        console.debug(r)
        await sleep(delay)

Anything else?

I really think it should return the result only when the message is actually send for REAL. It seems that it goes to a queue system and return right away only the first that was sent. And sometimes it returns a empty array.

If there is no way to trully know that the message was sent (or not), It is almost uselles because the whatsapp crases so many times, the whatsapp web reloads very often, it syncs a lot of times during the day, session get lost sometimes.. If the function doesn't return that information, messages will get lost and there is no point of using this library.

smashah commented 2 years ago

Thanks for thoroughly filling out the template.

I've pushed new patches that should address this. Can you try them out and report back if the issue is fixed for you please.

Thanks

linconrezende commented 2 years ago

Thanks for thoroughly filling out the template.

I've pushed new patches that should address this. Can you try them out and report back if the issue is fixed for you please.

Thanks

Thank you @smashah I've tested the new patches and I noticed the changes. There is some serious improvements, it is faster, the initialization is reliable and seems very stable!

But, still some weird stuff going on. Maybe you can try to help me understand. With the same code, I did the same test again, the first time, it was perfect!

I forwarded 5 messages to 5 groups. The 2 first groups, it returned a array of 6 messages IDs, but the last 3 groups, it returned the right thing, array of 5 messages ids. Before doing this tests, I cleared all group messages and restarted the client, cleared cookies, killed the session, restarted everything I could to at least try to make sure that it wasn't old messages stacking up..

**Forwarding messages**
Message id: false_554891733353@c.us_B2E9D97AE64BAFE5A5248A4F7D8371AF
Message id: false_554891733353@c.us_CEE2E2B51FE44FBE064F0583BCD3C5B9
Message id: false_554891733353@c.us_C437493B21048A978A4FF002CE2EA25D
Message id: false_554891733353@c.us_05440984E9C25F956B535613972513A8
Message id: false_554891733353@c.us_5A6D0FCCAD05B3B52CAA62298E13C896
5 messages forwarded to chat [120363023523566434@g.us]
The result of the forwardMessages fonction is:
[
  'true_120363023523566434@g.us_3EB0CB2001E8B7C73C20_553499295807@c.us',
  'true_120363023523566434@g.us_3EB06F0F10541F72B181_553499295807@c.us',
  'true_120363023523566434@g.us_3EB0F7DA0A3F64CB6C4D_553499295807@c.us',
  'true_120363023523566434@g.us_3EB06F14BE4BEF3C6405_553499295807@c.us',
  'true_120363023523566434@g.us_3EB026B55F9D1B9D0BA8_553499295807@c.us',
  'true_120363023523566434@g.us_3EB0D5E7E3AC5DC8B4F6_553499295807@c.us'
]

**Forwarding messages**
Message id: false_554891733353@c.us_B2E9D97AE64BAFE5A5248A4F7D8371AF
Message id: false_554891733353@c.us_CEE2E2B51FE44FBE064F0583BCD3C5B9
Message id: false_554891733353@c.us_C437493B21048A978A4FF002CE2EA25D
Message id: false_554891733353@c.us_05440984E9C25F956B535613972513A8
Message id: false_554891733353@c.us_5A6D0FCCAD05B3B52CAA62298E13C896
5 messages forwarded to chat [120363022932071379@g.us]
The result of the forwardMessages fonction is:
[
  'true_120363022932071379@g.us_3EB098FEED76F7B979AD_553499295807@c.us',
  'true_120363022932071379@g.us_3EB0C59025520C058FFF_553499295807@c.us',
  'true_120363022932071379@g.us_3EB09CB39B0C15707564_553499295807@c.us',
  'true_120363022932071379@g.us_3EB0946FE38F5D8B2A5F_553499295807@c.us',
  'true_120363022932071379@g.us_3EB02DC62293022B1C6F_553499295807@c.us',
  'true_120363022932071379@g.us_3EB0BC6FC5D953673D9C_553499295807@c.us'
]

**Forwarding messages**
Message id: false_554891733353@c.us_B2E9D97AE64BAFE5A5248A4F7D8371AF
Message id: false_554891733353@c.us_CEE2E2B51FE44FBE064F0583BCD3C5B9
Message id: false_554891733353@c.us_C437493B21048A978A4FF002CE2EA25D
Message id: false_554891733353@c.us_05440984E9C25F956B535613972513A8
Message id: false_554891733353@c.us_5A6D0FCCAD05B3B52CAA62298E13C896
5 messages forwarded to chat [120363021962229555@g.us]
The result of the forwardMessages fonction is:
[
  'true_120363021962229555@g.us_3EB0684EBF2424E96501_553499295807@c.us',
  'true_120363021962229555@g.us_3EB0BF0A82B11BB1D114_553499295807@c.us',
  'true_120363021962229555@g.us_3EB02CA152E94F4707A2_553499295807@c.us',
  'true_120363021962229555@g.us_3EB06C09EDA2A1BAA196_553499295807@c.us',
  'true_120363021962229555@g.us_3EB0C1D003A0E3302D6C_553499295807@c.us'
]

**Forwarding messages**
Message id: false_554891733353@c.us_B2E9D97AE64BAFE5A5248A4F7D8371AF
Message id: false_554891733353@c.us_CEE2E2B51FE44FBE064F0583BCD3C5B9
Message id: false_554891733353@c.us_C437493B21048A978A4FF002CE2EA25D
Message id: false_554891733353@c.us_05440984E9C25F956B535613972513A8
Message id: false_554891733353@c.us_5A6D0FCCAD05B3B52CAA62298E13C896
5 messages forwarded to chat [120363022049828950@g.us]
The result of the forwardMessages fonction is:
[
  'true_120363022049828950@g.us_3EB06A2C58DC02FC8C88_553499295807@c.us',
  'true_120363022049828950@g.us_3EB00E90BF07EE5244F0_553499295807@c.us',
  'true_120363022049828950@g.us_3EB06A91A7B1B7C857EF_553499295807@c.us',
  'true_120363022049828950@g.us_3EB04D3E44129A20C216_553499295807@c.us',
  'true_120363022049828950@g.us_3EB0C79F3008DB165012_553499295807@c.us'
]

**Forwarding messages**
Message id: false_554891733353@c.us_B2E9D97AE64BAFE5A5248A4F7D8371AF
Message id: false_554891733353@c.us_CEE2E2B51FE44FBE064F0583BCD3C5B9
Message id: false_554891733353@c.us_C437493B21048A978A4FF002CE2EA25D
Message id: false_554891733353@c.us_05440984E9C25F956B535613972513A8
Message id: false_554891733353@c.us_5A6D0FCCAD05B3B52CAA62298E13C896
5 messages forwarded to chat [120363040385752068@g.us]
The result of the forwardMessages fonction is:
[
  'true_120363040385752068@g.us_3EB0EC90D33D8FECA88E_553499295807@c.us',
  'true_120363040385752068@g.us_3EB01D2AE97D75945A18_553499295807@c.us',
  'true_120363040385752068@g.us_3EB01E001DED2C1A9920_553499295807@c.us',
  'true_120363040385752068@g.us_3EB09C9533F5AC833B78_553499295807@c.us',
  'true_120363040385752068@g.us_3EB02AD785BFA6E9A638_553499295807@c.us'
]

And still does not return when the message is sent. Because the messages are trully send only a few moments after the function returns. You may say that it is because whatsapp may take a few seconds to send mesasges or for me to receive them back but.. When I tried forwarding those 5 messages to 105 groups, it took less than a minute to fire client.forwardMessages and get the result but it took one hour to actually send every message.

The problem I see is that I have no controll of which message was trully sent. Because I got the forwardMessages return, which I should considerer that the message was sent but it was not.

What if whatsapp crashes? What if the session is lost or reconnect? Of course you took care of this, as I could see, I forced a network problem, crashes, It seems that you already manage everything and It continues sending messages even after a reconnect. But I have no controll of that. I mean.. I need to know if everything was sent, the only way I see is to get all group messages and check if the message is there but it takes too much time, not practical.

Still the best version yet. Do you think it will be possible to get the function returning only when the message was send? Does the API let us send multiple messages at once? Is is possible to forward 5 messages to 5 chats at once, like the way we can do on the Whatsapp Web ?

See where I am going? Maybe, if there is no way of knowing that the message was sent, maybe we can send it faster so it matches up with the return of the function.

Thank you again!

linconrezende commented 2 years ago

image This is what I mean. The function sends the messages successfully but the whatsapp web itself, takes some time to actually send.

I though it would be better if we could know or get a callback when the message was truly sent. But now I know that we have some limitations from whatsapp web.

smashah commented 2 years ago

@linconrezende I understand where you're coming from but the library does not wait for the message to be sent before returning a result. No function works that way, including sendText. WA themselves recently implemented some preventative measures around message forwarding.

What you need to do is listen to client.onAck(message=>{...}) and check for the message to get an ack (acknowledgement) of 1. 1 represents the message was sent from the host account, 2 represents the recipient device received the message, 3 represents that the recipient read the message (not guaranteed).

smashah commented 2 years ago

https://docs.openwa.dev/classes/api_Client.Client.html#onAck

linconrezende commented 2 years ago

hmmm okay, I get it. So I need to keep a list of messages sent with the recipient, and once I know it was realy sent, I remove from the list. If the app crashes, I can try again from where I stopped. I'll try it then. Thak you very much.

smashah commented 2 years ago

try something like this.

//global scope
let trackedForwardedMessages = []

//your forwarding code
let r = await client.forwardMessages(chat.id, lstMsg)
if(r && !Array.isArray(r)) r = [r];
trackedForwardedMessages.push(r)

//somewhere else

client.onAck(message => {
    if(message.ack == 1 && trackedForwardedMessages.includes(message.id)) {
        //message is sent from host account
        ...continue message processing
        trackedForwardedMessages = trackedForwardedMessages.filter(id=>id!==message.id)
    }
})