LINEのBot開発 超入門（前編） ゼロから応答ができるまで


# 概要

この記事ではLINEで動作するBotを開発する方法をチュートリアル形式で記載しています。カバーする内容は、「寿司の出前を受付するBot」を開発するというもので、LINE側での必要な設定、Bot本体の開発とクラウド環境へのデプロイ、そして自然言語解析を組み込んでユーザーの意図を特定する機能などBotに共通して求められる基本的な動作を含みます。今回のBot本体はNode.jsで作っていきます。

# 必要なスキルと環境

- Node.js/Javascriptの基本的な知識
- Herokuのアカウントを作成済みでHeroku CLIが作業PCにインストールされていること

# 開発の流れ

- まず最初にBotのアカウントを作成します。この作業はLINE Developers コンソールというWebサイトで「Channel」を作成するという作業になります。 *＊以後BotのアカウントのことをChannelと呼びます。*
- 次にBot本体のプログラムを開発し、クラウド上の実行環境へデプロイします。これでBot自体は稼働している状態になります。
- そしてBotのChannelの設定でWebhookを設定し、Botに送信されたメッセージなどを含むイベントがBotのインスタンスに転送されるようにします。
- あとはBot本体のプログラムをカスタマイズしてクラウドにデプロイするという作業を繰り返してBotを拡張していくことになります。


# 手順

## Channelを作成する

[LINE Developer コンソール](https://developers.line.me/ja/)にアクセスし、ログインボタンをクリックして自身のLINEアカウントでログインします。
![login.png](https://qiita-image-store.s3.amazonaws.com/0/26079/869f72dd-d485-d8eb-ec6c-08fc6d60a438.png "login.png")


はじめてログインしたときには開発者登録を求められますので必要事項を入力してください。
![first login.png](https://qiita-image-store.s3.amazonaws.com/0/26079/b78f6caf-7302-c573-8662-8589b58b94c6.png "first login.png")


「はじめる」をクリックして次のスクリーンに移ります。
![get_started.png](https://qiita-image-store.s3.amazonaws.com/0/26079/a1d7bb5e-77c6-2e93-fc8e-25eff50d136c.png "get_started.png")


次にプロバイダーを作成します。プロバイダーとはこれから作成するBotの提供元として表示される情報です。
![welcome_to_console.png](https://qiita-image-store.s3.amazonaws.com/0/26079/a6a3aafd-552c-8ba1-f4c0-078334943741.png "welcome_to_console.png")


必要情報を入力して進んでください。
![new provider.png](https://qiita-image-store.s3.amazonaws.com/0/26079/17c03b9d-954c-1c1c-df87-9f1482dac914.png "new provider.png")


次にChannelを作成します。ChannelにはLINEログインとMessaging APIの2つが存在します。今回作成するのはBotなのでMessaging APIを選択してください。
![new_provider_created.png](https://qiita-image-store.s3.amazonaws.com/0/26079/504bc7c7-0df7-fe92-59a5-5316ca8861ec.png "new_provider_created.png")


こちらの画面で必要情報を入力していきます。
![new channel.png](https://qiita-image-store.s3.amazonaws.com/0/26079/338e030a-06db-e4d8-2a1d-22d973e4b4d5.png "new channel.png")


- アプリ名: **任意のアプリ名**
- アプリ説明: **任意のアプリ説明**
- プラン: **Developer Trial**
- 大業種: **飲食店・レストラン**
- 小業種: **すし**
- メールアドレス: **ご自身のメールアドレス**

これでChannelが作成されますが、まだもう少し設定が必要です。「設定が完了していません」をクリックします。
![configure_channel.png](https://qiita-image-store.s3.amazonaws.com/0/26079/80683ebd-d650-d544-f7c9-df09fc903299.png "configure_channel.png")


メッセージ送受信設定のセクションにあるアクセストークンの「再発行」ボタンをクリックします。
![issue_channel_access_token.png](https://qiita-image-store.s3.amazonaws.com/0/26079/b848603d-e7f2-a5e3-606a-214ba70420c9.png "issue_channel_access_token.png")


そのまま再発行をクリックします。
![reissue.png](https://qiita-image-store.s3.amazonaws.com/0/26079/a191fb50-4ba1-82e5-42d7-f690a6aea67e.png "reissue.png")


これでアクセストークンが発行されます。このトークンはMessaging APIの呼び出し時に必要になります。

あと残りの項目を下記の通り設定します。

**メッセージ送受信設定**

- Webhook送信: **利用する**

**LINE@機能の利用**

- 自動応答メッセージ: **利用しない**
- 友達追加時あいさつ: **利用しない**

これでChannelの設定は**ほぼ**完了です。Bot本体をクラウドにデプロイしてからWebhook URLの設定だけ、後ほどおこないます。
また、これからおこなうBot本体の開発でChannel Secretとアクセストークンが必要になりますのでこのページは開いたまま、次のステッップへ進みます。


## Bot本体（Node.jsのプログラム）を開発する

> 特にWindowsを利用される場合、すべてのソースコードがUTF-8で保存されるように注意してください。また、各ファイルに自動的に.txtなどの拡張子がついていないことを確認してください。

まずソースコードを格納するディレクトリを作成します。今回ディレクトリ名はsushi-botとしておきます。

```
$ mkdir sushi-bot
$ cd sushi-bot/
```

npm initコマンドでpackage.jsonファイルを作成します。

```
$ npm init --yes
```

必要となるnpmパッケージをインストールします。Expressはリクエストの取り扱いを容易にする汎用的なライブラリで、@line/bot-sdkはMessaging APIのNode.js用SDKになります。

```
$ npm install --save express @line/bot-sdk
```

ではこのプログラムの核となるindex.jsファイルをまず下記の通り作成します。

```javascript:index.js
// -----------------------------------------------------------------------------
// モジュールのインポート
const server = require("express")();
const line = require("@line/bot-sdk"); // Messaging APIのSDKをインポート

// -----------------------------------------------------------------------------
// パラメータ設定
const line_config = {
    channelAccessToken: process.env.LINE_ACCESS_TOKEN, // 環境変数からアクセストークンをセットしています
    channelSecret: process.env.LINE_CHANNEL_SECRET // 環境変数からChannel Secretをセットしています
};

// -----------------------------------------------------------------------------
// Webサーバー設定
server.listen(process.env.PORT || 3000);


// -----------------------------------------------------------------------------
// ルーター設定
server.post('/bot/webhook', line.middleware(line_config), (req, res, next) => {
    res.sendStatus(200);
    console.log(req.body);
});

```



## Bot本体をHerokuにデプロイする


Herokuへプログラムをデプロイするにはgitを利用します。
したがってまずローカルファイルシステム上でgitレポジトリを初期化します。

```
$ git init
Initialized empty Git repository in /Users/nkjm/node/sushi-bot/.git/
```

.gitignoreファイルを作成し、gitの管理対象外にしたいファイルを一行一ファイルで列挙します。

```text:.gitignore
npm-debug.log
node_modules
```

Herokuにプログラムの起動方法を教えるための設定ファイル、Procfileを作成します。

```text:Procfile
web: node index.js
```


Heroku CLIを使ってHerokuにログインします。

```
$ heroku login
Enter your Heroku credentials.
Email: あなたのEmail
Password (typing will be hidden): 
Logged in as あなたのEmail
```

続けてHeroku CLIでHeroku上にアプリケーションを作成します。

```
$ heroku apps:create あなたのアプリ名
Creating ⬢ あなたのアプリ名... done
https://あなたのアプリ名.herokuapp.com/ | https://git.heroku.com/あなたのアプリ名.git
```

Messaging APIのSDKで必要となる環境変数をセットします。

```
$ heroku config:set LINE_CHANNEL_ID=あなたのChannel ID
$ heroku config:set LINE_CHANNEL_SECRET=あなたのChannel Secret
$ heroku config:set LINE_ACCESS_TOKEN=あなたのアクセストークン
```


これまでに作成したコードをレポジトリにコミットし、Herokuへデプロイします。

```
$ git add .
$ git commit -m "First commit"
$ git push -u heroku master
// 途中出力省略
remote: Verifying deploy.... done.
To https://git.heroku.com/あなたのアプリ名.git
 * [new branch]      master -> master
```

ちなみにこのデプロイ処理は何度もおこなうので、下記のようなスクリプトを作っておくと楽です。


```shell:deploy.sh
#!/bin/sh

git add . && git commit -m 'Improve' && git push
```

```
$ chmod +x deploy.sh
```




## Webhookを設定する

WebhookはLINEでBotに関連するイベントが発生した場合に、そのイベントをBotインスタンスに通知してもらうためのアクセスポイント（URL）です。

このURLは開発者が指定することができ、そのURLに対してLINEからPOSTリクエストが送信されることになります。今回は下記のURLをWebhookとして設定します。

https://あなたのアプリ名.herokuapp.com/webhook

LINE Developers コンソールでWebhook URLを下記の通り設定します
。

```
https://あなたのアプリ名.herokuapp.com/bot/webhook
```

Webhook URLをセットすると表示させる「接続確認」ボタンをクリックしてWebhookに正しく接続できるか確認します。「成功しました」と表示されればOKです。
![webhook_verify_connection.png](https://qiita-image-store.s3.amazonaws.com/0/26079/8a2521cc-8fb7-896d-aed8-3630143f279d.png "webhook_verify_connection.png")


また、heroku logsコマンドでサーバー側をデバッグ（ログを表示）すると下記のように出力されているはずです。

```
$ heroku logs
//省略
2017-11-29T07:24:54.842751+00:00 heroku[router]: at=info method=POST path="/bot/webhook" host=bootcamp-sushi-bot.herokuapp.com request_id=fc0dc87e-b674-4412-8dcc-1b37a6148bf6 fwd="203.104.156.76" dyno=web.1 connect=0ms service=61ms status=200 bytes=125 protocol=https
2017-11-29T07:24:54.845530+00:00 app[web.1]: { events: 
2017-11-29T07:24:54.845572+00:00 app[web.1]:    [ { replyToken: '00000000000000000000000000000000',
2017-11-29T07:24:54.845574+00:00 app[web.1]:        type: 'message',
2017-11-29T07:24:54.845574+00:00 app[web.1]:        timestamp: 1511940294165,
2017-11-29T07:24:54.845575+00:00 app[web.1]:        source: [Object],
2017-11-29T07:24:54.845575+00:00 app[web.1]:        message: [Object] },
2017-11-29T07:24:54.845576+00:00 app[web.1]:      { replyToken: 'ffffffffffffffffffffffffffffffff',
2017-11-29T07:24:54.845577+00:00 app[web.1]:        type: 'message',
2017-11-29T07:24:54.845577+00:00 app[web.1]:        timestamp: 1511940294165,
2017-11-29T07:24:54.845578+00:00 app[web.1]:        source: [Object],
2017-11-29T07:24:54.845578+00:00 app[web.1]:        message: [Object] } ] }
```

一行目がアクセスログで、status=200となっています。2行目がconsole.log()で出力させた内容で、転送されたイベントのデータとなっています。これでイベントを受信して処理できるようになっていることがわかります。

ここでBotを友達に追加しておきましょう。スマホでLINEを起動し、LINE Developers コンソールのchannelにあるQRコードをスキャンして追加します。iOS版の場合は下記のような手順になります。

![IMG_0027.png](https://qiita-image-store.s3.amazonaws.com/0/26079/2b0d3c7f-e9ec-e47f-add4-e1ffb0e39692.png "IMG_0027.png") ![IMG_0028.png](https://qiita-image-store.s3.amazonaws.com/0/26079/049844ef-7271-251f-e91a-1a98fa6f09b8.png "IMG_0028.png")

> ここまででどうしてもうまく動かない場合、下記のgitコマンドで現時点の動作するコードをダウンロードし、自分のHeroku環境にデプロイできます。

```
$ git clone -b v1 --depth=1 https://github.com/nkjm/bootcamp-sushi-bot.git
$ cp -a sushi-bot/* ./
$ rm -rf sushi-bot
$ git add . && git commit -m 'improving' && git push heroku master
```

## メッセージの返信

それでは、ユーザーがBotに「こんにちは」とテキストメッセージを送ってきたら「これはこれは」と返信するようにしてみます。

まずBotを友達に追加しておきましょう。LINE Developers コンソールで、作成したChannelのQRコードをスマートフォンのLINEでスキャンして友達追加します。

次にindex.jsを編集してコードを追加します。既存のルーター設定の部分を下記のコードで置き換えてください。

```javascript:index.js
//省略

// APIコールのためのクライアントインスタンスを作成
const bot = new line.Client(line_config);

// -----------------------------------------------------------------------------
// ルーター設定
server.post('/bot/webhook', line.middleware(line_config), (req, res, next) => {
    // 先行してLINE側にステータスコード200でレスポンスする。
    res.sendStatus(200);

    // すべてのイベント処理のプロミスを格納する配列。
    let events_processed = [];
    
    // イベントオブジェクトを順次処理。
    req.body.events.forEach((event) => {
        // この処理の対象をイベントタイプがメッセージで、かつ、テキストタイプだった場合に限定。
        if (event.type == "message" && event.message.type == "text"){
            // ユーザーからのテキストメッセージが「こんにちは」だった場合のみ反応。
            if (event.message.text == "こんにちは"){
                // replyMessage()で返信し、そのプロミスをevents_processedに追加。
                events_processed.push(bot.replyMessage(event.replyToken, {
                    type: "text",
                    text: "これはこれは"
                }));
            }
        }
    });

    // すべてのイベント処理が終了したら何個のイベントが処理されたか出力。
    Promise.all(events_processed).then(
        (response) => {
            console.log(`${response.length} event(s) processed.`);
        }
    );
});
```

更新したプログラムをクラウドへデプロイします。先ほど作ったスクリプトを実行しましょう。

```
$ ./deploy.sh
```

正しく動作すれば下図のようになるはずです。「こんにちは」には反応しますが、「おっす」には反応しないという。
![premitive_bot.jpeg](https://qiita-image-store.s3.amazonaws.com/0/26079/13de237b-129c-0343-617e-312afc9e59ac.jpeg "premitive_bot.jpeg")


> ここまででどうしてもうまく動かない場合、下記のgitコマンドで現時点の動作するコードをダウンロードし、自分のHeroku環境にデプロイできます。

```
$ git clone -b v2 --depth=1 https://github.com/nkjm/bootcamp-sushi-bot.git
$ cp -a sushi-bot/* ./
$ rm -rf sushi-bot
$ git add . && git commit -m 'improving' && git push heroku master
```

# 次のステップ

[（後編）メッセージの意図と文脈を意識した会話を実現する](http://qiita.com/nkjm/items/4de41988969e6f17adcb)