きっかけ
「あ〜、今日雨なら傘を持って来れば良かった。」と思う時、ありませんか?
私は稀によくあります。
天気予報は毎朝確認しなくとも、雨の日だけ分かれば。
ということで、雨の日には「傘を持てよ!」と通知してくれるbotを、毎朝必ずと言って良いほど確認するLINEで作ってみました。
概要
実装する機能
以下の2点を機能として実装します。
・傘が必要な日のみ、毎朝6:00〜7:00の間に天気予報をLINEにて通知する。
・予報内容は、当日9:00〜21:00までの3時間刻みの天気情報とする。
使用するサービス
今回使用するサービスは以下の3点です。
・LINE - Messaging API
https://developers.line.me/ja/services/messaging-api/
・Google Apps Script(GAS)
https://developers.google.com/apps-script/
・OpenWeatherMap - Weather API
https://openweathermap.org
システムの全体像

処理は、① → ② → ③ という流れで進みます。
①・・・毎朝6:00〜7:00の間にGASが実行され、Weather API(OpenWeatherMap)より天気予報を取得する。
②・・・Weather APIより天気予報が返ってくる。
③・・・LINE送信用にメッセージを編集し、Messaging API(LINE)に送信する。
各種サービスの事前準備
Weather APIの登録
下記のサイトでFreeプランで登録します。(「Get API key and Start」を押下)
https://openweathermap.org/price
登録後、取得したAPIkeyをメモります。
GASの登録
GASはgoogleのアカウントがあれば利用可能です。
以下、利用方法の参考記事です。スクリプトファイルの新規作成まで実施してください。
LINE developersの登録
Messaging APIを利用するにあたり、LINE developersへの登録が必要になります。
以下の記事を参考に、Channelの設定まで実施してください。(プランは「Developer Trial」)
実装
コード全体
実装に移ります。以下、GASのコードの全てです。(GAS以外のコーディングは不要です。)
詳細は後ほど小分けで説明します。
//諸々の設定
var channel_access_token = 'LINEdevelopersのChannelより取得'
var user_id = 'LINEからuserIdを取得'
var line_url = 'https://api.line.me/v2/bot/message/push'
var openweathermap_url = 'http://api.openweathermap.org/data/2.5/forecast?id=1850147' //idで東京を指定
var openweathermap_appid = 'Weather APIで取得したAPIkey'
var text
var text_jp = []
var rain_info
var final_text
//毎日AM6:00〜7:00に以下のメソッドを起動
function weatherforecast() {
//openweathermapから東京の天気予報を取得
var weatherforecast_finalurl = openweathermap_url + '&APPID=' + openweathermap_appid
var response = UrlFetchApp.fetch(weatherforecast_finalurl)
var json = [JSON.parse(response.getContentText())]
Logger.log(json[0]) //意図した場所の天気が取得できているか確認
//天気情報を日本語に変換
for (var i = 0; i <= 4; i++) {
text = JSON.stringify((json[0].list[3 + i].weather[0].icon))
Logger.log(json[0].list[3 + i]) //意図した時間の天気が取得できているか確認
start_weatherforecast(text)
text_jp[i] = text
}
//天気情報をline送信用に編集する
text_edit()
//lineへ送信する
weatherforecast_to_line(channel_access_token,user_id,final_text);
}
//天気情報を日本語に変換
function start_weatherforecast(weather) {
if (weather == '"01n"' || weather == '"01d"'){
text = '快晴'
}
if (weather == '"02n"' || weather == '"02d"'){
text = '晴れ'
}
if (weather == '"03n"' || weather == '"03d"'){
text = '曇り'
}
if (weather == '"04n"' || weather == '"04d"'){
text = '曇り'
}
if (weather == '"09n"' || weather == '"09d"'){
text = '小雨'
rain_info = '今日は傘を持ちましょう。\n'
}
if (weather == '"10n"' || weather == '"10d"'){
text = '雨'
rain_info = '今日は傘を持ちましょう。\n'
}
if (weather == '"11n"' || weather == '"11d"'){
text = '雷雨'
rain_info = '今日は傘を持ちましょう。\n'
}
if (weather == '"13n"' || weather == '"13d"'){
text = '雪'
rain_info = '今日は傘を持ちましょう。\n'
}
if (weather == '"50n"' || weather == '"50d"'){
text = '霧'
}
}
//line送信用にテキストを編集
function text_edit() {
final_text = '天気予報です。\n' + rain_info + '\n09:00 ' + text_jp[0] + '\n12:00 ' + text_jp[1] + '\n15:00 ' + text_jp[2] + '\n18:00 '
+ text_jp[3]+ '\n21:00 ' + text_jp[4] + '\n\n今日も一日頑張りましょう!'
}
//LINEへ送信
function weatherforecast_to_line(channel_access_token,user_id,text){
if (rain_info == '今日は傘を持ちましょう。\n') {
//LINEに取得結果を送る
UrlFetchApp.fetch(line_url,{
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + channel_access_token,
},
'method': 'post',
'payload': JSON.stringify({
'to': user_id,
'messages' : [
{
'type':'text',
'text':final_text,
}
]
})
});
}
}
コード詳細の説明
諸々の設定
まずは諸々の設定から説明します。
//諸々の設定
var channel_access_token = 'LINEdevelopersのChannelより取得'
var user_id = 'LINEからuserIdを取得'
var line_url = 'https://api.line.me/v2/bot/message/push'
var openweathermap_url = 'http://api.openweathermap.org/data/2.5/forecast?id=1850147' //idで東京を指定
var openweathermap_appid = 'Weather APIで取得したAPIkey'
var text
var text_jp = []
var rain_info
var final_text
❶ 「channel_accsess_token」の宣言
LINE developersのChannel画面で取得します。
❷ 「user_id」の宣言
LINEからpostされたときに一緒に送信される情報で、pushメッセージを送信するときに必要になります。user_idはLINEからのメッセージに含まれているため、LINEからのメッセージに対してuser_idを返すプログラムを作成して取得しました。(もっと効率の良い取得方法があるかと思います。。)
LINEからのメッセージをおうむ返しするという以下の記事を参考に、user_idを返すプログラムを作成できます。
https://qiita.com/nogizakaJinro/items/e2a178c1cb7a0699a80f
❸ 「openweathermap_url」の宣言
3時間ごとの天気予報が取得できるurlの一部です。"id=〜"の部分を変更することで、特定の都市の天気予報を取得できます。天気予報を都市名で取得するなど、取得方法は色々ありますので、詳しくは公式サイトをご参照ください。
❹ 「openweathermap_appid」の宣言
weather API登録時にメモしたAPIkeyを設定します。openweathermap_urlに結合することで、実際に天気予報を取得することができるurlが完成します。
❺ その他変数の宣言
後ほど使用しますので、ここでは説明を割愛します。
メインメソッド
次に、毎朝起動するメインメソッドを説明します。
//毎日AM6:00〜7:00に以下のメソッドを起動
function weatherforecast() {
//openweathermapから東京の天気予報を取得
var weatherforecast_finalurl = openweathermap_url + '&APPID=' + openweathermap_appid
var response = UrlFetchApp.fetch(weatherforecast_finalurl)
var json = [JSON.parse(response.getContentText())]
Logger.log(json[0]) //意図した場所の天気が取得できているか確認
//天気情報を日本語に変換
for (var i = 0; i <= 4; i++) {
text = JSON.stringify((json[0].list[3 + i].weather[0].icon))
Logger.log(json[0].list[3 + i]) //意図した時間の天気が取得できているか確認
start_weatherforecast(text)
text_jp[i] = text
}
//天気情報をline送信用に編集する
text_edit()
//lineへ送信する
weatherforecast_to_line(channel_access_token,user_id,final_text);
}
❶ 天気予報取得用のurl作成
諸々の設定で宣言した「openweathermap_url」と「openweathermap_appid」を組み合わせて、天気予報取得用のurl「weatherforecast_finalurl」を作成します。
❷ 天気予報の取得
「UrlFetchApp.fetch」を使用し、「weatherforecast_finalurl」より取得した天気予報をjson形式に変換し、「json」に格納します。
❸取得した天気予報から必要な情報を抜き取る
欲しい情報は「6:00〜7:00の間で天気予報を取得した時の、9:00・12:00・15:00・18:00・21:00時点の天気5つ」です。以下のページで各天気のコードを確認します。
https://openweathermap.org/weather-conditions
ログを残す「Logger.log(data)」を使用して「json」の中身を確認し、天気のコードを探します。どうやら天気のコードは「json[0].list[3〜7].weather[0].icon」に格納されているようなので、for文で各時間帯の天気ごとに処理を実行します。
for文の中では取得した天気の情報を日本語に変換し、配列である「text_jp」に格納します。(日本語への変換は「start_weatherforecast(text)」で実施。中身は後ほど説明します。)
❹天気情報をLINE送信用に編集
「text_edit()」を呼び出し、LINE送信用のメッセージを作成します。(中身は後ほど説明します。)
❺LINEにメッセージを送信
「weatherforecast_to_line(channel_access_token,user_id,final_text)」を呼び出し、LINEにメッセージを送信します。(中身は後ほど説明します。)
❻メインメソッドの自動起動を設定
以下の記事を参考に、毎日AM6:00〜7:00の間に自動で起動するよう設定します。
https://tonari-it.com/gas-trigger-set/
天気コードの日本語変換
次に、メインメソッドの❸で呼び出したメソッド(start_weatherforecast(text))を説明します。
//天気情報を日本語に変換
function start_weatherforecast(weather) {
if (weather == '"01n"' || weather == '"01d"'){
text = '快晴'
}
if (weather == '"02n"' || weather == '"02d"'){
text = '晴れ'
}
if (weather == '"03n"' || weather == '"03d"'){
text = '曇り'
}
if (weather == '"04n"' || weather == '"04d"'){
text = '曇り'
}
if (weather == '"09n"' || weather == '"09d"'){
text = '小雨'
rain_info = '今日は傘を持ちましょう。\n'
}
if (weather == '"10n"' || weather == '"10d"'){
text = '雨'
rain_info = '今日は傘を持ちましょう。\n'
}
if (weather == '"11n"' || weather == '"11d"'){
text = '雷雨'
rain_info = '今日は傘を持ちましょう。\n'
}
if (weather == '"13n"' || weather == '"13d"'){
text = '雪'
rain_info = '今日は傘を持ちましょう。\n'
}
if (weather == '"50n"' || weather == '"50d"'){
text = '霧'
}
}
「text」に格納された天気コード("01n"など)を判断し、日本語に変換します。また、雨・雪が振る場合は"傘を持ちましょう。"という文言を「rain_info」に格納します。(理由は後ほど説明します。)
天気情報をLINE送信用に編集
次に、メインメソッドの❹で呼び出したメソッド(text_edit())の説明です。
//line送信用にテキストを編集
function text_edit() {
final_text = '天気予報です。\n' + rain_info + '\n09:00 ' + text_jp[0] + '\n12:00 ' + text_jp[1] + '\n15:00 ' + text_jp[2] + '\n18:00 '
+ text_jp[3]+ '\n21:00 ' + text_jp[4] + '\n\n今日も一日頑張りましょう!'
}
日本語に変換した天気情報(text_jp)を使用してLINE送信用のメッセージを編集し、「final_text」に格納します。なお、”\n”は改行を意味します。
LINEにメッセージを送信
最後に、メインメソッドの❺で呼び出したメソッド(weatherforecast_to_line(channel_access_token,user_id,final_text))の説明です。
//LINEへ送信
function weatherforecast_to_line(channel_access_token,user_id,text){
if (rain_info == '今日は傘を持ちましょう。\n') {
//LINEに取得結果を送る
UrlFetchApp.fetch(line_url,{
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + channel_access_token,
},
'method': 'post',
'payload': JSON.stringify({
'to': user_id,
'messages' : [
{
'type':'text',
'text':final_text,
}
]
})
});
}
}
以下のMessaging APIのAPIリファレンスより、プッシュメッセージの送信に必要な情報を確認し、実装しています。
https://developers.line.me/ja/docs/messaging-api/reference/
→「プッシュメッセージを送る」を参照
「if (rain_info == '今日は傘を持ちましょう。\n')」で傘が必要な場合だけLINEに送信するようにしていますが、このif文を外せば毎朝天気予報をLINEに送信するようになります。(雨が振る場合だけ「rain_info」に格納していたのはこのためです。)
テスト
さて、実装が完了したので、意図した通りに動くかテストします。
8:00にラインを確認すると、以下の通知がありました。

なんとか無事に天気予報をpush送信することができたようです。
これにて傘通知bot、完成となります。
作り終えてみての感想
小さなシステムではありますが、プログラミング初心者、かつ、使用した3つのサービス全てが初めてであったため、作り終えるのに苦戦しました。(なんだかんだで着手から1週間ほどかかりました。)
そんな苦戦の中で以下の2点を痛感しています。
・何かしら実現したいものを考え、実現に向けて思考することで体系的な知識が身につく。
・プログラミングはワクワクの塊。
ということで、引き続き高いモチベーションをキープして学習したいと思います。
お読みいただき、ありがとうございました。
※記事にミスや改善点等ありましたら、ご指摘いただけると幸いです。