Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9034

[LINE bot] NowとHerokuで常時起動化させる

$
0
0

この記事の内容

  • LINEボットの完成形、常時稼働化のやり方
  • そもそもモヤついていたところを自分なりにまとめてみた

完成品

(いじってたらなぜかアイコンが黒く怪しくなってしまった・・・どうやって戻すんだろう)
image.png

猿よりは賢いアプリを作った。(ただし、人間ほど完璧な回答はできない。)

  • ?を付けて聞くと文章で返します
  • ?がない時はwikipediaのリンクを返します
  • お猿さんが知らない単語のときは、、無視します。。

QRコード(お友達になってあげてね!)

※このアプリはこの後紹介するHerokuを使ってます。
smartmonky.png

作っていて思ったこと・・・

そもそもexpress,ngrok,now,herokuってそれぞれなんだろう。普通のサーバーと何が違うのだろう。

この辺りがモヤつくポイントだと思うので、自分なりの理解でまとめます。

普通のサーバー

以前、レンタルサーバーにphpファイルを置いて、そこでwebhookを受けて処理をするように作り替えた。
常に動くLINEBOTにお引っ越し(レンタルサーバ+PHP編)

こんなイメージ。
レンタルサーバ.png

Express

Node.jsで利用できるwebアプリケーションフレームワーク。

constexpress=require('express');constapp=express();

requireでExpressを利用可能にし、expressのアプリケーションオブジェクトをappに格納する。
そうすることで、app.post()postリクエスト時の処理や、app.listen()サーバー起動などの処理が簡単に記述できる。

Expressでローカル環境にアプリケーションを構築することができるが、ローカル環境は基本的に外部に公開しないのでLINEbotからの外部とのやりとりができない。
express.png

ngrok

Expressを用いて作った手元のlocalhostにグローバルからアクセスできるようにするトンネリングツール。
設定等はこちらを参照。
ngrokのサブドメインを取得して、その/webhookに対してアクセスすることでngrokを通して、

app.post('/webhook',line.middleware(config),(req,res)=>{....}

の処理を呼ぶことができる。
ただし、PCを閉じてしまうとこのngrokサーバも終了してしまい、常時動かすには不便。
ngrok.png

now

とてもデプロイが簡単なPaas。
サーバにアクセスされるとnow.jsonの設定の通り処理が実行される。
設定等はこちらを参照。
now.png

Heroku

Paas。Gitを使ってデプロイする必要がある。
今回公開しているアプリはHerokuを使っています。なので手順を下記に記載する。

初期化

npm init -y

必要なライブラリインストール

npm i body-parser express

.ignoreファイルの作成

# Dependency directories
node_modules/

# Optional npm cache directory
.npm

1番上の階層にProcfileの作成

web: node index.js

git

初期化

git init

herokuアプリを追加する。アプリケーションネームはお好きな名前を決める。

heroku create アプリケーションネーム

add -> commit -> pushをする

git add --a
git commit -m "commit"
git push heroku master

Nowで常時化

Nowを使って常時動くようにします。先述の通りNowはGitも不要で非常に簡単です。

準備

下記にあるようにngrokで動いていたモノが、nowでは正しい挙動をしない時があったので、前回記事から少し修正をした。
LINE BOTで天気を返すサンプルがngrokで動いてnowで動かない件

コード

linebot-now.js
'use strict';constexpress=require('express');constline=require('@line/bot-sdk');constPORT=process.env.PORT||3000;// 追加constaxios=require('axios');constconfig={channelSecret:'XXXXXXXXXXX',channelAccessToken:'XXXXXXXXXXX'};constapp=express();app.get('/',(req,res)=>res.send('Hello LINE BOT!(GET)'));//ブラウザ確認用(無くても問題ない)app.post('/webhook',line.middleware(config),(req,res)=>{// LINE上で入力されたconsole.log(req.body.events[0].message.text);//ここのif文はdeveloper consoleの"接続確認"用なので後で削除して問題ないです。if(req.body.events[0].replyToken==='00000000000000000000000000000000'&&req.body.events[1].replyToken==='ffffffffffffffffffffffffffffffff'){res.send('Hello LINE BOT!(POST)');console.log('疎通確認用');return;}Promise.all(req.body.events.map(handleEvent)).then((result)=>res.json(result));});constclient=newline.Client(config);asyncfunctionhandleEvent(event){if(event.type!=='message'||event.message.type!=='text'){returnPromise.resolve(null);}letmes=''// console.log(event.message.text);if(event.message.text.indexOf('')>-1){// ?を含んでいる場合にはwikiで検索したものを出して、含んでない場合はurlを返すvarstr=event.message.text;varresult=str.split('').join('');//?を取り除く処理mes=result+'の説明:';//wikiのbodyの前の一言awaitclient.replyMessage(event.replyToken,{type:'text',// text: event.message.text //実際に返信の言葉を入れる箇所text:mes});// このreturnはポイントreturngetBody(event.source.userId,result,mes);//wiki APIで取得できたらプッシュメッセージ}else{varresult=event.message.text;mes=result+'のURL:';//wikiのurlの前の一言awaitclient.replyMessage(event.replyToken,{type:'text',// text: event.message.text //実際に返信の言葉を入れる箇所text:mes});// このreturnはポイントreturngetUrl(event.source.userId,result);//wiki APIで取得できたらプッシュメッセージ}}constgetBody=async(userId,word,message)=>{constres=awaitaxios.get('http://wikipedia.simpleapi.net/api?keyword='+encodeURIComponent(word)+'&output=json');constitem=res.data;console.log(item);awaitclient.pushMessage(userId,{type:'text',text:item[0].body,});}constgetUrl=async(userId,word)=>{constres=awaitaxios.get('http://wikipedia.simpleapi.net/api?keyword='+encodeURIComponent(word)+'&output=json');constitem=res.data;// console.log(item); awaitclient.pushMessage(userId,{type:'text',text:item[0].url,});}(process.env.NOW_REGION)?module.exports=app:app.listen(PORT);console.log(`Server running at ${PORT}`);

Herokuで常時化

Herokuとは

参考
Herokuってなんなの?

ソースコード

linebot-heroku.js
'use strict';constexpress=require('express');constline=require('@line/bot-sdk');constPORT=process.env.PORT||3000;// 追加constaxios=require('axios');constconfig={channelSecret:'XXXXXXXX',channelAccessToken:'XXXXXXXX'};constapp=express();app.get('/',(req,res)=>res.send('Hello LINE BOT!(GET)'));//ブラウザ確認用(無くても問題ない)app.post('/webhook',line.middleware(config),(req,res)=>{//ここのif文はdeveloper consoleの"接続確認"用なので後で削除して問題ないです。if(req.body.events[0].replyToken==='00000000000000000000000000000000'&&req.body.events[1].replyToken==='ffffffffffffffffffffffffffffffff'){res.send('Hello LINE BOT!(POST)');console.log('疎通確認用');return;}Promise.all(req.body.events.map(handleEvent)).then((result)=>res.json(result));});constclient=newline.Client(config);functionhandleEvent(event){if(event.type!=='message'||event.message.type!=='text'){returnPromise.resolve(null);}letmes=''// console.log(event.message.text);if(event.message.text.indexOf('')>-1){// ?を含んでいる場合にはwikiで検索したものを出して、含んでない場合はurlを返すvarstr=event.message.text;varresult=str.split('').join('');//?を取り除く処理mes=result+'の説明:';//wikiのbodyの前の一言getBody(event.source.userId,result);//wiki APIで取得できたらプッシュメッセージ}else{varresult=event.message.text;mes=result+'のURL:';//wikiのurlの前の一言getUrl(event.source.userId,result);//wiki APIで取得できたらプッシュメッセージ}returnclient.replyMessage(event.replyToken,{type:'text',text:mes});}constgetBody=async(userId,word)=>{constres=awaitaxios.get('http://wikipedia.simpleapi.net/api?keyword='+encodeURIComponent(word)+'&output=json');constitem=res.data;// console.log(item); awaitclient.pushMessage(userId,{type:'text',text:item[0].body,});}constgetUrl=async(userId,word)=>{constres=awaitaxios.get('http://wikipedia.simpleapi.net/api?keyword='+encodeURIComponent(word)+'&output=json');constitem=res.data;// console.log(item); awaitclient.pushMessage(userId,{type:'text',text:item[0].url,});}app.listen(process.env.PORT||8080);// console.log(`Server running at ${PORT}`);

どんどん試そう

レンタルサーバを除いて、無料なのでお好きややり方でどんどん試していきましょう!


Viewing all articles
Browse latest Browse all 9034

Trending Articles