この記事の内容
- LINEボットの完成形、常時稼働化のやり方
- そもそもモヤついていたところを自分なりにまとめてみた
完成品
(いじってたらなぜかアイコンが黒く怪しくなってしまった・・・どうやって戻すんだろう)
猿よりは賢いアプリを作った。(ただし、人間ほど完璧な回答はできない。)
- ?を付けて聞くと文章で返します
- ?がない時はwikipediaのリンクを返します
- お猿さんが知らない単語のときは、、無視します。。
QRコード(お友達になってあげてね!)
作っていて思ったこと・・・
そもそもexpress
,ngrok
,now
,heroku
ってそれぞれなんだろう。普通のサーバーと何が違うのだろう。
この辺りがモヤつくポイントだと思うので、自分なりの理解でまとめます。
普通のサーバー
以前、レンタルサーバーにphpファイルを置いて、そこでwebhookを受けて処理をするように作り替えた。
常に動くLINEBOTにお引っ越し(レンタルサーバ+PHP編)
Express
Node.jsで利用できるwebアプリケーションフレームワーク。
constexpress=require('express');constapp=express();
requireでExpressを利用可能にし、expressのアプリケーションオブジェクトをappに格納する。
そうすることで、app.post()
postリクエスト時の処理や、app.listen()
サーバー起動などの処理が簡単に記述できる。
Expressでローカル環境にアプリケーションを構築することができるが、ローカル環境は基本的に外部に公開しないのでLINEbotからの外部とのやりとりができない。
ngrok
Expressを用いて作った手元のlocalhostにグローバルからアクセスできるようにするトンネリングツール。
設定等はこちらを参照。
ngrokのサブドメインを取得して、その/webhookに対してアクセスすることでngrokを通して、
app.post('/webhook',line.middleware(config),(req,res)=>{....}
の処理を呼ぶことができる。
ただし、PCを閉じてしまうとこのngrokサーバも終了してしまい、常時動かすには不便。
now
とてもデプロイが簡単なPaas。
サーバにアクセスされるとnow.jsonの設定の通り処理が実行される。
設定等はこちらを参照。
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で動かない件
コード
'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とは
ソースコード
'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}`);
どんどん試そう
レンタルサーバを除いて、無料なのでお好きややり方でどんどん試していきましょう!