Buttons and Lists get deprecated by many WhatsApp Web libraries
Tags: node, typescript, automation, whatsapp
Published: 2023-06-23 23:16:41

Over the past few months, most libraries in the WhatsApp Web automation space deprecated the fancy Templates and useful Lists and the good old Buttons.

For a bit of background, in the open-source space there exist a bunch of different libraries that serve one purpose: WhatsApp Web automation. The reason for the existence of this workaround is for personal use. The official API strictly serves business use ONLY. I personally have been denied many applications for API access and especially through partners for a personal use API (business legal documents needed). We require this access for personal use projects like smart home notification and userbots (chatbots with cool commands for users).

The topic of concern in this article is the Buttons feature, and the Lists feature, originally belonging to the WABA (WhatsApp Business API), and since its so intuitive and revolutionary for userbots and bot interaction, we thought of sending them through these libraries via WhatsApp Web.

This was made possible due to the technical and architectural change of WhatsApp Web (multi-device update) that meant that the message is encrypted and sent in the Web and not the mobile device. This meant that WA had no way to verify the content, simply to ship and view it. Also, it only worked on WA personal not WA Business (probably since they missed the personal numbers in the rendering logic), though this meant that only the majority of the use of it was personal and NOT business. Technically not breaking the Terms of Service, though the entire idea of using a library is.

Thunder struck. By August 4 2021, it was no longer possible to send the button messages. We had spent a few months experimenting with fixes to send them again after getting patched by WhatsApp. We fixed it by wrapping the buttons message with a view once message, which circumvented the logic checking the validity of the buttons message. 

This worked for a bit, on selected versions of these buttons messages. Then, the war hammer struck again on this by April 2022, as part of a campaign against these libraries by WhatsApp, we are sure this was deliberate. 

We countered this by launching an all-out coalition!!! The community, setting aside differences and beef, worked together as one against this in one final show of teamwork. This team consisted of:
- WWebJS (Node.js library, JS, Puppeteer lib, 13k stars)
- Baileys (Node.js, library, TS, direct WS connection, 7k stars)
- open-wa (Node.js library, TS, Puppeteer, 3k stars)
- Cobalt (formerly whatsappweb4j, Java/Kotlin, direct WS, 500 stars)
- WppConnect (any env (directly executable in browser and Node), TS, 1.5k stars)

Personally, I am the active maintainer of WWebJS and Baileys,  and I was able to connect all of these people who had beef with each other for this final call against this cool feature that made all our lives easier. We all worked together on reverse engineering the On-Premises API binary, collectively hundreds of hours reverse engineering.

For those unfamiliar, WhatsApp uses XMPP in all its official clients, except Desktop and Web, in which there is a WebSocket that literally emulates the node format of XMPP, so for example an outgoing message would look like this: 

#### Usual client: 
```xml
<message 
  to="12312312312@s.whatsapp.net" 
  id="MESSAGE_ID_HERE" 
  timestamp="891237897123891"
  type="text"
  (... other attributes here)
>
  <enc> (encrypted payload)
    VGhpcyBpcyBzb21lIGVuY3J5cHRlZCBjb250ZW50LCBhbmQgaW4gcmVhbGl0eSBpdHMgbm90IEhBSEFIQSEgSSBsaWtlIHlvdXIgY3VyaW91c25lc3MgdG8gZGVjb2RlIHRoaXM= 
  </enc>
</message>
```

#### WhatsApp Web:
```json
{
  "tag": "message",
  "attributes": {
    "to": "12312312312@s.whatsapp.net",
    "id": "MESSAGE_ID_HERE",
    "timestamp": "891237897123891",
    "type": "text"
    (... other attributes here)
  },
  "content": [
    {
      "tag": "enc",
      "attributes": {},
      "content": Buffer(78)
    }
  ]
}
```

Turns out, WhatsApp created a new and ingenious method to determine business chats from normal ones, this was probably what caused their controversial Privacy Policy changes. Let's call it the "`<biz>`" node. This `<biz>` node was different in that it was not encrypted, it was passed alongside `<enc>` in the `<message>` content. It included timestamps, paid conversation id (this was because WABA moved to a paid conversation model) and other relevant info like button type and version. 

This was important, as the client then ONLY viewed a Button message if the `<biz>` node was there, it was clear that WhatsApp prohibited YOUR message from including this (as it can now check for this) and allow its businesses to send it. 

What did we do? We simply added this to our message payloads, we ignored any id-related and timestamp-related attributes and simply passed in the version and type, this was determined after reverse engineering the client to see what kind of check was made.

Good news! We managed to get buttons and lists, except templates working. 

We implement this change in Baileys (at the time with 5k stars), and it worked for a bit (4 weeks).

On May 8, I decided to port this change to WWebJS as well, since that missed the (then experimental) support.

Not a day later though, on May 9, Meta/WhatsApp already rolled out a patch, after posting a patch to a repository with more than 10,000 stars. This was only expected though, we are a big community, there bound to be some engineers and lawyers looking within us.

Either way, we spend a lot of time just maintaining the library, so playing this little game of hide-and-seek was too tiring. 

We collectively made the choice to deprecate and remove this feature entirely, and it will take effect soon. The buttons can be restored, but the effort to do it is just too big. We are no longer adding it to official repositories.

I have a full video about this topic:

{% embed https://youtu.be/hv1R1rLeVVE %}