LINE BOTをHeroku + Node.jsでやるまで

この投稿は LINEBot&Clova Advent Calendar 2018の16日目の投稿です。お邪魔します。

# この記事でやること

![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/f4aab4d8-4fda-c6d9-a536-af2e57f6631d.png)
上のようなLINE BOTを動かすまでのステップを説明していきます。
これからLINE BOTをやってみようかな、という人向けの記事です。(JavaScript/Node.jsをちょっと知ってる前提ですが、頑張れば知らなくてもできるかも。)
手順解説なので長くなってしまいましたが、沿って行けばLINE BOTを動かすことができるはずです。
冬休みも近いので、ぜひやってみましょう！

ここで使う道具は以下の通りです。

- Windows 10 PC
- コマンドプロンプト
- LINEアカウント(プライベートのでOK)
- Heroku
  - PaaSです。linebotからのメッセージを処理して返事するAPIサーバとして利用します。Herokuである必要はありません。私が選んだ理由は[公式でガイド](https://developers.line.biz/ja/docs/messaging-api/building-sample-bot-with-heroku/)があり、自身でAPIサーバ建てたことないためですが、要はRest APIができれば何でもよかったです。**Herokuとlinebotはちゃんと疎結合**です。でもHerokuはサーバの面倒ごとを全部引き受けてくれるので楽です(特に`git push`すれば勝手にデプロイされるのが楽)。自由にやりたい人には逆に苦痛かも。
- Node.js
  - サーバサイドでJavaScriptを動かすプログラムです。
- [line-bot-sdk-nodejs](https://github.com/line/line-bot-sdk-nodejs)
  - LINEのボットサーバ開発で必要なことをラッピングしてくれているものです。requireして使います。以前はこれを使わずにやっていたのですが、今回記事を書くにあたって使ってみるとすごい楽になった！おすすめです。

# 手順

1. 道具を準備
2. LINE@アカウントの作成
3. ボットサーバの開発

# 構成図

[公式](https://developers.line.biz/ja/docs/messaging-api/overview/)より。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/a107502c-a719-da75-e345-4a4f0db75f8f.png)

上図の[Messaging Servers]というところを「ボットサーバ」として、Heroku＋Node.jsで構築していきます。

# [手順1]道具を準備

道具を準備していきます。

## Windows 10 PC

[買います](http://kakaku.com/pc/note-pc/itemlist.aspx?pdf_Spec103=2&pdf_Spec201=2600-&pdf_Spec301=14.5-&pdf_Spec307=128-&pdf_Spec308=8-)。

## コマンドプロンプト

`Windowsボタン`を押して`cmd`と入力すると検索結果に`コマンドプロンプト`が出てきます。

## LINEアカウント

もってますよね？もってなければ[こちら](https://line.me/ja/download)から！友達とアカウント交換しましょう！

## Node.jsとHerokuの準備

以下の記事に沿って作成してください。Rest APIでJSONを返すまでを解説しています。
[裸の窓使いがHerokuにNodeでRestAPIで「こんにちは」するまで](https://qiita.com/TakuTaku04/items/6ecc533385559f4660bd)

# [手順2]LINE@アカウントの作成

優しいくわかりやすい人の記事を引用いたします。
[LINE BOTの作り方を世界一わかりやすく解説（１）【アカウント準備編】](https://qiita.com/yoshizaki_kkgk/items/bd4277d3943200beab26#line-business-%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90)

# [手順3]ボットサーバの開発

ボットサーバとして使うサーバは、[Node.jsとHerokuの準備](#nodejsとherokuの準備)で準備したHerokuのインスタンスを使用します。
これをボットサーバとして機能するように修正していきます。
必要なことは、

- LINE Developersからチャネルの開設してChannel Secretとアクセストークンを取得
- Heroku上のREST APIをLINE BOTのWebhookに反応できるように修正
- LINE DevelopersでREST APIのURLをWebhookとして設定

です。Webhookとは、LINEプラットフォームからボットサーバへ送信されるリクエストとそれに対するレスポンスをさします。ボットサーバのURLをWebhook URLとしてLINE Developersで設定することで、接続が可能となります。

## LINE Developersからチャネルの開設してChannel Secretとアクセストークンを取得

[チャネル]がいわゆる[友達]にあたるものです。そのチャネルからデータの送受信をしますが、その時に以下の2つの情報利用が必要になります。

- 当該チャネルからの通信であることを証明するための[Channel Secret]
- メッセージ送受信するためのトークンとして利用する[アクセストークン]

ここではチャネルを開設し、上記2つをを取得します。

1. [LINE Developers](https://developers.line.biz/ja/)のサイトから、[プロダクト] - [Messaging API] - [今すぐ始めよう]に進んでください
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/b0cc45e7-207a-3867-ceb4-4fda54c2ae89.png)
1. [プロバイダ]が出ていると思うので、選択して[次のページ]を押してください。なければ、[新規プロバイダー作成]でよいです(この場合プロバイダ名を設定することになります。任意の名前でOKです)。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/55be95c0-e7d0-1569-503f-ba92e1e82aca.png)
1. アプリ名やアイコンを決定していきます。ここで[プラン]選択に[Developer Trial]と[フリー]が出ると思います。[Developer Trial]のほうはpush通知ができますが友達が50人までに制限されます。[フリー]はpush通知はできませんが友達数は無制限です。今回はpush通知はしないので、ここでは[フリー]を選択します。練習なので、業種なんかは適当でよいです。確認ボタンを押すと確認事項のダイアログが出てくるので、同意します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/7ec0830e-71cd-1957-f484-282becb4ce7b.png)
2. 確認画面にくるので、問題なければ[作成]を押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/ab3d5e14-18f3-6dc6-ff44-78b11da5198c.png)
1. 少し待つとチャネルが作成されます。
 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/7b3707bb-5f51-f2e9-3461-5e23276370ee.png)
1. チャネルをクリックして[チャネル基本設定]タブ - [基本情報] - [Channel Secret]を確認します。これを後ほどHeroku側で使い、発行されたリクエストがこのチャネルからのものかを検証するために使います。(以下のChannel Secret配下黒塗りの部分)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/a1fce5a2-910e-2b10-18de-e4cffe9aba02.png)
1. 同じく[チャネル基本設定]タブ内の、 [メッセージ送受信設定] - [アクセストークン(ロングターム)] - [再発行]を押してトークンを取得します。(初めてでも[再発行]です。)古いアクセストークンの失効時間を設定させるダイアログがでますが、まだ持ってないので0時間でよいです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/675413b8-ed86-a012-1486-00dbff98dfc2.png)
1. 少しするとアクセストークンが表示されます(以下の黒塗りの部分、結構ながい)。これも後ほどHeroku側で使用していきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/4672c592-a558-592f-7ede-e80b975dc577.png)

## Heroku上のREST APIをLINE BOTのWebhookに反応できるように修正

続いてボットサーバを実装していきます。ここがメインの作業です。
[Node.jsとHerokuの準備](#nodejsとherokuの準備)で作成したインスタンスの`index.js`を修正していきます。

まずはREST APIを用意します。Messaging APIはPOSTでリクエストされてくるので、POSTに反応できる口を作ります。ここでは"./hook"をインターフェースとします。

```javascript:index.js
const express = require('express')
const path = require('path')
const PORT = process.env.PORT || 5000

express()
  .use(express.static(path.join(__dirname, 'public')))
  .set('views', path.join(__dirname, 'views'))
  .set('view engine', 'ejs')
  .get('/', (req, res) => res.render('pages/index'))
  .get('/g/', (req, res) => res.json({method: "こんにちは、getさん"}))
  .post('/p/', (req, res) => res.json({method: "こんにちは、postさん"}))
  .post("/hook/", (req, res) => res.json({ test: "hook" }))// 追加
  .listen(PORT, () => console.log(`Listening on ${ PORT }`))
```

`heroku local`コマンドでローカルサーバを立ち上げ、curlコマンドでPOSTしてみます。

```console:コマンドプロンプト
$ curl -X POST localhost:5000/hook
{"test":"hook"}
```

思った返事です。pushします。

```console:コマンドプロンプト
$ git add .
$ git commit -m "add lineBot"
$ git push heroku master
```

いろいろわーっと出て問題なければ完了します。
curlで、今度はサーバ側に届くか確認してみましょう。

```console:コマンドプロンプト
$ curl -X POST https://Herokuのアプリ名.herokuapp.com/hook
{"test":"hook"}
```

ベネ(よし)。
ではこれで「LINE DevelopersでREST APIのURLをWebhookとして設定」をやってみちゃいましょう。(えっ？て思った方もとりあえず)

### LINE DevelopersでWebhookを設定

まずは、Webhookを有効にします。[チャネル基本設定]タブ - [メッセージ送受信設定] - [Webhook送信] - [編集]で[利用する]を選択し[更新]を押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/a687b2b3-1dce-eeef-cfac-88324dd1f7e5.png)

次に直下にある[Webhook URL]に、Herokuに用意したREST APIのURLを入れます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/b05b28a4-4249-914f-7bf8-c899c2217dce.png)

最後に、[接続確認]ボタンで接続を確認します。直下に「成功しました」と出ればOKです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/e7960975-e101-9c4a-f427-00d7dadd4447.png)
なお、Herokuは無料プランだと最後の動作から30分でスリープする設定になっています。そのため、久しぶりに接続確認を行うとタイムアウトで接続確認に失敗することがあります。その場合は、再度行ってみると成功するかと思います。

ついでに、同じ画面で[LINE@機能の利用]から[自動応答メッセージ]と[友達追加時あいさつ]をオフにしておきましょう。イベントはこちらでハンドリングするので、いらないものは止めておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/cc2328bc-1e60-b4e5-ff82-1047a35c37d7.png)

また、同じ画面の下にある[LINEアプリへのQRコード]から、自身のスマホで友達登録をしておきましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/04ee1852-9c2c-33ae-8c21-83b4c5693dd9.png)

さて、これで繋がりました。良かった良かった、完了。とは当然いきません。

試しに追加したチャネルに何か送信してみてください。はい、既読スルーです。LINEプラットフォームに`{"test":"hook"}`と返しても、LINE BOTはなにも表示してくれません。
ではボットサーバは何をすればよいでしょうか。LINEプラットフォームからは何が送られてきて、こちらは何を返せばよいのか確認し、いよいよ実装を進めていきましょう。

### 受信する内容

特定のトークに返事をするための識別子として、Messaging APIでは`replyToken`を利用することになっています。この情報は、LINE BOTから受信した内容に埋め込まれています。

[公式リファレンス](https://developers.line.biz/ja/reference/messaging-api/)の[Webhook]の章を見ると、以下の例があります。

>```json:Webhookイベントオブジェクトの例
{
  "destination": "xxxxxxxxxx", 
  "events": [
    {
      "replyToken": "0f3779fba3b349968c5d07db31eab56f",
      "type": "message",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U4af4980629..."
      },
      "message": {
        "id": "325708",
        "type": "text",
        "text": "Hello, world"
      }
    },
    {
      "replyToken": "8cf9239d56244f4197887e939187e19e",
      "type": "follow",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U4af4980629..."
      }
    }
  ]
}
```

`events[n]`に`replyToken`がありました。このトークンをボットの返信に取り込むことで、LINEプラットフォームはトークを特定することができます。また、`events[0].message.text`には、LINEのトーク上でユーザーが送信した文字内容が書かれています。画像や音声も対応可能で、何が送られてきたかは`events[n].message.type`で判断可能です。
※なお、お気づきかと思いますが`events`は配列となっています。つまり、一時に複数のイベント情報が来る可能性があることを留意しておいてください。この例では、`type`が`message`とともに`follow`のものがあります。これはチャネルがフォローされたときに発火されるイベントです。

### 返信する

さて、前項で「何が送られてくるか」が分かりました。では次に、どうしたら返信できるかを確認します。

またもや[公式リファレンス](https://developers.line.biz/ja/reference/messaging-api/)を確認すると、以下のことが必要であることが分かります。

- 署名を検証する
- さっと200番を返す
- 応答メッセージを送る

ではそれぞれ対応していきましょう。なお、これからコードを書いていきますが、実装をアロー関数の右辺にそのまま書いていくとかなりつらいです。とりあえず以下のように`function`を切ってその中で実装していきます。

```javascript:index.js
const express = require('express')
const path = require('path')
const PORT = process.env.PORT || 5000

express()
  .use(express.static(path.join(__dirname, 'public')))
  .set('views', path.join(__dirname, 'views'))
  .set('view engine', 'ejs')
  .get('/', (req, res) => res.render('pages/index'))
  .get('/g/', (req, res) => res.json({method: "こんにちは、getさん"}))
  .post('/p/', (req, res) => res.json({method: "こんにちは、postさん"}))
  .post("/hook/", (req, res) => lineBot(req, res)) // 変更
  .listen(PORT, () => console.log(`Listening on ${ PORT }`))

// 追加
function lineBot(req, res) {
  res.json({ test: "hook" })
}
```

#### Herokuの環境変数にトークン情報をセットする

実装に入る前に、返信に必要なトークン情報2つをHerokuの環境変数にセットします。
JavaScript上に書いてももちろん動きますが、秘密の情報なのでセキュリティ上よろしくないですので。

Herokuのリモート上の環境変数は、以下のコマンドで設定できます。[^1]

```console:コマンドプロンプト
$ heroku config:set SECRET_KEY=XXXX --app Heroku上のアプリ名
$ heroku config:set ACCESS_TOKEN=XXXX --app Heroku上のアプリ名
```

JavaScriptからは、以下の形で取得できます。

```javascript
const SECRET_KEY = process.env.SECRET_KEY;
const ACCESS_TOKEN= process.env.ACCESS_TOKEN;
```

変数名はもちろん任意で結構です。このサーバで複数チャネル面倒見るなどの場合は、チャネル名つけたりなんだリで管理するとよいでしょう。

[^1]: ちなみにこの環境変数の設定はリモート側にのみ反映されますが、ローカルと動機させる便利なプラグインもあります。[こちら](https://dackdive.hateblo.jp/entry/2016/01/26/121900)(外部サイト)に分かり易く書いてくれています。

#### 署名を検証する

まずは、ボットサーバへのリクエストが当該LINEチャネルからきたものかどうかを検証します。

署名検証の方法は、[公式リファレンス](https://developers.line.biz/ja/reference/messaging-api/)に開発言語ごとに載っています。が、実は自分で実装しなくてもできます。LINEが各言語ごとに提供してくれている`line-bot-sdk`というライブラリで実現可能です。

Node.js用は[こちら](https://line.github.io/line-bot-sdk-nodejs/)です。それでは早速インストールします。

```console:コマンドプロンプト
$ npm install @line/bot-sdk --save
```

インストールが完了したら、署名検証を実装していきましょう。
実装については公式の[Basic Usage](https://line.github.io/line-bot-sdk-nodejs/getting-started/basic-usage.html#basic-usage)を参考にしていきます。どうやら`middleware`というものを利用するとよいそうです[^2]。もとの実装に反映すると、以下のような形になります。

[^2]: [middlewareのusage](https://line.github.io/line-bot-sdk-nodejs/api-reference/middleware.html#usage)に、次のように記載されています。`The middleware returned by middleware() parses body and checks signature validation, so you do not need to use validateSignature() directly.`

```javascript:index.js
const express = require("express");
const path = require("path");
const PORT = process.env.PORT || 5000;
const line = require("@line/bot-sdk"); // 追加
// 追加
const config = {
  channelAccessToken: process.env.ACCESS_TOKEN,
  channelSecret: process.env.SECRET_KEY
};

express()
  .use(express.static(path.join(__dirname, "public")))
  .set("views", path.join(__dirname, "views"))
  .set("view engine", "ejs")
  .get("/", (req, res) => res.render("pages/index"))
  .get("/g/", (req, res) => res.json({ method: "こんにちは、getさん" }))
  .post("/p/", (req, res) => res.json({ method: "こんにちは、postさん" }))
  .post("/hook/", line.middleware(config), (req, res) => lineBot(req, res)) // 変更、middlewareを追加
  .listen(PORT, () => console.log(`Listening on ${PORT}`));

function lineBot(req, res) {
  res.json({ test: "hook" });
  console.log("pass"); // 追加
}
```

これで、`/hook`は当該チャネルからのリクエストしか反応しないようになりました。
※`lineBot()`関数が呼ばれているのを確認するためにログをしこみました。
LINE Developersの[Webhook URL]から[接続確認]を行うと、成功することが分かると思います。また、`heroku logs`を実行すると、コンソールに`pass`が表示されていることが分かるはずです。
また、コンソールからcurlを投げてみましょう。これは当該チャネルからのリクエストではありませんのではじかれるはずです。

```console:コマンドプロンプト
$ curl -X POST https://Herokuのアプリ名.herokuapp.com/hook
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Internal Server Error</pre>
</body>
</html>
```

ちゃんとエラーメッセージが返ってきました。`heroku logs`を確認しても`pass`が表示されていません。少しさみしい。

#### さっと200番を返す

疎通できたので早速応答メッセージを送りたいところですが、まず200番だけを返すようにし、それを返した後に応答メッセージを返すようにします。
理由は、「返事の処理に時間がかかる」とか「メッセージが同時多発できた」という場合、すぐに200番を返してあげないとLINEプラットフォーム側にこちらに対するキューが溜まってしまい、後のお客様がいつまでたっても返事を受け取れないからです。
[この方の「大量メッセージが来ても安心なLINE BOTサーバのアーキテクチャ」という記事](https://qiita.com/yoichiro6642/items/6d4c7309210af20a5c8f)で非常に詳しく解説いただいているので、ご参照ください。とてもためになります。

では200番を返しましょう。

```javascript:index.js(抜粋)
function lineBot(req, res) {
  res.status(200).end(); // 変更
  console.log("pass");
}
```

これだけです。`heroku logs --tail`でリモート環境のログを見ながらLINE Developersで[Webhook URL]の[接続確認]を行えば、成功しつつログにも`pass`が表示されることが分かると思います。
※`res.json({ test: "hook" })`はいらないので削除しました。

#### 応答メッセージを送る

ではいよいよ応答メッセージを送ります。
署名検証でも利用した`line-bot-sdk`に、これまた便利なものがあります。[Client](https://line.github.io/line-bot-sdk-nodejs/api-reference/client.html)というものです。
本来であればURLの指定やヘッダの構築、ボディの構築諸々を行って応答すべきなのですが、`Client`がいろいろラップしてくれます。助かるわ～

では、「**<ユーザー名>さん、今<受信テキスト>って言いました？**」と応えるbotを作ってみましょう。
こんな感じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/284915/f4aab4d8-4fda-c6d9-a536-af2e57f6631d.png)

すごいうっとうしい。

次に、実装は以下の通りです。

```javascript:index.js
const express = require("express");
const path = require("path");
const PORT = process.env.PORT || 5000;
const line = require("@line/bot-sdk");
const config = {
  channelAccessToken: process.env.ACCESS_TOKEN,
  channelSecret: process.env.SECRET_KEY
};
const client = new line.Client(config); // 追加

express()
  .use(express.static(path.join(__dirname, "public")))
  .set("views", path.join(__dirname, "views"))
  .set("view engine", "ejs")
  .get("/", (req, res) => res.render("pages/index"))
  .get("/g/", (req, res) => res.json({ method: "こんにちは、getさん" }))
  .post("/p/", (req, res) => res.json({ method: "こんにちは、postさん" }))
  .post("/hook/", line.middleware(config), (req, res) => lineBot(req, res))
  .listen(PORT, () => console.log(`Listening on ${PORT}`));

function lineBot(req, res) {
  res.status(200).end();
  // ここから追加
  const events = req.body.events;
  const promises = [];
  for (let i = 0, l = events.length; i < l; i++) {
    const ev = events[i];
    promises.push(
      echoman(ev)
    );
  }
  Promise.all(promises).then(console.log("pass"));
}

// 追加
async function echoman(ev) {
  const pro =  await client.getProfile(ev.source.userId);
  return client.replyMessage(ev.replyToken, {
    type: "text",
    text: `${pro.displayName}さん、今「${ev.message.text}」って言いました？`
  })
}
```

解説していきます。

大まかな流れとしては、

- 受信したbodyからeventを解析
- `client.getProfile()`を使ってユーザー名を取得
- `client.replyMessage()`を使って返事を送信
- 一通り終わったらログだけ出しておく

です。

##### 受信したbodyからeventを解析

まず`req.body`ですが、すでに`line.middleware`がパースしてくれているので普通に使えます。ありがたい。逆に、自前で`body-parser`使ったりしてると注意が必要です。以下[公式のmiddleware Usage](https://line.github.io/line-bot-sdk-nodejs/api-reference/middleware.html#usage)より抜粋です。

>You do not need to use body-parser to parse webhook events, as middleware() embeds body-parser and parses them to objects. Please keep in mind that it will not process requests without X-Line-Signature header. If you have a reason to use body-parser for other routes, please do not use it before the LINE middleware. body-parser parses the request body up and the LINE middleware cannot parse it afterwards.

bodyの内容は[受信する内容](#受信する内容)で述べた通りです。
ここでは`client.getProfile()`で使う`event.source.userId`と、`client.replyMessage()`で使う`event.message.text`を使います。

##### `client.getProfile()`を使ってユーザー名を取得

ユーザー情報を取得します。

```javascript:index.js(echoman()より抜粋)
  const pro =  await client.getProfile(ev.source.userId);
```

LINEプラットフォームから非同期通信でデータを取得しています。その情報を後続の処理で利用するので、async/awaitを使って同期化します。

##### `client.replyMessage()`を使って返事を送信

ここでメッセージを返します。

```javascript:index.js(echoman()より抜粋)
return client.replyMessage(ev.replyToken, {
    type: "text",
    text: `${pro.displayName}さん、今「${ev.message.text}」って言いました？`
  })
```

先ほど取得したユーザー情報から名前と、ユーザーが送信したtextを返信bodyに詰め込んで返信を送ります。
`client.replyMessage`は非同期通信で、`Promise`を返します。これを`echoman()`の呼び出し元で取得して、完了後の処理を行います。

##### 一通り終わったらログだけ出しておく

最後に、処理の完了だけ検知してログを出しておきます。これはついでなので、別にやる必要はないですが。

```javascript:index.js
  const events = req.body.events;
  const promises = [];
  for (let i = 0, l = events.length; i < l; i++) {
    const ev = events[i];
    promises.push(
      echoman(ev)
    );
  }
  Promise.all(promises).then(console.log("pass"));
```

`echoman()`で返却される`Promise`を配列に格納して、全部の完了を`Promise.all()`で検知し、`then()`の中で`console.log()`を呼び出してログを表示します。
`Promise`周りの仕様を確認したい方は、[NDM](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)をご参照ください。

さて、長くなりましたがここで本記事で作るものは完成しました。

# LINE BOTでもっといろいろ

いろいろやるためのヒントをリンクを交えて(というかメインで)お送りします。

## いろいろな返信

[LINE Messaging API でできることまとめ【送信編】](https://qiita.com/kakakaori830/items/52e52d969800de61ce28)

文字だけでなく、スタンプや動画音声も送れます。また、テンプレートを使うと見やすいレイアウトでユーザーに送ることもできます。このあたりのレイアウトを、自分で考えずにJSON送れば共通のUIで良しなにやってくれるのがLINE BOTのいいところだと思います。すぐに訴求可能なメッセージを送れる。

## いろいろなREST API

世の中にはいろんな情報を取得可能なAPIがあります。
`API 面白い`とかで調べるといろいろ出てくるかと思います。

[フロントエンド制作に華を！ 面白いWebAPI 7選](https://techblog.kayac.com/13_webapi_7_web.html)
[海外・国内の便利なAPI一覧 - API LIST 100+](http://smsurf.app-rox.com/api/)

ほかにもいろいろ出てきます。結構いろいろ妄想すると楽しいですね。
例えば「画像で物知り博士」と題して、ユーザーから画像を受け取り、`Google Cloud Vision`で画像ラベルを取得 -> `Google Translate API`でラベルを日本語に翻訳 -> `MediaWiki API`を使ってそれぞれの検索結果を取得 -> `カルーセルテンプレート`で表示、とか。
考え始めると「じゃああのAPIはないかな！？」とか気になりだして面白くなってきます。アイデアをメモっておいて、まとまった休みに実装してみるとかいいですね。

# 終わりに

手順に書き下すと長いですが、一度できてしまえばあとはいろいろやりやすいです。LINE BOTではレイアウトに悩むことが少ないことも、継続開発の助けになります。開発とかよく知らない友人に自分のチャネルを紹介すれば、「マジやばくな～い？すごくな～い？」と言われることうけあいです。
まだやったことない人も、ぜひやってみましょう！