はじめに
LINE Messaging API を使ったBotを Python + Google App Engine 環境で作ってみたときに、色々知らなかったことがあったので備忘録としてここに書き記しておきたいと思います。
環境の構築時の注意点
GoogleAppEngine などと検索すると色々情報は出てきますので、インストールや設定の詳しいことはそちらにおまかせしたいと思います。
今回はPythonのStandard environmentを利用しました。PythonにはFlexible environmentの環境も用意されていて、スタンダード環境よりも環境は良いですが無料枠がないらしいです。
- 今回利用したPythonは2.7.9ですがPython3版のAnacondaによるバージョン管理下にあります。
- そのためGoogle Cloud SDK をコマンドで素のまま使うことはできず、一度Anacondaでpy27環境を作成して、
activate py27
などしてからコマンドを打ち込む必要がありました。 - ちなみにAnacondaで別のバージョンをactivateして利用しているときはコマンドのとこに(py27)と表示されます。
- そのためGoogle Cloud SDK をコマンドで素のまま使うことはできず、一度Anacondaでpy27環境を作成して、
- デプロイはGoogle Cloud SDKを使ってコマンドでやります。詳しくはこれもGAEのドキュメントを読めばわかります。
- 初期起動時は
gcloud auth login
でアカウントの紐付け、gcloud init
して画面に従って設定をして、gcloud app deploy [プロジェクトのyamlファイル]
もしくはプロジェクトのルートディレクトリでgcloud app deploy
をすればOK。 -
gcloud app deploy --version 2
などデプロイするときにバージョンを管理することも可能。
- 初期起動時は
デプロイ時の注意点
- スタンダード環境ではPythonのライブラリがファイルに「これを使います!」と書いただけでは使えず、自分でメインのファイルと一緒にデプロイする必要があります。
-
pip install [モジュール] -t [インストール場所]
などを使って依存関係などを解決した形でインストールしたほうが良いです。(-t = --targetで通常のモジュールの場所とは違うところにインストールするときに使います。)- ちなみにコマンドで
pip install -help
などと入力するとpipのinstallに於けるhelpが表示されます。最初からこれがわかればあんなに苦労しなかったのに...
- ちなみにコマンドで
- また、ただ単にライブラリを一緒にデプロイしただけでも十分ではなく、色々と設定が必要です。 公式DOCによればappengine_config.pyなるものを一緒にデプロイすることでモジュールが入ったlibディレクトリを認識可能にすることができます。 他のディレクトリを認識させる場合は下のコードでlibを[任意の名前]に変えれば大丈夫だと思います。
# [START vendor]
import os
from google.appengine.ext import vendor
# Add any libraries installed in the "lib" folder.
vendor.add(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib'))
# [END vendor]
- またどう必要かはよくわかりませんでしたがrequirements.txtも一緒にしておいたほうが良さそうです。
pip freeze
した結果を貼り付ければとりあえずOKっぽいです。
以上の設定でようやくコード側で
import flask
とかができるようになります。
LINE Messaging API利用の注意点
LINE Messaging APIにはpython用のライブラリがあり、実は今回はその利用というのも目的の一つでした。line-bot-sdk-python on GitHub (pipでインストールできます。)
またここでの注意点は、line-bot-sdk-pythonにはrequestsというモジュールが外部との通信のため要求されていますがGAEではrequestsは使えない。ということです。(GAEでget,postなどをするためにはURLFetchというGoogleのモジュールが必要)
色々と調べた結果URLFetchとrequestsの橋渡しをするモジュールがあったのでインストールし、以下のようにline-bot-sdk-pythonに追加・変更しました。
#※/libはモジュールをインストールしたディレクトリです。
# [START imports]
import requests
import requests_toolbelt.adapters.appengine
# Use the App Engine Requests adapter. This makes sure that Requests uses
# URLFetch.
requests_toolbelt.adapters.appengine.monkeypatch()
# [END imports]
これでline-bot-sdk-pythonに大きな変更を加えずにGAEで利用する事ができます。
このライブラリがあると、自分でLINE返信用のオブジェクトを作る必要がなくなります。
LINE Messaging API の詳しい仕様はこちら:Line API Reference
line-bot-sdk-pythonの解説を少し
jsonObject = request.json
line_request = jsonObject['events'][0] # requestが送られてきた内容
ここではline_requestでLINEから来たメッセージの内容を見ることができます。
メッセージ処理をするコードの頭にこのように書いておきます。
line_bot_api = LineBotApi(your_channel_access_token)
parser = WebhookParser(your_channel_secret))
あとはかんたんです。(ここでのメッセージオブジェクトとはLINE側で言うSend message objectのことです。)
line_bot_api.reply_message(
replyToken,
TextSendMessage(text=event.message.text)
)
-
line_bot_api.reply_message(replyToken, メッセージオブジェクト)
で返信
メッセージオブジェクトの作り方
オブジェクト(テキスト) = TextSendMessage(text="テキスト")
オブジェクト(写真) = ImageSendMessage(original_content_url="元画像のURL", preview_image_url="サムネイルのURL")
オブジェクト(動画) = VideoSendMessage(original_content_url="元動画のURL", preview_image_url="サムネイルのURL")
オブジェクト(動画) = AudioSendMessage(original_content_url="元音声のURL", duration="長さ(1分以内)")
オブジェクト(動画) = LocationSendMessage(title="タイトル", address="住所", latitude="緯度", longitude="経度")
オブジェクト(動画) = StickerSendMessage(package_id="パッケージID", sticker_id="ステッカーID")