Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to edit Gmail messages as they arrive?

Ultimately my objective is to prevent email tracking via auto-loaded images with unique links. I'm aware that Google uses a proxy to load the images so at least they won't reveal my IP address, but there are certain individuals and organizations that annoyingly embed trackers into their emails -- and they actively check whether or not I read their emails.

In the Gmail app specifically, I can turn off auto-loading of images, but I'd like to have similar protection for other apps that don't have this setting. For example, apparently there isn't a way to do this with Google Inbox.

My current thought is to write a back-end script that can run on new mail (received either from an event or frequent polling) to turn embedded HTML images into hyperlinks links to those images -- only used if I really need the image. That way, no matter what app I use to open the email, I'm in control of how/when I'm tracked. Editing emails is something that I've done with the MS Exchange Server APIs, and I'm looking for a way to do this with Gmail -- by whatever means available.

I found a couple of threads from 2010 on how to modify the subject line using Google Apps Script and Gmail itself. At the time, you couldn't do that, but it seems possible that these have been updated since then or that there are solutions using the Gmail API or IMAP.

tl;dr

For my Gmail account, how can I programmatically modify (and save changes to) received emails?

Possible solutions:

  • Google Apps scripts
  • Gmail API
  • IMAP
  • Other?
like image 603
Logical Fallacy Avatar asked Mar 16 '23 07:03

Logical Fallacy


1 Answers

I think the Gmail API would suit your needs perfectly.

Let's say I'm polling my Inbox every minute for new messages, with the Users.messages.list()-request. I'm careful to use the after-parameter in my query with the value of the last time I checked my Inbox, as seconds since the epoch. I only ask for Ids of the potential new messages. You could also subscribe to push events to mitigate the risk of your user pressing the message before you poll and alter the messages, as mentioned by @Max in the comments. Probably not an issue if the script is just for you.

q = after:<TIME_IN_SECONDS_SINCE_EPOCH_OF_LAST_POLL>
fields = messages/id

GET https://www.googleapis.com/gmail/v1/users/me/messages?fields=messages%2Fid&q=after%3A1437677475478&access_token={YOUR_API_KEY}

Response:

{
 "messages": [
    {
     "id": "14ebc16800d1fdc0"
    }, ...
  ]
}

Ha! I have a new message. I get it raw, decode its URL safe base64-encoded content, and have a look.

format = raw
fields = raw

GET https://www.googleapis.com/gmail/v1/users/me/messages/14eb68cb028163ba?fields=raw&format=raw&access_token={YOUR_API_KEY}

Response:

{
 "raw": "RGVsaXZlcmVk..."
}

Let's do the aforementioned base64-decoding. Replace all the "-" with "+", and "_" with "/" to transform it from URL safe base64 data to regular base64-encoded data.

atob("RGVsaXZlcmVk...".replace(/\-/g, '+').replace(/\_/g, '/'));

Result:

<html lang="en">
<head>
<title>
Computerphile just uploaded a video
</title>

.
.
.


<img class="open_tracking_img" src="http://www.youtube.com/attribution_link?a=vi-KC3YA0Qc&u=/gen_204%3Fa%3Dem-uploademail" width="1" height="1">

.
.
.
</html>

Contains a lot of img-tags, for sure.

I just extract the img-tags, get the URLs, and remove all the img-tags in the mail with my favourite XML Parser.

After the tags are removed, I just insert the URLs in the mail where I see fit, and encode it back to the URL safe base64-encoded data it was retrieved in.

btoa("<html lang="en">...".replace(/\+/g, '-').replace(/\//g, '_'));

Finally, I delete the original mail and insert the modified one.

DELETE https://www.googleapis.com/gmail/v1/users/me/messages/14eb68cb028163ba?access_token={YOUR_API_KEY}

POST https://www.googleapis.com/gmail/v1/users/me/messages?access_token={YOUR_API_KEY}

{
 "raw": "RGVsaXZlcmVkLVRvO..."
}

My new, modified mail is now in the inbox instead!

enter image description here

like image 88
Tholle Avatar answered Apr 28 '23 13:04

Tholle