tawn33y / whatsapp-cloud-api

A Node.js library for creating bots and sending/receiving messages using the Whatsapp Cloud API.
https://www.npmjs.com/package/whatsapp-cloud-api
GNU General Public License v3.0
182 stars 51 forks source link

How to check if a business has initiated a conversation with a client? #40

Open alfonsusac opened 1 year ago

alfonsusac commented 1 year ago

In WhatsApp Business API, you cannot send a freeform text message to a client UNLESS you have initiated a conversation.

Initiating a conversation with a client requires either the user to contact the business account first or the business to send a templated pre-approved templated message to the user.

Now the question is, how do I check if a conversation has been initialized with a certain phone number? If I recall correctly, the websocket payload provides an extra information whether or not the message has been sent to an established conversation.

tawn33y commented 1 year ago

I looked at the official docs and there doesn't seem to be such an api for querying this: https://developers.facebook.com/docs/whatsapp/cloud-api/guides I may be wrong, please feel free to point me to the link with this functionality.

Assuming no such api exists, the easiest way to do this would be to send a request and then catch an error, if any, and consecutively send a template message.

An example (not clean code, just to highlight example):

try {
  await bot.sendText(to, 'Hello');
} catch (err) {
  if (err.message.includes('Not initiated')) { // I don't remember the full error message, you will need to run & replace the string accordingly 
    // user has not initiated conversation, send template
    await bot.sendTemplate(...);
 } 
}

You can create a function, eg initializeConversation which has several functionalities (eg sending template message, etc) and then call this function in the catch scenarios you need.

You can also use a data store (eg cache or database) which stores the user id & the time the conversation started, and if 24 hours have ended, send a template request to re-initiate the conversation. But this feels like an overkill.

Again, I agree. This would be much easier if the api above existed, since all you would need to do is create a function that calls the api. You would then put this api at the top of your application, and based on the response, (1) send a template message to initiate a conversation, or (2) send the request you want (eg send text, media, etc).

alfonsusac commented 1 year ago

Hello, it is not written in the documentaries but I have tested it my own and it will receive a "statuses" object within the payload once the request to post message is sent to user that has not been initiated yet.

This is the sample payload received This is part of the response of sending the message, received via the /webhook post method when I tried it using Glitch:

console.log(req.body.entry[0].changes[0])

{
 "value": {
  "messaging_product": "whatsapp",
  "metadata": {
   "display_phone_number": "1555xxxxxx3",
   "phone_number_id": "10xxxxxxxxxxxx9"
  },
  "statuses": [
   {
    "id": "wamid.HBgNNjI4MTI5ODM2MjI0NRUCABEYEkJFODBBOUVGNzFBODEzN0VERQA=",
    "status": "failed",
    "timestamp": "1666678076",
    "recipient_id": "xxxxxxxxxxxx",
    "errors": [
     {
      "code": 131047,
      "title": "Message failed to send because more than 24 hours have passed since the customer last replied to this number.",
      "href": "https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes/"
     }
    ]
   }
  ]
 },
 "field": "messages"
}

Assuming no such api exists, the easiest way to do this would be to send a request and then catch an error, if any, and consecutively send a template message.

That is my initial thing to do, but upon further inspection, WA will not give an error even if we try to send a message to a non-initiated conversation. They still give OK status

NB: The error codes can be seen here (131047) https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes/

tawn33y commented 1 year ago

Ah, I see your point. Currently, we are ignoring the statuses events when it's received, which is why you don't get the error via the library. We only publish new messages events. You can read more here in this issue: #23

Until we work on publishing statuses events, I don't think it'll be possible to get the error as you referenced.