Create Google Tasks by sending email to Google GMail
Jump to navigation
Jump to search
Goals:
- Send email to a specified address - in this case to Gmail address named yourgmail+task@gmail.com. (If Gmail ID is ittichai, the email address to send to will be ittichai+task@gmail.com.) Read more about the hidden feature with Gmail - http://gmailblog.blogspot.com/2008/03/2-hidden-ways-to-get-more-from-your.html
- Script will parse that email based on a Gmail label assigned by filter, and grab the email's subject to create a new Google task.
Instructions:
- Create two new Gmail labels - newtask and newtaskdone.
- Create a Gmail filter to apply "newtask" label to all incoming yourgmail+task@gmail.com.
- Create a new Google Sheet. Enter Processed tasks in cell A1. It will be used to display how many tasks have been processed. Start the Script Editor from Tools menu.
- Create a new blank project.
- Copy and paste the whole script here. Note below will walk through the codes.
// Original Source: http://www.pipetree.com/qmacro/blog/2011/10/automated-email-to-task-mechanism-with-google-apps-script/ // ----------------------------------------------------- // Globals, constants // ----------------------------------------------------- TASKLIST = "Ittichai's list"; LABEL_PENDING = "newtask"; LABEL_DONE = "newtaskdone"; // ----------------------------------------------------- // getTasklistId_(tasklistName) // Returns the id of the tasklist specified // Oddly, we should be able to use: // Tasks.Tasklists.get(tasklistName) // but it always gives an error "Invalid Value". // ----------------------------------------------------- function getTasklistId_(tasklistName) { var tasklistsList = Tasks.Tasklists.list(); var taskLists = tasklistsList.getItems(); for (tl in taskLists) { var title = taskLists[tl].getTitle(); if (title == tasklistName) { return taskLists[tl].getId(); } } } // ----------------------------------------------------- // processPending(sheet) // Process any pending emails and then move them to done // ----------------------------------------------------- function processPending_(sheet) { var label_pending = GmailApp.getUserLabelByName(LABEL_PENDING); var label_done = GmailApp.getUserLabelByName(LABEL_DONE); // The threads currently assigned to the 'pending' label var threads = label_pending.getThreads(); // Process each one in turn, assuming there's only a single // message in each thread for (var t in threads) { var thread = threads[t]; // Grab the task data // This email's subject will be task's title. var taskTitle = thread.getFirstMessageSubject(); // This email's body will be task's body. Most email message now is HTML-based. // It is desirable to remove all HTML tags so that only actual content will be populated. // Use a custom function getTextFromHtml to strip out all HTML tags. // In addition, the string size will be limited to 3000 characters in case an email is very long. var taskNote = getTextFromHtml((thread.getMessages()[0]).getBody()).substring(0,3000); // Insert the task //addTask_(taskTitle, TASKLIST); addTask_(taskTitle, taskNote, TASKLIST); // [Optional] Send email for every new task //MailApp.sendEmail('ittichai@gmail.com', taskTitle, taskNote); // Set to 'done' by exchanging labels thread.removeLabel(label_pending); thread.addLabel(label_done); } // Increment the processed tasks count var processedRange = sheet.getRange("B1"); processedRange.setValue(processedRange.getValue() + threads.length) } // ----------------------------------------------------- // addTask_(title, taskListId) // Create new task and insert into given tasklist // ----------------------------------------------------- function addTask_(title, message, tasklistId) { //var newTask = Tasks.newTask().setTitle(title); var newTask = Tasks.newTask(); newTask.setTitle(title); newTask.setNotes(message); Tasks.Tasks.insert(newTask, getTasklistId_(tasklistId)); } // ----------------------------------------------------- // main() // Starter function; to be scheduled regularly // ----------------------------------------------------- function main_taskconverter() { // Get the active spreadsheet and make sure the first // sheet is the active one var ss = SpreadsheetApp.getActiveSpreadsheet(); var sh = ss.setActiveSheet(ss.getSheets()[0]); // Process the pending task emails processPending_(sh); } // Strip out all HTML tags. // Source: http://stackoverflow.com/questions/8936092/remove-formatting-tags-from-string-body-of-email function getTextFromHtml(html) { return getTextFromNode(Xml.parse(html, true).getElement()); } function getTextFromNode(x) { switch(x.toString()) { case 'XmlText': return x.toXmlString(); case 'XmlElement': return x.getNodes().map(getTextFromNode).join(''); default: return ''; } }
- Make sure that the name of the task list in TASKLIST variable is changed to your primary task list name.
TASKLIST = "Ittichai's list"; LABEL_PENDING = "newtask"; LABEL_DONE = "newtaskdone";
- Integrate the script with Google API.
Pay attention to the Integrate the script with Google API in the Script Code section especially if this is your first time coding this. You will have to enable Google API service to allow access the Task API - https://developers.google.com/apps-script/articles/google_apis_reading_list. If not doing so, you will receive an error message saying "Tasks - not defined" when running the script.
- Confirm whether or not it is working by forwarding the email to yourgmail+task@gmail.com, then manually running the script.
- If it works, you can now schedule to run this script via the time-driven even trigger.
END
Notes
Here is just a quick walk through explaining what I've done differently from the original codes.
- Add the email's body in addition to email's subject.
// Grab the task data // This email's subject will be task's title. var taskTitle = thread.getFirstMessageSubject(); // This email's body will be task's body. Most email message now is HTML-based. // It is desirable to remove all HTML tags so that only actual content will be populated. // Use a custom function getTextFromHtml to strip out all HTML tags. // In addition, the string size will be limited to 3000 characters in case an email is very long. var taskNote = getTextFromHtml((thread.getMessages()[0]).getBody()).substring(0,3000);
- Most email message now is HTML-based. Without stripping out the HTML tags, the task's note will be populated with many useless tags. I use functions mentioned on this web site http://stackoverflow.com/questions/8936092/remove-formatting-tags-from-string-body-of-email to get only text message. Basically, add these two functions in the script.
function getTextFromHtml(html) { return getTextFromNode(Xml.parse(html, true).getElement()); } function getTextFromNode(x) { switch(x.toString()) { case 'XmlText': return x.toXmlString(); case 'XmlElement': return x.getNodes().map(getTextFromNode).join(''); default: return ''; } }
- Add new parameter of task's note to addTask_
// Insert the task //addTask_(taskTitle, TASKLIST); addTask_(taskTitle, taskNote, TASKLIST);
- Update the addTask_ to include setNotes
Thanks Bernard Goldberger (http://www.linkedin.com/profile/view?id=204142846) for updating script to fix some recent setNotes issue by separating setTitle and setNotes into separate lines.
function addTask_(title, message, tasklistId) { //var newTask = Tasks.newTask().setTitle(title); //var newTask = Tasks.newTask().setTitle(title).setNotes(message); // 2013-06 .setTitle concatenated with.setNotes Failed var newTask = Tasks.newTask(); newTask.setTitle(title); newTask.setNotes(message); Tasks.Tasks.insert(newTask, getTasklistId_(tasklistId)); }
- Optionally, an email can be sent out for every new task.
// [Optional] Send email for every new task MailApp.sendEmail('ittichai@gmail.com', taskTitle, taskNote);