0

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 = 'vupd@hihi.com'
    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

BinChanhKun
  • 73
  • 2
  • 8
  • Does this answer your question? [Node.js get image from web and encode with base64](https://stackoverflow.com/questions/17124053/node-js-get-image-from-web-and-encode-with-base64) – eol Sep 28 '22 at 07:44
  • @eol Now there have been many changes bufet is no longer in use – BinChanhKun Sep 28 '22 at 07:57

2 Answers2

1

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 = 'vupd@hihi.com'
  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' })
  }
}
Thomas Zimmermann
  • 1,485
  • 8
  • 18
1

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)
WitoldW
  • 749
  • 10
  • 11