Search code examples
node.jsamazon-web-servicesamazon-ses

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


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: "Source_test@email.com", //dummy email for now
    Destination :{
      ToAddress: ["to_test@email.com"] // 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>

enter image description here


Solution

  • 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");