I have an endpoint that is supposed to make a call to the WhatsApp API with the Media URL just like they said to do here: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#download-media, and just return it the same way it was returned from whatsapp as well as save the file for later use.
exports.downLoadMedia = async (req, res) => {
const url = req.query.url;
request.get(
{
url: url,
headers: {
Authorization: `Bearer ${process.env.AUTH_TOKEN}`,
Accept: 'audio/ogg',
},
encoding: null, // Set encoding to null to receive binary data
},
function (err, resp, body) {
if (err) {
console.log("Error:", err);
res.status(500).json({ error: "An error occurred." });
} else {
const fileName = 'downloaded_audio.ogg';
const filePath = path.join(__dirname, fileName); // Construct file path
fs.writeFile(filePath, body, 'binary', (writeErr) => {
if (writeErr) {
console.log("Error writing file:", writeErr);
res.status(500).json({ error: "An error occurred while saving the audio." });
} else {
// Use res.download() to send the saved file as a download response
res.download(filePath, 'downloaded_audio.ogg', (downloadErr) => {
if (downloadErr) {
console.log("Error sending download:", downloadErr);
res.status(500).json({ error: "An error occurred while sending the download." });
}
});
}
});
}
}
);
};
when i make a get request in Postman with the WhatsApp Media url directly it shows up like this:
and the audio plays as it should.
However, when i make a request to my endpoint above it shows up like this:
The audio is saved but it does not play.
Basically, my endpoint should be the proxy to get the audio/voice note file.
Got it to work after switching from using the request package to axios to handle the call to whatsapp api, then setting a couple more headers for the response.
Also setting the response type as a stream, then piping the response using axios.
The file is not saved; however, the response is the file itself, just like when i make the call to the url directly in postman, where i can download the file and it is easier to work with.
exports.downLoadMedia = async (req, res) => {
const url = req.query.url;
try {
// Fetch the audio data from the external URL with the auth token
const audioResponse = await axios.get(url, {
responseType: 'stream',
headers: {
Authorization: `Bearer ${process.env.META_AUTH_TOKEN}`,
}
});
// Set appropriate headers for streaming audio
let fileName = Date.now().toString() + "_audio.ogg";
res.setHeader('Content-Type', 'audio/ogg');
res.setHeader('Content-Disposition', `attachment; filename=${fileName}`);
res.setHeader('Transfer-Encoding', 'chunked');
// Pipe the audio stream from the external response to the current response
audioResponse.data.pipe(res);
} catch (error) {
res.status(500).send('Error fetching audio data: ' + error.message);
}
};