How to display base64 string as image in email, using AWS SES

All we need is an easy explanation of the problem, so here it is.

I am trying to show an image inside my e-mail. But that image is not getting displayed. I am using base64 string, which I am fetching from S3 bucket.

I am able to get email in inbox, but only thing image is not working when passing url, if directly using base64 hard coded string in html its working.

I need to fetch image from s3 and that image should be inline with email.

"use strict";
const fs = require("fs");
const path = require("path")
const Handlebars = require('handlebars');
const {SESClient, sendEmailCommand} = require("@aws-sdk/client-ses");
const {S3Client, GetObjectCommand} = require("@aws-sdk/client-s3");

let S3=null, SES=null;

const streamToBuffer = async(stream) =>{
  return new Promise((resolve, reject) =>{
    const chunks = [];
    stream.on("data", (chunk) =>{chunks.push(chunk)});
    stream.on("error", reject);
    stream.on("end", () =>{resolve(Buffer.conact(chunks))});
  })
}


export.handler = async(event) =>{
  if(S3 === null){
    S3 = new S3Client ({region: MY_REGION})
  }
  
  if(SES === null){
    SES = new SESClient ({region: MY_REGION})
  }
  try{
   let deatils = event.detail.fullDocument;
   
   let imageKey = `${deatils.dir}/myimage.png`;
   
   let imageFileFromS3 = await S3.send(
                         new GetObjectCommand({
                         Bucket: MY_BUCKET_NAME, key: imageKey 
                         }))
   let imageFileBuffer = await streamToBuffer(imageFileFromS3.Body)
   let bufferToBase64 = imageFileBuffer.toString("base64");
   
   const emailSubject = "Hey!! Test mail with image";
   const emailData = {
    Name: "Email Tester"
    ImageSrc: `data:image/png;base64, ${bufferToBase64}`
   }
   
   let htmlTemplate =       Handlebars.complie(fs.readFileSync(path.join(__dirname, 'templateSrc', email.html)).toString())
   
   let textTemplate = Handlebars.complie(fs.readFileSync(path.join(__dirname, 'templateSrc', email.txt)).toString())
   
   let emailResult = await SES.send( new SendEmailCommand({
    Source: "[email protected]", //dummy email for now
    Destination :{
      ToAddress: ["[email protected]"] // dummy address 
    },
    Message: {
      Subject: {
        Charset: 'UTF-8',
        Data: emailSubject
      },
      Body: {
        Text: {
          Charset: 'UTF-8',
          Data: textTemplate(emailData)
        },
        Html:{
          Charset: 'UTF-8',
          Data: htmlTemplate(emailData)
        }
      }
    }
   }))
   return emailResult
  }catch(error){
    console.log(error)
  }
  
  
}
email.txt

Dear {{Name}}

Thanks for asking images on email.

Please find your requested images below
   
 Face image

 Bus image

   -----Thanks
Email.html

<h1>Dear {{Name}}</h1>
<p>Thanks for asking images on email.</p>
<p>Please find your requested image below</p>

 <p>face Image</p>
 <img src={{ImageSrc}} />

  <p>Bus Image</p>
<img src="data:image/gif;base64,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">

//This image is working
 
<p>-------Thanks</p>

How to display base64 string as image in email, using AWS SES

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I have just resolved this issue…
So I thought, about posting answer for others help.

The root cause of this was- large size of my buffer response form S3, and email only supports 128MB data, as I found in cloud watch logs ( I can comment about AWS SES only, not sure about other email clients)

So the ultimate solution for my problem is just to resize the buffer response, which we are getting from S2.

So I have used sharp https://www.npmjs.com/package/sharp

And add these line in index.js

//Here I will resize the image

const resizedImageFileBuffer =
await sharp(imageFileBuffer)
.resize ({
width:200,
height:200,
fit: ‘contain’
})
.toFormat(‘png’)
.png({
quality:100,
compressionLevel: 6
})
.toBuffer()

//Now we will convert resized buffer to base64
let bufferToBase64 =
resizedImageFileBuffer.toString("base64");

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply