从 Google Apps 脚本创建 Asana 任务

Creating Asana tasks from Google Apps Script

我正在尝试使用 google 应用程序脚本在 Asana 中创建任务。 我确实设法从 asana 读取(GET 方法)任何类型的信息,但是当我尝试执行 POST 时,例如在特定工作区和项目中创建新任务,它会创建任务但使用默认值忽略 json我传的数据

这是我一直在使用的代码:

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;
  }
}

我试过 body 之外的数据,数据之外的工作区,我已经更改了顺序,但它总是使用默认值创建任务。 有任何想法吗? 谢谢

尝试将您的 body 字符串化,此外,google 使用有效载荷方法,不知道这是否适用于所有 REST 请求:

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);

原本要 post 作为注释,但那里的代码不可读。

我发现有两个方面导致了这个问题,尽管这花了很多时间 反复试验和调试。

选项object格式

我认为主要问题是 'options' object 的格式。我认为它需要有主要元素 "method": "headers": 和 "payload": 而不是 "body" 和 "data" 元素。

授权 授权方面花了我很长时间才弄清楚。 对于像这样的小型应用程序,请使用个人访问令牌方法。 重要的是使用 header 中的授权选项和参数 "Bearer " + PERSONAL_ACCESS_TOKEN

PERSONAL_ACCESS_TOKEN 完全 是注册个人访问令牌时在 Asana Web 应用程序中提供给您的字符串。它不需要任何进一步的授权/交换/OAuths/刷新,也不需要任何 base 64 编码或任何冒号。

调试

我使用 Postman (https://www.getpostman.com/) 和 asana 开发人员中的资源管理器 API 参考来测试这些选项是如何工作的,特别是在授权方面。

我还设置了一个虚拟函数来创建定义的名称任务,这样我就可以在 google 脚本编辑器中访问调试器。

代码: 请注意,我已经调整了 id 等,所以你必须自己输入。

/*************************
 * 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;
    }
};