google-apps-scriptgmailemail-attachments

How to get attachments in Gmail with Google Apps Script that are only attached to the messege itself


I have a very simple code written for Google Apps Script that searches my email for a specific subject and save its attachments to a folder in my drive, if found.

However, the email sometimes has another email attached to it with the extension .eml and this email attached also have its own attachments.

When I run the code it get the attachments from both emails, as if they were all in the "main" email and save them to my drive.

Is there a way of filtering these attachments, or identifying that they are not from the message so they don't get saved?

Here is the code:

var threads = GmailApp.search('subject:' + 'test subject');
var folder = DriveApp.getFolderById('someID');

if(threads.length <= 0){
    //email not found
    return "email not found";
}

for (var i = 0; i < threads.length; i++) {
var messages = threads[i].getMessages();


for (var m = 0; m < messages.length; m++) {
        var msg = messages[m].getBody();

        var subject = messages[m].getSubject();

        var attachments = messages[m].getAttachments();
  
        Logger.log('attachments found ' + attachments.length);

        if (attachments.length > 0) {

    attachments.forEach(function(a){
                //create the file and limit the name to 30 characthers
        var file = folder.createFile(a.copyBlob()).setName(a.getName().substring(0,30));

    });

    
  }

  
}

Tried searching the documentation and looking for answers in other forums


Solution

  • SUGGESTION

    The getAttachments() method seems to detect attachments in eml files by default. However, I must emphasize that my observations lack documented support due to the absence of official references. This inference is drawn solely from my own replication.

    As an alternative, I suggest utilizing the getRawContent method to clean the email's content data. This approach enables precise data filtering, excluding eml contents before saving attachments. For more details, refer to the adjusted script below:

    Tweaked Script

    function testingFunction() {
      var threads = GmailApp.search('subject:' + 'test subject');
      var folder = DriveApp.getFolderById('1uHzF0Vvr4-K4SDgprNtnwbT2VmQqeqYr');
    
      if (threads.length <= 0) {
        //email not found
        return "email not found";
      }
    
      for (var i = 0; i < threads.length; i++) {
        var messages = threads[i].getMessages();
    
    
        for (var m = 0; m < messages.length; m++) {
          var msg = messages[m].getBody();
          var subject = messages[m].getSubject();
          var attachments = messages[m].getAttachments();
    
          //Split data by eml type or 'rfc882' to separate MAIN email attachments from the .eml file attachments
          let rawData = messages[m].getRawContent().split('rfc822');
    
          //Find a chunk that DO NOT contain '.eml' file attachement
          let mainEmailMessage = rawData.filter(d => !d.includes('.eml'));
    
          //Get the attachments from the main email message.
          let mainEmailAttachments = mainEmailMessage.map(d => d.split('Content-Disposition').filter(d => d.toLowerCase().includes('attachment') || d.includes('inline')));
    
          //Process main email attachements
          mainEmailAttachments.forEach(a => {
            console.log(`Source: ${subject}\n`)
            a.forEach((b, i) => {
              let filename = b.match(new RegExp('filename="(.*?)"'))[1];
              let contentType = mainEmailMessage[0].split('Content-Type').filter(d => d.includes(filename))[0].match(/: (.*?); name/)[1];
              let base64 = Utilities.newBlob(Utilities.base64Decode(b.match(/Content-ID:([\s\S]+?)--/)[1].split('\r\n\r\n')[1]), contentType);
              folder.createFile(base64.setName(filename));
              console.log(`Attachment #${i + 1} has been saved:\n\nFile name: ${filename}\nFile type: ${contentType}`);
            })
          });
        }
      }
    }
    

    Demo

    image

    image

    image

    Reference