Empty emails from specific address from gmail trash
Tags: javascript, googlecloud
Published: 2020-06-15 01:45:23

# Problem

One of my clients uses Gmail and their abuser keeps emailing them. They read them and get affected.

Gmail allows us to filter incoming emails to spam or trash. They've done that. But they go and read them in trash (emotions are hard).

Gmail doesn't have a filter to let us empty emails from specific senders from trash.

# Solution

A Google script that automatically empties abuser's email from Gmail trash.

# Notes

Skip to end of article for full script if that's all you need.

This script only empties emails from specific sender from trash. It does not filter incoming ones to trash. To do that, use Gmail's [filters](https://support.google.com/mail/answer/6579?hl=en). Remember to set "never send to spam" so the emails always go to trash.

Some have pointed out that emails might be evidence. Think about that before using this script. I cobbled this script together because we're prioritising mental health for now.

# APIs

This solution uses two main APIs. I don't know their exact names but:

[Gmail](https://developers.google.com/gmail/api/v1/reference/users/threads).

[GmailApp (Apps-Script)](https://developers.google.com/apps-script/reference/gmail/gmail-app).

# Code walkthrough

The script has to run from the client's Google account. We can test it on our own first.

First, log into our Google account. Then go to [script.google.com](https://script.google.com). This is where we type in the following code.

## Some prep

Take a glance at the preparatory stuff before I explain them:

```
const clientGmail = 'myClient@This-Has-To-Be-Gmail-Here.com'

const page = {
    q: "in:trash from:abuser@Whatever-Their-Email-Is.com",
    pageToken: null,
    }

const limit = 5400000
```

Client's email in `const clientGmail`. Note: the script has to run from the client's Google account, so this has to be their Gmail address. However, because we're testing this on our own accounts first, set this to our own Gmail address.

`page` object contains details in its `q` property that allows Gmail to search for the abuser's email in gmail trash.

`const limit` is the time period from which we want to delete the abuser's email. I've set it to 1.5 hours in milliseconds. This means the script deletes any email from the abuser that came in within the last 1.5 hours.

## The function itself

Take a brief look and I'll explain:

```
function deleteFromTrash() {
  const threadList = Gmail.Users.Threads.list('me', page);
  
  threadList.threads.forEach(thread => {
  const id = thread.id
  const threadByOtherAPI = GmailApp.getThreadById(id)
  
  const threadDate = threadByOtherAPI.getLastMessageDate()
  const timeNow = new Date
  const period = timeNow - threadDate
  const recent = period < limit
    
  if (recent) {
    Gmail.Users.Threads.remove(clientGmail, id);
    }
  })
}
```

`threadList` uses the Gmail API to find all the threads that fit the description in `page.q`:

```
const threadList = Gmail.Users.Threads.list('me', page);
```

To clarify: `threadList` contains multiple threads. A thread contains one or more emails.

We then loop through `threadList` with a `forEach` loop:

```
threadList.threads.forEach(thread => {
    ...
}
```

As far as I know, the Gmail API doesn't let us access the thread itself, but it gives us its ID. So, during each loop, we use the `GmailApp` (Apps-Script) API to get the thread by its ID. Like this:

```
const id = thread.id
const threadByOtherAPI = GmailApp.getThreadById(id)
```

Next, we get the date of the latest email in the thread, and check if it's within our time period. We do this because emails from long ago are of sentimental or other value to our client, so we don't want to delete them.

Here's how we check:

```
const threadDate = threadByOtherAPI.getLastMessageDate()
const timeNow = new Date
const period = timeNow - threadDate
const recent = period < limit
```

Finally, if the email is definitely `recent`, we empty it from trash using the Gmail API:

```
if (recent) {
  Gmail.Users.Threads.remove(clientGmail, id);
  }
```

# Turn on Gmail in Google Services

The script won't work just yet. In script.google.com where we've just written the script:

- Go to "Resources" in the menu
- Click on "Advanced Google services"
- Scroll down to Gmail API and turn it on

# Set project trigger

Final step here. From script.google.com:

- Go to "Edit" in the menu
- Click on "Current project's triggers"
- In the new window that opens up, click the "Add Trigger" button in the lower right of the screen
- Set the interval during which the script should run. Note that we've set `const limit` to 1.5 hours. My own interval is "every hour". So the script runs every hour and checks if any abusers from the abuser arrived in the last 1.5 hours.

The last point bears some thinking. I will do this in the next section.

# Rate limits

Rate limits for scripts and their triggers can be found [here](https://developers.google.com/apps-script/guides/services/quotas). The problem is, it's not clear to me if we should be looking at "Current quotas" or "Current limitations".

I also don't know what the difference is between Consumer, G Suite Basic, and G Suite free edition. Is our regular gmail account the first, second, or third? No idea.

Anyway, I've far exceeded trigger limits in both tables by now. So maybe they don't matter? I have no flippin' clue.

But it might matter to you, for whatever reason. So, keep these limits in mind.

# Full script

Remember to run this script and enable Gmail in Google Services on client's account.

```
const clientGmail = 'myClient@This-Has-To-Be-Gmail-Here.com'

const page = {
    q: "in:trash from:abuser@Whatever-Their-Email-Is.com",
    pageToken: null,
    }

const limit = 5400000

function deleteFromTrash() {
  let threadList = Gmail.Users.Threads.list('me', page);
  
  threadList.threads.forEach(thread => {
  const id = thread.id
  const threadByOtherAPI = GmailApp.getThreadById(id)
  
  const threadDate = threadByOtherAPI.getLastMessageDate()
  const timeNow = new Date
  const period = timeNow - threadDate
  const recent = period < limit
    
  if (recent) {
    Gmail.Users.Threads.remove(clientGmail, id);
    }
  })
}
```