GoogleAppsScript で気象庁XMLのサブスクライバを動かす

いつ書いたかわからない記事が下書きに残っていたので公開します。

みなさん、気象庁XMLを利用していますか？
おそらく利用している人は少ないでしょう。この記事を見ている方は興味がある方だと思って書きます。

#そもそも『気象庁防災情報XML』ってなに？
Google大先生等で「気象庁XML　受信」とかで検索してきている方たちだと思うのでいまさらこんなこと説明されても必要ないと思いますが一応。
まぁ[公式のページ](http://xml.kishou.go.jp/)をそのまま引用するだけなんですが・・・
>気象庁は、気象・海洋や地震・火山などを常に監視し、さらに起こり得る現象の予測を行い、的確な気象警報や津波警報、地震情報等の防災情報を提供することにより、自然災害の軽減、国民生活の向上、交通安全の確保、産業の発展などを実現することを任務としています。
気象庁の発表する防災情報が効果的に利用されるためには、その情報の精度が高く、ニーズに応じていることはもちろんのこと、防災情報を広く周知・利用する防災機関・報道機関・民間事業会社等にとって、届けられた防災情報が取り扱いやすいことが重要です。
気象庁は過去長年にわたり、それぞれの防災情報毎に情報の性質・利用形態などを考慮し、気象庁独自の電文形式（フォーマット）を作成してきました。この方式は、防災情報の種類が少なく、情報の伝達がFAXや低速の通信回線の時代はそれぞれの情報に適していましたが、高度にICT化された社会において、より詳細で高度化された防災情報をより効果的に活用していただくために、新たな防災情報の提供様式を検討すべきと考え、「気象庁防災情報XMLフォーマット」を策定することとし、平成23年5月12日より運用を開始しました。
フォーマットの策定にあたっては、10年程度に渡り利用可能とすることを目標とし、フォーマットの標準化を図るためにXMLコンソーシアムの協力を仰ぐとともに、検討途中でドラフトを公開し、より多くの利用者からの声を検討に反映させました。
気象庁は、気象庁防災情報XMLフォーマットのより一層の利活用が、国民の安全・安心の確保の一助になるものと確信しており、今後も利活用促進・改善に努めてまいります。 

だそうです。はい。

#なんで GAS なの？
気象庁さんが[利活用セミナーで提供しているサンプル](http://xml.kishou.go.jp/seminar/pdf/20130312/03.pdf)では ```PHP``` を使ってサブスクライバを構築しています。
でも、敷居が高いですよね。自前でWebサーバーを用意するかレンタルサーバーを借りるか。自前ならIPアドレスを静的にしなきゃいけない。無料のレンタルサーバーでもクレジットカード必須だとか。こういう~~面倒な~~事もあってあまり知られていない気がしなくもないですが・・・。
```GAS (Google Apps Script)``` は ```Google Spread Sheet``` で使えるマクロのようなものを組めるものなのですが、調べていくと無料でWebサーバーのように使えるみたいで、「もしや？」と思いやってみたら意外と簡単にできちゃったので共有しておきます。

# ※※※ 注意事項 ※※※
この使い方はGoogle側も性能面等で保証などは一切しておりませんので、短時間に大量のアクセスがあるようなサービスはたぶん無理です。
今回は気象庁XMLを受信できるサブスクライバを書きますが、おそらく全ては受信できないでしょう。
また、**スクリプトのURLが複雑かつ長いので気象庁の担当者に迷惑です。これで受信するのは控えましょう。**

#構築しよう
```GAS``` には ```GET``` リクエストに反応する ```doGet``` というメソッドと、 ```POST``` リクエストに反応する ```doPost``` というメソッドが用意されています。今回はそれらを使ってサブスクライバを作っていきます。
**参考にさせていただいたページは[こちら](https://qiita.com/kunichiko/items/7f64c7c80b44b15371a3)**

###1.Spreadsheetに空のシートを作る
[sheet.new](https://sheet.new/) で作成してください。

###2.スクリプトエディタを表示する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204925/297ee34c-3544-c645-df26-550cc67b0923.png)
ツール -> スクリプトエディタ で開いてください。


###3. サブスクライバを書く
```GET``` リクエストに対し ```hub.challenge``` を返し、 ```POST``` リクエストでは ```Atom``` のURLをSpreadsheetに追記していくものです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204925/ce7e6ac6-e8c6-bde4-8329-2283961bbc7d.png)

```javascript:JMAXML_Receiver.gs
function doGet(e) { // GET処理 hub.challenge をそのまま返す
  const hubmode = e.parameter["hub.mode"];
  if (hubmode == "subscribe" || hubmode == "unsubscribe") {
    const output = ContentService.createTextOutput(e.parameter["hub.challenge"]);
    output.setMimeType(ContentService.MimeType.TEXT);
    return output;
  }
}

function doPost(e) { // POST処理
  let match = e.postData.contents.match(/<link href="(.+?)" type="application\/xml"\/>/g); // AtomのURLを抽出
  for (let i = 0; i < match.length; i++) {
    match[i] = match[i].replace('<link href="', '').replace('" type="application/xml"/>', ''); // それぞれ整形
  }
  match.unshift(new Date()); // 配列の頭に日付時刻を追加
  SpreadsheetApp.getActive().getActiveSheet().appendRow(match); // Spreadsheetに追記
}
```

#4.公開してみよう
詳しくは[参考にしたページ](https://qiita.com/kunichiko/items/7f64c7c80b44b15371a3)をご覧ください（他人任せ）。

#※※※ これで受信するのは控えてください ※※※
ここまで簡単に組めるとは思っていませんでした。
ですが、冒頭にも書いたように複雑なURLを指定するのは迷惑なので**やめましょう。**
受信できる保証もありません。一応、私が受信している2系統の片方を使ってテストしてみましたが正常に動作していたのでサブスクライバとしては使えると思います。今後、独自ドメインを割り振れるようになったら便利かもしれませんね。