3

How do you set the due date for a task with the google tasks service in apps script?

Tasks Service

Trying to set this value to a given date, but this seems to only update the local value not the server value as tehhowch suggests

task.due = new Date();

How do you update the server? Here is what I tried

var x = {
    due: new Date()
};
Tasks.Tasks.update(x, "MDE2NzI3NTAzNjc5NTQ1ODY5MTY6MDow", task);

but it throws the error

Invalid value for: Invalid format: "Tue Apr 10 20:45:26 GMT-04:00 2018"

Completed Project

I used this code to create this project for keeping Google Tasks up to date:

Keep Google Tasks Updated

https://github.com/CTOverton/Keep-Google-Tasks-Updated

CTOverton
  • 616
  • 2
  • 9
  • 20
  • "It doesn't work" is not a problem statement. What errors do you get? What behavior occurs? What behavior should occur? What specific research have you uncovered? Are there other people who have encountered this issue? What do you do with `task` object after you run the following line? https://stackoverflow.com/help/how-to-ask – tehhowch Apr 10 '18 at 23:13
  • My guess is you are successfully modifying the local representation of the resource, but fail to update the server with the new resource. See https://developers.google.com/google-apps/tasks/v1/reference/tasks/update – tehhowch Apr 10 '18 at 23:16
  • Thank you, I have revised my question and tried what you suggested. Still not totally sure how you use the data you have to update the server. Could you maybe offer an example? – CTOverton Apr 11 '18 at 00:46

2 Answers2

3

In accordance with the Google Tasks API documentation for the Task resource, the due parameter must be an RFC 3339 timestamp. So instead of "Tue Apr 10 20:45:26 GMT-04:00 2018" it should be "2018-04-11T0:45:26.000Z". See related question: Generate an RFC 3339 timestamp similar to Google Tasks API?

This is the same format used by other datetime properties of the task, so if one were to log the task:

console.log(Tasks.Tasks.get(listId, taskId));

Then the due, completed and updated properties, if present, would indicate the required format.

From a native Javascript Date in Google Apps Script, this is easiest done as:

function getExtension(listId, taskId) {
  var now = new Date();
  var deadline = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 7));
  var newTask = {
    due: Utilities.formatDate(deadline, "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'")
  };
  // Since we supply only a partial resource, call .patch() rather than .update()
  Tasks.Tasks.patch(newTask, listId, taskId);
}
Community
  • 1
  • 1
tehhowch
  • 9,645
  • 4
  • 24
  • 42
  • Thanks for that example. That was helpful – Cooper Apr 11 '18 at 02:48
  • Perfect! Thank you so much! – CTOverton Apr 11 '18 at 17:15
  • It is worth noting that at the time of writing: "The due date only records date information; the time portion of the timestamp is discarded when setting the due date. It isn't possible to read or write the time that a task is due via the API". See https://developers.google.com/tasks/reference/rest/v1/tasks – zr0gravity7 Dec 19 '21 at 07:05
1

Go ahead and give @tehhowch the check but here's a routine made up from the tutorials found in the Task API which is found here which goes through all of your tasks and adds one day to their due date if their current due date is in the past. I've never used the Task API before so the tehhowch's getExtension example was very helpful.

function addOneDayToDueDates(){
  var seconds=1000;
  var minutes=60*seconds;
  var hours=60*minutes;
  var days=24*hours;//this is just my simple minded way of get the millisecond in a day
  var nowValue=new Date().valueOf();
  var taskLists=Tasks.Tasklists.list();
  if(taskLists.items){//loop through all lists
    for(var i=0;i<taskLists.items.length;i++){
      var taskList=taskLists.items[i];
      var tasks=Tasks.Tasks.list(taskList.id);
      if(tasks.items){
        for(var j=0;j<tasks.items.length;j++){//loop through all task in list
          Logger.log('i=%s,j=%s\n',i,j);
          var task=tasks.items[j];
          var dueValue=new Date(task.due).valueOf();
          if(dueValue<nowValue){//date comparison
            var newDue = new Date(new Date(task.due).valueOf() + 1*days);
            Logger.log('newDue=%s,Due=%s',newDue,task.due);
            var newTask = {due: Utilities.formatDate(newDue, "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'")};
            Tasks.Tasks.patch(newTask, taskList.id, task.id);
          }
        }
      }
    }
  }
}

@tehhowch I spent some time trying to use the pageToken idea you suggested. I was finally able to see the iterations goto to two after getting upto about 350 tasks spread over 35 lists.

Here's my code: (btw I wish the Apps Script documentation was a little more user friendly. I'm using this reference page and the API Explorer to try to figure it all out. If you see any obvious errors I'd appreciate a comment as I'm always trying to learn more)

 function listTasks() {
  var taskToken;
  var iteration=0;
  var opts={pageToken:taskToken,maxResults:100};
  do{
    iteration++;
    var myLists=Tasks.Tasklists.list(opts)
    if(myLists.items){
      for(var i=0;i<myLists.items.length;i++){
        var item=myLists.items[i];
        Logger.log(item.title + '\n' + item.id + '\n');
        var myTasks=Tasks.Tasks.list(item.id)
        if(myTasks.items){
          for(var j=0;j<myTasks.items.length;j++){
            Logger.log(myTasks.items[j].title + '\n');
          }
        }else{
          Logger.log('No tasks for ' + item.title + '\n');
        }
      }
    }
    Logger.log('Get Page Token ' + 'Iterations: ' + iteration);
    opts.pageToken=myLists.nextPageToken;
  }while(opts.pageToken);
  Logger.log('End of Function');
}
Cooper
  • 59,616
  • 6
  • 23
  • 54
  • As a note, the `.list()` methods do not return all items in a single call, just the first page (unless you ask for a different page via optional `pageToken` parameter). – tehhowch Apr 11 '18 at 17:22
  • @tehhowch Thanks for that comment. I don't use tasks myself so my example only had two tasks total. So that will complicate the code quite a bit. – Cooper Apr 11 '18 at 19:32
  • @Cooper it's not too bad - call `.list(opts)` in a `do {...} while (opts.pageToken);` loop, and aggregate the result's `.items` into an object of your choice. Then set the `opts.pageToken` to `.nextPageToken`. – tehhowch Apr 11 '18 at 21:33
  • @tehhowch I came back to this to try to implement your suggestion, but everything continues to complete in one path through the loop. I've created about 30 tasks in 3 different lists. Perhaps I need a lot more...don't know. I'd appreciate a look when you have time. – Cooper Apr 21 '18 at 23:07
  • @Cooper max page size is usually 20-100 items. If you want to test the loop, set the `maxResults` to 1 – tehhowch Apr 22 '18 at 11:23
  • Good idea. I didn’t think about that. – Cooper Apr 22 '18 at 13:25
  • Wow. I'll remember that. The pages iterations go way up. – Cooper Apr 22 '18 at 16:26