Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove an attachment of a Gmail email with Google Apps Script

Using Google Apps Script (http://script.google.com), I know from the docs, how to send, forward, move to trash messages, etc. but I don't find how to remove a file attachement of an email, i.e.:

  1. keep the text content (either in HTML or just plain text would be fine)
  2. keep the original sender, keep the recipient
  3. keep the original message date/hour (important!)
  4. remove the attachment

If it's not possible via the API, is there a way to resend the message to myself, while keeping 1, 2 and 3?


Note: the GmailAttachment class looks interesting and allows to list recipients:

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

but I don't find how to remove an attachment.

Note: I've already studied many other solutions for doing this, I've already read nearly every article about this (solutions with dedicated web services, with local clients like Thunderbird + Attachment extractor plugin, etc.), but none of them are really really cool. That's why I was looking for a solution to do it manually via Google Apps Script.

like image 253
Basj Avatar asked Sep 26 '17 19:09

Basj


People also ask

Can you remove an attachment from a Gmail email?

And while it's impossible to delete attachments from emails natively in Gmail without having to delete the original message itself, it's worth deleting obsolete messages with large files attached to save some space.

How do you remove an attachment from an email?

Open the email that contains the attachment you want to delete. In the Attached box, right-click the attachment, and click Remove or select the file in the Attached box and then press the delete key on your keyboard.

Does Gmail have email scripting?

If you know JavaScript, you can use Google Apps Script to add features to many Google products including Gmail. If you've used Office scripting, the idea is the same, although obviously the implementation is very different.


1 Answers

Looks like messages will have to be re-created-ish:

Messages are immutable: they can only be created and deleted. No message properties can be changed other than the labels applied to a given message.

Using Advanced Gmail Service with the Gmail API insert() you can hack your way around it using: Gmail.Users.Messages.insert(resource, userId)

This advanced service must be enabled before use.

Example: [fill in the EMAIL_ID with an email_id or in whatever way you want to get the email]

function removeAttachments () {
  // Get the `raw` email
  var email = GmailApp.getMessageById("EMAIL_ID").getRawContent();

  // Find the end boundary of html or plain-text email
  var re_html = /(-*\w*)(\r)*(\n)*(?=Content-Type: text\/html;)/.exec(email);
  var re = re_html || /(-*\w*)(\r)*(\n)*(?=Content-Type: text\/plain;)/.exec(email);

  // Find the index of the end of message boundary
  var start = re[1].length + re.index;
  var boundary = email.indexOf(re[1], start);

  // Remove the attachments & Encode the attachment-free RFC 2822 formatted email string
  var base64_encoded_email = Utilities.base64EncodeWebSafe(email.substr(0, boundary));
  // Set the base64Encoded string to the `raw` required property
  var resource = {'raw': base64_encoded_email}

  // Re-insert the email into the user gmail account with the insert time
  /* var response = Gmail.Users.Messages.insert(resource, 'me'); */

  // Re-insert the email with the original date/time 
  var response = Gmail.Users.Messages.insert(resource, 'me', 
                      null, {'internalDateSource': 'dateHeader'});

  Logger.log("The inserted email id is: %s",response.id)
}

This will remove the attachments from the email and re-insert it into your mailbox.

edit/update: New RegExp to work with html&plain-text only emails - should now work on multiple boundary strings

like image 82
random-parts Avatar answered Oct 09 '22 13:10

random-parts