python anywhereでline botをデプロイする

# はじめに
- ~~チーム開発でAWSにデプロイしようとしたら,クレカ登録で弾かれた。~~
- 別のデプロイ先を調べてたらPythonAnywhereを見つけたので試すことに。意外と記事が少なかったので一通り流れだけまとめてみた。
## ターゲット
- AWSやAzure,GCP,Herokuなどに登録をしてない人
- line botのデプロイを比較的に簡単にやりたい人
## 前提スキル
- Python及びFlaskの基礎が分かる人
## 開発環境
- Windows10
- Python 3.10.7

| フレームワーク | バージョン | 
| -------------- | ---------- | 
| flask          | 2.2.2      | 
| line-bot-sdk   | 2.3.0      | 

# 環境の下準備
## LINE Messaging APIの登録
- line messaging apiの登録にline business idの発行が必要です。
参考記事は以下に
> [LINE Messaging APIの利用登録方法～LINEアカウント開発に必要なAPIキー発行申請](https://auto-worker.com/blog/?p=5117)

- 参考記事通りに進めていくと,プロバイダーが作成され,チャンネルアクセストークンとチャンネルシークレットが発行されるので控えてください。

## PythonAnywhereの登録
デプロイ先としてPythonAnywhereを利用するので登録をします。
参考記事を以下に
> [PythonAnywhereの初心者アカウント（無料）へ登録する](https://laboratory.kazuuu.net/register-for-a-free-pythonanywhere-beginner-account/)

## フレームワークのインストール
* フレームワークとして,line-bot-sdkとflaskを使うのでインストールします。
ターミナルで以下のコマンドを実行してください。
```
>pip install line-bot-sdk
>pip install flask
```
* インストールを確認する際は以下のコマンドを実行してください。
```
>pip list
```
* コマンド後の結果
flaskとline-bot-sdkのインストールが完了してることが確認できると思います。
![module list.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/02eb687a-f0c2-932b-5e2b-ea57a062bab9.png)
~~ターミナルでpipコマンドを打ってエラー吐かれた場合は,pip.exeがあるパスまで移動して同じpipコマンドを打つとできるかもしれません~~

これで、line botとpythonanywhereが扱える環境になりました。実際にデプロイしていきます。
※今回はデプロイを目的としてるので、メッセージを送信するとオウム返しする簡易的なline botにしています。
- ファイル構成
test_deploy/
├ main.py
├ requirements.txt

pip freeze > requirements.txt とコマンドを打つとテキストファイルが生成されます。

コードを以下に
```main.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, TextSendMessage, QuickReply, QuickReplyButton, MessageAction, PostbackAction, FollowEvent, ImageMessage
)

app = Flask(__name__)

LINE_CHANNEL_SECRET = os.getenv("LINE_CHANNEL_SECRET")
LINE_CHANNEL_ACCESS_TOKEN = os.getenv("LINE_CHANNEL_ACCESS_TOKEN")

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

## 1 ##
#Webhookからのリクエストをチェックします。
@app.route("/callback", methods=['POST'])
#この関数は、LINE Bot API 経由で入力テキストを処理します。
def callback():
    # リクエストヘッダーから署名検証のための値を取得します。
    signature = request.headers['X-Line-Signature']
    # リクエストボディを取得します。
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)
    # handle webhook body
    # 署名を検証し、問題なければhandleに定義されている関数を呼び出す。
    try:
        handler.handle(body, signature)
    # 署名検証で失敗した場合、例外を出す。
    except InvalidSignatureError:
        print("Invalid signature. Please check your channel access token/channel secret.")
        abort(400)
    return 'OK'
@handler.add(MessageEvent, message=TextMessage)
# ここから実装開始
def handle_message(line_reply_event):
    line_bot_api.reply_message(line_reply_event.reply_token,TextSendMessage(text=event.message.text)) #ここでオウム返しを実装

if __name__ == "__main__":
    app.run()
```
下準備も終わったので、実際にデプロイしていきます。
# デプロイの流れ
## PythonAnywhereのデプロイ準備
- Bash consoleをクリックします。
![Consoles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/89b493e2-6b4e-eaa7-6985-0311f27f1eae.png)
- ローカルと同じくpythonanywhereにもflaskとline-bot-sdkをインストールします。
以下のコマンドを順に実行してください。
```
$pip install line-bot-sdk
$pip install flask
$pip list
```
![bash pip list.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/d727475a-199f-dec5-efc2-fd716f68832e.png)
- line-bot-sdkとflaskが確認できればインストール完了です。

## デプロイ
- Filesをクリックし,Directoriesに適当なディレクトリ名を入力してください。入力が完了したら、New directoryをクリックしてください。
![file.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/efea85c1-c7ee-bbf1-fc54-5aaf832c4d44.png)
- クリック後以下の画面になればディレクトリの作成は完了です。
![upload file.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/8e9c1203-eb79-6a5f-6875-b73141637271.png)
- Upload a fileをクリックして作成したpythonファイルをアップロードします.
~~requirements.txtは基本なくもよさそう~~

- Webをクリックします。クリックすると以下の画面が表示されます。Nextをクリックします。
![new web app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/689dec44-81f8-40d7-35fd-4221de994d6a.png)
- フレームワーク選択欄があるので、Flaskを選択します。pythonのバージョンは3.9.0を選択します ※3.10でも可能
![select web app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/d58ad899-3835-7b9e-3252-59c08e542536.png)
- Pathに作成したディレクトリを指定します。
~~写真ではPythonファイルを指定してますが、基本ディレクトリの方が無難です~~
Nextをクリックします。
![flask project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/386374ae-7853-8815-7150-f569b427ae2b.png)
- 以下の画像の **ユーザー名.pythonanywhere.com** はwebhookへのリクエストに扱うためのURLとなります。
![URL image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/b0eb34d4-8556-296b-9150-53adc1d297b3.png)
- httpsの設定をEnabledとし,Reloadをすると **https://....** のURLが取得できます。
![https admin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/bbd52728-4864-50c8-150d-cf9a7cf4083c.png)
![webhook url.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/960f9c0a-61e8-8bb2-27d0-47be2436a2b7.png)

- LINE Developerに移り,Webhookの設定を行います。先ほど取得した **https://** のURLをWebhook URLに設定します。
※main.pyで/callbackの指定をしているため,以下の画像では,pythonanywhereで取得したURL後に/callbackを指定してます。
![webhook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/3151b38e-3d51-6a55-b95d-d0f4a74c88de.png)
- 検証をクリックし,成功が出ればline botの作成は完了です。
![deploy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/875d7a67-c0d8-067d-d983-49f4076af586.png)
# おわりに
マイナーなインフラの参考記事って少ないよね～、と思いながら記事を書きました。少しでも役立てれば幸いです。