Python&&HerokuでLINEmessagingAPI使ってみる

#環境
- Pythpn 3.7.0
- heroku 7.26.2 win32-x64 node-v11.14.0
- Flask 1.0.2
- line-bot-sdk 1.12.1


herokuはアカウント作成とherokuCLインスールは先人様の知恵をお借りします。

https://qiita.com/abeichi/items/72966bbc04f9aa428ff2
https://webbibouroku.com/Blog/Article/heroku-getting-started
https://hajipro.com/heroku/heroku-cli-install

##別途
LINEビジネスアカウントにて取得
- Channel secret
- アクセストークン



#経緯
会社のLINE公式アカウント開設に合わせてなにかおもしろいこと出来ないかと思案中
とりあえず環境構築と実際に動くところを自分の手でやりたかった。
サンプルにある「オウム返し」をやってみる

あとGoogle Apps Script使ってみたけど
Javascriptわからん


#初期設定

##LINEで必要なものを取得しておく

###Channel secret

https://account.line.biz/login
にてLINE OFFICIAL ACCOUNT MANAGERにログイン

紐づけされているビジネスアカウントの一覧が表示されますので該当アカウントをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/a6d334a8-d505-8682-fdfa-edd75965d67d.png)


右上の設定から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/99970529-030b-faf2-80a2-9b749aa046bc.png)

Messaging APIで必要項目を入力すると表示されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/63ed8a2e-f043-10b3-2f01-6c1445893f2a.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/3907e8be-1f08-2a5d-666b-2d7fb80fe4ef.png)

###アクセストークン

Channel secretが表示されてる画面の「LINE Developersから行えます」からDevelopersにアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/73d43677-94cf-32b0-f1d1-74a0768a9b00.png)

続けて作業するとログインしてる状態でページに飛びますので右側歯車アイコンクリック
プロバイダーリスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/61f1b051-1d17-f9c2-4fb3-6a01d1491ae4.png)

先程作ったプロバイダーを選択

チャンネルを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/6fd1c8ff-c4f5-4357-9190-f93d608bc9e4.png)

アクセストークンから「再発行をクリック」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/00d78e31-1fbe-7f1d-2261-5a6c2e516313.png)

画像の黒塗りされているとことに表示されます。

それと
Webhook送信が利用しないになっていたら利用するに変更

自動応答メッセージを利用するになっていたら利用しないに変更



##必須ライブラリのインストール
```
pip install Flask
pip install line-bot-sdk
```



##ファイルの作成
専用フォルダを作成しておくと楽

```
mkdir line_bot
```

##用意
- requirements.txt
- runtime.txt
- Procfile
- main.py

### requirements.txt
heroku側でライブラリをインストールするのに必要

```:requirements.txt
Flask==1.0.2
line-bot-sdk==1.12.1
```

###runtime.txt
herokuで動作するPythonのバーションを指定する

```:runtime.txt
python-3.7.0
```

###Procfile
herokuでの実行命令のようなものらしい

```:Procfile
web: python main.py
```

###main.py
動作させるPythonのコード

※pylintを使用しているとapp.logger.info()でエラーが出るけどきにしなくておｋ


```Python:main.py
# インポートするライブラリ
from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    FollowEvent, MessageEvent, TextMessage, TextSendMessage, ImageMessage, ImageSendMessage, TemplateSendMessage, ButtonsTemplate, PostbackTemplateAction, MessageTemplateAction, URITemplateAction
)
import os
import requests
from bs4 import BeautifulSoup
import random

# 軽量なウェブアプリケーションフレームワーク:Flask
app = Flask(__name__)

#herokuの環境変数を取得なので環境によって自由に変更可能
#環境変数からLINE Access Tokenを設定
LINE_CHANNEL_ACCESS_TOKEN = os.environ["LINE_CHANNEL_ACCESS_TOKEN"]
#環境変数からLINE Channel Secretを設定
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():
    # 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)
    )

```


##ファイル構成
```
line_bot
 ├── requirements.txt
 ├── runtime.txt
 ├── Procfile
 └── main.py
```

##Herokuにデプロイ

あとはherokuにデプロイする

ブラウザで操作も可能ですがコマンドでやっていきます。
そっちの操作に関してはご自身で検索等々お願いいたします。

まずherokuにログイン

```
の前にディレクトリ移動しときましょう
cd line_bot


heroku login
```
メールアドレスとパスワードを聞かれる？？
すいませんが初回のログイン時の記憶が無いです。。。


2回目移行(現在自分の環境では)
heroku: Press any key to open up the browser to login or q to exit:
が返ってきます。

「q」以外を押す。
するとブラウザが立ち上がりますのでの「Log in」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/30680383-e7b8-43c9-733e-e6b05fb59a08.png)
みたいな感じになっております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/8c1e824c-3bff-90fb-799e-0781089335c9.png)

ログイン完了です。

ここからがデプロイ
- herokuにアプリケーションを作成
- アプリケーションに環境変数の付与
- gitにリポジトリを作成
- gitを追加
- コミット
- プッシュ


```:コマンド
heroku create <アプリ名>

heroku config:set LINE_CHANNEL_SECRET=<LINEで取得したChannel secret> -a <アプリ名>

heroku config:set LINE_CHANNEL_ACCESS_TOKEN=<LINEで取得したトークン> -a <アプリ名>

git init

git add .

git commit -m "linebot commit"

git push heroku master
```

アプリケーションを作成では世界で同じアプリケーション名は1つしか持てないので
Name <アプリ名> is already taken
と返ってきたら別の名前に変更してみて下さい。

git initは初回のみファイルの中身など変更があった場合はそれ移行のコマンドは再度実行して下さい。

##LINE Webhookの設定

最後にLINEとherokuの紐づけをします。

LINE OFFICIAL ACCOUNT MANAGERのMessaging APIの設定画面で

Webhook URLに[https://<アプリ名>.herokuapp.com/callback]を入力して保存

おわりーーーー


##余談

やってて関係無いところで詰ったので余談にしておきます。

動いてるはずなのにLINEDevelopersにある接続確認でこうなる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247370/1d21a781-1347-f107-7150-2ae28179bd5e.png)


原因
PythonのコードがMessageが来たときの処理しか書いてないので
こっちで接続確認すると404とか500が返ってきたり処理エラーが出るからだった。