PythonからLINE Messaging APIで通知する方法【現行SDK対応】

現在はLINE公式SDKのv3系を使用する

この記事後半のLineBotApiを使うコードはSDK 2系の記録です。公式Python SDKは3系のlinebot.v3へ移行しており、Python 3.10以上が必要です。

python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade line-bot-sdk

push messageの最小例

import os

from linebot.v3.messaging import (
    ApiClient,
    Configuration,
    MessagingApi,
    PushMessageRequest,
    TextMessage,
)

configuration = Configuration(
    access_token=os.environ['LINE_CHANNEL_ACCESS_TOKEN']
)

with ApiClient(configuration) as api_client:
    api = MessagingApi(api_client)
    api.push_message(
        PushMessageRequest(
            to=os.environ['LINE_USER_ID'],
            messages=[TextMessage(text='テスト通知です')],
        )
    )

アクセストークンやユーザーIDをソースコードへ直接書かず、環境変数やシークレット管理機能を使います。LINE Notifyは2025年3月31日に終了しましたが、この記事で扱うMessaging APIは別サービスです。送信数はMessaging APIの料金・メッセージ通数に従います。

LINE公式Python SDKメッセージ送信の公式ガイド

Pythonで気象情報を取得してLINE通知するシステムを作ってみます。流れとしては以下の通り非常にシンプルなものとします。
  1. 気象情報APIから天気予報を取得
  2. 予報内容を通知用に加工
  3. LINEに通知する

気象情報APIから天気予報を取得

まず、気象情報ですが、Rakuten Rapid APIで「Open Weather Map」というAPIを見つけましたので、こちらを活用してみたいと思います。
https://api.rakuten.net/community/api/open-weather-map/details
利用には事前にRakuten Rapid APIへの登録が必要となります。 「Open Weather Map」は世界中の気象情報を提供しているAPIで商用利用可能という事です。100件/日であればBasic0円プランで利用できます。世界中の都市ごとの天気であったり、3時間置きの天気であったり様々な取得が可能です。 Open Weather Mapの具体的な使い方は、以下などで良く纏められています。
https://tacs-port.tech/blog/api/blog-132/
API使用時には 管理画面より API_KEY を取得し控えておきます。
#! /usr/bin/python3
import json
import datetime
import os
import requests
import sys

from linebot import LineBotApi
from linebot.models import TextSendMessage
from pytz import timezone

user_id = "[任意のUSER_ID]"
LINE_CHANNEL_ACCESS_TOKEN = "[任意のACCESS_TOKEN]"
line_bot_api = LineBotApi(LINE_CHANNEL_ACCESS_TOKEN)

# 天気情報取得
def getWeather():
	url = "https://community-open-weather-map.p.rapidapi.com/forecast"
	querystring = {"q":"Kyoto,jp","units":"metric","lang":"ja"}
	headers = {
		'x-rapidapi-host': "community-open-weather-map.p.rapidapi.com",
		'x-rapidapi-key': "[任意のAPI_KEY]"
		}
	response = requests.request("GET", url, headers=headers, params=querystring)
	#print(response.text)
	forecastData = json.loads(response.text)
	
	if not ('list' in forecastData):
		print('error')
		return
	
	# 通知内容作成
	words = '【今日の天気】\n'
	beforeDate = ''
	print(forecastData['list'][0])
	for item in forecastData['list']:
		forecastDatetime = timezone('Asia/Tokyo').localize(datetime.datetime.fromtimestamp(item['dt']))

		# 本日分のみ通知対象とする
		if beforeDate != '' and beforeDate != forecastDatetime.strftime('%Y-%m-%d'):
			break
		else:
			beforeDate = forecastDatetime.strftime('%Y-%m-%d')

		weatherDescription = item['weather'][0]['description']
		emoji = ''
		# 絵文字の分岐は適当
		if '曇' in weatherDescription:
			emoji = '\uDBC0\uDCAC'
		elif '雪' in weatherDescription:
			emoji = '\uDBC0\uDCAB'
		elif '雨' in weatherDescription:
			emoji = '\uDBC0\uDCAA'
		elif '晴' in weatherDescription:
			emoji = '\uDBC0\uDCA9'

		temperature = item['main']['temp']
		rainfall = 0
		if 'rain' in item and '3h' in item['rain']:
			rainfall = item['rain']['3h']
		words += '\n{0}\n天気:{1} {2}\n気温(℃):{3}\n雨量(mm):{4}\n'.format(forecastDatetime.strftime('%Y-%m-%d %H:%M'), emoji, weatherDescription, temperature, rainfall)
	
	return words

予報内容を通知用に加工

APIからはJSON形式で結果が送られてきますので、取得した予報内容を適宜LINEで通知したい内容に整形します。 今回は京都市の3時間置きの天気情報を本日分だけ通知するようにしてみました。ソースコードは上記 getWeather() の後半部分です。 一応テストも兼ねて絵文字も表示させてみました。天気を 晴れ・雨・雪・曇り で分けて表示されるようにしてみました。この辺りの分岐は適当ですので適宜変更してください。 LINE Massaging APIから通知を送る際に、文中に使える絵文字の種類は以下の通りです。 https://developers.line.biz/media/messaging-api/emoji-list.pdf 絵文字同様にスタンプも送る事が可能ですが、使えるスタンプは以下に限られています。 https://developers.line.biz/media/messaging-api/sticker_list.pdf

LINEに通知する

LINEへの通知方法はいくつかありますが、今回はLINE Messaging APIを使用してみます。 LINE Developersへの登録は事前に済ませておいてください。登録手順などはこちらでは割愛します。 まずは、LINE Developersの管理画面より、USER_IDACCESS_TOKENを取得してください。取得出来ましたらそちらを使用して以下のコードで任意のLINEユーザー(グループ)に通知を送る事ができます。
# 指定のLINEユーザー(グループ)に通知
def push_message(self, to, messages, timeout=None):
	if not isinstance(messages, (list, tuple)):
		messages = [messages]

	data = {
		'to': to,
		'messages': [message.as_json_dict() for message in messages]
	}

	self._post(
		'/v2/bot/message/push', data=json.dumps(data), timeout=timeout
	)

動作検証

実際に上記までで作成したスクリプトを実行してみます。
def main():
	# 天気情報取得
	wetherText = getWeather()
	messages = TextSendMessage(text=wetherText)

	# 指定のLINEユーザー(グループ)に通知
	line_bot_api.push_message(user_id, messages=messages)


if __name__ == "__main__":
	main()
これまでのソースコードを一まとめにしたスクリプトを用意し、実行は単純にpythonスクリプトを実行するのみです。実行すると指定のLINEグループに正常に通知が来ました。 こちらがLINEに送信した結果です。雨の画像バリエーションが少なかったので小雨とはちょっと違いますが、絵文字としては一応正しく送信の確認ができました。

まとめ

今回は、APIから取得してきたデータをLINEで送信(通知)する仕組みを作ってみました。 あくまでサンプルとして気象情報を選びましたが、実際にはLINEのサービスとして LINEお天気 などもありますので、気象情報の有用性は低いと思います。 しかしながら、利用用途に合わせて他のAPIに転用できますので、何か有効的な使い方が出来るかもしれません。
タイトルとURLをコピーしました