GASでBacklogの期限切れチケットを定時に自動で拾いChatworkに通知する

## やりたいこと

タイトルの通りです。（いわゆるBacklog警察）

### 想定読者
* GAS（GoogleAppsScript）やWebAPIについて、ある程度知識をもっていること
* Backlogユーザーであること
* ChatWorkユーザーであること

## 処理概要
* ある特定のBacklogプロジェクトの期限切れコンテンツをBacklogAPI経由で取得します。
* 毎日定時に特定のChatWorkグループに取得した情報を通知します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131112/e4066706-40ad-8b29-acb1-b3cb5576f27e.png)

## 参考にさせていただいた記事とメモ
[GASでつくる #Backlog 警察 - 暗黒エンジニアブログ](https://inet-engineer.hatenablog.com/entry/2018/12/26/092016)
スクリプトのベースはこちらの記事を参考にさせていただきました。ありがとうございます。

[課題一覧の取得 | Backlog Developer API | Nulab](https://developer.nulab.com/ja/docs/backlog/api/2/get-issue-list/#%E8%AA%B2%E9%A1%8C%E4%B8%80%E8%A6%A7%E3%81%AE%E5%8F%96%E5%BE%97)
本家のサイト。細かいAPI仕様やクエリー文字列の作り方はこちらで。

[Backlog APIを使ってみた - Qiita](https://qiita.com/mako2kano/items/fd4c6c397b2d8db4f862)
BacklogAPIのチケット検索APIを利用する際に各プロジェクトIDを指定する必要がるのですが、その探し方はこちらで見つけました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131112/0da5b955-0d17-2ab1-91bc-3de7e0246aee.png)

[【GAS】Backlogの残タスク（課題チケット）をGASで取得してチャットワークに流す - Qiita](https://qiita.com/kingpanda/items/44667f2ddc39e760ea8b)
後で見つけたのですが、こちらで良かったのかもしれません。今回はスプレッドシートへの転記は不要だったので一旦（汗）

## スクリプト
もし不手際あれば、どうか優しくご指導ください:relaxed:

```javascript
function BacklogPolice() {
  var response = fetchBacklogIssues();
  console.log(response.length);
  postChatwork(JSON.parse(response));
}

var backlogNamespace = 'XXX';//お使いのBacklogのネームスペースを入れてください
var backlogUrl = 'https://' + backlogNamespace + '.backlog.jp/';

function fetchBacklogIssues() {
  var baseUrl = backlogUrl + 'api/v2/issues';
  var apiKey = 'XXXXXX'//BacklogのAPIキーを入れて下さい
  // 取得対象のプロジェクトIDのリストを指定
  var projectIds = [X];//対象のプロジェクトIDを入れて下さい
  var statusIds = [0, 1, 2, 3];
  var sysdate = new Date();
  sysdate.setDate(sysdate.getDate() - 1);
  var params = {
    'apiKey': apiKey,
    'dueDateUntil': formatDate(sysdate)
  };
  for (var i = 0; i < projectIds.length; i++) {
    params['projectId[' + i + ']'] = projectIds[i];
  }
  for (var i = 0; i < statusIds.length; i++) {
    params['statusId[' + i + ']'] = statusIds[i];
  }  
  var paramString = '';
  for (var key in params) {
    if (0 < paramString.length) {
      paramString += '&';
    }
    paramString += key + '=' + params[key];
  }
//  paramString += '&sort=assignee&dueDate&order=true';//期限日順
  paramString += '&sort=assignee';//担当者順

  return UrlFetchApp.fetch(baseUrl + '?' + paramString);
}

function postChatwork(issues) {
  if (issues.length <= 0) {
    return;
  }
  console.log(issues.length);
  var token = 'XXXXXXXXXXXX'; // ここにトークンを入力してください
  var roomId = 'XXXXXXXXXX'; // ここに投稿したい部屋のIDを入力してください
  var subject = 'Backlogのタスクが期限切れになっています！速やかにタスクを処理するか、期限日を調整してください。'//この辺はご自由に
  var body  = '[info][title]' + subject + '[/title]' + createPostMessage(issues) + '[/info]';
  var payload = {
    'body': body
  }
  var headers = {
    'X-ChatWorkToken': token
  }
  var options = {
    'method' : 'POST',
    'payload' : payload,
    'headers' : headers
  }
  var url = 'https://api.chatwork.com/v2/rooms/' + roomId + '/messages';
  UrlFetchApp.fetch(url, options);
}


function createPostMessage(issues) {
  var message = '';
  for (var i = 0; i < issues.length; i++) {
    var issue = issues[i];
    message += formatDate(new Date(issue.dueDate)) + ', ';
    message += issue.assignee.name + ', ';
    message += '[' + issue.status.name + '], ';
    message += issue.summary+ ', ';
    message += backlogUrl + 'view/' + issue.issueKey   + '\n[hr]\n';
  }
  return message;
}

function formatDate(date) {
  var format = 'YYYY-MM-DD';
  format = format.replace(/YYYY/g, date.getFullYear());
  format = format.replace(/MM/g, ('0' + (date.getMonth() + 1)).slice(-2));
  format = format.replace(/DD/g, ('0' + date.getDate()).slice(-2));
  return format;
}
```
## GASトリガーへの設定（スケジュール設定）
[GASでQiitaOrganizationメンバーの新規投稿を自動で拾いChatworkに通知する - Qiita](https://qiita.com/yasuoyasuo/items/75273bf60b896c634ec2)
に書いた手順とほぼ同じです。今回は毎朝6~7時頃に仕込みました。

## 最後に
やっぱりGASは便利ですね！