Posts tagged with express

I am currently writing a chatbot for WhatsApp. I use the node js and WhatsApp Business API to create my API that send messages to users.

When the client sends a image message, I see the following JSON object in the logs of my application:

{ "object": "whatsapp_business_account", "entry": [ { "id": "116591461526821", "changes": [ { "value": { "messaging_product": "whatsapp", "metadata": { "display_phone_number": "15550383872", "phone_number_id": "107615645766004" }, "contacts": [ { "profile": { "name": "TW🐯" }, "wa_id": "26657963470" } ], "messages": [ { "from": "26657963470", "id": "wamid.HBgLMjY2NTc5NjM0NzAVAgASGCAyQjlFNENGRkFENDk4MkRDQkU4QjVFOTlERUU3RUM4MgA=", "timestamp": "1707306273", "type": "image", "image": { "mime_type": "image/jpeg", "sha256": "iNUQ9GcXEvo/mqx2HYvGYmoX4/sgw3JLLjNe5y3cYHM=", "id": "1549548012254387" } } ] }, "field": "messages" } ] } ] }

can't find any information in the documentation about how to download this file. In my case, I want to upload this image file that the client sends to my file storage. Please tell me which URL method from the WhatsApp API is responsible for this mechanism?

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

I am using Whatsapp cloud API. I have configured the webhook with a valid URL. It is working properly. But the issue is that once I receive a message from the business and if I send back a message immediately, the callback URL not getting invoked instantly. It waits for three minutes to invoke the endpoint. And if I wait for 3 minutes after a response and then send a message then it invokes instantly. Not able to find the reason. Nothing in the documentation also. I want to make it faster. For all the messages, the webhook should be triggered instantly.

https://developers.facebook.com/docs/whatsapp/cloud-api/get-started This is the documentation I followed.

Any help would be highly appreciable. Thanks in advance.

I tried sending back 200 OK for all the requests as per the documentation

My server code looks like this:

const fs = require('fs'); const token = process.env.ACCESS_TOKEN; // Imports dependencies and set up http server const request = require("request"),   express = require("express"),   body_parser = require("body-parser"),   axios = require("axios").default,   app = express().use(body_parser.json()); // creates express http server // Sets server port and logs message on success var https = require('https'); var credentials = {     key: fs.readFileSync(process.env.key),     cert: fs.readFileSync(process.env.cert),     ca: fs.readFileSync(process.env.ca, 'utf-8') } var httpsServer = https.createServer(credentials, app); httpsServer.listen(process.env.PORT, async () => {   console.log("Whatsapp server listening to port: "+process.env.PORT);   // await mysqlConnector.initializeMySql(app);   // await redis.initializeRedis(); }); 

And my webhook post method looks like this:

app.post("/inbound", async (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 (       body.entry &&       body.entry[0].changes &&       body.entry[0].changes[0] &&       body.entry[0].changes[0].value.messages &&       body.entry[0].changes[0].value. Messages[0]     ) {       res.sendStatus(200);        //if the business needs to send a text message       //async function call to send a text message (It is a promise function that makes API call to the /message endpoint of WhatsApp business API)        // if the business needs to send an interactive message       //async function call to send interactive message(promise function)     //if the business needs to send a template     //async function call to send message template(Promise function) } } } 

And the function that send the text message:

 sendMessage: async function (message, incomingMessageFrom, outgoingMessageFrom, accessToken) {     return new Promise(async function (resolve, reject) {       try {         axios({           method: "POST",           url: "https://graph.facebook.com/v16.0/" +             outgoingMessageFrom +             "/messages?access_token=" +             accessToken,           data: {             messaging_product: "whatsapp",             "to": incomingMessageFrom,             "type": "text",             "text": {               "body": String(message)             }           },           headers: { "Content-Type": "application/json" }         }).then(response => {           resolve(response.data)         });       } catch (error) {         //log Error         resolve("error: " + JSON.stringify(error.message));       }     })   } 

And the function that sends the template:

 sendMessageTemplate: async function (templateName, params, incomingMessageFrom, outgoingMessageFrom, accessToken) {     await this.bindParams(params, templateName);     return new Promise(async function (resolve, reject) {       try {         //call bind params         let data = {           "messaging_product": "whatsapp",           "to": incomingMessageFrom,           "type": "template",           "template": templates[templateName]         }         let url = "https://graph.facebook.com/v12.0/" +         outgoingMessageFrom +         "/messages?access_token=" +         accessToken;         axios({           method: "POST", // Required, HTTP method, a string, e.g. POST, GET           url:url,           data: data,           headers: { "Content-Type": "application/json" },         }).then(response => {           resolve(response.data)         }).catch(err =>{           appLogger.logMessage("error","Failed to call template api due to: "+JSON.stringify(err.message),className,"sendMessageTemplate","ADMIN","Server",moduleName);         });         appLogger.logMessage("debug","The request data send is: "+JSON.stringify(data),className,"sendMessageTemplate","ADMIN","SERVER",moduleName);         appLogger.logMessage("debug","The request url send is: "+url,className,"sendMessageTemplate","ADMIN","SERVER",moduleName);       } catch (error) {         appLogger.logMessage("error","error occured while sending message template: "+JSON.stringify(error.message),"sendMessageTemplate","ADMIN","SERVER",moduleName);         //logError         resolve("error: " + JSON.stringify(error.message));       }     })   }