3
function getClickupTeam() {
  let response = UrlFetchApp.fetch(clickupUrl + "team", {
    "method": "GET",
    "Authorization": clickupToken,
    "muteHttpExceptions": true
  })
  Logger.log(response)
  let json = JSON.parse(response);
  Logger.log(json);
}

This URLFetchApp call returns {ECODE=OAUTH_017, err=Authorization header required} even though I am including my personal clickup token in the request. Am I missing something? Any help would be appreciated.

Tim Post
  • 33,371
  • 15
  • 110
  • 174
jdavis
  • 429
  • 6
  • 16
  • did you verify that your token credentials are correct? – Baby_Boy Jan 19 '21 at 14:41
  • also maybe check out https://stackoverflow.com/questions/60572510/apps-script-urlfetchapp-fetch-url-method-get-to-a-gzip-gets-failed-with?rq=1 – Baby_Boy Jan 19 '21 at 14:42
  • Yes, I'm not sure if I should be including another header labelled token with my personal token or if it should be the value recorded in the "Authorization" field. But it is correct. – jdavis Jan 19 '21 at 14:43
  • I would try that as it specifies "header" in the error message – Baby_Boy Jan 19 '21 at 14:45
  • That is not working. I'm not sure the exact syntax that would be required but I can't find anything in the clickup api documentation and a couple of variations all gave the same error code. – jdavis Jan 19 '21 at 16:36
  • Im still looking but i found this on clickup api documentation: `Authorization Header Required`: The authorization token was missing in the `Authorization` http header. `OAUTH_017` – Baby_Boy Jan 19 '21 at 17:20
  • what is this for? is it a web-hook or attachment or something else? – Baby_Boy Jan 19 '21 at 17:33
  • It's for auto-generation and editing of tasks. I have lots of things that have to happen at certain points (checklists added to tasks, members assigned, labels removed) that would use all 10,000 automations given per month very quickly and we can't afford to have that happen. – jdavis Jan 19 '21 at 17:37
  • one last thing, are you using team id and team url? i notice you add team to the url – Baby_Boy Jan 19 '21 at 17:39
  • Team is just the highest level object to retrieve from the api. I don't think I need the id if I'm asking the api for the team - https://jsapi.apiary.io/apis/clickup20/reference/0/teams/get-teams.html – jdavis Jan 19 '21 at 17:42

2 Answers2

4

It looks like your request is malformed (be sure to check out the reference documentation for the UrlFetchApp.fetch(url, params) method.) The Authorization header should be in an explicit headers object. Plus, you don't need to set method to GET since its the default.

Something else to keep in mind for when you're making POST requests - Google Apps Script has this funny quirk where you have to define the Content-Type header using the contentType property. If you try to set that header in the headers object if will just get overridden by the default (application/x-www-form-urlencoded I believe).

So here's how you'd set up your GET request:

function getClickupTeam() {
    let response = UrlFetchApp.fetch(clickupUrl + "team", {
        "muteHttpExceptions": true,
        "headers": {
            "Authorization": clickupToken
        }
    }
    
    console.log(response.getContentText());
    let json = JSON.parse(response.getContentText());
    
    console.log(json);
   
);

And for POST requests with a JSON payload you'd do something like this:

function getClickupTeam() {
    let response = UrlFetchApp.fetch(clickupUrl + "team", {
        "method": "POST",
        "contentType": "application/json",
        "muteHttpExceptions": true,
        "headers": {
            "Authorization": clickupToken
        },
        "payload": JSON.stringify({
            "key": "value"
        });
    }
    
    console.log(response.getContentText());
    let json = JSON.parse(response.getContentText());
    
    console.log(json);
   
);
TheAddonDepot
  • 8,408
  • 2
  • 20
  • 30
1

While doing some research on the topic through https://clickup.com/api, I stumbled across some code. There are a couple of different ones for different things, I'd recommend the first, JavaScript (as that's whats closest to what your currently doing). In a comment you said it was for editing tasks so that's what this code is aimed for.

javascript

var request = new XMLHttpRequest();

request.open('PUT', 'https://api.clickup.com/api/v1/task/{task_id}');

request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('Authorization', '"access_token"');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

var body = {
  'name': 'New Task Name',
  'content': 'New Task Content',
  'assignees': {
    'add': [
      1
    ],
    'rem': [
      2
    ]
  },
  'status': 'Closed',
  'priority': 3,
  'due_date': '1508369194377'
};

request.send(JSON.stringify(body));

curl

curl --include \
     --request PUT \
     --header "Content-Type: application/json" \
     --header "Authorization: "access_token"" \
     --data-binary "{
    \"name\": \"New Task Name\",
    \"content\": \"New Task Content\",
    \"assignees\": {
        \"add\" : [
            1
        ],
        \"rem\" : [
            2
        ]
    },
    \"status\": \"Closed\",
    \"priority\": 3,
    \"due_date\": \"1508369194377\"
}" \
'https://api.clickup.com/api/v1/task/{task_id}'

node.js

var request = require('request');

request({
  method: 'PUT',
  url: 'https://api.clickup.com/api/v1/task/{task_id}',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': '\'access_token\''
  },
  body: "{  \"name\": \"New Task Name\",  \"content\": \"New Task Content\",  \"assignees\": {    \"add\": [      1    ],    \"rem\": [      2    ]  },  \"status\": \"Closed\",  \"priority\": 3,  \"due_date\": \"1508369194377\"}"
}, function (error, response, body) {
  console.log('Status:', response.statusCode);
  console.log('Headers:', JSON.stringify(response.headers));
  console.log('Response:', body);
});

This is aimed for production let me know if you need mock server or debugging proxy

Baby_Boy
  • 346
  • 3
  • 18
  • I found this online too and it did not help me as XMLHttpRequest is not available on GAS. This is also for their v1 api which is deprecated. – jdavis Jan 19 '21 at 17:57
  • i must say I don't Know what else to try are you sure the method is get not post? – Baby_Boy Jan 19 '21 at 18:19
  • did you try with Curl? – Baby_Boy Jan 19 '21 at 19:06
  • Google apps script doesn't support curl unfortunately. I may end up just writing it in a node.js app and hosting it somewhere. – jdavis Jan 19 '21 at 21:52
  • Thanks for your help, I plus one'd your answer. I'm currently working with clickup's support team. I'll answer my own question if they're able to help me. – jdavis Jan 20 '21 at 14:28
  • Thanks for the upvote, and good luck. Sorry I couldn't help! – Baby_Boy Jan 21 '21 at 14:00