1

I am trying to figure out how to send attachments in transactional emails with Mailchimp. According to the documentation, the attachments array must contain objects with type, name and content properties. The one that I can't figure out is content. And surprisingly I could find a related question on SO.

The documentation says its value must be:

the content of the attachment as a base64-encoded string

So I have this function that does send the email, but the attachment content is corrupt (the name and type look fine):

const sendEmail = emailObj => {
  console.log('sendEmail()');
  const URL = 'https://mandrillapp.com/api/1.0/messages/send';

  const { html, subject, toEmail, attachmentId } = emailObj;

  const file = DriveApp.getFileById(attachmentId);
  const type = file.getMimeType();
  const name = file.getName();
  const content = Utilities.base64Encode(file.getBlob().getDataAsString());

  const options = {
    header: {
      'Content-Type': 'application/json',
    },
    payload: JSON.stringify({
      key: 'key',
      message: {
        from_email: 'email@domain.com',
        subject,
        html,
        to: [
          {
            email: toEmail,
            type: 'to',
          },
        ],
        attachments: [
          {
            type,
            name,
            content,
          },
        ],
      },
    }),
  };


  const response = UrlFetchApp.fetch(URL, options);
  console.log(response.getContentText());
  return emailObj;
};

The attachment comes in as a corrupt PDF file with the right name.

I have also tried setting the content to:

  • file.getBlob()
  • file.getBlob().getDataAsString()
  • file.getBlob().getBytes()

Hopefully someone has done this before :)

Dmitry Kostyuk
  • 1,354
  • 1
  • 5
  • 21
  • 2
    I tried converting Base64 of my files in drive online and this method worked. `content = Utilities.base64Encode(file.getBlob().getBytes())`. `base64Encode` works on byte array. If it has special characters, you can add specific charset (e.g. Utilities.Charset.UTF_8) to it. If it still doesn't work, then try the variation `base64EncodeWebSafe`. Just always try to have the byte array as its parameter. – NightEye Sep 24 '21 at 19:37
  • best way to test it is that you check whether the one you get as base64 is working when you try to convert it into a file. You can try online sites that convert base64 to file or create a drive file from it and check if it is a proper base64. Base64 on `getDataAsString` return will error as I have tested. raw bytes is needed so `getBytes` did the trick on my test. – NightEye Sep 24 '21 at 19:45
  • 1
    @NaziA Thank you, this worked! If you write up an answer, I will be more than happy to accept it. – Dmitry Kostyuk Sep 25 '21 at 08:43
  • 1
    I am glad it worked @DmitryKostyuk, I have created an answer based on my comments. – NightEye Sep 27 '21 at 15:01

1 Answers1

1

Since I wasn't able to test fully the API due to my current limitations, I tried converting the Base64 of my files in drive online and this method worked.

content = Utilities.base64Encode(file.getBlob().getBytes())

base64Encode works on byte array as the documentation suggests. If it has special characters, you can add specific charset (e.g. Utilities.Charset.UTF_8) to it.

If it still doesn't work, then try the variation base64EncodeWebSafe. Just always use its byte array as its parameter.

Best way to test it is that you check whether the one you get as base64 is working when you try to convert it into a file. You can try online sites that convert base64 to file or create a drive file from it and check if it is a proper base64. Base64 on getDataAsString return will error as I have tested. Raw bytes is needed so getBytes did the trick on my test.

NightEye
  • 10,634
  • 2
  • 5
  • 24