Reputation: 73
currently I am trying to make a thin wrapper around Whatsapp Cloud API. One of the problem I am currently facing is that the uploading media files isn't working.
Looking through the documentation for uploading files, it seems that it expects a multipart/form-data
payload to the endpoint.
Here is my current implementation
import FormData from 'form-data';
import fs from 'fs';
import axios from 'axios';
const formData = new FormData();
formData.append('file', fs.createReadStream('path/to/my/file.jpg'));
formData.append('messaging_product', 'whatsapp');
formData.append('type', 'image/jpeg');
await axios.post('https://graph.facebook.com/v14.0/PHONE_NO_ID/media', formData, {
headers: { 'Authorization': ACCESS_TOKEN }
});
Looking at the error that it returns, it seems that I am somehow missing the messaging_product
field even though I have properly add it in the formData.
{
"error": {
"message": "(#100) The parameter messaging_product is required.",
"type": "OAuthException",
"code": 100,
"fbtrace_id": "FBTRACE_ID"
}
}
The Postman collection works for uploading media file, so I am thinking that the file
field of the formData is the problem. Is fs.createReadStream
on a file equivalent to how Postman handle file uploading
EDIT: The question has been solved, the problems was not adding in the headers generated by the formData, Thanks Phil below!
Upvotes: 6
Views: 5030
Reputation: 1
Try this, it worked for me:
var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
data.append('messaging_product', 'whatsapp');
data.append('file', fs.createReadStream('./images/fly.jpg'));
data.append('type', 'image/jpeg');
var config = {
method: 'post',
url: 'https://graph.facebook.com/v13.0/phone_number_id/media',
headers: {
'Authorization': 'Bearer access_token',
...data.getHeaders()
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
Upvotes: -1
Reputation: 164785
Love the documentation... they say type
is a required parameter then go on to show a curl
example without it 🤦.
Also, file
is not the...
Path to the file stored in your local directory
but instead a mime-encoded binary.
In any case, the type
needs to be part of the mime-encoding by way of the content-type
meta data and you then need to forward the content-type header generated by FormData
.
You also may be missing the Bearer
authentication token scheme.
const PHONE_NO_ID = "something";
const ACCESS_TOKEN = "something";
const formData = new FormData();
formData.append("file", fs.createReadStream("path/to/my/file.jpg"), {
contentType: "image/jpeg",
});
formData.append("messaging_product", "whatsapp");
try {
const {
data: { id: mediaId },
} = await axios.post(
`https://graph.facebook.com/v14.0/${PHONE_NO_ID}/media`,
formData,
{
headers: {
Authorization: `Bearer ${ACCESS_TOKEN}`, // "Bearer" prefix
...formData.getHeaders(), // merge in FormData headers
},
}
);
console.log("media ID", mediaId);
} catch (err) {
console.error("upload", err.toJSON());
}
Upvotes: 7