1

I'm bit new to google app script and try figure out how to resolve my google mail problem with google app script


Update : only particular attachment need to be remove rest of the structure and attachment need to same. provided solution remove all the attachments !

Problem :

I daily get email with pdf attachments from my vendors and clients some are send to me using automatic systems and some from manual some of this email has attachment called "noname" which I cant open or read. I'm using automated application to download this pdf attachments when there is "noname " attachment that email fully ignored so I miss some pdf daily


Planed Solution :

using google app script I'm try to capture the "noname" attachment and delete only that file rest of the email content and pdf need to be same .

I have manage to implement code to capture specific email which send noname attachment and if they unread then check attachments and delete noname


Where I need advice : how to delete selected attachment ??

function myFunction() {

  Logger.log("unread emails: " +
             GmailApp.search('is:unread from:pdf_sender@gmail.com'));

  var deta = GmailApp.search('is:unread from:1031mymailx@gmail.com')

  var msgs = GmailApp.getMessagesForThreads(deta);

        for (var i = 0 ; i < msgs.length; i++) {
              Logger.log("msg object lenth " + msgs.length)

            for (var j = 0; j <  msgs.length; j++) {
                Logger.log("msg i object lenth " + msgs[i].length)
                var attachments = msgs[i][j].getAttachments();
                var m_id = msgs[i][j].getId()

              for (var k = 0; k < attachments.length; k++) {
                  Logger.log("attachment lenth " +  attachments.length)
                  Logger.log('Message "%s" contains the attachment "%s" (%s bytes)',  msgs[i][j].getSubject(), attachments[k].getName(), attachments[k].getSize());

                      if (attachments[k].getName() == "noname" ){

                     //  attachments[k].deleteAttachment();
                    Logger.log('Message "%s" contains the attachment "%s" (%s bytes)',  msgs[i] 
                      [j].getSubject(), attachments[k].getName(),attachments[k].getSize());

              }       
   }
  }
 }
}
Darshanak
  • 13
  • 3
  • 1
    Does this answer your question? [Remove an attachment of a Gmail email with Google Apps Script](https://stackoverflow.com/questions/46434390/remove-an-attachment-of-a-gmail-email-with-google-apps-script) – Casper Nov 13 '19 at 11:02
  • Thanks for the suggestion @Casper but it remove all the attachments. here I need to remove only noname attachment . – Darshanak Nov 13 '19 at 11:55

1 Answers1

0

GMail messages are immutable - that is, you cannot modify them. However, you can re-create them by downloading their content, modifying it, and inserting the modified message back into your account.

I have modified your code so that it does what you asked for, using the method explained. It iterates over the search results and checks whether the message contains a filename called noname. In case it does, it inserts a modification of the original message that does not contain the noname attachment.

Additionally, you may opt to uncomment two different lines so that:

  1. The new message gets inserted with INBOX label (so that it shows up in your inbox) and UNREAD labels.
  2. The original message gets trashed after inserting the new one.
var BOUNDARY_REGEX = new RegExp('boundary=\"(.+)\"');

function removeAttachment(msg) {
  var emailContent = msg.getRawContent();
  if (emailContent.indexOf('filename=noname') == -1) return;

  var boundary = BOUNDARY_REGEX.exec(emailContent)[1];
  var boundaryLine = '--' + boundary;

  var sections = emailContent.split(boundaryLine);

  var filteredSections = sections.filter(function(value, index, arr) {
    return value.indexOf('filename=noname') == -1;
  });

  var resultBody = filteredSections.join(boundaryLine);
  var encodedResultBody = Utilities.base64EncodeWebSafe(resultBody);
  var resource = {'raw': encodedResultBody};
  // OPTIONAL - LABEL YOUR NEWLY CREATED MAIL AS 'INBOX' & 'UNREAD'
  // resource['labelIds'] = ['INBOX', 'UNREAD'];
  var response = Gmail.Users.Messages.insert(resource, 'me', null, {'internalDateSource': 'dateHeader'});
  Logger.log("Inserted email id is: %s", response.id);
  // OPTIONAL - TRASH ORIGINAL MESSAGE
  // GmailApp.moveMessageToTrash(msg);
  return response.id;
}

function myFunction() {
  Logger.log("unread emails: " +
             GmailApp.search('is:unread from:pdf_sender@gmail.com'));

  var deta = GmailApp.search('is:unread from:1031mymailx@gmail.com')

  var msgs = GmailApp.getMessagesForThreads(deta);

  for (var i = 0 ; i < msgs.length; i++) {
    for (var j = 0; j < msgs[i].length; j++) {
      Logger.log("msg object length " + msgs[j].length);    
      removeAttachment(msgs[i][j]);
    }
  }
}

Before executing this code, please make sure that you have the GMail Advanced service enabled.

carlesgg97
  • 4,184
  • 1
  • 8
  • 24
  • Dear @carlesgg97 this help lot to me. I appreciate time & effort given for this answer after enable the advance services on first try I got issue with msg.getRawContent() . then I resolve it adding https://www.googleapis.com/auth/gmail.metadata to the **metadata** then I get this error with Access denied: : Metadata scope does not support 'q' parameter _line_ _ Logger.log("unread emails: " + GmailApp.search _ at the moment I'm stuck here – Darshanak Nov 20 '19 at 05:46
  • Hey @Darshanak, I assume that what you mean is that you added the scope `https://www.googleapis.com/auth/gmail.metadata` to your project. If I understood this correctly, then this is due to the `search()` method requiring less restrictive permissions. In order to execute every operation in the script you will need the `https://www.googleapis.com/auth/gmail.modify` scope (or if you still have issues with this one, then `https://mail.google.com/`). Let me know if that fixes your issue, Thanks. – carlesgg97 Nov 20 '19 at 08:18
  • Hi @carlesgg97 thanks for the advice and it resolve the issue . now there is a `TypeError: Cannot find function getRawContent in object GmailMessage.` – Darshanak Dec 02 '19 at 07:24
  • Hey @Darshanak, apologies. `GmailApp.getMessagesForThreads()` returns a 2D-list of Gmail messages. I have edited the answer above so that it doesn't throw that error. Kindly let me know should you have any other issue with it. – carlesgg97 Dec 02 '19 at 10:10
  • ok now I'm stuck here mate it say no regex define `var boundary = BOUNDARY_REGEX.exec(emailContent)[1];` if I user manual regex then I stuck at `(function(value, index, arr)` – Darshanak Dec 04 '19 at 09:37
  • Hey @Darshanak kindly make sure the first line of my code, `var BOUNDARY_REGEX = new RegExp('boundary=\"(.+)\"');` is in your code too. Let me know if it works for you now. Cheers – carlesgg97 Dec 04 '19 at 10:19
  • @Darshanak would be nice to mark this answer as solution if it helped you – AndriuZ Jun 17 '22 at 18:17