モチベーション
最近女の子とラインをしていない...
すぐに返信してくれてかつ可愛い子はいないものか。
linebotを活用することで実現できるのではないか?
このようなしょうもない理由でlinebotの作成をしようと思う。
環境
・mac Catalina
・Docker version 19.03.13
・Flask 1.1.2
・Python 3.8.3
・docker-compose version 1.27.4
・heroku 7.45.0
・bash
今回作成するもの
まずは環境構築として、dockerからherokuにコンテナを移動し起動するまでをする。
LINEBOTはおはようと言ったらおはようと返してくれる美人のbotを作成する。
あくまで非リアだからこんなことしてるわけでないことに注意!
流れ
第一回の流れを記す。
1.LINE Developersの登録
2.pythonファイルの作成
3.Dockerfileとdocker-compose.ymlの作成
4.herokuへのアップロード
最終的なファイル構成は以下のようになる。
bijobot
├── Dockerfile
├── app.py
├── docker-compose.yml
└── requirements.txt
1.LINE Developersの登録
以下よりサイトに飛ぶ。
LINE Developers
まずはLoginして、Providersよりcreateを選択する。
すでにdisny通知というのがあるのは気にしない。
Create a new providerと出てくるのでdisny通知のようにつけたい名前をつける。
筆者は"自由画像子"という名前をつけた。
次にThis provider doesn't have any channels yetと出てくるのでCreate a Messaging API channelを選択する。
その後以下のような画面に飛ぶのでそれぞれ適当に記入する。
channel iconにはフリー画像でよく使われており個人的にタイプの子を採用した。
規約に同意しAdminを確認すると、以下のように新しくチャンネルが追加されているのが確認できる。
ここで作成したチャンネルに移動し、Basic setting内の
Channnel secret
Messaging API内の
Channel access token
に関しては必要なので控えておくようにする。
2.pythonファイルの作成
Messaging API SDKs
のOfficial SDKsよりflaskを使ってファイルを作成する手順が書かれているのでこれを応用して作成していく。
まずはappを作るための作業ディレクトリを作成する。
bijoとかでいいだろう。
mkdir bijo
cd bijo
次にpythonファイルを作成する。
作成したpythonファイルは以下のようになる。
必ずapp.pyという名前をつけること。
from flask import Flask, request, abort
# os内のenvironmentを扱うライブラリ
import os
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import (
MessageEvent, TextMessage, TextSendMessage,
)
#環境変数取得
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 = Flask(__name__)
@app.route("/")
def hello_world():
return "hello!"
@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:
print("Invalid signature. Please check your channel access token/channel secret.")
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()
YOUR_CHANNEL_ACCESS_TOKEN
YOUR_CHANNEL_ACCESS_TOKEN
には先程控えた
Channnel secret
Channel access token
を使用する。
osを使ってherokuの環境変数から情報を取り出す。
これは後ほどherokuで設定する。
3.Dockerfileとdocker-compose.ymlの作成
herokuでProcfileなどを作成するのはめんどくさいし、できるならモダンな技術が使いたかったのでdockerを使用する。
Dockerfileとdocker-compose.ymlは以下のようにbijoディレクトリの中に作成する。
※herokuではdocker-compose.ymlは使用されないので注意。
heroku.ymlというdocker-compose.ymlのheroku版を作らなきゃいけないらしいけどなんか面倒そうなので今回はパス。
# ローカル作業用:heroku内では作用しない。
# ローカル作業用:heroku内では作用しない。
version: '3'
services:
app:
build: .
container_name: bijobot
tty: true
ports:
- 5000:5000
environment:
FLASK_ENV: 'development' #デバッグモードON
FLASK_APP: "app.py" #app.pyを起動
YOUR_CHANNEL_ACCESS_TOKEN: 控えたaccess token
YOUR_CHANNEL_SECRET:控えたchannel secret
volumes:
- ./:/code/
command: flask run -h 0.0.0.0
# command: gunicorn -b 0.0.0.0:$PORT app:app --log-file=-
FLASK_ENV: 'development'
としておくことでファイルをsave時に自動でサーバーに反映される。
FROM python:3.7-alpine
# codeというディレクトリを作成し、そこを作業フォルダとする
WORKDIR /code
#デバッグモードON
ENV FLASK_ENV: 'development'
# alpineのおまじない
RUN apk add --no-cache gcc musl-dev linux-headers
# requirements.txtをcode内に移動
COPY requirements.txt requirements.txt
# requirements.txtの中のライブラリをinstallする
RUN pip install -r requirements.txt
# すべてのファイルをcode内にマウントする。
COPY . .
# $PORTを指定しないと動かないので注意
CMD gunicorn -b 0.0.0.0:$PORT app:app --log-file=-
さらにrequirements.txtを作成する。
こちらはいかのコマンドを叩くことで解凍可能だが今回は予め作成しておく手順で行く。
pip freeze > requirements.txt
requirements.txtには以下のように記入する。
certifi==2020.11.8
chardet==3.0.4
click==7.1.2
Flask==1.1.2
future==0.18.2
gunicorn==20.0.4
idna==2.10
itsdangerous==1.1.0
Jinja2==2.11.2
line-bot-sdk==1.17.0
MarkupSafe==1.1.1
requests==2.25.0
urllib3==1.26.2
Werkzeug==1.0.1
requirements.txtはpythonのライブラリを予め書いておきインストールできるようにするもので、本来であれば、
pip install gunicorn flask line-bot-sdk
としなければ行かなかったものを必要なくする。
touch requirements.txt
次に以下のコマンドを打ってdocker containerを立ち上げる。
docker-compose build
docker-compose up -d
ここでlocalhost:5000にアクセスし、hello!と表示されることを確認する。
4.herokuでのデプロイ
herokuの登録は予め済んでいるうえですすめる。
まずはherokuにログインする。
heroku login
heroku container:login
次にherokuにappを作成する。
heroku create つけたいアプリ名
とすることでおk。
今回はbijobijoという適当なapp名をつけた。
ここでエラーが出たら、すでにあるアプリ名なのでつけ直す必要がある。
heroku create bijobijo
次にlocalのgitとremoteのgitを紐付ける必要がある。
以下のコマンドで紐付けは可能。
heroku git:remote -a アプリ名
次に
heroku config:set つけたい環境変数名="設定する環境変数の文字列" --app 自分のアプリケーション名
とすることでherokuに環境変数がセットできる。
そのため以下をセットする。
heroku config:set YOUR_CHANNEL_SECRET="Channel Secretの文字列" --app 自分のアプリケーション名
heroku config:set YOUR_CHANNEL_ACCESS_TOKEN="アクセストークンの文字列" --app 自分のアプリケーション名
configに関しては以下のようにherokuのサイトで自分のアプリよりsettingのconfig varsより確認することも可能。
セットした環境変数は
heroku config
で確認することもできる。
これで環境変数が設定できたのでuploadしていく。
ここで詰まったとこ
みんな安易に
heroku container:push web
としてたからdocker-compose.ymlの名前のことかと思い
heroku container:push app
としていたがうまく起動しなかった。
どういうことか検索していると、以下の記事に答えが書いてあった。
Container Registry & Runtime (Docker Deploys)
heroku container:push <process-type>
To push multiple images, rename your Dockerfiles using Dockerfile.:
つまり、Dockerfile.webという名前をつけていればこれを起動させることができる。
すぐにDockerfileをDockerfile.webに書き換えて、以下のコマンドを順々に叩く。
heroku container:push web
heroku container:release web
これでアプリがリリースされた状態になる。
ここで以下のコマンドを叩き、hello!と書いてあるページに遷移すればokである。
heroku open
実際に動いているコンテナについてはheroku公式より自身のアプリからResourcesより確認することができる。
以下であればwebが起動しているのがわかる。
最後に、LINE Developerより自身のchannelに移動し、Messaging APIより
Webhook settingsを選択し、
https://{自身のアプリ名}.herokuapp.com/callback
をセットしてやれば終わりである。
また、以下のようにUse webhook
をonにしないとlinebotが機能しないので注意。
これで毎日美人とメッセージのやり取りができる!!
あれ、なんか固定メッセージが来ているようなので対処します。
Messaging APIよりAuto-replay messages
を選択。
応答設定→詳細設定→応答メッセージ→応答メッセージ設定→オフ
でこれが解消される。
ではでは、
うまく返せていますね。
こころなしか虚しいです。
linebotを使うことで業務の自動化などもできそうなのでこれ以降も挑戦していきたいと思う。
参考記事
全体図
初心者でも簡単!PythonでLINEチャットボットを作成してみよう!
herokuでenvironmentを設定する方法
Python + HerokuでLINE BOTを作ってみた
requirements.txtの取り扱い
Python, pip list / freezeでインストール済みパッケージ一覧を確認
dockerのherokuへのpush
Container Registry & Runtime
↑これがreleaseの際に最も役に立った。
[Local Development with Docker Compose]
(https://devcenter.heroku.com/articles/local-development-with-docker-compose)
Python初心者がFlaskでLINEbotを作ることになった(Heroku+ClearDB編)