I am trying to create tasks in Asana using google apps scripts.
I do manage to read (GET method) any kind of information from asana, but when I try to do a POST like creating a new task in a specific workspace and project, it creates the task but using default values ignoring json data that I pass.
this is the code I've been using:
function createTask (taskName, wsId, projectId, asigneeId) {
var encoded = Utilities.base64Encode(asanaKey + ":");
var options = {
"method" : "POST",
"headers" : {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": "Basic " + Utilities.base64Encode(asanaKey + ":")
},
"body" : {
"data" : {
"name" : "\"" + taskName + "\"" ,
"asignee" : asigneeId,
"projects" : [projectId],
"workspace" : wsId
}
}
};
try {
var url = "https://app.asana.com/api/1.0/workspaces/" + wsId + "/tasks";
var result = UrlFetchApp.fetch(url, options);
var salida = result.getContentText();
}
catch (e) {
Logger.log(e);
var salida = "";
}
finally {
return salida;
}
}
I've tried with data outside body, workspace outside data, i've changed the order but it always create tasks with default values.
¿any ideas?
Thanks
I found two aspects that were causing the issue, though it took a great deal of
trial and error and debug.
OPTIONS object format
I think the main issue is the format of the 'options' object. I think it needs to have the main elements "method": "headers": and "payload": and not
the "body" and "data" elements.
Authoriziation
The authorisation aspect took me ages to figure out.
for small apps like this use the Personal Access Token method.
the important thing is to use the Authorization option in the header with the parameter of "Bearer " + PERSONAL_ACCESS_TOKEN
The PERSONAL_ACCESS_TOKEN is exactly the string as given to you in the Asana Web app at the time of registering a Personal Access Token. it DOES NOT need any further authorisation / exchanges / OAuths /refreshes, nor does it need any encoding in base 64 or any colons.
Debugging
I used Postman (https://www.getpostman.com/) and the explorer in the asana developers API reference to test out how the options worked, particularly around the authorisation.
I also setup a dummy function to create a defined name task so I could access the debugger in the google script editor.
CODE:
Note I have adjusted the ids etc. so you have to put your own in.
/*************************
* Asana Functions *
*************************/
// first Global constants ... Key Ids / tokens etc.
PERSONAL_ACCESS_TOKEN = "0/d3c41c435b0c3f70b399999952edee5"; // Put your unique Personal access token here
WORKSPACE_ID = "49489999934875"; // Put in the main workspace key you want to access (you can copy from asana web address)
ASSIGNEE = "jondoe@nomail.com"; // put in the e-mail addresss you use to log into asana
// ** testTask() ** is useful for using as a Debug start point. "select function" on script editor menu
// choose "testTask" then debug functionality is enabled
function testTask() {
quickTask("a quick task")
};
// ** quickTask(taskName) ** Made a short function so I could just add simple tasks easily
function quickTask(taskName) {
var newTask = {
name: taskName,
workspace: WORKSPACE_ID,
project: "", // if you have a project you like to add add it here
assignee: "me" // Me is understood by asana
};
createAsanaTask(newTask);
};
/******************************************************************************************
** createAsanaTask(task) **
************************
* creates a new asana task with information (like task name, project, notes etc.) contained in
* the object 'newTask" passed to it.
* 'task' should be of the format an object with option pairs that match the Asana task
* key parameters, as many or as few as you want.
* e.g.
* var newTask = {
* name: taskName,
* workspace: WORKSPACE_ID,
* project: "My Project", // if you have a project you like to add add it here
* assignee: "JohnDoe@madeupmail.com" // person the task should be assigned to.
* }
* you could add other info like due dates etc.
* it returns a "task" object containing all asana task elements of the one task created including the id.
*************************************************************************************************/
function createAsanaTask(task) {
// when creating an Asana task you must have at least a workspace id and an assignee
// this routine checks if you defined one in the argument you passed
if (task.workspace == null) {
task.workspace=WORKSPACE_ID
}
if (task.assignee == null) {
task.assignee="me";
}
/* first setup the "options" object with the following key elements:
*
* method: can be GET,POST typically
*
* headers: object containing header option pairs
* "Accept": "application/json", // accept JSON format
* "Content-Type": "application/json", //content I'm passing is JSON format
* "Authorization": "Bearer " + PERSONAL_ACCESS_TOKEN // authorisation
* the authorisation aspect took me ages to figure out.
* for small apps like this use the Personal Access Token method.
* the important thing is to use the Authorization option in the header with the
* parameter of "Bearer " + PERSONAL_ACCESS_TOKEN
* the PERSONAL_ACCESS_TOKEN is exactly the string as given to you in the Asana Web app at
* the time of registering a Personal Access Token. it DOES NOT need any further authorisation / exchanges
* NOR does it needo any encoding in base 64 or any colon.
*
* payload: this can be an object with option pairs required for each element to be created... in this case
* its the task elements as passed to this function in the argument "task" object.
* I found it doesn't need stringifying or anything.
*
********************************************************************************************************/
var options = {
"method": "POST",
"headers": {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": "Bearer " + PERSONAL_ACCESS_TOKEN
},
"payload": task
};
// using try to capture errors
try {
// set the base url to appropriate endpoint -
// this case is "https://app.asana.com/api/1.0" plus "/tasks"
// note workspace id or project id not in base url as they are in the payload options
// use asana API reference for the requirements for each method
var url = "https://app.asana.com/api/1.0/tasks";
// using url of endpoint and options object do a urlfetch.
// this returns an object that contains JSON data structure into the 'result' variable
// see below for sample structure
var result = UrlFetchApp.fetch(url, options);
//
var taskJSON = result.getContentText();
} catch (e) {
Logger.log(e);
return null;
} finally {
// parse the result text with JSON format to get object, then get the "data" element from that object and return it.
// this will be an object containing all the elements of the task.
return JSON.parse(taskJSON).data;
}
};
Try stringifying your body, also, google uses the method payload, dunno if this is applicable with all REST requests:
var options = {
"method" : "POST",
"headers" : {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": "Basic " + Utilities.base64Encode(asanaKey + ":")
}
}
var body = {
"data" : {
"name" : "\"" + taskName + "\"" ,
"asignee" : asigneeId,
"projects" : [projectId],
"workspace" : wsId
}
};
options.payload = JSON.stringify(body);
Was gonna post as a comment, but code is unreadeable there.
I had a few troubles doing what you are trying to do and couldn't get the other codes posted here to work, but i finally figured it out. Can't exactly remember what i changed, but you can easily use this function to create a task and get its id:
CODE:
function testTask(){
var taskName = "Test Task 2"; //Task Name
var wsId = "44492991234567"; //Workspace ID
var projectId = "9120451234567"; //Project ID
var assigneeId = "44645081234567"; //Assignee ID
var parentId = null; //Parent ID, can be null if no parent
createTask(taskName, wsId, projectId, assigneeId, parentId);
}
function createTask (taskName, wsId, projectId, assigneeId, parentId) {
var token = “access token goes here"; //your asana Personal Access Token
var bearerToken = "Bearer " + token;
var task = {
data: {
assignee : 'me',
notes : 'test',
workspace: wsId,
name : taskName,
projects : [projectId],
parent: parentId
}
};
var options = {
"method" : "POST",
"headers" : {"Authorization": bearerToken},
"contentType": 'application/json',
"payload" : JSON.stringify(task)
};
try {
var url = "https://app.asana.com/api/1.0/tasks";
var result = UrlFetchApp.fetch(url, options);
var reqReturn = result.getContentText();
Logger.log(reqReturn);
var createdTaskId = JSON.stringify(JSON.parse(reqReturn).data.id);
Logger.log(createdTaskId);
}
catch (e) {
Logger.log(e);
}
return createdTaskId;
}