Search code examples
javascriptgoogle-apps-scripttodoist

Invalid CSRF token in the Todoist SYNC API integrated with Google Apps Scrips


What I'm trying to accomplish here is fetching all the tasks for the day and putting them in a Google Sheets file, so that I can track my progress. I tried mimicking a cURL request (the sample one for all projects) and after failing a few attempts on my own, I tried following this solution, but no luck so far.

This is my version of the code:

function myFunction() {
  var apiURL = "https://todoist.com/API/v9/sync";
  var queryString = "?token=<my_token>&sync_token=%27*%27&resource_types=[%22projects%22]";

  //Get params
  var fetchParameters = {};
  fetchParameters.method = 'get';
  fetchParameters.contentType = 'x-www-form-urlencoded';
  fetchParameters.muteHttpExceptions = true;

  //make request and return
  var response = UrlFetchApp.fetch(apiURL + queryString, fetchParameters);
  var syncData = JSON.parse(response.getContentText());
  Logger.log(syncData);
  return(syncData);
}

I'm getting this error:

{
    error_tag = AUTH_INVALID_CSRF_TOKEN,
    error_extra = {
        access_type = web_session,
        retry_after=2.0,
        event_id = f187e5d823184fd0997935e031b017ec
    },
    error_code = 410.0,
    http_code = 403.0,
    error = Invalid CSRF token
}

Can anyone help me please?

Edit: Here’s the API documentation. Sorry for the delay


Solution

  • You're missing the API token in your request. It's supposed to go in the Authorization header, and it appears that you're adding it as the token= parameter in your URL, but the Todoist documentation doesn't say anything about adding it as a URL parameter:

    [You need] an authorization header containing the user's API token [...] You can find your token from the Todoist Web app, at Todoist Settings -> Integrations -> API token.

    So assuming that you already have your token from their integrations page, try to add it to the Authorization header like this:

      fetchParameters.headers = { 'Authorization':' Bearer '+'<YOUR_TOKEN>'}
    

    Modified code:

    function myFunction() {
      var apiURL = "https://todoist.com/API/v9/sync";
      var queryString = "?sync_token=%27*%27&resource_types=[%22projects%22]";
    
      //Get params
      var fetchParameters = {};
      fetchParameters.method = 'get';
      fetchParameters.contentType = 'x-www-form-urlencoded';
      fetchParameters.muteHttpExceptions = true;
      fetchParameters.headers = { 'Authorization':' Bearer '+'<YOUR_TOKEN>'}
    
      //make request and return
    
      var response = UrlFetchApp.fetch(apiURL + queryString, fetchParameters);
      var syncData = JSON.parse(response.getContentText());
      Logger.log(syncData);
      return(syncData);
    }