8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

近くのお店で電子マネーが使えるか教えてくれるLINE BotをNode-REDと公式サイトのスクレイピングでさくっとつくる

Last updated at Posted at 2021-07-29

最近引越したのですが、電子マネーが便利すぎて財布を持たずにその辺の店に入ったら現金のみの不意打ちを食らって恥ずかしくなることがあります。それを回避するために「このお店で電子マネー使える?」をすぐ教えてくれるLINE Botがあったら便利だなあと思い、プロトタイプを作ってみました。

できたもの(結果)

Image from Gyazo

今回はWAONが使えるかを調べるものにしてみました。
店舗名をBotに送ると、 https://www.waon.net/shop/ のHTMLを取得してスクレイピングして店舗名を配列で取得し、その配列の中に「ユーザーが送った店舗名」が存在するかしないか、で判断しています。

使ったもの

サービス

Node-RED上で追加インストールしたノード

パレットを管理 からインストールできます。

1. Heroku一発ボタンでNode-REDが使えるサーバーを5分で作る

joeartsea/node-red-heroku - Buttons - Heroku Elements

クリックするだけでお手軽に完了です。
Node-REDのユーザー名とパスワードは初期値のままは避けてしっかり設定しましょう。

2. フロー構成

Screen Shot 2021-07-29 at 20.18.26.png

先頭(左端)はhttp inノード、末尾(右端)は、インストールした ReplyMessageノードです。

1つめ:http in

Screen Shot 2021-07-29 at 20.24.48.png

LINEサーバーからのWebhookを受け付けるノードです。

2つめ:function

Screen Shot 2021-07-29 at 20.29.13.png

スクレイピングを行う次以降のノードでmsg.payloadに入っているLINEメッセージが失われてしまうので、一時的にmsg.lineに退避させています。ここはchangeノードでも同等のことができます。

3つめ:http request

Screen Shot 2021-07-29 at 20.31.15.png

WAON公式の「使えるお店を探す」ページをただただ取得しているだけです。このノードからは取得されたHTMLがそのままmsg.payloadに入って流れてゆきます。

4つめ:html

Screen Shot 2021-07-29 at 20.46.41.png

  1. p.useShopInner_boxText をセレクタとして
  2. 得られた要素の内側のテキストだけを
  3. 得られた数だけ配列にして1つのメッセージにして
  4. msg.payloadに入れて送出

ということをやっています。

Screen Shot 2021-07-29 at 20.49.49.png

実際に店舗名が入っているのがこの箇所だったので、この該当セレクタを全て抜き出して配列化しています。
このあたりは以下の記事を参考にしました。

5つめ:function

debugは省略します。
みんな大好きfunctionノードです。

Screen Shot 2021-07-29 at 20.57.56.png

LINEから来たメッセージはmsg.lineに入っており、メッセージ本文が格納されているのはmsg.line.events[0].message.textと、なんともややこしいところに入っています。ここに入っている文字列は「調べたい店舗名」を想定しているため、この文字列が先ほどの店舗配列が入っているmsg.payloadの中に存在するかを確認します。

そのあと、存在する・しないを表現する「返信メッセージ」を作り、msg.payload.events[0].message.textにそのメッセージを入れて送り出します。

6つめ:ReplyMessage

Screen Shot 2021-07-29 at 21.03.09.png

LINE DevelopersでMessaging APIチャネルを作成し、「チャネルアクセストークン」と「チャネルシークレット」をそれぞれ取得してきてここに入れます。

3. LINE DevelopersでWebhook URLを設定

Screen_Shot_2021-07-29_at_21_06_20.png

HerokuのURLに/webhookというパスを追加したものがエンドポイントとなります。
LINEとの連携において必要な情報はこのWebhook URLのほかにはシークレットとアクセストークンであり、あとはLINE公式アカウントマネージャーで、「応答設定」が以下のようになっているか確認するだけです。

Screen Shot 2021-07-29 at 21.12.07.png

4. インポート用のフロー

この記事で作ったNode-REDのフローを試していただけるJSONを以下に貼っておきましたのでご利用ください。
LINE関係のノードはあらかじめインストールしておいてね!

[{"id":"e8b02747.23f5d8","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"154b2525.fec9db","type":"http in","z":"e8b02747.23f5d8","name":"LINEサーバーからアクセス","url":"/webhook","method":"post","upload":false,"swaggerDoc":"","x":130,"y":40,"wires":[["bba70408.46ab88"]]},{"id":"bba70408.46ab88","type":"function","z":"e8b02747.23f5d8","name":"検索ワードを保持","func":"// LINEサーバーからの情報を「msg.line」に移動させる\nmsg.line = msg.payload;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":40,"wires":[["a8a136b3.2572f8"]]},{"id":"a8a136b3.2572f8","type":"http request","z":"e8b02747.23f5d8","name":"www.waon.net/shop/ へアクセス","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://www.waon.net/shop/","tls":"","persist":false,"proxy":"","authType":"","x":640,"y":40,"wires":[["94932a54.7ab588"]]},{"id":"11d8c7c5.9be6d8","type":"debug","z":"e8b02747.23f5d8","name":"返信メッセージの中身をdebug表示","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload.events[0].message.text","targetType":"msg","statusVal":"","statusType":"auto","x":520,"y":300,"wires":[]},{"id":"94932a54.7ab588","type":"html","z":"e8b02747.23f5d8","name":"店舗名だけ抜き出して配列化","property":"payload","outproperty":"payload","tag":"p.useShopInner_boxText","ret":"text","as":"single","x":940,"y":40,"wires":[["379230a2.79ac6","4d01bc93.b27434"]]},{"id":"379230a2.79ac6","type":"function","z":"e8b02747.23f5d8","name":"検索ワードが店舗一覧の中にあるか?","func":"const searchShop = msg.line.events[0].message.text;\nconst result = msg.payload.findIndex((shopName) => shopName == searchShop);\nmsg.payload = msg.line;\nmsg.payload.events[0].message.text = '電子マネーWAONは「'+searchShop+'」で'+((result == -1)?'のご利用はできません。':'ご利用いただけます。');\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":210,"y":160,"wires":[["567abac0.ee3784","11d8c7c5.9be6d8"]]},{"id":"4d01bc93.b27434","type":"debug","z":"e8b02747.23f5d8","name":"店舗配列をdebug表示","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1220,"y":40,"wires":[]},{"id":"567abac0.ee3784","type":"ReplyMessage","z":"e8b02747.23f5d8","name":"LINEで返信","replyMessage":"","x":590,"y":160,"wires":[]}]
8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?