2

I want to use Google Application Script to send email via mailgun with multiple attachments.

  var params = {
    "from": email.fromName+" <"+email.fromEmail+">",
    "to": email.toEmail,
    "subject": email.subject,
    "replyto": email.fromEmail,    
    "text": email.message,
    "html": email.htmlMessage,
  };

this works perfectly for one attachment.

params.attachment = DriveApp.getFileById("Google drive file ID").getBlob()

The official mailgun documentation states that "You can post multiple attachment values. Important: You must use multipart/form-data encoding when sending attachments."

How to do that using cURL is

curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <YOU@YOUR_DOMAIN_NAME>' \
    -F to='foo@example.com' \
    -F cc='bar@example.com' \
    -F bcc='baz@example.com' \
    -F subject='Hello' \
    -F text='Testing some Mailgun awesomness!' \
    --form-string html='<html>HTML version of the body</html>' \
    -F attachment=@files/cartman.jpg \
    -F attachment=@files/cartman.png

I cannot add two keys attachment to object params that is used in UrlFetchApp. Below is code that I tried to make multiple attachemnet work. I got inspired here with encodeURIComponent()

 email.attachments = {}
 email.attachments.file1 = "1Xq63awYnOfSeL7fStkn0jWsou"
 email.attachments.file2 = "1Iy96o9Tw9tvMw7VgZMzCA9mqm"


 if ("file1" in email.attachments){
   var attachment = []
   for (const fileTMP in email.attachments){
     const fileId =  email.attachments[fileTMP]
     const file = DriveApp.getFileById(fileId);

     var attachmentBlob = file.getBlob()

     attachment.push(attachmentBlob)
 //   attachment.push(encodeURIComponent(attachmentBlob))
   }
 //  params.attachment = attachment.join(",")  // doesnt work, even for 1 file
 //  params.attachment = attachment // doesnt work, even for 1 file
   params.attachment = attachment.join("&")  // doesnt work, even for 1 file, even with encodeURIComponent()
 }

Could some one help me to send multiple attachments from mailgun via Google Application Script. Can I use custom name for the attachment?

UPDATE

Reply to my enquiry from mailgun support

We don't have direct development support or are able to review
or debug any code in the level of capacity you are seeking so we
would not be able to help here. I suggest you look for online 
resources and look for community-made code libraries that might 
make what you are trying to accomplish easier, especially since 
the langue you are using is one we are not familiar with or in 
our documentation.
Radek
  • 13,813
  • 52
  • 161
  • 255
  • Based on solution on the link you provided, I think the problem is that you encode only the attachment object, while you should encode the payload object (includes 'to', 'subject' and so on). I can't realy try it sure that the ploblem. – Elchanan shuky Shukrun Aug 26 '21 at 18:42
  • and what structure should the attachment object have? in case of more than one attachment? – Radek Aug 27 '21 at 07:08
  • I think the payload structure became a string, so the key-value pairs inside of it are just srting with the format of `"key=val1&key=val2&key2=val3..."`. I would try someting like this: `"payload" : jsonToUrlencoded(payload)` with this function https://stackoverflow.com/a/58464724/9587368 – Elchanan shuky Shukrun Aug 27 '21 at 07:20
  • ok, I can try that but my question is what the structure of `attachment set up` in case of multiple attachments is – Radek Aug 27 '21 at 08:02
  • I would start with blob as it worked for you with one file: `...&attachment=blob1&attachment=blob2&...` but I feel like I'm just guessing at this point so you might wait for someone else to help... – Elchanan shuky Shukrun Aug 27 '21 at 08:10
  • 1
    FYI https://stackoverflow.com/a/21291573 (try ping author on SO) and https://github.com/mailgun/mailgun-js-boland/issues/151#issuecomment-317919768 – Kos Aug 28 '21 at 12:35
  • I think what you're looking for is multipart request, described well here https://www.labnol.org/code/20096-upload-files-multipart-post and https://gist.github.com/tanaikech/d595d30a592979bbf0c692d1193d260c with examples of course – Kos Aug 28 '21 at 12:45
  • @Kos Thank you so much. I got it working. Do you want to create the answer so I can accept it or I create one? – Radek Aug 28 '21 at 14:52
  • @Radek I would like to, but I have no chance to test it working with this API, so feel free to post your answer :) – Kos Aug 28 '21 at 15:20

1 Answers1

1

Thanks to @Kos and his first comment I got inspiration from MailGun API Python Requests so I can post working code how to send multiple attachments using GAS and mailgun.

function sendEmail(email) {
      
  var params = {
    "from": email.fromName+" <"+email.fromEmail+">",
    "to": email.toEmail,
    "subject": email.subject,
    "replyto": email.fromEmail,    
    "text": email.message,
    "html": email.htmlMessage,
  }    
  if ("attachments" in email){
      for(var i=0, len=email.attachments.length; i < len; i++){
        const fileId =  email.attachments[i]
        const file = DriveApp.getFileById(fileId);
  
        var attachmentBlob = file.getBlob()
        params["attachment["+i+"]"] = attachmentBlob
      }
  }

  if ( "bcc" in email){
    params.bcc = email.bcc
  }

  var options = {
    'method': 'post',
    'payload': params,
    'headers': {
      'Authorization': 'Basic ' + Utilities.base64Encode("api:" + MAILGUN_KEY)
    }
  }

  var response = JSON.parse(UrlFetchApp.fetch(email.url, options))
}

where the email data object could look like

  var email ={}
  email.toEmail = "TOemail@email.cz"
  email.fromEmail = "fromEmail@email.cz"
  email.fromName = "From email name"
  email.subject = "From email name"
  email.message = textVersionOfEmail
  email.htmlMessage = hTMLVersionOfEmail

  email.attachments = []
  email.attachments.push(file1ID)
  email.attachments.push(file2ID)

If you know how to be able to name files in the script please leave a note.

Radek
  • 13,813
  • 52
  • 161
  • 255