BETA

Python・ラズパイでLINE BOTを作ってみる!

投稿日:2018-11-30
最終更新:2018-11-30
※この記事は外部サイト(http://doboku-it-engineer.com/programming/...)からのクロス投稿です

今回はPythonのWebフレームワークであるFlaskを使ってLINE botを作成します!!

サーバーはHerokuを使おうか迷いましたが、今回はRaspberry Piで構築していきます!!

Herokuでの運用は別の機会で!

LINE botとは…

LINE BOTとは、一言でいえばコミュニケーションアプリLINEで動く、チャットボットだ。チャットボットとは?方は、当サイト記事のチャットボットとはを参考にして欲しいが、チャットアプリ上で動くロボットの事だ。 つまり、LINEBOTは、LINE上でユーザーの発言に対して自動応答するプログラムの総称とも言える。

LINEボットとは?より

LINE bot作成手順

「Line developers」に登録&設定

→ラズパイでLINE bot用のディレクトリを作成、仮想環境構築

→Python・Flaskでbot用のスクリプトを作成

→LINE botのトークンを環境変数に設定

→ngrokのインストール

→スクリプト・ngrokの起動

→Webhookの設定

→完成!!!

Line developersの登録・初期設定

LINE botを作るには、Line developersに登録しなければなりません。

以下を参考に登録と初期設定をしていきます。

PythonでLine botを作ってみたの「Line developers 登録&設定」を参考にして「Line developers」に登録&設定

ラズパイで環境構築

まずはRaspberry PiでLINE bot作成用の環境を構築していきます。

pyenv・Python3.7.0・pyenv-virtualenvのインストール

ラズパイにはPythonの2系と3系がプリインストールされていますが、当然ながら最新版ではありません。

なので今回はラズパイにpyenv・Python3.7.0・pip3をインストールしてvenv、pyenv-virtualenvで仮想環境の構築!を参考に、時点最新版のPythonの3.7.0と仮想環境構築に必要なpyenv-virtualenvをインストールし、そのまま仮想環境構築も構築していきましょう!

まずはPythonをインストールするためにpyenvをインストールしていきます。

git cloneコマンドでリポジトリのクローンを行います。

git clone ○○ ~/△△

○○:githubのURL △△:保存先

のように指定してダウンロードします。

# 保存するディレクトリを指定して、そこにダウンロード
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv

LinuxにSSHでログインすると、.bash_profileが実行されるようなのですが、自分の環境では.bash_profileが存在しなかっため、ファイルを作成し、編集していきます。

参考:.bash_profileと.bashrcについて

bashの設定ファイルの読み込みが複雑すぎて混乱する

ターミナルの設定ファイルを作る[.bash_profile]

# .bash_profileをカレントディレクトリに作成
$ touch ~/.bash_profile

# .bash_profileを編集
$ sudo nano ~/.bash_profile


# ~/.bash_profile
source ~/.profile

これでSSHでログインした際に~/.profileが読み込まれるようになりました。

同ディレクトリに存在する.profileに対してnanoコマンドで開いて以下を記述して、パスを通す。 記述後は「source」コマンドで再読み込みする。

$ sudo nano .profile

# .profileファイルに以下を追記
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

$ source .profile

パスが通ると「pyenv」コマンドが使えるのでPython3.7.0をインストール。 この際、すぐにインストールしようとすると下記のようなエラーがでる。

BUILD FAILED (Raspbian 9.4 using python-build 1.2.7-1-g71902168)

Inspect or clean up the working tree at /tmp/python-build.20180815100003.31236
Results logged to /tmp/python-build.20180815100003.31236.log

Last 10 log lines:
  File "/tmp/tmp99t4uw01/pip-10.0.1-py2.py3-none-any.whl/pip/_internal/__init__.py", line 42, in <module>
  File "/tmp/tmp99t4uw01/pip-10.0.1-py2.py3-none-any.whl/pip/_internal/cmdoptions.py", line 16, in <module>
  File "/tmp/tmp99t4uw01/pip-10.0.1-py2.py3-none-any.whl/pip/_internal/index.py", line 25, in <module>
  File "/tmp/tmp99t4uw01/pip-10.0.1-py2.py3-none-any.whl/pip/_internal/download.py", line 39, in <module>
  File "/tmp/tmp99t4uw01/pip-10.0.1-py2.py3-none-any.whl/pip/_internal/utils/glibc.py", line 3, in <module>
  File "/tmp/python-build.20180815100003.31236/Python-3.7.0/Lib/ctypes/__init__.py", line 7, in <module>
    from _ctypes import Union, Structure, Array
ModuleNotFoundError: No module named '_ctypes'
Makefile:1122: recipe for target 'install' failed
make: *** [install] Error 1

pyenvで3.7系のインストールに失敗したときのメモのサイトを参考にして「libffi-dev」を先にインストールする。

$ sudo apt install libffi-dev

$ pyenv install 3.7.0

Pythonのバージョンの切り替え

$ pyenv global 3.7.0

$ python -V
Python 3.7.0

これでPythonの最新版のインストールが完了しました!

pyenv global 3.7.0が効かない時はこれ→pyenvでPythonがSystemバージョンから切り替わらない時の対処

pipのアップグレード

Pythonをダウンロード時にpip自体はインストールされますが、古いバージョンなので、最新版にアップグレードしましょう。

# pipのアップグレード
pip install --upgrade pip

pyenv-virtualenvをインストール

参考:pyenv と pyenv-virtualenv で環境構築

pyenv-virtualenvでディレクトリ単位のpython環境構築

pyenvだけでも便利なのですが、プラグインであるpyenv-virtualenvもインストールしていきます。

pyenv-virtualenvは仮想環境の構築に使用されます。

pyenvではpipでインストールされたパッケージはPythonのバージョンごとに管理されていましたが、pyenv-virtualenvを利用すると同じバージョンでもディレクトリごとに別環境として利用することができ、環境を分けることが出来ます。

# pyenv-virtualenvをインストール
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv

# .profileファイルに追記
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.profile

pyenv-virtualenvで仮想環境の構築する

ディレクトリに対して仮想環境を用意します。

送ったメッセージをおうむ返しするbotを作成したいのでecho_botディレクトリを作成します。

# カレントディレクトリに移動
$ cd

#カレントディレクトリにecho_botディレクトリを作成し、移動
$ mkdir echo_bot
$ cd echo_bot

# 仮想環境用を構築
$ pyenv virtualenv 3.7.0 echo_bot

# echo_botディレクトリに仮想環境を適用
$ cd echo_bot

(echo_bot) $

既存のディレクトリに仮想環境を構築するときはこう

$ cd echo_bot

$ pyenv virtualenv 3.7.0 echo_bot

$ pyenv activate echo_bot

これでecho_botディレクトリに仮想環境が作成されました。

「$」の前に(echo_bot)と表示されるはずです。

これで仮想環境での作業が可能となります。

環境を削除する場合は以下のコマンドを実行

# 構築した環境(echo_bot)を削除する場合
(echo_bot)$ pyenv uninstall echo_bot

サンプルbotを作成する

チャネルを作成

Messaging APIを利用するにはという公式のチュートリアルを参考にチャネル作成します。

Pythonでbotの作成

チャネルの作成が終わったらスクリプトも作成していきます。

今回はPythonのFlaskというWebフレームワークで、簡単に書いていきます。

作成したスクリプトは以下の通り。

# Pythonファイルを作成
$ touch echo_bot.py

# echo_bot.pyを編集
$ nano echo_bot.py


# echo_bot.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__)

#環境変数取得
ECHO_BOT_ACCESS_TOKEN = os.environ["ECHO_BOT_ACCESS_TOKEN"]
ECHO_BOT_CHANNEL_SECRET = os.environ["ECHO_BOT_CHANNEL_SECRET"]

line_bot_api = LineBotApi(ECHO_BOT_ACCESS_TOKEN)
handler = WebhookHandler(ECHO_BOT_CHANNEL_SECRET)

@app.route("/callback", methods=['POST'])
def callback():
    # X-Line-Signatureヘッダー値を取得する
    signature = request.headers['X-Line-Signature']

    # リクエスト本文をテキストとして取得する
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # webhook本体を取り扱う
    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__":
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)

アクセストークンの設定

コンソールで作成したチャネルを開き、チャネルシークレットとチャネルアクセストークンを確認します。

上記スクリプトの

#環境変数取得
ECHO_BOT_ACCESS_TOKEN = os.environ["ECHO_BOT_ACCESS_TOKEN"]
ECHO_BOT_CHANNEL_SECRET = os.environ["ECHO_BOT_CHANNEL_SECRET"]

line_bot_api = LineBotApi(ECHO_BOT_ACCESS_TOKEN)
handler = WebhookHandler(ECHO_BOT_CHANNEL_SECRET)

の部分ですが、Messaging APIを利用してLINEbotを作成する際に、コンソールで取得したチャネルシークレットとチャネルアクセストークンをここに代入しなければ動作しないのですが、直接入力するとコードを見られた際に当然自分のシークレットキーとトークンがばれてしまいますので、環境変数に登録し、パスを通して隠しておきましょう!

参考:PATHを通すために環境変数の設定を理解する (Mac OS X)

# ~/.bashrcを編集
$ sudo nano ~/.bashrc

# ~/.bashrc
# .bashrcに「CHANNEL_ACCESS_TOKEN」と「CHANNEL_SECRET」の環境変数を追加
export ECHO_BOT_ACCESS_TOKEN='Channel Secretの欄の文字列'
export ECHO_BOT_CHANNEL_SECRET='アクセストークンの欄の文字列'

# 保存後、「~/.bash_profile」に「source ~/.bashrc」を追加して自動更新されるようにする
$ sudo nano ~/.bash_profile

# ~/.bash_profile
# 追記
source ~/.bashrc

# 実行すると更新される
$ source ~/.bash_profile

※"Channel Secretの欄の文字列"や"アクセストークンの欄の文字列"は実際に打ち込む際には"は入力しなくてよいので注意してください。

~/.bash_profileは起動時に毎回起動されるため、source ~/.bashrcの記述追加することで.bash_profile起動時に~/.bashrcも動き~/.bashrcに記載された環境変数が有効化されます。

これで、環境変数の設定は終わりました。

ラズパイでbotを動かす

参考:LINE Messaging APIをngrok経由でRaspberry Pi 3で使ってみる(サンプルbot編)

ngrokが便利すぎる

いよいよラズパイで先ほどのコードを動かしていきます。

tmuxのインストール

Raspberry Pi : tmuxをインストールする

tmuxの使い方

ngrok(エヌジーロック)のインストール

次にngrokをインストールしていきます。

ngrokはインターネットから自宅にあるサーバを簡単に公開するために使用するサービスです。

LINE Messaging APIはインターネットからhttpsでないとアクセスできませんが、ngrokはhttpsが使えます。

ngrokにsign in後、ラズパイにインストールします。 (/usr/local/binにunzipすることでパスが通る)

$ wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-arm.zip
$ sudo unzip ngrok-stable-linux-arm.zip -d /usr/local/bin/

ngrokにログイン後、左上のメニューから「Auth」を選択して、「Your Tunnel Authtoken」をメモする。

cdコマンドでホームディレクトリに戻り、以下のコマンドを実行。 (△△△△△△△△△△△△△△には先ほどメモしたYour Tunnel Authtokenが入る)

$ cd
$ ngrok authtoken △△△△△△△△△△△△△△

ラズパイにもモジュールをインストールする。(仮想環境に入ってから)

$ cd echo_bot
(echo_bot)$ pip install flask
(echo_bot)$ pip install line-bot-sdk

macにインストールする場合

[フロントエンド] ローカル環境を外部に公開できるngrokが便利

エラー時の参考:実行ファイルを実行すると「cannot execute binary file: Exec format error」エラー

botを起動させる

まずtmuxを起動させましょう!

(echo_bot)$ tmux
(echo_bot)$ python echo_bot.py

* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

この状態でcontrol + b → cを押してtmuxのコンソールをもう一つ出して、以下のコマンドを実行。 この時、ポートの番号は合わせる。(今回なら5000)

USER_NAMEにはアカウント名、○○○○○○○○には文字列が入っています。 「Forwarding https://○○○○○○○○.ngrok.io -> localhost:5000」 の「https://○○○○○○○○.ngrok.io」をメモします。 (同じ様なものが2つありますが、「https:」の方をメモしてください)

(echo_bot)$ ngrok http 5000

grok by @inconshreveable                                   (Ctrl+C to quit)

Session Status                online
Account                       USER_NAME (Plan: Free)
Version                       2.2.8
Region                        United States (us)
Web Interface                 http://127.0.0.1:4041
Forwarding                    http://○○○○○○○○.ngrok.io -> localhost:5000
Forwarding                    https://○○○○○○○○.ngrok.io -> localhost:5000

Webhookの設定

コンソールに戻り、再度Webhookの設定をします。「Webhook URL」を先ほどメモした「https://○○○○○○○○.ngrok.io」に変更してください。

Webhook送信:利用する

Webhook URL:https://○○○○○○○○.ngrok.io/callback

[email protected]機能の利用→自動応答メッセージを「利用しない」に設定

以上でLINEbotが起動するはずです!

お疲れ様でした!

herokuにデプロイする時はこちらを参考

Heroku + Python(Flask)でオウム返しLINE bot

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@nokonoko1203の技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!