Guilherme
Guilherme

Reputation: 115

How can I save an image received from a Webhook? (WhatsApp API)

So, I'm starting to understand a bit more of WhatsApp API and all the messages that my number received are sent to my server via Webhook. The text messages are fine, but I'm struggling with the media messages.

When the user sends an image for example, Facebook's Webhook only sends me the mime_type and the sha256 of the image.

Can anyone please guide me the steps of what I need to do?

Do I need to convert it to base64, and then write the file in my server? Do I need to use a specific function? Do I need to use another programming language that's not PHP?

I'm totally lost on this one.

Upvotes: 2

Views: 4820

Answers (2)

M Tanusri
M Tanusri

Reputation: 31

here is this code for receiving user sent messages-

  1. we check if its an audio file if it is then
  2. we try to get the url for the audio by sending a get request to specified url https://graph.facebook.com/v19.0/${mediaId}/
  3. and then we grab the image/ audio url
  4. then again we send a get request to this url which is only active for 2 minutes so with in 2 minutes we can try to download the file.
  5. store the data somewhere
app.post("/webhook", async (req, res) => {
  let audio = req.body.entry[0].changes[0].value.messages[0].audio.id; 
  console.log(audio)
 
  if (audio) {
       // Replace <MEDIA_ID> and <ACCESS_TOKEN> with actual values
      const mediaId = audio;
      const accessToken = token;

      // Make a GET request
      const response = await axios.get(`https://graph.facebook.com/v19.0/${mediaId}/`, {
        headers: {
          'Authorization': `Bearer ${accessToken}`
        }
      });
    
    // Handle the response as needed
    let url=response.data.url;
    const mediaUrl = url;
 

// Make a GET request to the media URL with authorization header
  axios.get(mediaUrl, {
    headers: {
      'Authorization': `Bearer ${accessToken}`
    },
    responseType: 'stream', // This is important to handle streaming response
  })
    .then(response => {
      const timestamp = Date.now();
      const directoryPath = path.join('media');
      const dynamicPath = path.join(directoryPath, `media_file_${timestamp}.ogg`);

      console.log('Dynamic Path:', dynamicPath);
// Replace with your desired file path
      const writer = fs.createWriteStream(dynamicPath);

      response.data.pipe(writer);

      writer.on('finish', () => {
        console.log('Media file saved successfully!');
      });

      writer.on('error', (err) => {
        console.error('Error saving media file:', err);
      });
    })
    .catch(error => {
      console.error('Error fetching media file:', error);
    });
    
      console.log(response.data);
    }   

Upvotes: 1

Elias Schablowski
Elias Schablowski

Reputation: 2812

The way to do this, as pointed out by @CBroe is to use the media endpoints.

Assuming message is the message from the Webhook

// Get the image information, including the download link
$image_url_handle = fopen("https://graph.facebook.com/v13.0/" . $message->id);
$image_url = "";
// Read all of the data before parsing
while (!feof($image_url_handle)) {
    $image_url .= fread($image_url_handle);
}
// Close the stream
fclose(image_url_handle);
// Get the url from the image information
$image_url = json_decode($image_url)->url;
// Start a request to the download URL.
$image_stream = fopen($image_url);

Note: There is no error handling or frameworks, though this should work most of the time

Upvotes: 1

Related Questions