Create Google Tasks by sending email to Google GMail
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.
Follow this step-by-step of this page. http://www.pipetree.com/qmacro/blog/2011/10/automated-email-to-task-mechanism-with-google-apps-script/
This is just an overview of what happens:
- Create Gmail new labels - newtask and newtaskdone.
- Create Gmail filter based on newtask label.
- Create script from Google Spreadsheet. Make sure that the name of the task list in TASKLIST variable is changed to yours.
- Integrate the script with Google API.
- Schedule it via the time-driven even trigger.
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.
In addition to above sample, I'd like to add the email's body into the G! task's note.
Here is what I do:
- Add a new variable to grab the email's body
// 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
function addTask_(title, message, tasklistId) {
//var newTask = Tasks.newTask().setTitle(title);
var newTask = Tasks.newTask().setTitle(title).setNotes(message);
Tasks.Tasks.insert(newTask, getTasklistId_(tasklistId));
}
This is the whole modified script.
// Source: http://www.pipetree.com/qmacro/blog/2011/10/automated-email-to-task-mechanism-with-google-apps-script/
// -----------------------------------------------------
// Globals, contants
// -----------------------------------------------------
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);
// 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().setTitle(title).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 '';
}
}