PythonでLINEの「Messaging API」でテンプレートメッセージを実装してみた

LINEの「Messaging API」は、一度は使ってみたいと思ったことがあるんじゃないでしょうか。
自作サービスと違って、完璧に整ったLINEのUIを使って、サービスを展開できるのがすごいところ!!

では、四の五の言わずに実装しましょう。

ちなみに、完成品はこちらを友達登録して、ご確認ください。
(プッシュ通知を設定していないので、分かりづらいですが、なんでもいいのでメッセージを適当に送ってください。)

ぜひ、この機能を実装したLINE Botを使ってみてください！
<a href="https://lin.ee/BbNwMMp"><img src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png" alt="友だち追加" height="36" border="0"></a>
(記事なキャプチャと違い「メジロ」というサービス名になっています。)


## 目次
- LINE Developerの登録
- テンプレートメッセージを実装
- Herokuの登録
- 参考サイト
- おまけ

## 対象
- LINEのMessaging APIを使ってみたい人
- Messaging APIのテンプレートメッセージを実装したい人
- Herokuの勉強をしたい人

## LINE Developerの登録
[Messaging API](https://developers.line.biz/ja/services/messaging-api/)のトップ画面の「はじめよう」から、LINE Developerに移れます。

すでにLINEアカウントをお持ちの方は、そのアカウントで登録することができます。すごく簡単＼＼\└('ω')┘//／／

## 新規チャネルの作成
Developerの登録が終わると、「新規チャネル作成」の画面になります。簡単な必要事項を入力するだけでokです。

作成するとこの画面になります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/185039/b9be799e-fbfc-aab7-e27b-d24e531d63d3.png)

## テンプレートメッセージを実装
では、メインのテンプレートメッセージを実装します。
フレームワークはとっても使いやすい`Flask`を使います。

### ライブラリの準備

```bash
$ pip install flask
$ pip install line-bot-sdk
```

### ディレクトリ構成
特に気を使わず、同階層で大丈夫です。

```
├── Procfile
├── app.py
├── requirements.txt
└── runtime.txt
```

### テンプレートメッセージの返信機能を実装
今回は、とりあえず動かすことを目的としていますので、細かい解説は、省きます。

```python:app.py
import os

from flask import Flask, request, abort
from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TemplateSendMessage, CarouselTemplate, CarouselColumn)

app = Flask(__name__)

LINE_CHANNEL_ACCESS_TOKEN = os.environ["LINE_CHANNEL_ACCESS_TOKEN"]
LINE_CHANNEL_SECRET = os.environ["LINE_CHANNEL_SECRET"]

line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(LINE_CHANNEL_SECRET)


@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def response_message(event):
    # notesのCarouselColumnの各値は、変更してもらって結構です。
    notes = [CarouselColumn(thumbnail_image_url="https://renttle.jp/static/img/renttle02.jpg",
                            title="【ReleaseNote】トークルームを実装しました。",
                            text="creation(創作中・考え中の何かしらのモノ・コト)に関して、意見を聞けるようにトークルーム機能を追加しました。",
                            actions=[{"type": "message","label": "サイトURL","text": "https://renttle.jp/notes/kota/7"}]),

             CarouselColumn(thumbnail_image_url="https://renttle.jp/static/img/renttle03.jpg",
                            title="ReleaseNote】創作中の活動を報告する機能を追加しました。",
                            text="創作中や考え中の時点の活動を共有できる機能を追加しました。",
                            actions=[
                                {"type": "message", "label": "サイトURL", "text": "https://renttle.jp/notes/kota/6"}]),

             CarouselColumn(thumbnail_image_url="https://renttle.jp/static/img/renttle04.jpg",
                            title="【ReleaseNote】タグ機能を追加しました。",
                            text="「イベントを作成」「記事を投稿」「本を登録」にタグ機能を追加しました。",
                            actions=[
                                {"type": "message", "label": "サイトURL", "text": "https://renttle.jp/notes/kota/5"}])]

    messages = TemplateSendMessage(
        alt_text='template',
        template=CarouselTemplate(columns=notes),
    )

    line_bot_api.reply_message(event.reply_token, messages=messages)


if __name__ == "__main__":
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)
```

### 設定ファイルを作成
pythonのバージョンの管理やライブラリの指定をします。

```:Procfile
web: python app.py
```

```requirements.txt
Flask==1.0.2
line-bot-sdk==1.7.2
```

```runtime.txt
python-3.6.6
```

※ [公式サイト](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-python)によると、Pythonのバージョンは、`python-3.7.0` `python-3.6.6` `python-2.7.15`のいずれかを指定する必要があるみたいです。

## Herokuの準備
[Herokuの公式サイト](https://devcenter.heroku.com/articles/heroku-cli)からもダウンロードできますし、下記のコマンドからでもインストールできます。

```bash
$ brew install heroku/brew/heroku
```

#### ちょいつまった
(上のコマンドで正しくインストールされれば、飛ばしてください。)
上のコマンドを打ったら、下のように怒られた。

```
Error: heroku 7.16.0 is already installed
To upgrade to 7.19.3, run `brew upgrade heroku`
```

アップグレードするだけでOK!

```
$ brew upgrade heroku
```

### Herokuへログイン
ターミナルで下記のコマンドを打つと、

```
$ heroku login
```

ブラウザに移行して、メールアドレスとパスワードを求められます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/185039/acb650d5-a1a9-1dd7-8ad4-9657b3f17a1a.png)

無事、ログインに成功すると、下の画面になります！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/185039/2f32a62f-5aec-241c-c9cf-2c9389f8c0b7.png)

※ 初めてHerokuを使う場合は、挙動が少し違う可能性があります。

### Herokuへアプリケーションの登録

```
# 英字の大文字はうまく登録できないようです
$ heroku create <自分のアプリ名>
```
## Herokuとチャネルの連携

[管理画面](https://developers.line.me/console/)から、`Channel Secret`と`アクセストークン`をコピーして、設定します。

```
$ heroku config:set YOUR_CHANNEL_SECRET="Channel Secretの欄の文字列" --app <自分のアプリ名>
$ heroku config:set YOUR_CHANNEL_ACCESS_TOKEN="アクセストークンの欄の文字列" --app <自分のアプリ名>
```

### Webhookの設定
下のように設定してください。

[管理画面](https://developers.line.me/console/)から、Webhookの設定をします。
Webhook送信：利用する
Webhook URL：https://<自分のアプリ名>.herokuapp.com/callback

![](https://i.gyazo.com/50e6023304707dba1942f7e24e79776c.gif)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/185039/bdf35ff5-c3e2-e50b-0a58-86981b30fdcb.png)

### デプロイ
commitして、pushしたら、デプロイ完了です。(Herokuって楽＼(^o^)／)

```
$ git init
$ git add .
$ git commit -m "new commit"
$ git push heroku master
```

これで、デプロイ完了です。
[管理画面](https://developers.line.me/console/)から、ご自身のQRコードをLINEで友だち追加して、遊んでみてください。

このような感じになれば、成功です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/185039/b9d2bb73-2906-9311-e9fa-5ba7f59b606b.png)


## つまったところ
### デプロイしたのに返信が返ってこない
原因:
エラーの原因は、たくさん考えられます。なので、logを見て判断してください。Herokuのログを見るコマンドは、以下の通りです。

```
$ heroku logs
```

## 参考サイト
[PythonでLine botを作ってみた](https://qiita.com/krocks96/items/67f7510b36945eb9689b)
[LINE Messaging APIのテンプレートメッセージをまとめてみる](https://dev.classmethod.jp/etc/line-messaging-api/)
[[python] LINEで画像を送ると商品検索するbotを作ってみた](https://qiita.com/mikan3rd/items/0e1bfe46e00cf434a126)

## おまけ
最後までお付き合いいただき、ありがとうございました。
少しでもお役に立てたのであれば、嬉しいです。

今後、プッシュ通知や他の機能に関しても、記事を書いていく予定です。

<a href="https://lin.ee/BbNwMMp"><img src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png" alt="友だち追加" height="36" border="0"></a>
(記事なキャプチャと違い「メジロ」というサービス名になっています。)