Help us understand the problem. What is going on with this article?

Python + AWS Lambda + Line Notify で自動で毎朝Lineに本日のお天気を通知してみた。

More than 1 year has passed since last update.

完成物

Screenshot_2018-09-27-01-50-36.png

こんな感じのものを毎朝通知してほしい!

きっかけ

昨日の天気予報では、雨ではなかったのに、当日、雨予報に変わっている時、傘を忘れてしまう。
残念ながら私のキャンパスは駅から離れたど田舎キャンパスであるため、雨の日傘が無いと必然的に死んでしまう。

→さてどうしよう
→翌日の天気を通知してくれるアプリも無いことはない。
→だが、Android側のタスクキラーで弾かれたり、細かい設定がいじれない。
→なら自分でつくろう  AWSのLambda使ってみたいし

みなさんでも無料で構築可能です。是非挑戦してみてください。

こんな感じで実装

bandicam 2018-09-27 14-58-41-060.jpg

お天気情報取得からLineに通知

なんと先人がここまで実装してくださってました。
きれいなコードで見やすい。とてもありがたい。
 Pythonで天気予報をLINE通知する

LineNotifyに登録

LineNotifyのAPIキーを取得します。
普段のLineアカウントで即登録できるのでとても早く取得できて驚き。
どうやらこれ自分以外にも送れそうなので、もしかしてめちゃくちゃ何かに使えるAPIなのでは・・・?(語彙力)

 [超簡単]LINE notify を使ってみる

Lambdaを構築

AWSに登録していない人はまず登録しましょう。
Amazon Web Service

[注]色々説明が入りますが、私自身、AWS初心者のため認識が間違っている場合があります。

AWSは基本は従量課金制ですが、Lambdaは個人使用ではなかなか消費できない量(一分間に何回も出来るレベル)の無料枠があるので、おそらく無料で出来ます!

■まずLambda関数を登録しましょう

エラーが出てますが、撮り忘れの写真をもう一度再現しただけなので、特に関係ありません。

終わったあとに気が付きましたが、ウェザーの綴りは「Weather」らしいです。。。
bandicam 2018-09-27 02-04-06-548.jpg

登録するとこういった画面が出てきます。

bandicam 2018-09-27 00-58-56-054.jpg
この画面の意味は、Whether_To_LineNotifyというLambda関数が存在して、Amazon CloudWatch Logsという機能が、そいつのログを監視しているよ~みたいな感じ(だと思います。)

その下にはこのようなエディタがあります。

bandicam 2018-09-27 00-31-07-098.jpg

画像右上のハンドラと書かれているのが、Lambdaが実行する関数です。
つまり、Lambda_functionのLambda_handler()を実行する。ということです。

AWSはなんとCLIからちょこまか操作せずに、ブラウザ上でサクサク開発出来るんですね。。。驚きです。(もちろんCLIからもデプロイ出来ます)

■スクリプトを作成

上記のお天気情報をLineに通知するソースを少し編集しました。 (Pythonで天気予報をLINE通知する)

GitHub https://github.com/Yougurut/WhetherToLineNotify

Line Notify API Keyは環境変数を使ってるので、柔軟に書き直してください。
CITY_CODEをいじれば全国各地の天気予報が取得可能です。

Lambda_function.py
import otenki

def lambda_handler(event, context):
    # TODO implement
    otenki.OtenkiNotify()
otenki.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import json
import sys
import urllib.parse
import urllib.request
import datetime
import os

# weather's API
WEATHER_URL="http://weather.livedoor.com/forecast/webservice/json/v1?city=%s"
CITY_CODE="130010" # TOKYO

# LINE notify's API
LINE_TOKEN= os.environ.get("LINE_NOTIFY_API_KEY")
LINE_NOTIFY_URL="https://notify-api.line.me/api/notify"

def get_weather_info():
    try:
        url = WEATHER_URL % CITY_CODE
        html = urllib.request.urlopen(url)
        html_json = json.loads(html.read().decode('utf-8'))
    except Exception as e:
        print ("Exception Error: ", e)
        sys.exit(1)
    return html_json

def set_weather_info(weather_json, day):
    min_temperature = None
    max_temperature = None
    try:
        weather = weather_json['forecasts'][day]['telop']
        max_temperature = weather_json['forecasts'][day]['temperature']['max']['celsius']
        min_temperature = weather_json['forecasts'][day]['temperature']['min']['celsius']
    except TypeError:
        # temperature data is None etc...
        pass
    msg = "\n天気: %s\n最低気温: %s\n最高気温: %s" % \
               (weather, min_temperature, max_temperature)
    return msg

def send_weather_info(msg):
    method = "POST"
    headers = {"Authorization": "Bearer %s" % LINE_TOKEN}
    payload = {"message": msg}
    try:
        payload = urllib.parse.urlencode(payload).encode("utf-8")
        req = urllib.request.Request(
            url=LINE_NOTIFY_URL, data=payload, method=method, headers=headers)
        urllib.request.urlopen(req)
    except Exception as e:
        print ("Exception Error: ", e)
        sys.exit(1)

def OtenkiNotify():
    weather_json = get_weather_info()

    now = datetime.datetime.now() + datetime.timedelta(hours=9) ## GMT+9:00
    weekday = now.weekday()
    yobi = ["月", "火", "水", "木", "金", "土", "日"]
    msg_header = "\n本日" + str(now.date()) +"(" + yobi[weekday] + ")"

    msg = set_weather_info(weather_json, 0)
    print (msg_header + msg)
    send_weather_info(msg_header + msg)
    if("雨" in weather_json['forecasts'][0]['telop']):
        send_weather_info(msg_header+"\n☔☔☔☔☔☔☔☔\n今日は雨が降ります。\n傘を忘れずに!\n☔☔☔☔☔☔☔☔")

(Pythonで天気予報をLINE通知する)
との変更点は
・時間をawsのシステムと合わせる
・曜日を追加
・日本語に
・雨の日は追加で傘を持っていくように通知
といった内容です。

この2つのコードをrootに追加したあとに、上部のバーの保存ボタンを押したあとにテストしてみてください。最初保存ボタンを押して無くて10分ぐらい格闘してました

bandicam 2018-09-27 00-36-29-589.jpg

これで自分のLineアカウントに今日のお天気の通知が行けばOKです。

■トリガー(予定)を登録。

先程のせたDesignerにCloudWatch Eventsというトリガーを追加します。
bandicam 2018-09-27 00-27-31-791.jpg
CloudWatch Eventsというトリガーはどの時間・間隔でLambda関数を走らせるのか?というものです。

そのトリガーの設定はこんな感じで設定してあげます。
bandicam 2018-09-27 00-28-42-569.jpg

スケジュール式はcron(0 21 * * ? *)となっていますが、これは毎日UTC21:00(日本時間の朝6:00)にLambda関数を走らせるという意味です。

結果

Screenshot_2018-09-27-13-53-31.png
ちゃんと朝6:00に天気予報のLine通知が来ました。
これで雨の日に傘を忘れることが無くなる。。。はず!!!

AWS初心者でも2時間ほどで実装できたので、雨の日の傘で困っている方は是非挑戦してください!!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away