超絶簡単！LINE bot開発

## はじめに
この記事は超絶簡単にLINE APIで開発する方法について解説します。[@nObisukeさんの記事](https://qiita.com/n0bisuke/items/909881c8866e3f2ca642)に影響されて書きました。
環境構築の方法は上記の記事を参考にしてます。流石に丸パクリはしたくないので、サンプルコードに自分なりの修正を加えました。

---
##  参考記事との違う点

1. アクセストークンとシークレットキーを環境変数を用いて呼び出す
2. 各メッセージごとの処理をswitch文で実装
3. 全タイプのメッセージを網羅

---

## 今回用いる開発ツール

- [Messaging API](https://developers.line.biz/ja/reference/messaging-api/)
- [Firebase](https://console.firebase.google.com/?hl=ja)
- [Node.js](https://nodejs.org/ja/)
- [express](http://expressjs.com/ja/)

---
## Messaging API
---
#### ざっくりとした説明
端的に言うとLINE botが作れるツール。
開発者は専用のLINEアカウントを作ることで思い思いのLINE bot開発が出来る。詳しい内容は[@kenakamuさんの記事](https://qiita.com/kenakamu/items/b2580f2546b925832045)を読もう。
Botアカウントの登録は[ここ](https://developers.line.biz/ja/)でする。

---
#### LINE botの開発（サーバ・クライアント）
- クライアント
    - サーバにメッセージを送る
    - LINEアプリがその役割を担う
- サーバ
    - メッセージを受け取りレスポンスを返す
    - **実際に開発するのはこちら側**

---
#### LINE botの開発（公式SDKに対応する言語）
- **[Node.js](https://github.com/line/line-bot-sdk-nodejs) <- 今回用いるのはこれ**
- Java
- PHP
- Python
- Go
- Perl
- Ruby

---
#### LINE botの開発（LINEから受け取るメッセージ）

- テキスト
- 画像
- 位置情報
- 音声
- 動画
- ファイル
- スタンプ
- [LINE Things(自動通信)](https://qiita.com/ufoo68/items/5009a2d87843430ed545)

---
#### LINE botの開発（サーバ環境の構築）
[Firebase](https://firebase.google.com)を使うと超絶楽。
プロジェクト開発には[Firebase CLI](https://firebase.google.com/docs/cli/?hl=JA)を使おう。
```npm install -g firebase-tools```
インストールしたらログインしよう。
```firebase login```

---
#### LINE botの開発（サーバ環境の構築）
プロジェクト用のディレクトリ（フォルダ）を作って
```firebase init```
と打つとプロジェクト用のファイルを作ってくれる。事前にプロジェクトの作成をサイト上で登録している必要がある。
開発したソースコードは`functions`のフォルダの中に入る。

---
#### LINE botの開発（サーバ環境の構築）
`firebase.json`の設定

```JavaScript:firebase.json
{
    "hosting": {
        "public": "./",
        "rewrites": [{
            "source": "/webhook",
            "function": "app"
        }],
        "ignore": [
            "firebase.json",
            "**/.*",
            "**/node_modules/**"
        ]
    }
}
```

この`rewrite`の設定が重要になる。

---
#### LINE botの開発（サーバ環境の構築）
必要なパッケージをインストールする。
今回は`express`というフレームワークを使います。

```bash
cd functions
yarn add @line/bot-sdk express
```

---
#### LINE botの開発（サーバ環境の構築）
`/functions/package.json`の設定

```JavaScript:/functions/package.json
{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "serve": "firebase serve --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "dependencies": {
    "@line/bot-sdk": "^6.7.0",
    "express": "^4.16.4",
    "firebase-functions": "^2.2.0"
  },
  "private": true,
  "engines": {
    "node": "8"
  }
}
```
ここは初期設定で問題なし！

---
#### LINE botの開発（サーバ環境の実装）
まず必要なキーが二つ

- Channel Secret
- アクセストークン（ロングターム）

これらは各チャンネルの基本設定より入手可能

---
#### LINE botの開発（サーバ環境の実装）
各キーをFirebaseの機能を使って環境変数として登録する。

```bash
firebase functions:config:set channel.secret="your secret key"
firebase functions:config:set channel.accesstoken="your accesstoken"
```

設定の確認方法は↓

```bash
firebase functions:config:get
```

---
#### LINE botの開発（サーバ環境の実装）
[練習用コード](https://github.com/ufoo68/messageApiTraining)を用意しときました。

```javascript:index.js
'use strict';

const functions = require('firebase-functions');
const express = require('express');
const line = require('@line/bot-sdk');
// https://www.npmjs.com/package/line-message-builder
const message = require('line-message-builder');

// channel secretとaccess tokenをFirebaseの環境変数から呼び出す
const config = {
    channelSecret: functions.config().channel.secret,
    channelAccessToken: functions.config().channel.accesstoken
};

const app = express();
//URL + /webhookで登録したWebhook URLが呼び出されたときに実行される。
app.post('/webhook', line.middleware(config), (req, res) => {
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);
//ユーザから受け取ったイベントについてのハンドリングを実装する
async function handleEvent(event) {
    //ユーザから送られた各メッセージに対する処理を実装する。
    //https://developers.line.biz/ja/reference/messaging-api/#message-event を参照。
    switch (event.message.type) {
        case 'text':
            return client.replyMessage(event.replyToken, message.buildReplyText('テキストを受け取りました。'));

        case 'image':
            return client.replyMessage(event.replyToken, message.buildReplyText('画像を受け取りました。'));

        case 'video':
            return client.replyMessage(event.replyToken, message.buildReplyText('動画を受け取りました。'));

        case 'audio':
            return client.replyMessage(event.replyToken, message.buildReplyText('音声を受け取りました。'));

        case 'file':
            return client.replyMessage(event.replyToken, message.buildReplyText('ファイルを受け取りました。'));

        case 'location':
            return client.replyMessage(event.replyToken, message.buildReplyText('位置情報を受け取りました。'));

        case 'sticker':
            return client.replyMessage(event.replyToken, message.buildReplyText('スタンプを受け取りました。'));
        default:
            return Promise.resolve(null);
    }
}

exports.app = functions.https.onRequest(app);
```

このコードより、`exports.app`が`rewrites`の`function`、`/webhook`が`rewrites`の`source`に対応する。

---
#### LINE botの開発（サーバへデプロイ）
以下のコマンドで可能

```bash
firebase deploy --only functions
```

Firebaseは無料枠ではサーバ側でリクエストをはじかれてしまうので、有料にする必要があります。オススメは従量課金のBlazeです。

---
#### 補足
以下のツールを使うとBotのUIをもっと拡張できる

- [Flex Message](https://developers.line.biz/ja/docs/messaging-api/using-flex-messages/)
- [リッチメニュー](https://developers.line.biz/ja/docs/messaging-api/using-rich-menus/)
- [クイックリプライ](https://developers.line.biz/ja/docs/messaging-api/using-quick-reply/)

[LIFF](https://developers.line.biz/ja/docs/liff/overview/)はMessaging APIとの組み合わせが公式非推奨になってしまった。。。


---
#### さいごに
今回はMessaging APIを使ってLINE botを開発する方法について書きました。
他にもLINEプラットフォームでは[LINE Clova](https://clova.line.me/)や[LINE Things](https://developers.line.biz/ja/docs/line-things/)とかもサポートしています。
既に各ツールを使った開発の記事は書いていますが。また次回以降にそれぞれの開発方法についても書いていこうと思います。