AWS Lambda

プログラミング一切わからんけどAWS LambdaでSlackお天気botを作った回。

ごあいさつ

こんばんは。大学時代に少しだけPythonをかじった程度の
プログラミングスキルを持つもに倉です。

今回はずっと作ろうと目論んでいた、Lambdaを使ってSlackに
天気予報を通知してくれるbotを実際に作ったので紹介しようと思います。

なお、コード全体はとてもじゃないけれど人に見せられる出来ではないので、
今回は、コードの中でも人様に見せられそうな一部分を
参考にさせていただいたサイトとともに紹介いたします。

構成図


CloudWatchイベントをトリガーに、毎日9時にLambdaを実行。
LambdaはOpenWeatherMapからお天気情報を取得して、
それをSlackに通知しています。

Lambdaの中身

Lambdaでお天気情報を取得する

OpenWeatherMapは、無料で使える天気予報のAPIサービスです(便利)。

取得方法は以下の通りです。

#お天気API取得
#参考URL↓
#https://qiita.com/naomaru/items/80e33233ce9a22df0143

def open_weather_map():
    api = "http://api.openweathermap.org/data/2.5/forecast?q=天気を知りたい地域,jp&lang=ja&units=metric&APPID=自分のAPIキー"
    response = requests.get(api)
    data = response.json()
    weatherInfo = json.dumps(data,indent=4)

    return weatherInfo

requestsはLambdaの標準モジュールには入っていないので、
別で読み込ませる必要があります。
方法はこちら↓
LambdaにPythonの外部モジュールをzipで読み込ませる方法
Cloud9でLambdaにPythonの外部モジュールを追加してみた。

APIの説明

http://api.openweathermap.org/data/2.5/forecast?q=天気を知りたい地域,jp&lang=ja&units=metric&APPID=自分のAPIキー

天気を知りたい地域:http://bulk.openweathermap.org/sample/city.list.json.gz
↑からDLできるJsonに載っている地域の天気は取りたい放題です(超田舎の私の地元もありました! すごい)。
今回は会社が大阪市にあるので「Osaka」にしています。

lang=ja:これを入れると「description」(天気)の部分が「晴天」「曇り」のように日本語になります。
実は今回は使っていないのですが、お試しでいろいろやっていたときの名残でいれたままになっています。

units=metric:これを入れると温度の単位が摂氏(日本でメジャーな「〇〇度」のやつ)になります。

自分のAPIキー:OpenWeatherMapに会員登録するともらえます。

どうやら三時間ごとのお天気情報をもらえるみたいです。
0時起点で、3時、6時、9時……といった具合。

日時の取得

#日付取得    
def now(weather):
    dic = json.loads(weather)   
    description = dic['list'][2]['dt_txt']
    date = datetime.datetime.strptime(description, '%Y-%m-%d %H:%M:%S')
    today = date.strftime("%m月%d日%時%分")

    return today

特に言うことなし。
拾ってきたお天気情報がいつのものかを取得できます。
結局本番で使ったのは日付だけになりましたが、上記のコードでは
時刻も出力されるようにしております。

['list'][2]~

↑この部分の数字を変えると、いつのお天気情報を取得するか変えられます。
2だと直近(9時にコード走らせたら9時の情報を取得できる)、
3だと2の三時間後で、逆に1だと2の三時間前といったかんじです。

天気の情報を取り出す

#今日の天気予報
#参考URL(API取得と同じサイトです)↓
#https://qiita.com/naomaru/items/80e33233ce9a22df0143

def todayweather(weather):
    dic = json.loads(weather) 

    #絵文字に変換
    def weatherList(content):
        List = {
            '01d':':sunny:',
            '02d':':barely_sunny:',
            '03d':':cloud:',
            '04d':':cloud:',
            '09d':':rain_cloud:',
            '10d':':sun_behind_rain_cloud:',
            '11d':':thunder_cloud_and_rain:',
            '13d':':snow_cloud:',
            '50d':':fog:',
            '01n':':sunny:',
            '02n':':barely_sunny:',
            '03n':':cloud:',
            '04n':':cloud:',
            '09n':':rain_cloud:',
            '10n':':sun_behind_rain_cloud:',
            '11n':':thunder_cloud_and_rain:',
            '13n':':snow_cloud:',
            '50n':':fog:'
        }
        data = List[content]
        return data

    icon = dic['list'][2]['weather'][0]['icon']

#汚いので中略

お天気情報を取得してから、iconのidを利用して絵文字に変換しています。

dic['list'][2]['weather'][0]['description']

として、普通にお天気を文字情報(「晴天」など)で出してもよかったのですが、
参考サイトのように絵文字で表現するのがわかりやすいと思ったので
そのように組んでみました。

体感気温を取り出す

def todayweather(weather):
    dic = json.loads(weather) 

#ここに↑の「天気の情報を取り出す」パートが入る

    temp = dic['list'][2]['main']['feels_like']

#汚いので略

普通の気温でもよかったのですが、体感気温も出せるのが面白かったので使っています。

Slackに通知する

#Slackに通知する文言
#参考URL↓
#https://qiita.com/suo-takefumi/items/b47922362366de897920

def post_slack():
    weather = open_weather_map()
    zikan = now(weather)
    today_wether =  todayweather(weather)
    tomorrow_weather = tomorrowweather(weather)
    messages = f"*今日は{zikan}!* はりきっていこー:yoshi:\n------------------------------------------\n:ピンクの生物透過:*今日のお天気と体感気温*:ピンクの生物透過:\n{today_wether}\n------------------------------------------\n:ピンクの生物透過:*明日のお天気と体感気温*:ピンクの生物透過:\n{tomorrow_weather}\n------------------------------------------"

    #Slackに通知するための設定
    send_data = {
        "text": messages,
    }
    send_text = json.dumps(send_data)
    request = urllib.request.Request(
        "https://hooks.slack.com/services/XXXX/XXXX/XXXX", 
        data=send_text.encode('utf-8'), 
        method="POST"
    )
    with urllib.request.urlopen(request) as response:
        response_body = response.read().decode('utf-8')

#トリガー引かれたらSlackに通知
def lambda_handler(event, context):
    post_slack()

本番では今日と明日の天気予報を取得して、それをSlackに通知しています。
実行するとこうなります↓

できてる~よかった~~。

まとめ

というわけで、いまいち知識のない私でも参考サイトを見たり
検索しまくったりすることでどうにかこのようなbotを作ることができました。

前々からずっとほしかったものなので、できあがってからの
愛着もすさまじいです。これからも頼りにしたいと思います。

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA