JavaScript
Node.js
Line
linebot
LINEmessagingAPI

1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest

この資料について

  • この資料をハンズオンなどに活用してNode.js普及を促進させてもらえたら幸いです。
    • 使うときにコメント欄にコメント貰えると嬉しいです!
    • ハンズオン進めてみた感想などもコメント貰えると嬉しいです!
  • 会の流れとしてはハンズオン -> もくもく会 -> (可能な人は)もくもく会で作ったBOTを発表という流れです。
  • アップデート
    • 2018/3/14 ngrokのインストールをnpm経由に変更


はじめに

  • 対象者: Node.js初心者向け
  • 目的: LINE BOTを作ってNode.jsに触れる
  • ゴール目標: LINE BOTを作ってデプロイする
  • 性質上、Node.js以外の話の方が多いかも
  • 1Hしかないのでコード理解よりも動くものを
  • 早く終わった人はもくもくタイム

自己紹介


LINE BOT

  • LINE上で動作するBOT
  • 様々なプログラムと連携させることができる
  • LINE自体のユーザー数が多いことで、追加でアプリインストールがほぼ不要なことが利点
  • LINEがUIになるのでUIを考える手間が少なく、サーバーサイドエンジニア的に嬉しい

事例: みずほ、出前館


事例: ヤマト運輸


LINE Messaging API

LINE BOTを作るためのAPIです。

Messaging APIを利用することで、あなたのサービスをLINEのトークルーム上で提供することができます。
LINEユーザー一人一人に合わせたユーザー体験を提供できます。


スクリーンショット 2017-02-05 9.10.01.png


Push APIとReply API

スクリーンショット 2017-02-05 9.09.22.png

基本的にPushとReplyの二つのAPIがあります。

PushはBotアプリケーション側が起点となってユーザーにアクションします。
Replyはユーザーの発言を起点としてBotアプリケーションを呼び出します。


作ってみよう


1. Botアカウントを作成する

LINEのBotはTwitterなどと違い、通常のユーザーのアカウントをBot化することは出来ず、専用のアカウントを作る必要があります。

まずはLINE developerのサイトMessagin APIのページにアクセスします。

二つあるボタンの右側の 「Messaging APIを始める」を選択しましょう。


LINEへのログイン

LINEアカウントへのログインを求められます。

設定がまだの方はLINEのスマートフォンアプリ画面から 設定>アカウントでメールアドレスを設定できます。

LINEでメールアドレスを新規登録・確認・変更・登録解除(削除)する方法


プロバイダー登録


BOT情報

  • Developer Trial

MessagingAPIを利用したBotを試すプランです。友だちとメッセージの送受信を行うことができます。
※追加可能友だち数は50人に制限されています。また、Developer Trialからプランの切り替えやプレミアムIDの購入はできません。

  • フリー

MessagingAPIを利用したBotを開発するプランです。友だちの人数に制限はありませんが、Push messagesを利用してBotから友だちにメッセージを送信することはできません。
※サービス拡張に向けプラン変更が可能です。

今回はDeveloper Trialを選択


Botの設定確認

Bot設定の画面に遷移します。 利用可能なAPIの項目にREPLY_MESSAGEPUSH_MESSAGEの二つが表示されていることを確認して下さい。

一番最初の画面の選択で 「Developer Trialを始める」を選択していれば大丈夫ですが、 「Messaging APIを始める」を選択していた場合はREPLY_MESSAGEしか利用できません。

また設定ですが、にWebhook送信を「利用する」にしましょう。
その他は以下の設定にしておくことをオススメします。

  • Webhook送信: 利用する
  • Botのグループトーク参加: 利用する
  • 自動応答メッセージ: 利用しない
  • 友達追加時あいさつ: 利用する

それぞれ設定が終わったら「更新」を選択しましょう。


Botと友達になろう

画面下部にあるLINEアプリへのQRコードを確認します。

ここで表示されるQRコードを使って、自分が作成したBotアカウントと友達になりましょう。

ここからはスマートフォン画面のキャプチャになります。

QRコードリーダーを開きBotを友達追加しましょう。

「追加」を選択します。

「同意する」を選択します。

Botが友達に追加されました。


2. Node.jsでBot開発

ここからは手元のターミナルなどでの作業がメインになります。
Node.jsのインストールがまだの方は参考記事などをもとに準備をして下さい。


ちなみに、筆者の環境は以下になります。

  • Node.js v9.2.0
  • npm v5.5.1
  • macOS High Sierra 10.13

プロジェクトを作成とハローワールド

Node.jsのプロジェクトはpackage.jsonがあるディレクトリが起点となります。
まずはnpm initコマンドpackage.jsonを作成します。

$ mkdir mylinebot
$ cd mylinebot
$ npm init -y
Wrote to /Users/n0bisuke/dotstudio/2_events/20171125_nodefest/linebot/mylinebot/package.json:

{
  "name": "mylinebot",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

次に依存モジュールを追加します。 今回はこちらのSDKを利用します。

ちなみに以前は公式のNode.js SDKが無かったので依存なしでも書いてました。

$ npm i --save @line/bot-sdk express

次にプログラムのメインとなるserver.jsを作成します。

$ touch server.js

ディレクトリ内は現状こんな感じ

$ ls
server.js            node_modules      package-lock.json package.json

エディタでserver.jsを編集します。
以下をコピー&ペーストしましょう。

server.js
'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;

const config = {
    channelAccessToken: '',
    channelSecret: ''
};

const app = express();

app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: event.message.text //実際に返信の言葉を入れる箇所
  });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);

Channel Secretとアクセストークンの確認

先ほどの「LINE developers」の画面でChannel SecretChannel Access Tokenを確認します。

  • Channel Secret確認

  • アクセストークン発行


server.jsのソースコードのchannelAccessTokenchannelSecretの部分に値を指定しましょう。

アプリケーションを起動してみます。

$ node server.js

起動すると以下がターミナルに表示されることを確認しましょう。

Server running at 3000

3. ngrokでトンネリング


LINE Botを作るためにはWebhookURLをLINE developersに登録する必要があります。


この際SSLが必須になるのですが証明書取得などの手間もありますし、PaaSなどにホスティングして試すのはデバッグが大変なので、手元のPCのlocalhostにグローバルからアクセスできるようにするトンネリングツールを利用しましょう。

などが有名です。今回はngrokを利用します。


まずはngrokのサイトにいき、本体をダウンロードして解凍します。

この辺の手順を更新しました。(2018/3/14)

npm経由でngrokをインストールできます。

https://www.npmjs.com/package/ngrok

$ npm i -g ngrok

次にトンネリングサーバーを起動します。 ngrok http ポート名と指定します。
今回はNode.jsアプリケーションを3000番ポートで利用するので3000を指定しましょう。

$ ngrok http 3000

ngrok by @inconshreveable                                    (Ctrl+C to quit)

Session Status                online
Account                       n0bisuke (Plan: Free)
Version                       2.1.18
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://1148cbd9.ngrok.io -> localhost:3000
Forwarding                    https://1148cbd9.ngrok.io -> localhost:3000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

起動すると表示されるhttps://で始まるアドレスを利用します。
この場合はhttps://1148cbd9.ngrok.ioです。このアドレスは起動の度に変わるため、ngrokは起動し続けて開発を行うことをおススメします。


以下のように、ngrokのプロセスとNode.jsアプリケーションのプロセスを並行して実行しての開発になります。


Webhook URLの更新

https://1148cbd9.ngrok.io/webhookがWebhook URLになります。

LINE developers画面のWebhook URLを更新します。

ここに先ほどのアドレスを指定しましょう。


この状態でBotに話しかけてみて下さい。

Botがおうむ返ししてくれます。


4. nowでデプロイ

nowって?



インストール

$ npm i -g now

デプロイ

package.jsonに"start"を追加

package.json


  "scripts": {
    "start": "node server.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  }, 



$ now

途中で[y|N]と聞かれるのでyをタイプすれば完了です。


Webhook URLの更新

先ほどの例の場合mylinebot-vqjnolsqqc.now.shにデプロイされています。

mylinebot-vqjnolsqqc.now.sh/webhookをWebhook URLに指定しましょう。


補足資料

  • event.message.textがユーザーから送られてきた文字列
  • こんにちはとBOTに送るとこんばんわの時間ですよと言われて、それ以外だとうざと返されるプログラムが以下になります。
  • client.replyMessage()でBOTのリプライになります。
server.js

省略


function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  let replyText = '';
  if(event.message.text === 'こんにちは'){
    replyText = 'こんばんわの時間ですよ';
  }else{
    replyText = 'うざ';
  }

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: replyText
  });
}

省略



補足資料その2

npm i --save axios
server.js
'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
const PORT = process.env.PORT || 3000;

const config = {
    channelAccessToken: '',
    channelSecret: ''
};

const app = express();

app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  let mes = ''
  if(event.message.text === '天気教えて!'){
    mes = 'ちょっとまってね'; //待ってねってメッセージだけ先に処理
    getNodeVer(event.source.userId); //スクレイピング処理が終わったらプッシュメッセージ
  }else{
    mes = event.message.text;
  }

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: mes
  });
}

const getNodeVer = async (userId) => {
    const res = await axios.get('http://weather.livedoor.com/forecast/webservice/json/v1?city=400040');
    const item = res.data;

    await client.pushMessage(userId, {
        type: 'text',
        text: item.description.text,
    });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);

補足資料その3

花粉ボットと実装サンプル


応用

  • Node.jsの最新バージョンを教えてくれるBOTを作ってみよう
  • 時間までもくもくLINE BOT開発しましょう!

応用回答例: Node.jsの最新を教えてくれるBOT 答え合わせ

  • Node.jsの最新バージョン教えて!と言われたらとりあえずちょっと待ってねとリプライメッセージ
  • https://nodejs.org/ja/ にスクレイピングしにいって、完了したらプッシュメッセージで教えてくれる
  • async/awaitでaxiosのHTTPリクエストとLINE MASSAGING APIへのリクエストを同期処理的に記述

axiosを追加インストール

npm i --save axios
server.js
'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: '',
    channelAccessToken: ''
};

const app = express();

app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  let mes = ''
  if(event.message.text === 'Node.jsの最新バージョン教えて!'){
    mes = 'ちょっとまってね'; //待ってねってメッセージだけ先に処理
    getNodeVer(event.source.userId); //スクレイピング処理が終わったらプッシュメッセージ
  }else{
    mes = event.message.text;
  }

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: mes
  });
}

const getNodeVer = async (userId) => {
    const res = await axios.get('https://nodejs.org/ja/');
    const item = res.data;
    const version = item.match(/最新版"  data-version="(.*?)">/)[1]; //正規表現で(無理やり)取得
    console.log(version);

    await client.pushMessage(userId, {
        type: 'text',
        text: `今の最新は${version}だよ!`,
    });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);

レポート: 参加者の方々が作ったBOTを紹介(ハンズオン後に追記)

もくもくタイムは20min程度でしたが、皆さんすごいです。

1. Node.jsの最新バージョン+ヤフー検索ができるBOT

応用課題で出していたNode.jsのバージョンを教えてくれる機能もLTSと最新版の両方に対応してくれました。
スクレイピングの勢いでヤフー検索まで繋いでいます。

2. 調べたい単語を入れるとWikipediaの検索結果を返してくれるBOT

これめっちゃ便利です。
Wikipediaまでわざわざ調べに行かなくても色々な言葉の概要を知ることができます。

3. URLを入れると話題のdev.toとどっちが速いかを教えてくれるBOT

話題ですね。

dev.toと阿部寛のホームページについてちゃんと計測させてくれ

dev.toと入力したサイトのどちらが早いか計測してくれます。
トレンドを捉えるアイディアの柔軟性がすごい。

4. 今日のご飯何にするかを絵文字で提案してくれるBOT!

ご飯何にしようか迷いますよね。
絵文字で推薦してくれるのでもう迷わない......!

コード指定すればNode.jsからも絵文字扱えるんだよっていう良い例だと思います。

5. 何でも人に聞く人にググらせるBOT

「調べる前になんでも人に聞く人を駆逐したい」らしいです笑

検索ワードを入れるとググれってことでGoogleに飛ばされます。
ハンズオンで触れていないリッチメニューまで活用してくれました。

6. Polymerと会話?できるBOT

Polymerが好きすぎてPolymerちゃんと会話できるBOTを作ったそうです笑

7.検索ワードを入れるとunsplash.comから画像を取得してくるBOT

画像検索も出て来ました。
画像扱えるとビジュアルが圧倒的に良くなりますね。


まとめと所感

Node.jsとNowを使うと爆速でLINE BOTを作れますし、細かいものを作るときにこの組み合わせはかなり使えます。 (デバッグの際はngrokがおすすめ)

応用してどんどん開発していきましょう。

見て回った限り、大半の人がデプロイまでたどり着くことができて、7人もオリジナルBOTを作って発表までできるのはさすがの学園祭的なレベルの高さを感じます。

時間内に終わらなかった人もこの記事を見直してチャレンジしてもらえたら幸いです。

参加してくださった皆さんありがとうございました!