JavaScript
Hubot
Slack
PubSubHubbub

Slackに気象庁の情報(災害情報)を投下するHubotを作った(JavaScript)

はじめに

ちょっとした地震などの時にどこが揺れたんだろうとかをわざわざ調べに行かなくていい様に、Slackに気象庁から災害情報を取ってきて投稿するBotを作りました。
意外と気象庁が配っている情報をPubSubHubbub(現:WebSub?気象庁の表記に合わせてPubSubhubbubと表記)で取得する方法について情報がなかったので書きます。
今回のコード : https://github.com/kakudo415/alert

おしながき

  • Subscriberを書く(登録部分)
  • 気象庁にSubscriberを登録する
  • Subscriberをさらに書く(受け取り部分)

環境

  • JavaScript
  • Hubot

つくる

今回はPubSubHubbubをいかに受け取るかがメインなので投稿部分などは省かせていただきます(詳細はコードを見てください)。

Subscriberを書く(登録部分)

URLの最後に /sub をつけて運用してます(正直いらなかった)
とりあえず登録処理を正しく返せるとこまで書きます。やってることとかは下で書きます。
出来たらデプロイして登録リクエストに備えます。
気象庁が出してる仕様 : http://xml.kishou.go.jp/open_trial/detailinformation.pdf

'use strict';

 const verifyToken = process.env.JMA_VERIFY_TOKEN;

 module.exports = (robot) => {
  robot.router.get('/sub', (req, res) => {
    const query = req.query;
    if (query['hub.mode'] !== 'subscribe') {
      res.status(404).send('MODE ERROR').end();
      return;
    }
    if (query['hub.verify_token'] !== verifyToken) {
      res.status(404).send('VERIFY_TOKEN ERROR').end();
      return;
    }
    res.status(200).send(query['hub.challenge']).end();
  });
};

なにがしたいか

気象庁から情報をもらうにはPubSubhubbubを利用する必要があります。
これは情報が更新されたら気象庁からHUBと呼ばれるサーバーに情報を伝え、HUBから利用者のサーバーへHTTPリクエストで情報へのリンクを送るものです。
なので使うためにはまずHUBに自分のサーバーを登録してもらう必要があります。

やってること

HubotにはExpressが備えつけられてるらしいので、それを使ってHUBからのアクセスを受け付けます。
登録手続きをするとHUBから確認のGETが飛んできます。
そこに登録に必要なクエリが付いてくるので、適切に返してやる必要があります。

  • hub.verify_token
  • hub.challenge
  • hub.topic
  • hub.mode
  • hub.lease_seconds

以上5つのクエリが来るので一つずつ説明していきます。

hub.verify_token

Subscriberはサーバー上で動くので当然他の人からいたずらなどで登録を装ったリクエストが送られてくる可能性があります。
それを防ぐために気象庁への登録時にパスワードのようなものを登録しておくことができ、それを毎回送ってこさせることが可能です。
それを照合することで本物のリクエストかどうか判別できます。(合わなければリクエストを捨てればいい 404を使うようにPubSubHubbubの仕様で決まってたはず)。
ちなみに、あまりえげつない文字列にすると気象庁の職員さんでハマる可能性があるとのこと(メールで登録なので打ち間違える可能性が・・・)。

hub.challenge

これは逆にSubscriberを確かめるための文字列です。
SubscriberはこれをそっくりそのままHUBに返してやる必要があります。 レスポンスの最後の改行とか入ると駄目なので注意!
登録時の処理のメインはこれ

hub.topic

このリンク以下で情報を送ります的な意味だと思われる(どう使えばいいのか不明)。

hub.mode

登録時は subscribe 登録解除時は unsubscribe が入る。

hub.lease_seconds

HUBはちゃんと利用者のサーバーが正しく動作しているか定期的に登録時と同じリクエストを送ってきます。
その確認用の次のリクエストが何秒後かを表しています。

気象庁にSubscriberを登録する

とりあえずSubscriberが出来たら「気象庁」に登録申請を投げます。
5日とかかかるので登録処理が受けられるようになった時点で申請を投げておいたほうがいいです。
http://xml.kishou.go.jp/open_trial/registration.html
このページにあるように、登録したい情報の種別や個人情報などを気象庁へ決められたフォーマットでメールします(テンプレートが置いてあります)。
メール送って数日すると唐突に確認リクエストがSubscriberに飛んでくるので常時起動しておいてください。

Subscriberをさらに書く(受け取り部分)

登録が完了したら、登録したジャンルの情報が更新されるたびにPOSTでAtomフィードが送られてきます。
feed内のentry内のlinkのhref属性に個々の情報へのリンクがあります(だいたい24時間で消えるので早めに取りに行きましょう)。
情報はXMLなのでパースしないといけませんが、当然情報の種類が違うと構造も違います。
Report内Head内InfoKindが情報の構造の種類を表しているのでこれで分岐すると良さげです。
http://xml.kishou.go.jp/tec_material.html
このサイトからXMLの構造などについての情報が得られます。
パース出来たら後はそのままHubotで投稿するだけですね。

さいごに

そこそこN高Slackでお役に立てている模様でありがたいです。
初めて作ったBotなので間違いがあれば指摘していただけると嬉しいです。