前置き
毎朝、帰宅時間の18時に雨が降るかどうかをLINEで通知するBotを作成しました。この記事では、その作成手順を解説します。
GitHub
0. 記事の構成
- 天気予報API(livedoor天気互換)の動作確認
- 天気予報APIで降水確率をPythonで取得する
- LINE Messaging APIの設定
- AWS Lambdaの設定
- AWS Lambdaのテスト
- 天気予報APIの結果をLINEで通知する
- AWS EventBridgeの設定
- まとめ
- 参考文献
- []の数字は参考文献です。
1. 天気予報API(livedoor天気互換)の動作確認[1][2]
天気予報APIのリクエストURLは以下の通りです:
https://weather.tsukumijima.net/api/forecast/city/<場所のID>
動作確認手順
- APIドキュメントに従い、リクエストURLに場所のIDを指定します。
- 場所のIDは全国の地点定義表[3]に記載されています。
- 福井市(ID: 180010)を指定して実行します。
実行結果
以下は、福井市の天気予報を取得した際のレスポンス例です。
https://weather.tsukumijima.net/api/forecast/city/180010
{
"publicTime": "2024-12-27T13:00:00+09:00",
"publicTimeFormatted": "2024/12/27 13:00:00",
"publishingOffice": "福井地方気象台",
"title": "福井県 福井 の天気",
"link": "https://www.jma.go.jp/bosai/forecast/#area_type=offices&area_code=180000",
"description": {
"publicTime": "2024-12-27T10:41:00+09:00",
"publicTimeFormatted": "2024/12/27 10:41:00",
"headlineText": "",
"bodyText": " 日本付近は冬型の気圧配置となっています。\n\n 福井県は、おおむね雨や雪となっています。\n\n 27日は、冬型の気圧配置が続く見込みです。\n このため、嶺北は雪か雨、嶺南は雨か雪で、共に雷を伴う所があるでしょう。\n\n 28日は、引き続き冬型の気圧配置となる見込みです。\n このため、雪か雨で、雷を伴う所があるでしょう。",
"text": " 日本付近は冬型の気圧配置となっています。\n\n 福井県は、おおむね雨や雪となっています。\n\n 27日は、冬型の気圧配置が続く見込みです。\n このため、嶺北は雪か雨、嶺南は雨か雪で、共に雷を伴う所があるでしょう。\n\n 28日は、引き続き冬型の気圧配置となる見込みです。\n このため、雪か雨で、雷を伴う所があるでしょう。"
},
"forecasts": [
{
"date": "2024-12-27",
"dateLabel": "今日",
"telop": "雪か雨",
"detail": {
"weather": "雪か雨 所により 雷 を伴う",
"wind": "北の風 やや強く 後 南の風 やや強く 海上 では 西の風 強く",
"wave": "4メートル"
},
"temperature": {
"min": {
"celsius": null,
"fahrenheit": null
},
"max": {
"celsius": "8",
"fahrenheit": "46.4"
}
},
"chanceOfRain": {
"T00_06": "--%",
"T06_12": "--%",
"T12_18": "90%",
"T18_24": "90%"
},
"image": {
"title": "雪か雨",
"url": "https://www.jma.go.jp/bosai/forecast/img/400.svg",
"width": 80,
"height": 60
}
},
・・・
],
"location": {
"area": "中部",
"prefecture": "福井県",
"district": "嶺北",
"city": "福井"
},
"copyright": {
"title": "(C) 天気予報 API(livedoor 天気互換)",
"link": "https://weather.tsukumijima.net/",
"image": {
"title": "天気予報 API(livedoor 天気互換)",
"link": "https://weather.tsukumijima.net/",
"url": "https://weather.tsukumijima.net/logo.png",
"width": 120,
"height": 120
},
"provider": [
{
"link": "https://www.jma.go.jp/jma/",
"name": "気象庁 Japan Meteorological Agency",
"note": "気象庁 HP にて配信されている天気予報を JSON データへ編集しています。"
}
]
}
}
出力結果より
"chanceOfRain": {
"T00_06": "--%",
"T06_12": "--%",
"T12_18": "90%",
"T18_24": "90%"
}
ここで、chanceOfRain
プロパティのT12_18
部分を使用して18時の降水確率を取得します。
2. 天気予報APIで降水確率をPythonで取得する[4][5]
以下のPythonコードを使用してAPIから降水確率を取得します。
import requests
url = requests.get("https://weather.tsukumijima.net/api/forecast/city/180010")
data = url.json()
chanceOfRain = data["forecasts"][0]["chanceOfRain"]["T12_18"]
print(f"T12_18の降水確率: {chanceOfRain}")
実行結果
$ \WeatherLine> python3 .\get_chanceOfRain.py
T12_18の降水確率: 90%
改良版:例外処理と条件分岐を追加
以下のコードでは、降水確率が50%以上の場合のみ結果を出力します。
import requests
try:
response = requests.get("https://weather.tsukumijima.net/api/forecast/city/180010",timeout=5)
response.raise_for_status()
data = response.json()
chanceOfRain_str = data["forecasts"][0]["chanceOfRain"]["T12_18"].strip("%")
chanceOfRain = int(chanceOfRain_str)
if chanceOfRain >= 50:
print(f"T12_18の降水確率は{chanceOfRain}%です。雨の可能性があります。")
except requests.exceptions.Timeout:
print("リクエストがタイムアウトしました。")
except requests.exceptions.HTTPError as e:
print(f"HTTPエラーが発生しました: {e.response.status_code} {e.response.reason}")
except requests.exceptions.RequestException as e:
print(f"リクエスト中にエラーが発生しました: {e}")
実行結果(福井市の場合)
$ \WeatherLine> python3 .\get_chanceOfRain.py
T12_18の降水確率は90%です。雨の可能性があります。
これで動作確認とローカル環境で設定が終わったため、あとはLINE Messaging APIの設定とAWS Lambdaの設定をしクラウドで動作確認を行います。
3. LINE Messaging APIの設定
- LINE Developersでプロバイダーを作成[6]
- Messaging APIチャンネルを作成
- チャネルアクセストークンを発行
LINE公式アカウントを使用し、Messaging APIの設定をする。
4. AWS Lambdaの設定
1. AWS Management ConsoleでLambda関数を作成
- 関数名:
WeatherLine
- ランタイム: Python 3.13
2. 必要なライブラリ(requests)をインストールし、レイヤーとしてアップロード
-
レイヤーの準備(ローカル)
$ pip install requests -t ./python $ zip -r python.zip ./python
ハマったところ No module named 'requests' [9]
フォルダ名は必ず"python.zip"とすること。
他のフォルダ名だとエラーがでて使えない!!
3. 環境変数にLINEチャネルアクセストークンを設定[7]
5. AWS Lambdaのテスト[8]
以下は、LINEで固定メッセージを送信するテストコードです。
import os
import requests
def lambda_handler(event, context):
# 環境変数の取得
CHANNEL_ACCESS_TOKEN = os.environ['CHANNEL_ACCESS_TOKEN']
# LINEの返信APIにメッセージを送信
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {CHANNEL_ACCESS_TOKEN}'
}
# メッセージ内容の作成
body = {
"messages": [
{
"type": "text",
"text": "TEST Message!!" # LINEに送信するメッセージ
}
]
}
# リクエストの送信
response = requests.post(
'https://api.line.me/v2/bot/message/broadcast',
headers=headers,
json=body
)
return {
'statusCode': response.status_code,
'body': response.text
}
実行結果:LINE
6. 天気予報APIの結果をLINEで通知する
天気予報APIから取得した降水確率をLINEで通知するLambda関数です。
import os
import requests
def lambda_handler(event, context):
# 環境変数の取得
CHANNEL_ACCESS_TOKEN = os.environ['CHANNEL_ACCESS_TOKEN']
# LINE APIのヘッダー
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {CHANNEL_ACCESS_TOKEN}'
}
# 天気予報APIを呼び出して降水確率を取得
message = ""
try:
# タイムアウトを5秒に設定
response = requests.get("https://weather.tsukumijima.net/api/forecast/city/180010", timeout=5)
response.raise_for_status()
data = response.json()
# 降水確率を取得(T12_18の値を取得)
chanceOfRain_str = data["forecasts"][0]["chanceOfRain"]["T12_18"].strip("%")
if chanceOfRain_str == "--":
message = "T12_18の降水確率が未設定または不明です。"
else:
chanceOfRain = int(chanceOfRain_str)
if chanceOfRain >= 50:
message = f"本日18時の降水確率は{chanceOfRain}%です。雨の可能性があります。"
else:
message = f"本日18時の降水確率は{chanceOfRain}%です。雨の可能性は低いです。"
except requests.exceptions.Timeout:
message = "天気予報の取得に失敗しました(タイムアウト)。"
except requests.exceptions.HTTPError as e:
message = f"天気予報の取得に失敗しました(HTTPエラー: {e.response.status_code} {e.response.reason})。"
except requests.exceptions.RequestException as e:
message = f"天気予報の取得中にエラーが発生しました: {str(e)}"
# LINEにメッセージを送信
body = {
"messages": [
{
"type": "text",
"text": message # 天気予報の結果をLINEに送信
}
]
}
try:
line_response = requests.post(
'https://api.line.me/v2/bot/message/broadcast',
headers=headers,
json=body
)
line_response.raise_for_status()
except requests.exceptions.RequestException as e:
return {
'statusCode': 500,
'body': f"Error sending message to LINE: {str(e)}"
}
# 正常終了
return {
'statusCode': line_response.status_code,
'body': line_response.text
}
実行結果:LINE
7. AWS EventBridgeの設定[10]
- AWS Management ConsoleでEventBridgeを開き、新規ルールを作成
- スケジュール式に以下を設定
(日本時間、平日8時に実行)
cron(0 8 ? * MON-FRI *)
実行結果:LINE
8. まとめ
この記事では、天気予報APIを活用して、帰宅時間18時の降水確率をLINEで通知するBotを作成する手順を解説しました。今後は、降水確率が高い場合に雨雲レーダー情報を追加通知する機能の実装を検討しています。
9. 参考文献
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
[10]