Python
GoogleAppEngine
linebot
LINEmessagingAPI

LINE Messaging APIのsdkをPython(2.7.9)+GoogleAppEngineで利用した際のいろいろ備忘録

More than 1 year has passed since last update.

はじめに

LINE Messaging API を使ったBotを Python + Google App Engine 環境で作ってみたときに、色々知らなかったことがあったので備忘録としてここに書き記しておきたいと思います。

環境の構築時の注意点

  • GoogleAppEngine などと検索すると色々情報は出てきますので、インストールや設定の詳しいことはそちらにおまかせしたいと思います。

  • 今回はPythonStandard environmentを利用しました。PythonにはFlexible environmentの環境も用意されていて、スタンダード環境よりも環境は良いですが無料枠がないらしいです。


  • 今回利用したPythonは2.7.9ですがPython3版のAnacondaによるバージョン管理下にあります。
    • そのためGoogle Cloud SDK をコマンドで素のまま使うことはできず、一度Anacondaでpy27環境を作成して、activate py27などしてからコマンドを打ち込む必要がありました。
    • ちなみにAnacondaで別のバージョンをactivateして利用しているときはコマンドのとこに(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などと入力するとpipinstallに於けるhelpが表示されます。最初からこれがわかればあんなに苦労しなかったのに...

  • また、ただ単にライブラリを一緒にデプロイしただけでも十分ではなく、色々と設定が必要です。 公式DOCによればappengine_config.pyなるものを一緒にデプロイすることでモジュールが入ったlibディレクトリを認識可能にすることができます。 他のディレクトリを認識させる場合は下のコードでlib[任意の名前]に変えれば大丈夫だと思います。
appengine_config.py
# [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/linebot/api.py
#※/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の解説を少し

HTTPSの受付側コード
    jsonObject = request.json
    line_request = jsonObject['events'][0]  # requestが送られてきた内容

ここではline_requestでLINEから来たメッセージの内容を見ることができます。
メッセージ処理をするコードの頭にこのように書いておきます。

BOTのメインのコード
    line_bot_api = LineBotApi(your_channel_access_token)
    parser = WebhookParser(your_channel_secret))

あとはかんたんです。(ここでのメッセージオブジェクトとはLINE側で言うSend message objectのことです。)

BOTのメインのコード
        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")