本当に手っ取り早いのか?
LINE BOTを作ろうと思いまず最初にぶつかった壁がHTTPSでしかメッセージを受け取れないため証明書を用意しなくてはならない点だった。
Let's encryptなどのサービスを使えばいいのですがやっぱりめんどくさかった...
というわけでBluemixであれば最初からHTTPSでサーバが用意されるのでそれを利用すれば最も手っ取り早いと信じています。
その上無料枠もあるのでこれでずっと無料で...
もちろん問題点もありますがそれはあとで述べます。。。
使用するもの
まずはざっくりと使うものについて
- LINE ビジネスアカウント
- LINE Messaging API
- IBM Bluemix
- Node.js
とりあえずBOT用のアカウント作成
LINE BUSINESS CENTERにアクセスして自分のLINEアカウントでログインします。
そしてビジネスアカウントを用意します。
このあたりは他の記事をご参照ください。
IBM Bluemixのアカウント作成
次にBluemixを使用するためアカウントを作成します。
Bluemixにアクセスして登録を行います。
そして今回のBOTの用に「組織」と「スペース」を作成します。
「地域」や組織名、スペース名は別になんでも構いません。
BOT用のサーバを建てる
それではBluemixでBOT用のNode.jsのサーバを建てます。
SDK for Node.jsにアクセスして適当にアプリ名を入力します。
ホスト名はアプリ名を入力した際に自動で用意されるので気にせずそのまま作成ボタンをクリックします。
LINEからメッセージを受け取るようにする
BOTアカウントに向けて送られてきたメッセージを受け取るようにLINE developersでWebhook URLを設定します。
ここに設定するURLは先程Bluemixで作成したNode.jsのサーバのURLになります。
Bluemixで作成ボタンをクリックした後に遷移したページの上部に「アプリの表示」というボタンがあるのでクリックしてアプリサーバのURLを確認します。
「アプリの表示」をクリックして開いたページのURLをLINE developersのWebhook URLに設定しましょう。
この時http://
ではなくhttps://
でURLが始まるようにしておきます。
さらに末尾に/api
と追加します。
https://設定した名前.mybluemix.net/api
と言った具合になっているはずです。
メッセージを送るためのTokenをメモる
返信するときにTokenが必要になるため生成します。
Webhook URLのすぐ下にあるISSUEボタンを押してChannel Access Tokenを取得します。
表示されたTokenは後で使うのでメモしておいてください。
プログラムを編集する
WEB IDEを有効にする
Web上でプログラムを編集していきます。(手軽ですね)
Bluemixに作成したNode.jsのアプリケーションの詳細ページにアクセスし「概要」を開きます。
中央下部の継続的なデリバリー内にある「Gitリポジトリーの(ry」をクリックします。
ダイアログが出てきて自動的にデプロイするかと尋ねられるので「継続」をクリックします。
しばらくするとGitリポジトリが作成されて先のがぞうのようにGIT URLが表示されるようになります。
表示されたらクリックします。
実際にコードを書き換える
開いたページの右上にあるEDIT CODE
をクリックしてWeb IDEを起動します。
package.json
package.jsonを開きdependencies
にbody-parser
とrequest
を追記します。
body-parser
はLINEから送られてきたメッセージを読み込むため、
request
はNode.jsで簡単にHTTPのリクエストを生成するために使用します。
{
"dependencies": {
"body-parser": "^1.15.2",
"cfenv": "1.0.x",
"express": "4.13.x",
"request": "^2.75.0"
}
}
app.js
次にapp.jsに実際のプログラムを記述していきます。
おそらく最初は以下のようになっているはずです。
/*eslint-env node*/
//------------------------------------------------------------------------------
// node.js starter application for Bluemix
//------------------------------------------------------------------------------
// This application uses express as its web server
// for more info, see: http://expressjs.com
var express = require('express');
// cfenv provides access to your Cloud Foundry environment
// for more info, see: https://www.npmjs.com/package/cfenv
var cfenv = require('cfenv');
// create a new express server
var app = express();
// serve the files out of ./public as our main files
app.use(express.static(__dirname + '/public'));
// get the app environment from Cloud Foundry
var appEnv = cfenv.getAppEnv();
// start server on the specified port and binding host
app.listen(appEnv.port, '0.0.0.0', function() {
// print a message when the server starts listening
console.log("server starting on " + appEnv.url);
});
これはpublicフォルダをウェブ公開用のフォルダにしているだけです。
まずはLINEから送られてくるJSON形式のリクエストを受け付けられるように次の用にコードを追記します。
...
// create a new express server
var app = express();
// ----------ここから----------
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
// --------ここまで追加--------
// serve the files out of ./public as our main files
app.use(express.static(__dirname + '/public'));
これでJSON形式のものを受け付けられるようになりました。
もしかしたらurlencodedは有効にする必要がないかもしれないです...
次にLINEからデータを受け取ってそのまま返信する部分を追記します。
app.use(bodyParser.json()); // さっき追記した部分です
// ----------ここから----------
var request = require('request');
app.post('/api', function(req, res) {
var options = {
method: 'POST',
uri: 'https://api.line.me/v2/bot/message/reply',
body: {
replyToken: req.body.events[0].replyToken,
messages: [{
type: "text",
text: req.body.events[0].message.text
}]
},
auth: {
bearer: 'Channel Access Token' // ここは自分のtokenに書き換える
},
json: true
};
request(options, function(err, res, body) {
console.log(JSON.stringify(res));
});
res.send('OK');
});
// --------ここまで追加--------
// serve the files out of ./public as our main files
app.use(express.static(__dirname + '/public'));
app.post
でPOSTメソッドで送られてくるリクエストを処理することができます。
今回はURLに/api
を指定しています。(これはLINEのWebhook URLで末尾に追加した部分と同じである必要があります)
そして受け取ったリクエストreq
のbodyに入っているメッセージに対しメッセージをそのまま送り返すよう設定をしています。
このとき、送られてきたHTTPのリクエストに対するレスポンスとしてメッセージを返すわけではないのでご注意ください。
返信はリクエストに含まれていたtokenを使用してLINEのMessaging APIに対してメッセージを送ることで行います。
Channel Access Token
の部分にはLINE developersでWebhook URLを取得した際にメモしたTokenに置き換えてください
コードの変更を保存する
package.json
とapp.js
を編集したらプログラミングは完了なので変更を保存します。
画面左側にあるGitのマークをクリックしてください。
そしてコミットメッセージ(1)を入力してコミットというボタン(2)を押してください
画面左側にある発信というところが「発信(1)」となるのでその横のプッシュをクリックしてください
こうすると変更が自動的にサーバに公開されます。
デプロイが完了したか確認する
画面右上のBUILD&DEPLOYをクリックして進捗を確認します。
Deploy Stageがステージの成功となれば問題なくデプロイされています。
ホワイトリストにIPアドレスを追加する
LINEではホワイトリストに登録されたIPアドレスからしかAPIのアクセスを許可していないのでBluemixで作成したアプリケーションサーバのIPアドレスをホワイトリストに追加します。
Bluemixのログを見る
Bluemixのコンソールから今回のアプリの概要ページを開きます。
ログのタブを開き、ログの種類を「アプリケーション(APP)」に変更します。
ここでBOTアカウントに対して何か話しかけてみましょう。
すると以下のような403エラーの内容が出てくるはずです。
ここに記載されているIPアドレス(赤い部分)をLINE developersのServer IP Whitelistページで追加します。
サブネットは指定せずにADDボタンを押しましょう。
しばらく待って反応があれば完成!
完全に反映されるには1,2分くらいかかるようです。
ログに表示されるステータスが403から200に変わったら成功です。
問題点
この構成の大きな問題点が固定IPでないという点です。
アプリをデプロイするたびにIPを見てホワイトリストに追加して上げる必要があります...
ただ一旦デプロイするとそれ以降は変わっていないようなのでデプロイ作業だと思えば面倒ではないですね!
最後まで読んでいただきありがとうございました。
LINEのBOTを作るのも案外簡単ですよね
今回の構成だとWebhook URLで区別できているので、Bluemix上の一つのCloud FoundryアプリケーションでいくつもBOTのを管理するなんてこともできますね。
無料でここまでできるなんていい時代ですホント
どうもありがとうございました。