javascriptnode.jsfile-uploadmediawhatsapp-cloud-api

Issue with WhatsApp Cloud API Upload: Receiving "invalid_request" Error due to Incorrect MIME Type


I encountered an issue while trying to upload an image to the WhatsApp Cloud API using Axios. Despite setting the content type of the form data to image/png for an image with a .png extension, I keep receiving an error message from WhatsApp indicating an invalid_request. The error message specifically mentions that the parameter "file" must be a file with one of the specified MIME types, but it's receiving a file of type "application/octet-stream".

The error message received from WhatsApp is:

OAuth 'Facebook Platform' 'invalid_request' '(#100) Param file must be a file with one of the following types: audio/aac, audio/mp4, audio/mpeg, audio/amr, audio/ogg, audio/opus, application/vnd.ms-powerpoint, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.presentationml.presentation, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/pdf, text/plain, application/vnd.ms-excel, image/jpeg, image/png, image/webp, video/mp4, video/3gpp. Received file of type 'application/octet-stream'

Here is the screen shot of pipdream post request

Here is code for the node.js file

(async () => {
      const formData = new FormData();
      formData.append("messaging_product", "whatsapp");
      formData.append("type", "image/png");
      const stream = await streamToBlob(
        fs.createReadStream(
          "/filepath"
        )
      );
      formData.append("file", stream);

      console.log("formData", formData);
      let config = {
        method: "post",
        maxBodyLength: Infinity,
        url: `https://graph.facebook.com/v18.0/${phoneNumberId}/media`,
        headers: {
          Authorization:
            `Bearer ${token}`,
          "Content-Type": "multipart/form-data;image/png",
        },
        data: formData,
      };

      axios
        .request(config)
        .then((response) => {
          console.log(JSON.stringify(response.data));
        })
        .catch((error) => {
          console.log(error);
        });
    })();

Solution

  • Despite setting the content type of the form data to "image/png" for an image with a .png extension

    You have added an extra parameter with the name type, and the value image/png - which has nothing whatsoever to do with the actual Content-Type of anything else.

    And you have set Content-Type: multipart/form-data;image/png, which simply makes no sense. The Content-Type of the request needs to be just multipart/form-data. image/png is only the Content-Type of one of the parts inside this multipart request.

    https://www.npmjs.com/package/stream-to-blob shows that streamToBlob takes an optional second parameter, mimeType - and that is where you need to set the Content-Type for the BLOB that you are creating here.

    const stream = await streamToBlob(
            fs.createReadStream(
              "/filepath"
            ),
            "image/png"
          );