Home > Net >  How to convert a remote path to base64 for mail attachment?
How to convert a remote path to base64 for mail attachment?

Time:09-28

I am doing mail function and the provider requires me to convert the file to base64, before I used smtpjs and just put a link pointing to the file now I am using sengrid and I am getting this error...

The attachment content must be base64 encoded.

Here my code:

'use strict'
const axios = require("axios");
/**
 * Read the documentation () to implement custom controller functions
 */


module.exports = {
  
  send: async (ctx) => {
    const body = ctx.request.body
    const sendTo = '[email protected]'
    strapi.log.debug(`Trying to send an email to ${sendTo}`)
  
    const attachmentUrl ='https://cms.gstech.space/uploads/Cover_Go_Studio_204fca7084.png'
    try {
      const emailOptions = {
        to: sendTo,
        subject: 'Test',
        text:"Test",
        attachments:[{
          content: undefined,
          filename: 'doSomething',
          type: undefined,
          disposition: "attachment",
        }]
      };
  
      // This could be an async function to fill your emailOptions item
      await axios.get(attachmentUrl, {responseType: "arraybuffer"})
        .then(response => {
          const contentType = response.headers["content-type"];
          const dataString = Buffer.from(response.data).toString("base64");
          emailOptions.attachments[0].content = `data:${contentType};base64,${dataString}`;
          emailOptions.attachments[0].type = contentType;
        });
  
      await strapi.plugins['email'].services.email.send(emailOptions)
      strapi.log.debug(`Email sent to  ${sendTo}`)
      ctx.send({ message: 'Email sent' })
    } catch (err) {
      strapi.log.error(`Error sending email to ${sendTo}`, err)
      ctx.send({ error: 'Error sending email' })
    }
  }
}


I tried fs.readFileSync('link').toString("base64") but it didn't work because the picture I took from the remote repository... Hope to get help from everyone. Thanks

CodePudding user response:

I'm doing this with axios in a messaging app I did, the trick is to not encode the response by providing responseType: "arraybuffer":

const axios = require("axios");

...(axios or whatever tool to make http get on http/https)...

send: async (ctx) => {
  const body = ctx.request.body
  const sendTo = '[email protected]'
  strapi.log.debug(`Trying to send an email to ${sendTo}`)

  const attachmentUrl ='https://xxx.xxx.xx/uploads/Cover_Go_Studio_204fca7084.png'
  try {
    const emailOptions = {
      to: sendTo,
      subject: 'Test',
      text:"Test",
      attachments:[{
        content: undefined,
        filename: 'doSomething',
        type: undefined,
        disposition: "attachment",
      }]
    };

    // This could be an async function to fill your emailOptions item
    await axios.get(attachmentUrl, {responseType: "arraybuffer"})
      .then(response => {
        const contentType = response.headers["content-type"];
        const dataString = Buffer.from(response.data).toString("base64");
        emailOptions.attachments[0].content = `data:${contentType};base64,${dataString}`;
        emailOptions.attachments[0].type = contentType;
      });

    await strapi.plugins['email'].services.email.send(emailOptions)
    strapi.log.debug(`Email sent to  ${sendTo}`)
    ctx.send({ message: 'Email sent' })
  } catch (err) {
    strapi.log.error(`Error sending email to ${sendTo}`, err)
    ctx.send({ error: 'Error sending email' })
  }
}

CodePudding user response:

You can use fetch to get the image as a Blob and do some processing with it.

const imageURL ='https://xxx.xxx.xx/uploads/Cover_Go_Studio_204fca7084.png'
const response = await fetch(imageURL);
const imageBlob = await response.blob();
const attachments = URL.createObjectURL(imageBlob)

https://developer.mozilla.org/en-US/docs/Web/API/Blob

https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL

EDIT : with axios

Don't use .then(), you want to await the result of your axios call.

const response = await axios.get(attachmentUrl, {responseType: "arraybuffer"})
const dataString = Buffer.from(response.data).toString("base64");
emailOptions.attachments[0].content = `data:${contentType};base64,${dataString}`;
...
await strapi.plugins['email'].services.email.send(emailOptions)
  • Related