Posted at

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のアカウントを取得します。








  • LINE@ MANAGERから作成したLINE@アカウントのBOT設定を有効化します。








  • LINE Developersで設定するをクリック。








  • Webhook URLを指定し、Channel Access Tokenをメモしておきます。




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


  • BluemixのカタログページからNode-RED Starterを選択します。







  • 任意のアプリ名を入力して作成ボタンをクリック。その他の項目はそのままでOKです。







  • この画面が表示されればプロジェクトの作成は完了です。







  • ランタイム→環境変数にNode-REDのユーザー認証設定を追加します。NODE_RED_USERNAMENODE_RED_PASSWORDに設定してください。







  • カタログページに戻り、Weather Company Dataをクリックします。







  • 左の接続から、先程作成したNode-REDプロジェクトを指定して作成ボタンをクリックします。







  • ダッシュボード→接続→Weather Company Data→資格情報の表示からurlをメモしておきます。これで事前準備は終了です。




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

メインのロジック部分に入ります。

右上のアプリの表示からNode-REDのフローエディターを開きます。

※FireFoxが推奨環境です。Mac + Chrome環境で、エディターのカーソルがずれる不具合が起きました。

この画面で、先程指定したユーザーネームとパスワードを入力してログインを行います。





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


  • 左側のメニューからinjectノードを配置し、intervalを1 hoursに設定します。





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



  • http requestjsonのノードを以下のように配置します。







  • 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を以下のように配置します。







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








  • 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を以下のように配置します。








  • httpノードをクリックし、MethodをPOST、urlを先程指定したWebhook URLのパスにします。








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


  • リクエストの内容を元に、switchで友だち追加リクエストのときだけ処理を行うように分岐します。







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


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

return msg;


  • cloudantに以下の設定をして、データを保存します。





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


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








  • 先程指定したDatabaseから全データを取得します。







  • 取得したデータの数、POSTリクエストを組み立てます。

    複雑なので画像とコードを全て貼っておきます。







// 重複を排除した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を追加します。







  • 追加したhttp requestにLINE APIのエンドポイント(https://api.line.me/v2/bot/message/push)を設定します。








完成


最終的なフロー





メッセージ


まとめ

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

BluemixもNode-REDも初めて使用しましたが、日本語ドキュメントも充実しており、お手軽感はかなり高めでした。(普段、私がScalaで大規模なアプリケーションばっかり書いてるのもあるとは思いますが・・・)

ハッカソンのようなTwitterやLINEの外部APIを利用して、サクッとアプリケーションをデプロイしたい!みたいなユースケースには最適かと思います。

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


参考