GCEからLINEのMessaging APIを使ってみる


Introduction

ぼくはLINEが好きじゃないです.どちらかと言えばSlackを使いたいと思うタイプの人間なのです.
ところが,ぼくの周りにはLINEを多用してやまない人たちがたくさんいます.彼らと共に作業をこなすために,/remind等が使えるbotを作りました.

今回はそのデモを行ってみたいと思います.
恥ずかしいことにぼくはこの道のプロではないので,至らない点は数多くあると思います.ご了承ください.(身内で使うものなんて,動けばなんだって良い.そう思いますよね?)

Environment

UbuntuとNode.jsを使います.

Procedure

さて,では実際の手順を書いていきたいと思います.

Create an instance

Compute Engineからインスタンスを作りましょう.USリージョンのf1-microは1つまで常時無料らしいです.
ここではUbuntu 16.04 LTSを選びます.HDDは30GBまで無料だったはずなのでそうします.

ポイントとしてはトラフィックを許可することと,静的な外部IPを設定するくらいでしょうか.
SSH接続ができるようにしておいてください.

Install Node.js, Nginx, Certbot and MongoDB

早速インスタンスに接続してください.

$ sudo apt-get install build-essential nodejs npm -y
$ sudo npm install n -g
$ sudo n lts
$ sudo apt-get purge nodejs npm -y
$ sudo apt autoremove -y

として,Node.js LTSをインストールします.nが嫌な人は他のものをお使いください.
(参考: Ubuntuに最新のNode.jsを難なくインストールする - Qiita)

次に,

$ curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
$ VCNAME=`cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d= -f2` && sudo -E sh -c "echo \"deb http://nginx.org/packages/ubuntu/ $VCNAME nginx\" >> /etc/apt/sources.list"
$ VCNAME=`cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d= -f2` && sudo -E sh -c "echo \"deb-src http://nginx.org/packages/ubuntu/ $VCNAME nginx\" >> /etc/apt/sources.list"
$ sudo apt-get update
$ sudo apt-get install nginx -y

として,Nginxをインストールします.
(参考: Ubuntuに最新のnginxをインストールする - Qiita)

$ sudo apt-get update
$ sudo apt-get install software-properties-common -y
$ sudo add-apt-repository ppa:certbot/certbot -y
$ sudo apt-get update
$ sudo apt-get install python-certbot-nginx -y

として,Certbotをインストールします.ただし,証明書はまだ取得しないでください.まだドメインがないので出来ないのです.
(参考: Nginx on Ubuntu 16.04 (xenial) - Certbot)

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5
$ echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
$ sudo apt-get update
$ sudo apt-get install mongodb-org -y
$ sudo systemctl enable mongod
$ sudo systemctl start mongod

として,MongoDBをインストールします.
(参考: Install MongoDB Community Edition on Ubuntu - MongoDB)

ここまで,そしてこの先についても,適宜

$ sudo reboot

してください.少なくとも手順に従っていてエラーに出会うことはないはずなので,困ったら再起動です.

Get a free domain

ドメインを取得します.もちろん無料じゃなくても良いですが,今回はFreenomを使うことにします.

ここではqiita.gaを取得しました.

Edit /etc/nginx/conf.d/default.conf

正直,この辺は本当に理解していないので参考程度にしてほしいです.ネスペの友人に助けてもらいたいくらい.

$ sudo vim /etc/nginx/conf.d/default.conf

として,3行目のlocalhostを今しがた取得したドメインに書き換えてください.ここではqiita.gaです.

$ sudo certbot --nginx

として,ようやく証明書を取得します.英語の質問に頑張って答えてくださいね.

これでhttpsが使えるようになったはずです.LINEのWebhookにはセキュアさがマストなのです.

Write code

さて,コーディングを始めましょう.と言いたいところですが,面倒なのでリポジトリを用意しました.boilerplateとは名ばかりで,中身は雑です.

$ git clone https://github.com/shamofu/line-bot-boilerplate.git
$ cd line-bot-boilerplate
$ npm install

コードを実行する前に,.envファイルを埋めましょう.
MONGODB_URIは次の操作で得られます.

$ mongo
MongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3
...
> exit

この場合,MONGODB_URImongodb://127.0.0.1:27017/reminderとしてください.

CHANNEL_で始まる値はMessaging APIのChannel基本設定から得られます.
CHANNEL_SECRET基本情報>Channel SecretCHANNEL_ACCESS_TOKENメッセージ送受信設定>アクセストークン(ロングターム)です.

さて,設定を閲覧したついでに,Webhookを設定しておきましょう.
ここでは,メッセージ送受信設定>Webhook URLhttps://qiita.ga/line/webhookとします.https://(domain)/line/webhookです.

Launch bot

それではbotを起動しましょう!今回はpm2を使います.

$ sudo npm install pm2 -g
$ sudo pm2 startup
$ sudo pm2 start main.js --watch --name=line-bot
$ sudo pm2 save

これでインスタンスを再起動しても自動でbotが立ち上がるようになりました.

あとはNginxにbotを認識させるだけです.

$ sudo vim /etc/nginx/conf.d/default.conf

より,

  1. upstreamを定義
  2. proxyを設定

します.
(参考: nginxでリバースプロキシ - Qiita)

まず1番.serverブロックの上に

upstream line-bot {
    server localhost:1124;
}

を追記してください.

そして2番.

location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
}

の下に,

location /line {
    proxy_pass http://line-bot;
}

proxy_redirect                      off;
proxy_set_header Host               $host;
proxy_set_header X-Real-IP          $remote_addr;
proxy_set_header X-Forwarded-Host   $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;

を追記してください.

Congratulations!

さあ,botを友だちに追加して,こう話しかけてみてください.

/remind
簡単なのだ!
イエオイア!
in 10 seconds

10秒後に想像通りのメッセージを受信するはずです.
最初の行でコマンドを指定,最後の行で日時を指定します.
日時にはin an hour | 3/9 | 3:34 | ...などなど使えます.(参考: chrono-node - npm)

Summary

お疲れ様でした.最初は各々の意味を理解するのに苦労するかもしれませんね.
ですが,思ってたより難しくなかったのではないでしょうか.

自作したbotを友人たちに使ってもらえると嬉しいですね!(一方,万が一にもデータベースをふっ飛ばしたときには...ワナワナ)