Posts tagged with webhooks

When sending messages through the cloud Whatsapp Business API, is there a way to send custom fields that will be returned in the webhook notification?

Apart from saving the ID received in the response when sending the message, I could not find a way to connect between the sent message and the returned webhook.

I am working on a project using FastAPI to handle incoming WhatsApp messages and respond to them. I've set up the webhook, and I can successfully receive messages. However, I'm encountering issues when trying to send a response back to the user using the WhatsApp Business API.

Here is the relevant part of my code:

from fastapi import FastAPI, Request, HTTPException, Query from fastapi.responses import JSONResponse from pydantic import BaseModel import requests app = FastAPI() VERIFY_TOKEN = "tourism"   class WhatsAppEvent(BaseModel):     message: dict WHATSAPP_API_ENDPOINT = "https://graph.facebook.com/v18.0/***(Entered my phone number ID)/messages" WHATSAPP_API_TOKEN = "***(Entered my API access token)" @app.post("/") async def handle_post_request(request: Request):     # Process the incoming POST request here     data = await request.json()     print("Received POST request data:", data)     # Send a response     return {"status": "success", "message": "POST request received"} @app.get("/") def verify(request: Request):     mode = request.query_params.get('hub.mode')     challenge = request.query_params.get('hub.challenge')     token = request.query_params.get('hub.verify_token')     if mode and token:         if mode == 'subscribe' and token == VERIFY_TOKEN:             print("WEBHOOK_VERIFIED")             return JSONResponse(content=int(challenge), status_code=200)         else:             raise HTTPException(status_code=403, detail="Verification failed")     return {"code": 200, 'message': 'test'} @app.post("/incoming-message") def receive_message(event: WhatsAppEvent):     try:         user_message = event.message['text']         sender_id = event.message['sender']['id']         bot_response = f'You said: {user_message}' #sending an echo message                  # Prepare response for WhatsApp         response_data = {             'recipient': {'id': sender_id},             'message': {'text': bot_response}         }         send_whatsapp_message(sender_id, bot_response)         return JSONResponse(content=response_data, status_code=200)     except Exception as e:         raise HTTPException(status_code=500, detail=f"Error processing message: {str(e)}")      def send_whatsapp_message(recipient_id, message_body):     headers = {         'Authorization': f'Bearer {WHATSAPP_API_TOKEN}',         'Content-Type': 'application/json'     }     data = {         'phone': recipient_id,         'message': {             'text': message_body         }     }     try:         response = requests.post(WHATSAPP_API_ENDPOINT, headers=headers, json=data)         response.raise_for_status()  # Raises HTTPError for bad responses         print("WhatsApp API response:", response.text)  # Add this line for debugging         return response.json()  # If you want to return the API response data     except requests.exceptions.HTTPError as errh:         print("HTTP Error:", errh)         raise HTTPException(status_code=response.status_code, detail=f"HTTP Error: {errh}")     except requests.exceptions.RequestException as err:         print("Request Error:", err)         raise HTTPException(status_code=response.status_code, detail=f"Request Error: {err}") if __name__ == "__main__":     import uvicorn     uvicorn.run(app, reload=False, host="0.0.0.0", port=8000) 

I have verified that the webhook is working (WEBHOOK_VERIFIED is printed in the console), and I can see the incoming messages in the logs. However, the send_whatsapp_message function does not seem to be sending messages successfully.

The response from the WhatsApp API is as follows:

WEBHOOK_VERIFIED INFO:     2a03:2880:23ff:5::face:b00c:0 - "GET /?hub.mode=subscribe&hub.challenge=1310749767&hub.verify_token=tourism HTTP/1.1" 200 OK Received POST request data: {'object': 'whatsapp_business_account', 'entry': [{'id': '**(My ID)', 'changes': [{'value': {'messaging_product': 'whatsapp', 'metadata': {'display_phone_number': '**(My number)', 'phone_number_id': '**(My Phone number ID)'}, 'contacts': [{'profile': {'name': 'Rishikesh Dasari'}, 'wa_id': '**(recipient Number)'}], 'messages': [{'from': '**(recipient Number)', 'id': 'wamid.HBgMOTE5MzkwMzYwMjYyFQIAEhgWM0VCMEMyRUU3MzQ4Q0VCNjFGQUIzRgA=', 'timestamp': '1705643757', 'text': {'body': 'hello'}, 'type': 'text'}]}, 'field': 'messages'}]}]} INFO:     2a03:2880:20ff:b::face:b00c:0 - "POST / HTTP/1.1" 200 OK 

I have double-checked the WhatsApp API endpoint, token, and the structure of the request, but I'm still unable to send messages. I suspect there might be an issue with my send_whatsapp_message function.

Can someone please review the code and provide insights on what might be causing the problem? Additionally, if there's a better way to handle sending WhatsApp messages in FastAPI, I'm open to suggestions.

I am currently facing an issue with the Meta Cloud API and WhatsApp Business API and I'm seeking some guidance.

Issue Description:

I have a WhatsApp chatbot for customers, and to facilitate testing and development, I've set up three different environments (stages). Each stage has its own test number and is associated with a separate app using the Meta Cloud API and WhatsApp Business API. Every app is connected to its unique webhook and is subscribed to the 'messages' field.

However, I am encountering an unexpected behavior where every webhook is receiving events from all other numbers, not just its corresponding number.

Setup Details:

For each app, I have the following configuration in the meta developer web app:

Quickstart Configuration: To get alerted when you receive a message or when a message's status has changed, a Webhooks endpoint is set up for each app.

Callback URL: Each app has a different callback URL, something like https://.....com/webhook.

Verify token: Different for each app

What actually happens:

Despite having distinct endpoints and configurations for each app, messages intended for one stage are being received by the webhooks of the other stages as well.

Object received from Meta Cloud API when I send "hi" to the test number – gets delivered to all three webhooks:

{     "object": "whatsapp_business_account",     "entry": [         {             "id": "id_1",             "changes": [                 {                     "value": {                         "messaging_product": "whatsapp",                         "metadata": {                             "display_phone_number": "test_stage_phone_no",                             "phone_number_id": "test_stage_phone_no_id"                         },                         "contacts": [                             {                                 "profile": {                                     "name": "Leon"                                 },                                 "wa_id": "my_phone_number"                             }                         ],                         "messages": [                             {                                 "from": "my_phone_number",                                 "id": "wamid.HBgNNDk...",                                 "timestamp": "1704481181",                                 "text": {                                     "body": "hi"                                 },                                 "type": "text"                             }                         ]                     },                     "field": "messages"                 }             ]         }     ] } 

Object received from Meta Cloud API when I send "hi" to the production number – gets delivered to all three webhooks:

{     "object": "whatsapp_business_account",     "entry": [         {             "id": "id_2",             "changes": [                 {                     "value": {                         "messaging_product": "whatsapp",                         "metadata": {                             "display_phone_number": "prod_stage_phone_no",                             "phone_number_id": "prod_stage_phone_no_id"                         },                         "contacts": [                             {                                 "profile": {                                     "name": "Leon"                                 },                                 "wa_id": "my_phone_number"                             }                         ],                         "messages": [                             {                                 "from": "my_phone_number",                                 "id": "wamid.HBgNN...",                                 "timestamp": "1704482444",                                 "text": {                                     "body": "hi"                                 },                                 "type": "text"                             }                         ]                     },                     "field": "messages"                 }             ]         }     ] } 

As a temporary workaround, in my webhook, I am checking the WhatsApp Business ID from which the message originates and filtering out messages that don't match the Business ID associated with that stage. However, I believe there should be a way to ensure each webhook only receives messages for its specific app.

Questions:

Has anyone else experienced this issue with the Meta Cloud API and WhatsApp Business API?

Is there a configuration step I might be missing that would ensure each webhook only receives messages intended for its associated app? Are there any best practices or additional settings I should consider to isolate the webhook events to their respective apps?

I´m testing the official WhatsApp Business API by Meta, and want to receive the messages that i send to the users through the webhook, because the logic on my program manage the messages that way (I´ve been using Ultramsg and they send a webhook event whenever i send a message to a user).

Could be because i´m using the test phone number provided by meta, or is it always like that?

I tried subscribing to every webhook event available but none of those seem to send the object that i need.

I am creating a whatsapp business api app that replies to whatsapp messages with a messages I have received from my API. However, it is triggerring multiple times after the initial messages has been sent.

app.post("/webhook", (req, res) => {   // Parse the request body from the POST   let body = req.body;   // Check the Incoming webhook message   console.log(JSON.stringify(req.body, null, 2));   // info on WhatsApp text message payload: https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/payload-examples#text-messages   if (req.body.object) {     if (       req.body.entry &&       req.body.entry[0].changes &&       req.body.entry[0].changes[0] &&       req.body.entry[0].changes[0].value.messages &&       req.body.entry[0].changes[0].value.messages[0]     ) {       let phone_number_id =         req.body.entry[0].changes[0].value.metadata.phone_number_id;       let from = req.body.entry[0].changes[0].value.messages[0].from; // extract the phone number from the webhook payload       let msg_body = req.body.entry[0].changes[0].value.messages[0].text.body; // extract the message text from the webhook payload      axios({     method: "POST",     url: API_URL,     data: {       id: phone_number_id,       question: msg_body,       email: "N/A",       conversation: [],       save: true,       resolved: "N/A",       ads: 0,     },     headers: {       "Content-Type": "application/json",       "x-api-key": process.env.API_KEY,     },   })     .then(apiResponse => {       if (apiResponse.status !== 200) {         throw new Error(`Request failed with status ${apiResponse.status}`);       }       return apiResponse.data;     })     .then(responseData => {       console.log(responseData);        axios({             method: "POST",             url: END_POINT_URL             headers: {               "Content-Type": "application/json",               Authorization: TOKEN,             data: {               to: from,                type: "text",               text: {                 preview_url: false,                 body: responseData.answer,                },               messaging_product: "whatsapp",               recipient_type: "individual"             },           })           .then(() => {             // Confirm the message has been sent             res.status(200).end();           })           .catch((error) => {             console.error("Error sending WhatsApp message: ", error);             res.status(500).end();           });     })     .catch(error => {       console.error(error);       res.status(500).json({         message: "An error occurred while chatting.",       });     });     }       }  }); 

I have tried debugging but to no avail, sometimes the messages are sent at super random periods too