PythonでLine botを作ってみた

#はじめに
[Seleniumを使ってみた](https://qiita.com/krocks96/items/86a8800f7bf3cd5d3216)の続き(？)にあたります。
ゆくゆくは活用したいと思いますが今のところはオウム返しするだけです。
初めて触ったので間違いがあればご指摘いただけると幸いです。

#環境
- OS X 10.11.1
- Python 3.6.3
- Heroku

#Line developers 登録＆設定
まずは[Line developers](https://developers.line.me/ja/services/messaging-api/)に登録していきます。
リンク先の今すぐはじめようをクリック
![スクリーンショット 2018-04-13 23.18.27.png](https://qiita-image-store.s3.amazonaws.com/0/245442/e4325687-116e-b934-51c1-c47389d1029e.png)

Lineにログインします。
![スクリーンショット 2018-04-13 23.20.33.png](https://qiita-image-store.s3.amazonaws.com/0/245442/9a38560c-5384-7e1b-2118-c03a9ff9c99a.png)

プロバイダ名(Botの提供元になる名前)を登録します。
確認→作成で作成できます。
![スクリーンショット 2018-04-13 23.21.50.png](https://qiita-image-store.s3.amazonaws.com/0/245442/ae195786-281b-8733-ec84-b69131f0a9b3.png)

今回はbot作成なのでMessaging APIを選択します。
![スクリーンショット 2018-04-13 23.23.41.png](https://qiita-image-store.s3.amazonaws.com/0/245442/b8490ac7-ae89-112e-5924-f43c82d071ef.png)

必要な情報を入力していきます。
![スクリーンショット 2018-04-13 23.25.51.png](https://qiita-image-store.s3.amazonaws.com/0/245442/cd9ae79a-9e27-cbed-d772-0a309a20f4f9.png)

アプリ名　　　任意のアプリ名
アプリ説明　　任意のアプリ説明
プラン　　　　Developer Trial
大業種　　　 個人
小業種　　 　個人(その他)
メールアドレス 自分のメールアドレス

利用規約に同意して作成
![スクリーンショット 2018-04-13 23.28.32.png](https://qiita-image-store.s3.amazonaws.com/0/245442/2f8ea82c-f260-61d4-5579-592e8f7e3fb8.png)

もう少し！基本設定からアクセストークンの再発行を実施します。
このアクセストークンは後ほど使います。
![スクリーンショット 2018-04-13 23.29.58.png](https://qiita-image-store.s3.amazonaws.com/0/245442/e2819339-a334-c860-e2d2-571b8f407d23.png)

#実装
まず、flaskとline-bot-sdkをインストールします。

```
$ pip3 install flask
$ pip3 install line-bot-sdk
```

いよいよPythonで実装していきます！
[ここ](https://github.com/line/line-bot-sdk-python)にBotのサンプルがあるのでコピペしてちょこっといじります。

```python:main.py

from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import os

app = Flask(__name__)

#環境変数取得
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

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

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

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

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=event.message.text))


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


#Herokuの設定
アカウント登録は済んでいる前提で進めます。
Pythonをクリック。
![スクリーンショット 2018-04-13 23.53.27.png](https://qiita-image-store.s3.amazonaws.com/0/245442/4315d01c-4b34-49ad-1503-0e42366764b0.png)

Download the Heroku CLI for MacOSをクリックしてダウンロード。
ダウンロードしたファイルをダブルクリックしてインストールを進めます。
![スクリーンショット 2018-04-13 23.52.30.png](https://qiita-image-store.s3.amazonaws.com/0/245442/a9d440d8-66d5-c5bf-9467-a520d0026de8.png)

無事にコマンドラインを使えるようになりましたのでここからはコマンドラインを使います。
まずはherokuにログインします。メールアドレスとパスワードを入力。

```
$ heroku login
Enter your Heroku credentials:
Email: XXX@XXX
Password: ***
```

アプリケーションを登録します。コマンドラインからcreateで作れます。
https://<アプリケーション名>.herokuapp.comをWebhookで使います。

```
$ heroku create <アプリケーション名>
```

環境変数の設定をします。
Channel Secretとアクセストークンを設定しておきます。

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

#設定ファイルの作成、デプロイ
下記のように設定ファイルを作成します。

```:runtime.txt(Pythonのバージョンを記載)
python-3.6.3
```

```:requirements.txt(インストールするライブラリの記載)
Flask==0.12.2
line-bot-sdk==1.5.0
```

```:Procfile(プログラムの実行方法を定義)
web: python main.py
```

Pythonのプログラムと設定ファイルデプロイします。

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

無事にpushできたらもう少し！
できないときは設定ファイルを見直すと上手くいくかも。
自分の場合はrequirements.txtにanaconda等が含まれていてエラーになりました。

#Webhookの設定
https://developers.line.me/console/ に戻り、Webhookの設定をします。
Webhook送信：利用する
Webhook URL：https://<アプリケーション名>.herokuapp.com/callback

![スクリーンショット 2018-04-14 22.22.23.png](https://qiita-image-store.s3.amazonaws.com/0/245442/e21e8805-6461-68a9-4279-f2ce121877c5.png)

#実験
チャンネル基本設定の画面からLineアプリへのQRコードを読み込み友達登録します。
→適当にメッセージを送ってオウム返しされたらOK!

![スクリーンショット 2018-04-14 22.27.04.png](https://qiita-image-store.s3.amazonaws.com/0/245442/cb36622c-6900-0c8a-c104-d58e0aa3f55f.png)

ちゃんと返ってきたら完成です。
駄目ならログを見て頑張りましょう。(何回もやりました)

```:ログの出し方
$ heroku logs --tail -a <アプリケーション名>
```

#詰まったところ
https://github.com/line/line-bot-sdk-python から取ってきたサンプルそのままで動かそうとしたところエラーが発生しました。どうやらHerokuは動的にポート番号を生成するとのこと…
その結果ポートを割り当てられずタイムアウトが発生していた模様。(間違ってたらごめんなさい)

```
$ heroku logs --tail -a <アプリケーション名>
中略
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
```

それがこの部分になります。

```main.py(抜粋)
    port = int(os.getenv("PORT", "5000"))
    app.run(host="0.0.0.0", port=port)
```

#参考リンク
下記の記事を参考にさせていただきました。ありがとうございます。
[LINE Messaging API + Python + Heroku でLINE Botを作る](http://cppx.hatenablog.com/entry/2017/10/31/165128)
[LINE BOT をとりあえずタダで Heroku で動かす](https://qiita.com/yuya_takeyama/items/0660a59d13e2cd0b2516)
[0.4.0 to 0.4.1 Introduced WebServer Issue #491](https://github.com/howdyai/botkit/issues/491)
[Node.jsのアプリをHerokuにデプロイするときポート番号に気をつけなくちゃいけない](https://qiita.com/kenju/items/1d61c9fb45496feed1bf)