IBM® Bluemix® Node-REDとWeather Company Data for IBM® Bluemix®で、お天気LINE BOTを作る

More than 1 year has passed since last update.

はじめに

この記事はteratail Bluemixアドベントカレンダーの投稿です。

誘われたので、Bluemixもnode.jsも全然触ったことないですが、挑戦してみます。
現在、一ヶ月間はフリートライアルとして無償で利用できます。

師走なだけあって、急な予定でヒーヒー言いながら書いてます。
後から間違い修正や加筆などするかもしれませんが、ご了承ください。

概要

私は渋谷のオフィスビルを行ったり来たりする毎日を過ごしているのですが、ずっと困っていることがあります。
渋谷駅周辺って意外と地下道がないので急な雨が降った時に逃げ場がなくて困るんですよね。
IT系企業が入っているビルは駅から10分ぐらい歩くことも多いのでなおさらです。
10分あればもう、びしょ濡れです。

そこで、渋谷で急な雨が降りそうになった時に、こじとらくんが教えてくれるLINE BOTを作ってみようと思います。

今回はせっかくなのでWeather Company Data for IBM® Bluemix®を使います。

今回作成するBOTのフローは以下のような感じになります。

1時間おきにNode-REDを実行
    ↓
現在の渋谷の天気を取得
    ↓
次の1時間の渋谷の天気予報を取得
    ↓
現在雨が降っていない かつ これから1時間の降水確率が70%を超えた場合、
LINEで通知を送る

事前準備

LINE BOTの作成にあたり、Node-REDプロジェクトの作成と、LINE BOTアカウントの作成を行います。

1. LINE BOTアカウントの作成

  • LINE BUSINESS CENTERDeveloper Trialを始めるより、Messaging APIのアカウントを取得します。
    スクリーンショット 2016-12-15 12.12.01.png

  • LINE@ MANAGERから作成したLINE@アカウントのBOT設定を有効化します。
    スクリーンショット 2016-12-15 12.10.40.png

  • LINE Developersで設定するをクリック。
    スクリーンショット 2016-12-15 12.13.26.png

  • Webhook URLを指定し、Channel Access Tokenをメモしておきます。
    スクリーンショット 2016-12-15 23.24.15.png

2. Node-REDプロジェクトの作成

  • BluemixのカタログページからNode-RED Starterを選択します。
    スクリーンショット 2016-12-15 10.42.33.png

  • 任意のアプリ名を入力して作成ボタンをクリック。その他の項目はそのままでOKです。
    スクリーンショット 2016-12-15 10.39.41.png

  • この画面が表示されればプロジェクトの作成は完了です。
    スクリーンショット 2016-12-15 11.06.59.png

  • ランタイム→環境変数にNode-REDのユーザー認証設定を追加します。NODE_RED_USERNAMENODE_RED_PASSWORDに設定してください。
    スクリーンショット 2016-12-15 14.11.39.png

  • カタログページに戻り、Weather Company Dataをクリックします。
    スクリーンショット 2016-12-15 21.56.34.png

  • 左の接続から、先程作成したNode-REDプロジェクトを指定して作成ボタンをクリックします。
    スクリーンショット 2016-12-15 21.59.05.png

  • ダッシュボード→接続→Weather Company Data→資格情報の表示からurlをメモしておきます。これで事前準備は終了です。
    スクリーンショット 2016-12-15 23.30.22.png

定期的に天気情報を取得する

メインのロジック部分に入ります。
右上のアプリの表示からNode-REDのフローエディターを開きます。
※FireFoxが推奨環境です。Mac + Chrome環境で、エディターのカーソルがずれる不具合が起きました。

この画面で、先程指定したユーザーネームとパスワードを入力してログインを行います。
スクリーンショット 2016-12-15 14.15.51.png

1. 1時間おきに定期実行させる。

  • 左側のメニューからinjectノードを配置し、intervalを1 hoursに設定します。 スクリーンショット 2016-12-15 13.58.06.png

2. Weather Company Data APIから天気情報を取得する。

  • http requestjsonのノードを以下のように配置します。
    スクリーンショット 2016-12-15 21.50.20.png

  • http requestを開き、URLに先程メモしたurl + /api/weather/v1/geocode/35.6581/139.701742/forecast/hourly/48hour.json?units=m&language=ja-JPを指定します。
    35.6581/139.701742の部分は渋谷の緯度経度です。
    Use basic authenticationにチェックが入っている場合は外します。

3. 通知判定を行う。

  • functionswitchdebugを以下のように配置します。
    スクリーンショット 2016-12-15 22.10.47.png

  • switchを開き、以下のように設定します。

    スクリーンショット 2016-12-15 22.15.47.png

  • functionに以下のコードを貼り付けます。

if(!msg.payload.forecasts[0].phrase_32char.match(/雨/)) {
    // 今の天気が雨ではない場合
    if(msg.payload.forecasts[1].pop >= 70) {
        // 降水確率が70%以上の場合
        msg.payload = "rainy";
        return msg;
    }
}

msg.payload = "not rainy";
return msg;

右上のDeployをクリックして、右のDebugタブにrainyもしくはnot rainyの文字列が表示されればOKです。(デバッグ時はInjectの間隔を短くしたほうが良いです。)

LINE APIを利用してBOTにメッセージを送らせる。

今回はLINEのPush Message APIを利用して、メッセージをユーザーに送信します。
ただし、現状のAPI仕様だと友達全員にメッセージを送ることができない(ユーザーのIDを指定しないといけない)ので、友達追加をした時にIDを保存する処理を追加します。

1. Webhook URLのエンドポイントを作成する。

  • httpswitchfunctioncloudantを以下のように配置します。

    スクリーンショット 2016-12-15 22.31.10.png

  • httpノードをクリックし、MethodをPOST、urlを先程指定したWebhook URLのパスにします。
    スクリーンショット 2016-12-15 22.33.58.png

2. 友達追加の際に、UserIdを保存する。

  • リクエストの内容を元に、switchで友だち追加リクエストのときだけ処理を行うように分岐します。
    スクリーンショット 2016-12-15 22.36.12.png

  • userIdだけを取り出すコードをfunctionに記述します。

msg.payload = msg.payload.events[0].source.userId;

return msg;
  • cloudantに以下の設定をして、データを保存します。 スクリーンショット 2016-12-15 22.40.21.png

3. 保存されているUserIdを取得する。

  • 通知判定後のswitchの先に、cloudantノードを配置します。

    スクリーンショット 2016-12-15 22.50.13.png

  • 先程指定したDatabaseから全データを取得します。
    スクリーンショット 2016-12-15 22.54.30.png

  • 取得したデータの数、POSTリクエストを組み立てます。
    複雑なので画像とコードを全て貼っておきます。
    スクリーンショット 2016-12-15 22.58.50.png

// 重複を排除したidの一覧を取得
function getId(data) {
  return data.payload;
}

msg.items = msg
    .payload
    .map(getId)
    .filter(function (x, i, self) {
        return self.indexOf(x) === i;
    });
return msg;
// for each
if( msg.i == undefined ) msg.i = 0;

msg.payload = msg.items[ msg.i ];

return msg;
// ++
if ( (msg.i += 1) < msg.items.length ) {
    return msg;
}
// POSTリクエストの組み立て
var id = msg.payload;
msg.payload = {
    'to':id,
    'messages':[
        {
            'type': 'text',
            'text': 'みみずくんのにおいがするよ、雨が降るかもしれないよ!ʕ ˙⃘ᗣ˙⃘ ʔ☔'
        }
    ]
}

msg.headers = {
    'content-type':'application/json',
    'Authorization':'Bearer ' + '<YOUR_ACCESS_TOKEN>'
};
return msg;

YOUR_ACCESS_TOKENの部分には、先程取得したLINE BOTのアクセストークンを入れてください。

4. メッセージを送信する。

  • debugの前に、http requestを追加します。
    スクリーンショット 2016-12-15 23.09.33.png

  • 追加したhttp requestにLINE APIのエンドポイント(https://api.line.me/v2/bot/message/push)を設定します。
    スクリーンショット 2016-12-15 23.10.51.png

完成

最終的なフロー

スクリーンショット 2016-12-15 23.12.44.png

メッセージ

IMG_4674.PNG

まとめ

今回は特にハマりどころもなく、調べながらでも半日程度で作成ができました。

BluemixもNode-REDも初めて使用しましたが、日本語ドキュメントも充実しており、お手軽感はかなり高めでした。(普段、私がScalaで大規模なアプリケーションばっかり書いてるのもあるとは思いますが・・・)
ハッカソンのようなTwitterやLINEの外部APIを利用して、サクッとアプリケーションをデプロイしたい!みたいなユースケースには最適かと思います。

青汁1年分がもらえるらしいので、アドベントカレンダーイベントページでこの投稿にniceをお願いいたします!

参考

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.