GASでLINE Botをネタに何か作りたいなと思い、調べて出てきた「天気予報を通知してくれるLINE Bot」を作成しました。
通知するデータは気象庁のものを活用します。気象庁のデータを取得するAPIが非公式ではありますが公開されているので、そちらを使ってみました。
今回の記事では、GASを使って気象庁から天気予報のJSONを取得して、その中身を確認してみるところまでやっていきます。
▼制作の過程をXでポストした様子
@nkkmd さんのこちらの記事で、気象庁のデータ取得を学びますhttps://t.co/hcMEvhX1mB
— おおさき🥔小さなIT活用で快適な農場づくりを (@massa_potato) 2024年2月8日
制作したいもの
今回作っていくものは、こちらのブログ記事で紹介されているものになります。
以下のような実装をしていきます。
- 気象庁の天気予報の情報をテキスト取得する
- LINE Messaging APIでプッシュメッセージを送る
- GASのトリガー設定で指定時間に実行
とてもシンプルなLINE Botですね。
LINE公式アカウントのチャネルを作成しアクセストークンを取得しておけば、すぐに使えるものになります。応答メッセージを使っていないため、GASスクリプトをデプロイしてWebhook設定する…といった作業は必要ありません。
気象庁のAPIについて
2021年2月に気象庁のWebページがリニューアルされ、以降、気象情報を取得できるAPIを公開(アクセス可能な状態)してくれています。スクレイピング不要で情報を取れるのはありがたいですね。
ただし、これはあくまで非公式なものになりますので、仕様が変わったりしても文句が言えません。その点に注意しつつ、ありがたく活用しましょう。
取得できる情報について
では、どんな情報を取得することができるのでしょうか?
たくさんあるようですが、簡単なものだけ整理しておきました。下記の各エンドポイントにデータが欲しい地域の予報区コード番号を入れてアクセスすると、情報がJSONデータとして得られます。
天気概況
今日〜明日にかけての天気の概況をまとめた情報です。エンドポイントは以下になります。(例:釧路・根室地方)
https://www.jma.go.jp/bosai/forecast/data/overview_forecast/{予報区のコード番号}.json
アクセスすると、下記画像の情報がJSONテキストで表示されます。
天気予報
明後日まで3日間の詳細な天気予報と、7日先までの週間天気予報の情報が得られるようですね。エンドポイントは以下になります。(例:釧路・根室地方)
https://www.jma.go.jp/bosai/forecast/data/forecast/{予報区のコード番号}.json
アクセスすると、下記画像の情報がJSONテキストで表示されます。
ちなみにこれらWebページの「天気概況」「天気予報」は、この気象庁のマップから地域を選んでいくと表示できます。
予報区について
地域コードの一覧
予報区コードについては、こちらのURLで確認できます。
https://www.jma.go.jp/bosai/common/const/area.json
アクセスすると、予報区コードの一覧がJSONでテキストで表示されます。
ただし、パッと見てわかりづいらいですね。自身の地域を探す際には、下記サイトの対応表を参考にさせて頂きました。
GASで天気予報のデータを取得してみよう
なにはともあれ、まずはGASで天気予報のデータを取得してログ表示してみましょう。先ほど紹介した中から「天気予報」の情報を取得してみます。
ここで、自身の地域の予報区コードが必要です。先ほどの一覧から自身の地域を調べておきましょう。
僕は十勝在住なので、十勝地域の情報が欲しいのですが…そのためには北海道の釧路・根室地方の予報区コード(04100)を使う必要があるようです。ややこしいですね。
では、ここからは実際に取得していきます。ただしJSONで得られるデータの中身は分量も多く複雑になっているので、まずはどんな構造になっているかを探っていきましょう。
データを取得してログ表示するスクリプト
まずは、取得したJSON形式のテキストをオブジェクトに変換したものを、変数data
に格納します。そしてその中身をconsole.log()
で表示するというスクリプトを書いて、実行してみます。
これで、取得したデータの構造だけを簡単に見ることができます。
function getForecastData() { const url = "https://www.jma.go.jp/bosai/forecast/data/forecast/014100.json"; // 釧路・根室地方 const res = UrlFetchApp.fetch(url); const data = JSON.parse(res.getContentText()); console.log(data); }
表示されるログがこちら。
[ { publishingOffice: '釧路地方気象台', reportDatetime: '2024-02-08T17:00:00+09:00', timeSeries: [ [Object], [Object], [Object] ] }, { publishingOffice: '釧路地方気象台', reportDatetime: '2024-02-08T17:00:00+09:00', timeSeries: [ [Object], [Object] ], tempAverage: { areas: [Object] }, precipAverage: { areas: [Object] } } ]
取得したデータの構造はどのようになっているか
先ほどのログの中身を見てみると、配列の中にオブジェクトが2つだけ入っていますね。
このログだけだとわからないのですが、どうやらそれぞれ以下の情報が入ってきているようです。
- 1つ目のオブジェクトに「明後日まで3日間の詳細な天気予報」
- 2つ目のオブジェクトに「7日先までの週間天気予報」
では、入れ子になっている各オブジェクトの中身はどんな構造になっているのでしょうか?
データの中身を詳しく見てみよう
「明後日まで3日間の詳細な天気予報」の中身
まずは、配列data
に格納されている1つ目のオブジェクトdata[0]
をconsole.log()
で見てみます。ログをコピペすると長くなるので、キャプチャを載せました。
このままだと構造がわかりづらいですが、JSON形式テキストとしてきれいに整理して表示すると、このようになっています。
{ "publishingOffice": "釧路地方気象台", "reportDatetime": "2024-02-13T11:00:00+09:00", "timeSeries": [ { "timeDefines": [ "2024-02-13T11:00:00+09:00", "2024-02-14T00:00:00+09:00", "2024-02-15T00:00:00+09:00" ], "areas": [ { "area": { "name": "釧路地方", "code": "014020" }, "weatherCodes": [ "100", "101", "215" ], "weathers": [ "晴れ", "晴れ 朝晩 くもり", "くもり 後 一時 雪" ], "winds": [ "南西の風 やや強く 海上 では 南西の風 強く", "南西の風 やや強く 後 西の風", "北の風" ], "waves": [ "3メートル", "3メートル 後 1.5メートル", "1.5メートル 後 1メートル" ] }, { "area": { "name": "根室地方", "code": "014010" }, "weatherCodes": [ "100", "111", "215" ], "weathers": [ "晴れ", "晴れ 夕方 から くもり", "くもり 後 一時 雪" ], "winds": [ "南西の風 やや強く 根室南部 では 南西の風 強く", "南西の風 後 北の風 海上 では 南西の風 やや強く", "北の風" ], "waves": [ "3メートル", "3メートル 後 1.5メートル", "1.5メートル 後 1メートル" ] }, { "area": { "name": "十勝地方", "code": "014030" }, "weatherCodes": [ "100", "101", "215" ], "weathers": [ "晴れ", "晴れ 朝晩 くもり", "くもり 後 一時 雪" ], "winds": [ "西の風 やや強く 海上 では 南西の風 強く", "西の風 やや強く 海上 では はじめ 南西の風 強く", "北の風" ], "waves": [ "2.5メートル", "2.5メートル 後 1.5メートル", "1.5メートル 後 1メートル" ] } ] }, { "timeDefines": [ "2024-02-13T12:00:00+09:00", "2024-02-13T18:00:00+09:00", "2024-02-14T00:00:00+09:00", "2024-02-14T06:00:00+09:00", "2024-02-14T12:00:00+09:00", "2024-02-14T18:00:00+09:00" ], "areas": [ { "area": { "name": "釧路地方", "code": "014020" }, "pops": [ "0", "0", "0", "0", "0", "0" ] }, { "area": { "name": "根室地方", "code": "014010" }, "pops": [ "0", "0", "0", "0", "0", "10" ] }, { "area": { "name": "十勝地方", "code": "014030" }, "pops": [ "0", "0", "0", "0", "0", "0" ] } ] }, { "timeDefines": [ "2024-02-13T09:00:00+09:00", "2024-02-13T00:00:00+09:00", "2024-02-14T00:00:00+09:00", "2024-02-14T09:00:00+09:00" ], "areas": [ { "area": { "name": "釧路", "code": "19432" }, "temps": [ "7", "7", "2", "8" ] }, { "area": { "name": "根室", "code": "18273" }, "temps": [ "8", "8", "1", "9" ] }, { "area": { "name": "帯広", "code": "20432" }, "temps": [ "10", "10", "-1", "11" ] } ] } ] }
「7日先までの週間天気予報」の中身
つぎに、配列data
に格納されている2つ目のオブジェクトdata[1]
をconsole.log()
で見てみます。ログのキャプチャはこちら。
こちらもJSON形式のテキストできれいに整理して表示すると、このようになっています。
{ "publishingOffice": "釧路地方気象台", "reportDatetime": "2024-02-13T11:00:00+09:00", "timeSeries": [ { "timeDefines": [ "2024-02-14T00:00:00+09:00", "2024-02-15T00:00:00+09:00", "2024-02-16T00:00:00+09:00", "2024-02-17T00:00:00+09:00", "2024-02-18T00:00:00+09:00", "2024-02-19T00:00:00+09:00", "2024-02-20T00:00:00+09:00" ], "areas": [ { "area": { "name": "釧路・根室・十勝地方", "code": "014000" }, "weatherCodes": [ "101", "215", "201", "101", "101", "200", "206" ], "pops": [ "", "60", "40", "10", "10", "30", "50" ], "reliabilities": [ "", "", "B", "A", "A", "B", "C" ] } ] }, { "timeDefines": [ "2024-02-14T00:00:00+09:00", "2024-02-15T00:00:00+09:00", "2024-02-16T00:00:00+09:00", "2024-02-17T00:00:00+09:00", "2024-02-18T00:00:00+09:00", "2024-02-19T00:00:00+09:00", "2024-02-20T00:00:00+09:00" ], "areas": [ { "area": { "name": "釧路", "code": "19432" }, "tempsMin": [ "", "-3", "-8", "-11", "-5", "-1", "-2" ], "tempsMinUpper": [ "", "-1", "-5", "-7", "-1", "3", "2" ], "tempsMinLower": [ "", "-6", "-11", "-13", "-9", "-4", "-6" ], "tempsMax": [ "", "4", "-1", "1", "6", "7", "4" ], "tempsMaxUpper": [ "", "6", "1", "4", "8", "9", "9" ], "tempsMaxLower": [ "", "2", "-3", "0", "3", "4", "1" ] } ] } ], "tempAverage": { "areas": [ { "area": { "name": "釧路", "code": "19432" }, "min": "-9.1", "max": "0.1" } ] }, "precipAverage": { "areas": [ { "area": { "name": "釧路", "code": "19432" }, "min": "0.9", "max": "7.3" } ] } }
まとめ
GASで気象庁のAPIを使って、天気予報の情報を取得してみました。JSONテキストから必要な情報を探して取り出すのが、なかなか大変そうですねー。
次回、ここから必要な情報を取り出してメッセージを作成するGASスクリプトを作っていきたいと思います。
参考
気象庁からAPIで取得できる情報はほかにもたくさんありそうです。こちらのまとめが参考になります!