Python Code Notes

Information by python engineer

Python LINEボットで遊ぶ!天気予報Webアプリを作ろう③ Herokuへデプロイ

オウム返しするLINEボットに、天気予報機能を搭載させていきます。 前回はweb上の天気予報APIを用いて、都市名を入力するとその地点の天気予報を取得するスクリプトファイルを作成しました。

今回は、作成した天気予報スクリプトファイルをLINEボットから呼び出し、都市名を入力するとその地点の天気予報を返信するようにしていきます。

目次

LINEボットファイルの修正

LINEボットを実行する、「app.py」を修正し、天気予報を取得できるようにしていきます。

まずは、作成した「weathergetter.py」をインポートします。

import os
import sys
import weathergetter   #new

これで「app.py」側から「weathergetter.py」内のクラスを使用できるようになります。

次に、LINEボットの返信内容を処理する「app.py」内のdef message_text(event):を以下の様に修正をしていきます。

コード

def message_text(event):
    input_text = event.message.text   #1
    city_data = weathergetter.GetPlaceData()   #2
    city_dict = city_data.get_city()   #3

    if input_text in city_dict:   #4
        r = weathergetter.GetWeatherData(city_dict[input_text])   #5
        reply_text = r.show_weather()   #6
    else:   #7
        reply_text = input_text   #8

    line_bot_api.reply_message(   #9
        event.reply_token,
        TextSendMessage(text=reply_text)
    )

コードの解説

  1. ユーザーが入力した文字を取得
  2. GetPlaceDataオブジェクトを生成
  3. 都市名とidを辞書型で取得
  4. ユーザーの入力値が辞書内にある場合に実行
  5. GetWeatherDataオブジェクトを生成
  6. 天気予報を取得し、返信用変数「reply_text」に格納
  7. ユーザーの入力値が辞書内にない場合に実行
  8. ユーザーの入力値をそのまま返信用変数「reply_text」に格納
  9. LINEボットの返信処理

gitコミット、デプロイ

完成した「weathergetter.py」と修正した「app.py」をHerokuへデプロイしていきます。

以下のコマンドを実行していきます。

  1. git add -A 追加ファイルを追加

  2. git commit -m "add weathergetter" コミット

  3. git push heroku master Herokuへデプロイ

これで準備は完了しました。

動作確認

ライン上から都市名を入力し、天気予報が返信されるか確認します。

適当な都市名を入力してみます。

f:id:vigilantPotato:20190302044719j:plain

無事に天気予報が返信されてきました。

入力した文字が都市リストにない場合は、従来通りオウム返しします。

f:id:vigilantPotato:20190302044734j:plain

コード全文

「app.py」の全文です。

import os
import sys
import weathergetter

from argparse import ArgumentParser
from flask import Flask, request, abort
from linebot import (
    LineBotApi, WebhookHandler
)

from linebot.exceptions import (
    InvalidSignatureError
)

from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)


app = Flask(__name__)

# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv('LINE_CHANNEL_SECRET', None)
channel_access_token = os.getenv('LINE_CHANNEL_ACCESS_TOKEN', None)

if channel_secret is None:
    print('Specify LINE_CHANNEL_SECRET as environment variable.')
    sys.exit(1)

if channel_access_token is None:
    print('Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.')
    sys.exit(1)

line_bot_api = LineBotApi(channel_access_token)
handler = WebhookHandler(channel_secret)


@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:
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)

def message_text(event):
    input_text = event.message.text
    city_data = weathergetter.GetPlaceData()
    city_dict = city_data.get_city()

    if input_text in city_dict:
        r = weathergetter.GetWeatherData(city_dict[input_text])
        reply_text = r.show_weather()
    else:
        reply_text = input_text

    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=reply_text)
    )

if __name__ == "__main__":
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)