Google Apps Script for Gmail Deletion - google-apps-script

I use a simple Script to delete all emails after 1 day if they are labelled 'camera'. This has been working for months. I haven't changed it but it suddenly stopped working.
The script still has permission to run on my Gmail but has stopped.
Any advice appreciated.
The script is;
function cleanUp() {
var delayDays = 1 // Enter # of days before messages are moved to trash
var maxDate = new Date();
maxDate.setDate(maxDate.getDate()-delayDays);
var label = GmailApp.getUserLabelByName("camera");
var threads = label.getThreads();
for (var i = 0; i < threads.length; i++) {
if (threads[i].getLastMessageDate()<maxDate)
{
threads[i].moveToTrash();
}
}
}
Thanks,
Sam

Can you log over the loop to check if it's iterating?

Related

Is there a way to set up a trigger for when I receive an email? [duplicate]

I've been reading through gmail addons. They have contextual triggers that trigger when you open an email.
Is it possible to trigger a service when an email is received by me? Best I can find is unconditional but that only triggers when the email is opened.
You can't create a trigger for every email, however you can do something similar as described in this answer.
For example you can:
Set up a filter that puts a special label on incoming emails that you want to process.
Set up a reoccurring script that runs every 10 minutes, or even every minute. In the script, you can pull all of the emails that have the given label, and process them accordingly, removing the label when you are done.
function processEmails() {
var label = GmailApp.getUserLabelByName("Need To Process");
var threads = label.getThreads();
for (var i = threads.length - 1; i >= 0; i--) {
//Process them in the order received
threads[i].removeLabel(label).refresh();
}
}
You can then set this on a time based trigger to have it run as often as you would like.
If you want to keep track of the emails you have processed, you can create another "processed" label and add that to the message when you are done processing.
I had a little trouble with getting the labels right so I'm including code to log your labels. I modified user3312395's code also to add new label also.
Thanks for the original answer too!
function emailTrigger() {
var label = GmailApp.getUserLabelByName('Name of Label to Process');
var newLabel = GmailApp.getUserLabelByName('New Label Name');
if(label != null){
var threads = label.getThreads();
for (var i=0; i<threads.length; i++) {
//Process them in the order received
threads[i].removeLabel(label);
threads[i].addLabel(newLabel);
//run whatever else here
}
}
}
function getLabels(){
var labels = GmailApp.getUserLabels();
for(i=0; i<labels.length; i++){
Logger.log(labels[i].getName());
}
}
Yes, you can trigger a function for every new email!
Just use the search query newer_than:1h. Have your trigger run every 10 minutes for example. Then you will essentially be running logic for every new email (with up to 10 minutes delay, which is probably fine).
var TRIGGER_NAME = 'handleNewEmails'
// Maximum number of threads to process per run.
var PAGE_SIZE = 150
var INTERVAL = 10
function Install() {
// First run 2 mins after install
ScriptApp.newTrigger(TRIGGER_NAME)
.timeBased()
.at(new Date(new Date().getTime() + 1000 * 60 * 2))
.create()
// Run every 10 minutes there after
ScriptApp.newTrigger(TRIGGER_NAME)
.timeBased().everyMinutes(INTERVAL).create()
}
function Uninstall() {
var triggers = ScriptApp.getProjectTriggers()
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === TRIGGER_NAME) ScriptApp.deleteTrigger(triggers[i])
}
}
function handleNewEmails() {
var threads = GmailApp.search("newer_than:1h", 0, PAGE_SIZE)
for (var i = 0; i < threads.length; i++) {
var thread = threads[i]
// Do something with the thread.
}
}
Actually, they have somewhat complex pub/sub service that requires setting up OAuth authentication. With this service you'll must be able to get push notifications. But I also think its easier to set up a trigger to run every 10 or even 1 minute.

How to fix google apps script memory problem?

So I created an infinite loop by accident today in Google Apps Script and I think it broke my script, because everything I run after it just throws out of memory error. Is there any way I can fix it or do I just have to wait 24 hours?
var carSheet = ss.getSheetByName(CAR_FORM);
var carData = carSheet.getDataRange().getValues();
var lastRow = carSheet.getLastRow() - 1;
for(var i = 0; i < carData; i++) {
//Do something here
}

Getting the body of individual emails from gmail to google sheets

I'm really new at using Google Apps Script, so if what I'm trying doesn't make sense, or just isn't possible please let me know.
Everyday I get several emails that look like the following:
Your Name: FirstName LastName
Phone Number: 555 867 5309
Email Address: FakeEmail#email.com
What do you need help with? Request someone makes.
I'm attempting to automatically send the body of these emails to a new line in a Google Sheet when they come in.
As of right now I have every email get the label "myLabel" when it comes in. I then run the following script, which is a slightly modified version of something I found here:
function myFunction() {
var ss = SpreadsheetApp.getActiveSheet();
var label = GmailApp.getUserLabelByName("MyLabel");
var threads = label.getThreads();
for (var i=0; i<threads.length; i++)
{
var messages = threads[i].getMessages();
for (var j=0; j<messages.length; j++)
{
var msg = messages[j].getBody();
ss.appendRow([msg])
}
threads[i].removeLabel(label);
}
}
I'm attempting to run this code with a timer trigger every 15 minutes. The issue I've run into is that every time the code runs it pulls from every email in the thread. I would like it to just pull from the emails that are new since the last time it ran. Any advice would be greatly appreciated.
Why not mark the messages as read when you finish processing them? Here is a sample from one of my scripts.
var pendingEmailLabel = "MyLabel";
var threads = GmailApp.getUserLabelByName(pendingEmailLabel).getThreads();
for (var t = 0; t < threads.length; ++t) {
var thread = threads[t];
var messages = thread.getMessages();
for (var m = 0; m < messages.length; ++m) {
var message = messages[m];
if (message.isUnread()) {
// INSERT YOUR CODE HERE THAT TAKES ACTION ON THE MESSAGE
message.markRead();
}
}
}
}

Google gmail script that triggers on incoming email

I've been reading through gmail addons. They have contextual triggers that trigger when you open an email.
Is it possible to trigger a service when an email is received by me? Best I can find is unconditional but that only triggers when the email is opened.
You can't create a trigger for every email, however you can do something similar as described in this answer.
For example you can:
Set up a filter that puts a special label on incoming emails that you want to process.
Set up a reoccurring script that runs every 10 minutes, or even every minute. In the script, you can pull all of the emails that have the given label, and process them accordingly, removing the label when you are done.
function processEmails() {
var label = GmailApp.getUserLabelByName("Need To Process");
var threads = label.getThreads();
for (var i = threads.length - 1; i >= 0; i--) {
//Process them in the order received
threads[i].removeLabel(label).refresh();
}
}
You can then set this on a time based trigger to have it run as often as you would like.
If you want to keep track of the emails you have processed, you can create another "processed" label and add that to the message when you are done processing.
I had a little trouble with getting the labels right so I'm including code to log your labels. I modified user3312395's code also to add new label also.
Thanks for the original answer too!
function emailTrigger() {
var label = GmailApp.getUserLabelByName('Name of Label to Process');
var newLabel = GmailApp.getUserLabelByName('New Label Name');
if(label != null){
var threads = label.getThreads();
for (var i=0; i<threads.length; i++) {
//Process them in the order received
threads[i].removeLabel(label);
threads[i].addLabel(newLabel);
//run whatever else here
}
}
}
function getLabels(){
var labels = GmailApp.getUserLabels();
for(i=0; i<labels.length; i++){
Logger.log(labels[i].getName());
}
}
Yes, you can trigger a function for every new email!
Just use the search query newer_than:1h. Have your trigger run every 10 minutes for example. Then you will essentially be running logic for every new email (with up to 10 minutes delay, which is probably fine).
var TRIGGER_NAME = 'handleNewEmails'
// Maximum number of threads to process per run.
var PAGE_SIZE = 150
var INTERVAL = 10
function Install() {
// First run 2 mins after install
ScriptApp.newTrigger(TRIGGER_NAME)
.timeBased()
.at(new Date(new Date().getTime() + 1000 * 60 * 2))
.create()
// Run every 10 minutes there after
ScriptApp.newTrigger(TRIGGER_NAME)
.timeBased().everyMinutes(INTERVAL).create()
}
function Uninstall() {
var triggers = ScriptApp.getProjectTriggers()
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === TRIGGER_NAME) ScriptApp.deleteTrigger(triggers[i])
}
}
function handleNewEmails() {
var threads = GmailApp.search("newer_than:1h", 0, PAGE_SIZE)
for (var i = 0; i < threads.length; i++) {
var thread = threads[i]
// Do something with the thread.
}
}
Actually, they have somewhat complex pub/sub service that requires setting up OAuth authentication. With this service you'll must be able to get push notifications. But I also think its easier to set up a trigger to run every 10 or even 1 minute.

How do I fix "Exceeded maximum execution time" error on this Google Apps Script?

I want to devise a script that will clean up my email. I want to create a few labels called "Auto Archive/# days" where # is a number between 0 and 9. I wrote this script below, but every time it runs, I receive an "Exceeded maximum execution time" error.
I have a time-driven (hour timer) trigger set up to run every 12 hours. I call the autoArchive method in the trigger. I tried adding Utilities.sleep a few times, but it didn't help. [Should I put them somewhere else in the code?]
Any help is greatly appreciated! Thank you in advance!
function cleanUp(delayDays) {
//var delay2Weeks = 14 // Enter # of days before messages are moved to archive
//var delay2Days = 2 // Enter # of days before messages are moved to archive
if (typeof delayDays != 'number') {
return null;
}
var maxDate = new Date();
maxDate.setDate(maxDate.getDate()-delayDays);
var label = GmailApp.getUserLabelByName("Auto Archive/" + delayDays + " days");
var threads = label.getThreads();
for (var i = 0; i < threads.length; i++) {
if (threads[i].getLastMessageDate()<maxDate)
{
var randnumber = Math.random()*5000;
Utilities.sleep(randnumber);
Utilities.sleep(randnumber);
threads[i].moveToArchive();
}
}
}
function autoArchive()
{
for (var i = 1; i < 10; i++) {
cleanUp(i);
}
}
So it seems I was getting all items with "Auto Archive/X days" and not limiting the result set to only items within the Inbox. After correcting that, the maximum execution time error went away. I corrected it by choosing the inbox items first, and next the items with the label.
function cleanUp(delayDays) {
//var delay2Weeks = 14 // Enter # of days before messages are moved to archive
//var delay2Days = 2 // Enter # of days before messages are moved to archive
if (typeof delayDays != 'number') {
return null;
}
var maxDate = new Date();
maxDate.setDate(maxDate.getDate()-delayDays);
var inboxItems = GmailApp.getInboxThreads();
for (var i = 0; i < inboxItems.length; i++) {
if (inboxItems[i].getLastMessageDate()<maxDate) {
var autoItems = inboxItems[i].getLabels();
for(var j=0; j < autoItems.length; j++) {
if (autoItems[j].getName() == "Auto Archive/" + delayDays + " days") {
inboxItems[i].moveToArchive();
break;
}
}
}
}
}
function autoArchive()
{
Session.getActiveUser().getEmail();
for (var i = 1; i < 10; i++) {
cleanUp(i);
}
}
There are many ways to speed it up. For starters dont call sleep as it will make the problem worse (makes the script take even more time from your daily quota and trigger 5min limit).
After that if the problem is that you have too many threads it might help to write a list of threads to archive (in scriptdb for example store the thread ids) but dont archive them yet.
Later from another trigger (say every 10min) you process your list by chunks (see https://developers.google.com/apps-script/reference/gmail/gmail-app#getThreadById(String)) and use more triggers if needed to avoid the 5min limit.