Google Apps ScriptでHipChat REST API V2にリクエストを通してチャットにKPIレポートを送る

以前、Apps ScriptからSlackにKPIメッセージを送っていたのですが、別プロジェクトでHipChatででも送りたくなったのでメモを記載しておきます。

# はじめに

メッセージを送るにはTokenが入ります。[API access Tokenには各種ある](https://developer.atlassian.com/hipchat/guide/hipchat-rest-api)のですが、今回はpersonal access tokenを使います。[ここのリンク](https://www.hipchat.com/account/api)からCreate new tokenで、「Send Message」と「Send Notification」のアクセストークンを作ります。

![image](https://qiita-image-store.s3.amazonaws.com/0/30079/61549240-6c2a-7b4d-e64b-05a5d33eda72.png)

# [Send Message API](https://www.hipchat.com/docs/apiv2/method/send_message)

簡易的なメッセージを送るためのAPIです。指定できるのはメッセージのみで1~1000文字までです。
送信すると以下のようになります。

![image](https://qiita-image-store.s3.amazonaws.com/0/30079/d931b9e4-62da-b46b-cd1f-ce29f7bc491c.png)

Apps Scriptのコードは以下となります。```Send Message```のほうのTokenを使います。

```js
function sendMessage() {
  var room_id_or_name = "bot_test";
  var params = {
    "contentType" : "application/json",
    "method": "post",
    'payload' : JSON.stringify({"message": "test"})
  };
  var responseString = UrlFetchApp.fetch(getMessageRequestURL(room_id_or_name), params).getContentText();
  Logger.log(responseString);
}

function getMessageRequestURL(room_id_or_name){
  var authToken = "xxx";
  var url = "http://api.hipchat.com/v2/room/" + room_id_or_name + "/message";
  return url + '?auth_token=' + authToken;
}
```

# [Send Room Notification API](https://www.hipchat.com/docs/apiv2/method/send_room_notification)

リッチなフォーマットのメッセージが送れます。各メッセージのサンプルは[Sending Message](https://developer.atlassian.com/hipchat/guide/sending-messages)のリンクにあります。

messageは1-10000文字までです。TokenはNotification用のを使います。

## TextのNotification

まずはTextで送ってみます。デフォルトで黄色のcolorがついています。

![image](https://qiita-image-store.s3.amazonaws.com/0/30079/631195cf-6556-8ba7-8b6b-e496c7d3bb4d.png)

コードは以下です。

```js

function sendNotification() {
  var room_id_or_name = "bot_test";
  var params = {
    "contentType" : "application/json",
    "method": "post",
    'payload' : JSON.stringify({"message": "test"})
  };
  var responseString = UrlFetchApp.fetch(getNotificationUrl(room_id_or_name), params).getContentText();
  Logger.log(responseString);
}

function getNotificationUrl(room_id_or_name) {
  var authToken = "xxx";
  var url = "http://api.hipchat.com/v2/room/" + room_id_or_name + "/notification";
  return url + '?auth_token=' + authToken;
}
```

## HTMLのNotification

KPIを送る事を想定して、HTMLのテーブルを使って送ってみます。
以下のような「レポート」シートがGoogleスプレッドシートにあるとします。

![image](https://qiita-image-store.s3.amazonaws.com/0/30079/3e43320f-d413-35f8-84af-304c91a1e98a.png)

結果は以下のようになりました。Slackではテーブルで出せないので、HipChatのほうがいい感じにだせます。

![image](https://qiita-image-store.s3.amazonaws.com/0/30079/cd19b875-796b-a533-8df7-bec832ba45ec.png)

以下のコードで実行できます。tokenとssID(スプレッドシートのID)は適当なものにしてください。

```js
var ssId = 'xxx';

function sendNotification() {
  var room_id_or_name = "bot_test";
  var params = {
    "contentType" : "application/json",
    "message_format": "html",
    "method": "post",
    'payload' : JSON.stringify({"message": getHtmlTable()})
  };
  var responseString = UrlFetchApp.fetch(getNotificationUrl(room_id_or_name), params).getContentText();
  Logger.log(responseString);
}

function getNotificationUrl(room_id_or_name) {
  var authToken = "yyy";
  var url = "http://api.hipchat.com/v2/room/" + room_id_or_name + "/notification";
  return url + '?auth_token=' + authToken;
}

function getHtmlTable() {
  var sheetName = 'レポート';
  var sheet = SpreadsheetApp.openById(ssId).getSheetByName(sheetName);
  var data = sheet.getSheetValues(1, 1, sheet.getMaxRows(), 3)
  var kpi_date = sheet.getRange(1, 2).getValue();
  var msg = "KPIレポート";
  msg += "<table>"
  
  for (var i = 0; i < data.length; i++) {
    var row_msg = "";
    for (var j = 0; j < data[i].length; j++) {
      var value = data[i][j];
      if (value == '' && i != 0) continue;
      if (Number(value) === value && value % 1 !== 0) {
        value = (value * 100).toFixed(2) + "%"; 
      }
      if (value instanceof Date) {
        value = formatDate(value, "MM月DD日");
      }
      if (j == 0 || j == 1 || j == 2) { // 2, 3列目
        if (typeof value === 'string') {
          value = value.replace(/ /g, "　");          
        }
        var output = HtmlService.createHtmlOutput();
        output.appendUntrusted(value);
        if (i == 0) {
          row_msg += '<th>' + output.getContent() + "</th>";
        } else {
          row_msg += '<td>' + output.getContent() + "</td>";
        }
      }
    }
    msg += "<tr>" + row_msg + "</tr>";      
  }
  
  msg += "</table>"
  msg = msg.replace(/<tr><\/tr>/gi, "");
  Logger.log(msg);
  return msg;
}

function formatDate(date, format) {
  if (!format) format = 'YYYY-MM-DD hh:mm:ss.SSS';
  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));
  format = format.replace(/hh/g, ('0' + date.getHours()).slice(-2));
  format = format.replace(/mm/g, ('0' + date.getMinutes()).slice(-2));
  format = format.replace(/ss/g, ('0' + date.getSeconds()).slice(-2));
  if (format.match(/S/g)) {
    var milliSeconds = ('00' + date.getMilliseconds()).slice(-3);
    var length = format.match(/S/g).length;
    for (var i = 0; i < length; i++) format = format.replace(/S/, milliSeconds.substring(i, i + 1));
  }
  return format;
};
```

なお、ユーザとしてではなくRoom Notification TokensとしてTokenを取得する場合は、ルーム事に、取得する必要があります。設定で以下のようにして取得してください。

![image](https://qiita-image-store.s3.amazonaws.com/0/30079/fe04b6ec-92d7-c66d-ba3c-5e685b66c159.png)

# まとめ

REST APIをつかえば、Apps ScriptからHipChatにKPIレポートを送る事ができました。
KPIをチームに定期的に共有し、いい感じにプロダクト改善していきましょう！