KCCS APIデータ配信サービスの災害データPUSH配信機能をつかって震度情報をSlack通知する

弊社がサービス提供しておりますKCCS APIデータ配信サービスでは、震度データなど災害データを取り扱っています。
災害データは、実績データをRESTで取得する機能と、Google Cloud Pub/Subを利用したPUSH配信機能があります。
今回は、PUSH配信された震度データを、GASを使ってslackへ連携する方法をご説明したいと思います。

Google Cloud Pub/Subについては、下記を参照ください。
震度データはサブスクリプションから抽出します。
抽出はpull方式とpush方式両方とも対応可能です。今回はpull方式で抽出してみたいと思います。

https://cloud.google.com/pubsub/docs/overview?hl=ja

### GASを使ったslack通知
それでは災害データとして、KCCS APIデータ配信サービスが取り扱っているデータの一つである、地震震度データを例にコードを書きます。

slackへの連携は「Incoming Webhook」を利用します。
https://slack.com/intl/ja-jp/help/articles/115005265063-Slack-%E3%81%A7%E3%81%AE-Incoming-Webhook-%E3%81%AE%E5%88%A9%E7%94%A8

#### GASのコード
コード全体は下記gitのURLに配置しています。

https://github.com/kccs-api/apps-script-samples/tree/master/sendslack_seismic

Cloud Pub/Sub APIを利用しています。

https://cloud.google.com/pubsub/docs/reference/rest



以下では、コードの一部をピックアップして記載していきます。


#### 1. 変数定義
必要な変数5つは事前に定義しておきます。
サブスクリプションの認証に必要なサービスアカウントのキーファイルもアップロードしておきます。

```php
const project = '<Google Cloud Project ID>';
const sub = '<Google Cloud subscription ID>'
const maxMessages = 3
const slackID = 'https://hooks.slack.com/services/<slack id>'
const key_file = '<jsonファイル名>'  // キーファイル(jsonファイル)をアップロード

function main() {
  // 認証確認
  var access = pubsubAccess()
  if (access) {
    // pullでmessage取得
    var ret = pull(sub);
    // retの値がnullでなければslack通知する
    if (ret) {
      // slack通知用メッセージ作成
      makeMessage(sub, ret)
    }
  }
}
```

#### 2. サブスクリプションからpullする関数
サブスクリプションからpullする方法については、以下を参考にしてください。
Project IDおよびsubscription IDをつかってurlを作成、リクエストを送ります。
https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/pull



```php
function pull(sub) {
  var service = getService();
  
  var url = 'https://pubsub.googleapis.com/v1/projects/[PROJECT]/subscriptions/[SUB]:pull'
  .replace("[SUB]", sub)
  .replace("[PROJECT]", project);
    
  var body = {
    "returnImmediately": false,
    "maxMessages": maxMessages
  };

    var response = UrlFetchApp.fetch(url, {
    method: "POST",
    contentType: 'application/json',
    muteHttpExceptions: true,
    payload: JSON.stringify(body),
    headers: {
      Authorization: 'Bearer ' + service.getAccessToken()
    }
  });
 
  var result = JSON.parse(response.getContentText());

  return {
    result: result
  }    
} 
```




#### 3. slackへメッセージを連携する関数
サブスクリプションから受信したメッセージをslackに送ります。
アイコンとタイトルもつけてみます。

```php
function sendSlackMessage( title , iconEmoji , message ){

  // Slack通知
  var options =
  {
    "method" : "post",
    "contentType" : "application/json",
    "muteHttpExceptions": true,
    "payload" : JSON.stringify({
      "username" : title,
      "icon_emoji" : iconEmoji ,
      "text" : message
    })
  };

  try {
    var res = UrlFetchApp.fetch(slackID, options);
    Logger.log(res)
    return res
  } catch(e) {
    // 例外エラー処理
    Logger.log('Error:')
    Logger.log(e)
    return null
  }
}
```

実行されると、下記のようにデータが出力されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1194651/97c472ff-f09b-22c9-6f41-8b8e48001290.png)



JSON形式そのままなので、わかりにくいですね。
整形して出すようにすれば、もっとわかりやすくなりそうです。

### JSONデータ整形をし、slackに分かりやすく表示してみる

JSONデータの必要な部分だけ抽出し、整形してみます。

```php
function replaceMessage(text) {

  var jsonObject = JSON.parse(text)
  var jsonReportDatetime = jsonObject.report_datetime //発表日時
  var jsonOriginTime = jsonObject.body.earthquake.origin_time　//発生時刻
  var jsonHypocenterArea = jsonObject.body.earthquake.hypocenter.area.name //震央地名
  var jsonMagnitudeDescription =  jsonObject.body.earthquake.magnitude_description //震源地マグニチュード文字列
  var jsonMaxInt = jsonObject.body.intensity.observation.max_int //最大震度
  var jsonPref = jsonObject.body.intensity.observation.pref //エリアごとの震度情報

  jsonString = "発表日時：" + getStringFromDate(jsonReportDatetime) + "\n" 
             + "発生時刻：" + getStringFromDate(jsonOriginTime) + "\n"
             + "震央地名：" + jsonHypocenterArea + "\n" 
             + "震源地マグニチュード文字列：" + jsonMagnitudeDescription + "\n" 
             + "最大震度：" + jsonMaxInt + "\n" 
             + "各都道府県の最大震度は下記の通り：\n"
  var jsonArray=[]
  for(i=0;i<jsonPref.length;i++){
    jsonArray.push("     " + jsonPref[i]["name"]+ "の最大震度："　+　jsonPref[i]["max_int"])
  }
  var jsonArrayString = jsonArray.join("\n");
  var jsonString = jsonString + jsonArrayString 
  return jsonString
}
```
分かりやすく情報を表示することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1194651/ff724087-cfb2-df84-f736-77962d8989ac.png)