asana

GAS-AsanaAPI カスタムフィールド指定でタスク生成する方法

はじめに

GASでAsanaAPIを使ってカスタムフィールドありのタスクを作成する際、
調べてもよく分からず暗中模索して困ったため、その答えを紹介します。

gidで指定する必要がある

Asanaの基本的な概念として「gid」というものがあります。
Asanaの内部IDだと認識しておけばOKです。
プロジェクトgidやユーザgidなどが存在します。

そして、カスタムフィールド1つ1つにもgidが存在します。
タスク作成時にカスタムフィールドに値を入力する場合、gidでの指定が必要です。
更にプロジェクト上でカスタムフィールドの選択肢を作成している場合、
その各選択肢にもgidが存在します。

タスク作成、APIでカスタムフィールドを操作する際は、
下記コード例のようにgidを用いて指示します。

function createTask() {
  const headers = {
    "Authorization": "Bearer " + "token"  
  };

  const payload = JSON.stringify({
    "data": {
      "workspace"    : "workspaceId",                            // ワークスペースID              
      "projects"     : ["projectId"],                            // プロジェクトID
      "name"         : "title",                                  // タスクタイトル
      "assignee"     : "assignee@mail.jp",                       // タスク担当者アドレス
      "followers"    : ["collab1@mail.jp", "collab2@mail.jp"],   // コラボレーターアドレス
      "html_notes"   : body,                                     // タスク本文html
      "due_on"       : "2024-03-30",                             // タスク期日
      "custom_fields":{1234567890:"1111111111",   // カスタムフィールドgid:選択肢gid
                       2345678901:"2222222222",   // カスタムフィールドgid:選択肢gid
                       3456789012:"text",         // カスタムフィールドgid:入力値テキスト
                       4567890123:"int"}          // カスタムフィールドgid:入力値数値
    }
  });

  const options = {
    "method"              : "post",
    "contentType"         : "application/json",
    "headers"             : headers,
    "payload"             : payload,
    "muteHttpExceptions"  : true
  };

  const response = UrlFetchApp.fetch("https://app.asana.com/api/1.0/tasks", options);

  if(JSON.parse(response.getContentText()).errors){
    throw new Error(`error:${response.getContentText()}`);
  }
  else{
    const responseJson = JSON.parse(response);
    const task_id  = responseJson.data.gid;
    const taskUrl  = `https://app.asana.com/0/プロジェクトID/${task_id}`;
    return taskUrl;
  }
}

サンプルコードではカスタムフィールド以外にも任意の属性を指定しています。
このコードを使用する場合は、必要に応じて置換してください。

カスタムフィールドのところを見てみると、
gidに対して選択肢のgidや、入力値を直接指定しているのが分かると思います。
選択式フィールドの場合はgidを、入力式フィールドの場合は直指定となります。

カスタムフィールドgidを取得するには

さて、このカスタムフィールドのgidですが、
現在Asanaのweb画面上から取得する方法はありません。

カスタムフィールドのgidを取得するには、
APIのGet a project’s custom fieldsGet a projectを使う必要があります。
前者の方がシンプルに情報取得できるため前者を例示しますが、
カスタムフィールド以外のプロジェクト情報も必要な場合は後者を使うと良いでしょう。

function getProjectCustomField(projectId){
  const baseUrl = `https://app.asana.com/api/1.0/projects/${projectId}/custom_field_settings?limit=100`;
  const options = {
                "method"              : "GET",
                "headers"             : {"Authorization": "Bearer " + token, 
                                        "accept": "application/json"
                                        },
                "muteHttpExceptions"  : true
              };
  let nextPage = null;
  let result = [];

  // ページループ
  do{
    const url = `${baseUrl}${nextPage ? `&offset=${nextPage.offset}` : ""}`;
    const singleResponse = UrlFetchApp.fetch(url, options);
    const jsonResult = JSON.parse(singleResponse);
    result = result.concat(jsonResult.data);
    nextPage = jsonResult.next_page;
  }
  while(nextPage)

  return result;
}

以下のような戻り値となります。
custom_field属性直下のgidがフィールドgidです、
typeがenumの場合、選択式フィールドである事を表しています。
選択肢はenum_optionsに格納されており、その中のgidが各選択肢のgidとなります。

{
  "data": [
    {
      "gid": "12345",
      "resource_type": "task",
      "project": {
        "gid": "12345",
        "resource_type": "task",
        "name": "Stuff to buy"
      },
      "is_important": false,
      "parent": {
        "gid": "12345",
        "resource_type": "task",
        "name": "Stuff to buy"
      },
      "custom_field": {
        "gid": "12345",
        "resource_type": "task",
        "name": "Status",
        "resource_subtype": "text",
        "type": "text",
        "enum_options": [
          {
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "enabled": true,
        "representation_type": "number",
        "id_prefix": "ID",
        "is_formula_field": false,
        "date_value": {
          "date": "2024-08-23",
          "date_time": "2024-08-23T22:00:00.000Z"
        },
        "enum_value": {
          "gid": "12345",
          "resource_type": "task",
          "name": "Low",
          "enabled": true,
          "color": "blue"
        },
        "multi_enum_values": [
          {
            "gid": "12345",
            "resource_type": "task",
            "name": "Low",
            "enabled": true,
            "color": "blue"
          }
        ],
        "number_value": 5.2,
        "text_value": "Some Value",
        "display_value": "blue",
        "description": "Development team priority",
        "precision": 2,
        "format": "custom",
        "currency_code": "EUR",
        "custom_label": "gold pieces",
        "custom_label_position": "suffix",
        "is_global_to_workspace": true,
        "has_notifications_enabled": true,
        "asana_created_field": "priority",
        "is_value_read_only": false,
        "created_by": {
          "gid": "12345",
          "resource_type": "task",
          "name": "Greg Sanchez"
        },
        "people_value": [
          {
            "gid": "12345",
            "resource_type": "task",
            "name": "Greg Sanchez"
          }
        ]
      }
    }
  ],
  "next_page": {
    "offset": "eyJ0eXAiOJiKV1iQLCJhbGciOiJIUzI1NiJ9",
    "path": "/tasks/12345/attachments?limit=2&offset=eyJ0eXAiOJiKV1iQLCJhbGciOiJIUzI1NiJ9",
    "uri": "https://app.asana.com/api/1.0/tasks/12345/attachments?limit=2&offset=eyJ0eXAiOJiKV1iQLCJhbGciOiJIUzI1NiJ9"
  }
}

さいごに

AsanaAPIにおけるカスタムフィールドへの理解は深まりましたでしょうか。
もし必要があればAsanaに関する他の記事も参照してお役立てください。
Asana APIトークンや各種IDを取得する基本的な方法を解説

GASとAsanaAPIを使って全ユーザーリストを出力するコード

はじめに

Asana管理者の方へ。全ユーザーリストの出し方をご紹介します。
概ねコピペでOKですが、ワークスペースIDやAPIトークン、シート名など
一部入力が必要な部分もあります。

ワークスペースIDやトークンの参照方法については過去記事で解説しています。
Asana APIトークンや各種IDを取得する基本的な方法を解説
必要に応じてあわせてご覧ください!

 

コード


/**
 * メインメソッド 日次トリガー設定するなど
 */
function writeSheetAsanaUsers(){
  try{
    // JSON形式で取得
    const usersJson = getAsanaUsersAll();
    
    // 二次元配列に整形
    let arr = usersJson.map(obj => ([obj.gid, obj.name, obj.email]));
    const header = ["gid","氏名","メールアドレス"];
    arr.unshift(header);

    // クリアして貼り付け
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("出力先シート名");
    sheet.getRange("A1:Z").clear(); // ご都合に合う範囲に変更してください。
    sheet.getRange(1,1,arr.length, arr[0].length).setValues(arr);

  }catch(e){
    // エラー処理 メール送信なりなんなり
    console.log(e);
    GmailApp.sendEmail("エラーメール送信先アドレス","メールタイトル",`メールbody ${e.message}`);
  }
}



/**
 * Asana全ユーザを取得
 * https://developers.asana.com/reference/getusers
 * @return {json} [{email:"str", name:"str", gid:"str"},...]
 */
function getAsanaUsersAll(){
  const workspaceId = "ワークスペースIDを入力";
  const token = "トークンを入力";

  const baseUrl = `https://app.asana.com/api/1.0/users?workspace=${workspaceId}&opt_fields=email,name&limit=100`;
  const options = {
                    "method"              : "GET",
                    "headers"             : {"Authorization": `Bearer ${token}`,
                                            "accept": "application/json"
                                            },
                    "muteHttpExceptions"  : true
                  };
  let nextPage = null;
  let result = [];

  // ページループ
  do{
    const url = `${baseUrl}${nextPage ? `&offset=${nextPage.offset}` : ""}`;
    const singleResponse = UrlFetchApp.fetch(url, options);
    const jsonResult = JSON.parse(singleResponse);
    result = result.concat(jsonResult.data);
    nextPage = jsonResult.next_page;
  }
  while(nextPage);

  return result;
}

 

簡易的な解説

まず始めにgetAsanaUsersAll関数でAsanaAPIを使用、JSON形式でユーザ情報を取得します。
リクエストURLのopt_fieldsに何を指定するかで、取得可能な値が変わります。
このAPIで取得可能な情報で有用なものはemailぐらいかなと思いemailを指定していますが、
取得可能な項目の詳細についてはは公式ドキュメントをご覧ください。

また、1回のリクエストで取得可能なユーザ数が100件ですので、
do-while文で全員分を取得できるまでループ実行している点もポイントです。

取得した情報は配列のmapメソッドで二次元配列に整形、貼り付けしています。
mapメソッドは非常に便利ですので分からない方は習得をオススメします。
mapメソッドについてはこちらの記事もご参考にどうぞ。
GAS初心者がfor文やif文の次に学ぶと急激にレベルアップする技術7選

尚、当コードはコピペしてもらう事を前提としているほか、
トリガーで毎日データを更新するような想定をしています。
貼り付け前のシートクリア、try-catch文でエラー時の通知は、それらの前提のための機能です。
単純に1回出力したいだけなら不要かと思います。要不要に応じて削ってください。

 

さいごに

無事に出力できましたでしょうか。
過去記事も参考にしながら、ぜひトライしてみてくださいね。

Asana APIトークンや各種IDを取得する基本的な方法を解説

はじめに

AsanaAPIを使う時など、各種必要情報をどう取得するか毎回忘れてしまうため、
ここに各種情報をまとめました。
定期的に使いそうな方はぜひブックマークして活用してください。
尚、当記事で参照しているのは全てAsanaのweb画面となります。

ユーザID

ホーム画面のURL末尾の16桁番号がユーザGIDとなります。
(サイドバーの「ホーム」からホーム画面へ遷移できます。)
これがAsanaシステムの内部ユーザIDです。
APIでユーザ情報を取得する際、「gid」として表示される、
ワークスペース内一意のIDとなります。

 

タスクID

タスクを選択している際のURLから取得できます。
URL内に16桁の数値が2つ表示されていると思いますが、
URL末尾側の16桁がタスクIDとなります。
タスクIDを要するAPIを実行する際など、このIDを使います。
タスク情報取得系のAPIからも取得可能です。

プロジェクトID

プロジェクトやタスクを選択している時のURLから取得できます。
プロジェクトやタスク選択時のURL内、1つ目の16桁数値がプロジェクトIDです。
プロジェクトIDを要するAPIも多く、このIDが必要となります。

ワークスペースID

Asanaへログインした状態で、以下のURLにアクセスしてください。
https://app.asana.com/api/1.0/workspaces
ご自身のアカウントが利用可能なワークスペース情報を参照可能です。
以下のような情報が表示されます。各オブジェクトごとの「gid」がワークスペースIDです。


{
    "data": [
        {
            "gid": "12345678901234",
            "name": "ワークスペース名称",
            "resource_type": "workspace"
        }
    ]
}

APIトークン

Asana画面上右上から設定を開きます。
設定画面上、「アプリ」メニューから「デベロッパーアプリを管理」を選択します。
ページ内に「個人アクセストークン」という箇所がありますので、
ここでトークンの新規作成が可能です。
トークンは作成時のみ参照可能です。作成時に必ずメモしておきましょう。

最後に

情報精度的には公式ドキュメントやフォーラムを参照するのがベストですが、
英文が煩わしい事も多く、お役立て頂けると幸いです。
万一、当記事の情報が古くなっているとお気付きの場合はコメントにてお知らせください。