HubotでWeather APIを使って天気を教えてくれるやつを作った


HubotでHotpepperグルメサーチAPIを使ってお店を紹介してくれるやつを作ったの続きです。

天気予報も知りたいなと思って作ってみました。
今回天気予報の取得にはOpenWeatherMapのWeather APIを使いました。
今回もSlackと連携することを想定しています。

APIキーの取得

Sign Upに必要情報を入力してAPIキーを発行する。price-listに色々プランがあるけど、勉強のためなので、Freeで十分。
登録が済むとAPIキーが発行されます。

使ってみる

完成形を先にお見せします。

# Description:

module.exports = (robot) ->
  robot.hear /(.*)の天気は?/i, (msg) ->

    cityName  = msg.match[1]
    query = encodeURIComponent msg.match[1]

    request = msg.http("http://api.openweathermap.org/data/2.5/forecast/weather?q=#{query}&APPID={APIキー}")
    .get()
    request (err, res, body) ->
      json = JSON.parse body
      switch json["list"][0]["weather"][0]["main"]
        when "Clear"
          weather = "晴れ"
        when "Clouds"
          weather = "くもり"
        when "Rain"
          weather = "雨"
        when "snow"
          weather = "雪"

        icon = json["list"][0]["weather"][0]["icon"]

      msg.reply "#{cityName}の天気は#{weather}です \n http://openweathermap.org/img/w/#{icon}.png"

説明

module.exports = (robot) ->
  robot.hear /(.*)の天気は?/i, (msg) ->

「◯◯の天気は?」というフレーズに反応して処理を実行します。◯◯の部分に調べたい地名を入力します。

cityName  = msg.match[1]
query = encodeURIComponent msg.match[1]

(.+)でマッチした文字列をエンコードしています。

request = msg.http("http://api.openweathermap.org/data/2.5/forecast/weather?q=#{query}&APPID={APIキー}")
    .get()

APIをたたきます。
weather?q=#{query}でエンコードされた地名をAPIに渡してます。

json = JSON.parse body
      switch json["list"][0]["weather"][0]["main"]
        when "Clear"
          weather = "晴れ"
        when "Clouds"
          weather = "くもり"
        when "Rain"
          weather = "雨"
        when "snow"
          weather = "雪"

返ってきたJSONに対して処理を書きます。
json["list"][0]で今日のデータを取得します。さらに["weather"][0]["main"]で天気を取得します。
Weather APIでは天気が英語で返ってくるので、文字に応じて日本語を返します。

icon = json["list"][0]["weather"][0]["icon"]
timestamp = (new Date()).toISOString().replace(/[^0-9]/g, "")

json["list"][0]["weather"][0]["icon"]によって天気アイコンは変わってるみたい。
"01d", "01n"のd、nは、d:day、n:nightの略っぽい。
また、Slackでは2回目以降の画像はサムネイルとして表示されないようなのでtimestamp = (new Date()).toISOString().replace(/[^0-9]/g, "")を画像名の最後に出力します。

あとはそれを
msg.reply "#{cityName}の天気は#{weather}です \n http://openweathermap.org/img/w/#{icon}.png?#{timestamp}"
で出力してやればOK

ではではやってみます。

mybot> 那覇の天気は?
mybot> 那覇の天気は晴れです
 http://openweathermap.org/img/w/02d.png?20160820234350565

いい感じでできました。