Wrike APIの叩き方

# 概要
- タスク管理ツール[Wrike](https://www.wrike.com/ja/)のAPIの叩き方について紹介します
- Curlでの叩き方とGASでの叩き方を紹介します
- APIを外部から使えるようになることで、Slackにタスク統計を通知したり、スプレッドシートにタスク状況をまとめることができるようになります

# 公式ドキュメント
- [Take a revolutionary approach to integration with Wrike](https://developers.wrike.com/)

# Access Tokenの取得
<img width="289" alt="スクリーンショット 2020-07-23 13.14.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/c28af199-c7ce-e3d1-88f8-5dabf3e7f0b5.png">
Wrikeにログインし、右上のプロフィールを開くと`アプリ＆統合`があるので開きます

<img width="834" alt="スクリーンショット 2020-07-23 13.17.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/96588c4f-5485-081f-2793-d755662dc347.png">
APIを開き、適当なアプリ名を入れて`新規作成`をします

<img width="552" alt="スクリーンショット 2020-07-23 13.18.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/c7bafc8c-3dee-bad6-b9f3-361f65f1b68b.png">
アプリを作成したらページの下部に`永久アクセス・トークン`の項目があるので
`トークンの作成`をクリックしトークンを作成します。
ここで表示されたトークンを保存しておきます

# APIを叩いてみる
取得したトークンを使ってAPIを叩いてみましょう

## Curl
```
curl -X GET -H "Authorization: bearer ACCESSTOKEN" https://www.wrike.com/api/v4/contacts?me=true
```

`ACCESSTOKEN`の部分に取得したトークンを当てはめて叩いてください
こんな感じのJSONが返ってくれば成功です

```responce.json
{
  "kind": "contacts",
  "data": [
    {
      "id": "KUAJ25LC",
      "firstName": "Test",
      "lastName": "User",
      "type": "Person",
      "profiles": [
        {
          "accountId": "IEAGIITR",
          "email": "test.user@myapp.com",
          "role": "User",
          "external": false,
          "admin": false,
          "owner": true
        }
      ],
      "avatarUrl": "https://www.wrike.com/avatars//7E/A2/Box_ffdf2a2e_84-84_v1.png",
      "timezone": "Europe/Moscow",
      "locale": "en",
      "deleted": false,
      "me": true
    }
  ]
}
```

## Google Apps Acript
GASの場合はこんな感じです
API関数に関しては[こちら](https://qiita.com/takoratta/items/4a0f3a5f9bb75c0646dc)の記事を参考にさせていただきました。

```javascript

function myFunction() 
{
  var responce = API('https://www.wrike.com/api/v4/contacts?me=true','GET',null);
  Logger.log(responce);
}

function API(url, method, payload) 
{
  var accessToken = 'ACCESSTOKEN'; // 入手したアクセストークン
  var headers = 
  {
    'Authorization': 'Bearer '+ accessToken
  };
  
  var options = 
  {
    'method': method,
    'headers': headers,
    'payload': payload,
  };

  var response = UrlFetchApp.fetch(url, options);
  return response;
}
```

# API紹介
ここからは私が実運用で使ったAPIを紹介していきます

## [Folders & Projects](https://developers.wrike.com/api/v4/folders-projects/)

Taskを取得するのにTask一覧を取得してフィルタしてもいいのですが、所定のフォルダやプロジェクトに属しているタスクを取得するユースケースが多いのではないでしょうか。
まずは、フォルダのIDを取得するためにフォルダ一覧を取得します

```
curl -X GET -H "Authorization: bearer ACCESSTOKEN" https://www.wrike.com/api/v4/folders
```

フォルダ一覧がJSONで返ってきます。
この中からタスクを検索したいフォルダの`id`を探します

```responce.json
{
  "kind": "folderTree",
  "data": [
    {
      "id": "IEABSJXKI7777777",
      "title": "Root",
      "children": [
        "IEABSJXKI4ARXXB5",
        "IEABSJXKI4ARXXBS",
        "IEABSJXKI4ARXXBQ"
      ],
      "childIds": [
        "IEABSJXKI4ARXXB5",
        "IEABSJXKI4ARXXBS",
        "IEABSJXKI4ARXXBQ"
      ],
      "scope": "WsRoot"
    },
    {
      "id": "IEABSJXKI7777776",
      "title": "Recycle Bin",
      "children": [],
      "childIds": [],
      "scope": "RbRoot"
    },
    {
      "id": "IEABSJXKI4ARXXCH",
      "title": "Modified Space Title",
      "children": [],
      "childIds": [],
      "scope": "WsFolder"
    }
  ]
}
```

このIDを使ってフォルダの詳細情報を取得することもできます

```
curl -X GET -H "Authorization: bearer ACCESSTOKEN" https://www.wrike.com/api/v4/folders/IEABSJXKI4ARXXCH
```

こうするとフォルダの`permalink`が取得できるので、同名のフォルダがある場合など、本当に取得したいフォルダなのか判別することができます

## [Tasks](https://developers.wrike.com/api/v4/tasks/)
このAPIが最も使うのではないでしょうか
各タスクの情報を取得できます

全タスクの取得は↓です。取得上限があるようなので、あまり使うことはないんじゃないかなと思います

```
curl -X GET -H "Authorization: bearer ACCESSTOKEN" https://www.wrike.com/api/v4/tasks
```


`/folders/{folderId}/tasks` で特定のフォルダ配下のタスクを取得できます

```
curl -X GET -H "Authorization: bearer ACCESSTOKEN" https://www.wrike.com/api/v4/folders/IEABSJXKI4ARXXCH/tasks
```

タスクのレスポンスはこんな感じです

```responce.json
{
  "kind": "tasks",
  "data": [
    {
      "id": "IEABSJXKKQARXXB2",
      "accountId": "IEABSJXK",
      "title": "Test task",
      "description": "Test task description
",
      "briefDescription": "Test task description",
      "parentIds": [
        "IEABSJXKI4ARXXBS",
        "IEABSJXKI4ARXXBU"
      ],
      "superParentIds": [
        "IEABSJXKI4ARXXBT"
      ],
      "sharedIds": [
        "KUGE2QYB",
        "KUGE2QYC"
      ],
      "responsibleIds": [
        "KUGE2QYB"
      ],
      "status": "Active",
      "importance": "High",
      "createdDate": "2020-06-19T09:36:58Z",
      "updatedDate": "2020-06-19T09:37:15Z",
      "dates": {
        "type": "Planned",
        "duration": 2880,
        "start": "2020-06-15T09:00:00",
        "due": "2020-06-20T17:00:00"
      },
      "scope": "WsTask",
      "authorIds": [
        "KUGE2QYB"
      ],
      "customStatusId": "IEABSJXKJMAAAAAA",
      "hasAttachments": false,
      "attachmentCount": 0,
      "permalink": "https://www.wrike.com/open.htm?id=18603066",
      "priority": "00e0c4008000000000003e00",
      "superTaskIds": [
        "IEABSJXKKQARXXBZ"
      ],
      "subTaskIds": [
        "IEABSJXKKQARXXB3"
      ],
      "dependencyIds": [
        "IEABSJXKIUARXXBZKMARXXB2"
      ],
      "metadata": [
        {
          "key": "testMetaKey",
          "value": "testMetaValue"
        }
      ],
      "customFields": [
        {
          "id": "IEABSJXKJUAANCRD",
          "value": "testValue"
        }
      ]
    },
    {
      "id": "IEABSJXKKQARXXBZ",
      "accountId": "IEABSJXK",
      "title": "Test task",
      "description": "",
      "briefDescription": "",
      "parentIds": [
        "IEABSJXKI4ARXXBT"
      ],
      "superParentIds": [],
      "sharedIds": [
        "KUGE2QYB",
        "KUGE2QYC"
      ],
      "responsibleIds": [],
      "status": "Active",
      "importance": "Normal",
      "createdDate": "2020-06-19T09:36:57Z",
      "updatedDate": "2020-06-19T09:37:12Z",
      "dates": {
        "type": "Planned",
        "duration": 2880,
        "start": "2020-06-15T09:00:00",
        "due": "2020-06-22T17:00:00"
      },
      "scope": "WsTask",
      "authorIds": [
        "KUGE2QYB"
      ],
      "customStatusId": "IEABSJXKJMAAAAAA",
      "hasAttachments": false,
      "attachmentCount": 0,
      "permalink": "https://www.wrike.com/open.htm?id=18603065",
      "priority": "00e0c4008000000000003c00",
      "superTaskIds": [],
      "subTaskIds": [
        "IEABSJXKKQARXXB2"
      ],
      "dependencyIds": [
        "IEABSJXKIUARXXBZKMARXXB2",
        "IEABSJXKIUARXXB3KMARXXBZ"
      ],
      "metadata": [
        {
          "key": "testMetaKey",
          "value": "testMetaValue"
        }
      ],
      "customFields": [
        {
          "id": "IEABSJXKJUAANCRD",
          "value": "testValue"
        },
        {
          "id": "IEABSJXKJUAANCRE",
          "value": "testValue"
        }
      ]
    }
  ]
}
```

## [Workflows](https://developers.wrike.com/api/v4/workflows/)
タスクのステータスにカスタムステータスを使っている場合、名前が簡単に取得できません。
`"customStatusId": "IEABSJXKJMAAAAAA",`
のように`customStatusId`という形で表現されています。
Workflow APIを使用することで、`customStatusId`を取得できます

```
curl -X GET -H "Authorization: bearer ACCESSTOKEN" https://www.wrike.com/api/v4/workflows
```

```responce.json
{
  "kind": "workflows",
  "data": [
    {
      "id": "IEABSJXKK776NWIW",
      "name": "Default Workflow",
      "standard": true,
      "hidden": false,
      "customStatuses": [
        {
          "id": "IEABSJXKJMAAAAAA",
          "name": "New",
          "standardName": true,
          "color": "Blue",
          "standard": true,
          "group": "Active",
          "hidden": false
        },
        {
          "id": "IEABSJXKJMANHLUW",
          "name": "In Progress",
          "standardName": true,
          "color": "Turquoise",
          "standard": false,
          "group": "Active",
          "hidden": false
        },
        {
          "id": "IEABSJXKJMAAAAAB",
          "name": "Completed",
          "standardName": true,
          "color": "Green",
          "standard": true,
          "group": "Completed",
          "hidden": false
        }
      ]
    },
    {
      "id": "IEABSJXKK4ANHLVA",
      "name": "New workflow",
      "standard": false,
      "hidden": false,
      "customStatuses": [
        {
          "id": "IEABSJXKJMANHLVA",
          "name": "Active",
          "standardName": false,
          "color": "Blue",
          "standard": false,
          "group": "Active",
          "hidden": false
        },
        {
          "id": "IEABSJXKJMANHLVK",
          "name": "In design",
          "standardName": false,
          "color": "Green",
          "standard": false,
          "group": "Active",
          "hidden": false
        },
        {
          "id": "IEABSJXKJMANHLVB",
          "name": "Completed",
          "standardName": false,
          "color": "Green",
          "standard": false,
          "group": "Completed",
          "hidden": false
        }
      ]
    }
  ]
}
```

これでカスタムステータスもIDが取得できるので、取得したタスクからステータスを使って集計ができるようになります。

# 最後に
これまでみてきた例は全てGETでしたが、POSTを使ってタスクを登録したりもできます。是非活用してみてください