1

I uploaded a photo via WhatsApp, which can be accessed via:

https://graph.facebook.com/v19.0/{imageId}

Requesting this API returns the URL of the image:

{
    "url": "https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid={imageId}&ext={ext}&hash={hash}",
    "mime_type": "image/jpeg",
    "sha256": "fd9d5ac5bb84b8a0b7a3402c3a99ed9ff3e9fadb4fa567cd101eaf4923d2b375",
    "file_size": 667836,
    "id": "{imageId}",
    "messaging_product": "whatsapp"
}

Then, accessing this URL by Postman successfully returns the image that I uploaded.

However, when I use Nodejs, it returns something that I cannot convert to an image to be displayed on browsers.

const url = (
  await axios.get("https://graph.facebook.com/v19.0/{imageId}", {
    headers: {
      Authorization: `Bearer ${process.env.WHATSAPP_API_KEY}`,
    },
  })
).data.url;
const image = Buffer.from(
  (
    await axios.get(url, {
      method: "GET",
      headers: {
        Authorization: `Bearer ${process.env.WHATSAPP_API_KEY}`,
      },
    })
  ).data
).toString("base64");
console.log(image); // 77+977+977+977+9ABBKRklGAAEBAQBgAGAAAO+...

This prints some base64-encoded string, but when I test it https://base64.guru/converter/decode/image here, it tells that the string represents an application/octet-stream data. Therefore, I cannot display the image in my Remix code.

<img src={`data:image/jpeg;base64,${image}`} /> // not working

How can I appropriately retrieve the image as base64 from the API?

2 Answers 2

0

When making a request with axios, you can tell it to get response body as base64 string by setting responseType to text, and responseEncoding to base64 (note it's for Node.js only, see: Request Config):

Try this:

const image = (await axios.get(url, {
      method: "GET",
      headers: {
        Authorization: `Bearer ${process.env.WHATSAPP_API_KEY}`,
      },
    responseType: 'text',
    responseEncoding: 'base64'      
    })
  ).data;
8
  • I added the headers and the response has certainly changed, but it is still an application/octet-stream data. Is it impossible for the API to return the image base64 then? Also, even though I specify base64 as the response encoding it still returns something non-encoded one.
    – kemakino
    Commented Jul 7 at 14:15
  • Try maybe saving the file to make sure it's the image fs.writeFileSync('file.jpg', image, {encoding:'base64'})
    – traynor
    Commented Jul 7 at 14:24
  • It is not an image (I saved it by fs and opened it in VSCode but it is not recognized as a valid file). Even when I try adding the two headers in Postman I still get an image as a response (not the base64-encoded string).
    – kemakino
    Commented Jul 7 at 14:27
  • Try inspecting response, maybe it's returning some error.. you can try fetching some random image, the code should get valid file
    – traynor
    Commented Jul 7 at 14:32
  • I tested the stackoverflow logo here: stackoverflow.design/assets/img/logos/so/logo-stackoverflow.png but it doesn't work. I still get some valid response like 77+9UE5HDQoaCgAAAA1JSERSAAAHSgAAAXQIBgAAAO+/... though (at least the response status is OK).
    – kemakino
    Commented Jul 7 at 14:40
0

I should have included responseType: bufferArray for the request.

const image = Buffer.from(
  (
    await axios(url, {
      responseType: "arraybuffer",
      headers: {
        Authorization: `Bearer ${process.env.WHATSAPP_API_KEY}`,
      },
    })
  ).data
).toString("base64");

Not the answer you're looking for? Browse other questions tagged or ask your own question.