はじめに
LINE Notifyを使用して天気予報を通知するBOTを作成しました。
GoogleAppsScript(GAS)にて1日1回通知プログラムを実行します。そのプログラムでは、天気予報APIからその日の天気予報を取得して、LINE Notifyに通知します。
機能としては下記の通りです。
- スプレッドシートに記録
- 当日雨が降る場合は「※今日は傘を持っていきましょう!!」を表示する
- 前日より最高気温が3℃高い場合は「※今日は暑くなります!!」を表示する
- 前日より最低気温が3℃低い場合は「※今日は寒くなります!!」を表示する
天気予報API
OpenWeatherMapは、Webやモバイルアプリケーションの開発者に、現在の天候や予測履歴を含む各種気象データの無料APIを提供するオンラインサービスです。有料プランもあります。詳しくは下記の記事に詳細が記載されています。
LINE Notify
GoogleAppsScript
- GoogleAppsScriptを開いて、以下のスクリプトを実装します。
LINE_NOTIFY_TOKEN
にLINE Notifyで発行したトークンを指定する。 -
SSID_WEATHER
にスプレッドシートのIDとSSN_WEATHER
にシート名を指定する。 -
WEATHER_API_KEY
にOpenWeatherMapで発行したAPIキーを指定する。
main.gs
/**
* 天気予報BOT
*
* OpenWeatherMap: https://openweathermap.org/current
* - city id: http://bulk.openweathermap.org/sample/
* - Weather Conditions: https://openweathermap.org/weather-conditions
*/
const SSID_WEATHER = '*****'; // WEATHERのスプレッドシートのID
const SSN_WEATHER = '*****'; // WEATHERのスプレッドシートのシート名
const LINE_NOTIFY_TOKEN = '*****'; // LINE NOTIFY用のアクセストークン
const WEATHER_API_KEY = '*****'; // OpenWeatherMapのAPIキー
const CITY_ID = 1850147; // 東京
const ABSOLUTE_ZERO = -273.15; // 絶対零度
/**
* メイン処理
*/
function main() {
try {
let itemList = [];
let spreadsheet = SpreadsheetApp.openById(SSID_WEATHER);
let sheet = spreadsheet.getSheetByName(SSN_WEATHER);
let lastRow = sheet.getLastRow();
if (0 < lastRow) {
itemList = sheet.getRange(1, 1, sheet.getLastRow(), 5).getValues();
itemList = itemList.map((row) => {
return {
timeStamp: row[0],
weatherId: row[1],
tempMax: row[2],
tempMin: row[3],
humidity: row[4],
}
});
}
let res = getWeatherInfo();
let weatherList = [];
let tempMax;
let tempMin;
let message = `\n今日の天気だよ!!\n\n`;
for (let i in res.list) {
let item = res.list[i];
let dt = new Date(item.dt_txt);
dt.setHours(dt.getHours() + 9);
let timeStamp = Utilities.formatDate(dt, 'Asia/Tokyo', `yyyy/MM/dd HH:mm:ss`);
tempMax = item.main.temp_max;
tempMin = item.main.temp_min;
if (parseInt(i) == 0) {
message += `時刻: ${timeStamp}\n`;
message += `天気: ${LanguageApp.translate(item.weather[0].description, 'en', 'ja')}\n`;
message += `最高気温: ${Math.round(tempMax + ABSOLUTE_ZERO)}℃\n`;
message += `最低気温: ${Math.round(tempMin + ABSOLUTE_ZERO)}℃\n`;
message += `湿度: ${item.main.humidity}%\n\n`;
sheet.appendRow([timeStamp, item.weather[0].id, tempMax, tempMin, item.main.humidity]);
}
if (parseInt(i) < 6) {
weatherList.push(item.weather[0].id);
}
}
let isRainGear = false;
for (let i in weatherList) {
let weather = weatherList[i];
if (weather < 700) {
isRainGear = true;
}
}
if (isRainGear) {
message += `※今日は傘を持っていきましょう!!\n`;
}
if (0 < itemList.length) {
let oldItem = itemList[itemList.length - 1];
if (3 < (tempMax - oldItem.tempMax)) {
message += `※今日は暑くなります!!\n`;
}
if (3 < (oldItem.tempMin - tempMin)) {
message += `※今日は寒くなります!!\n`;
}
}
sendLineNotify(message);
} catch (e) {
console.error(e.stack);
}
}
/**
* 天気予報を取得する
*/
function getWeatherInfo() {
let url = `http://api.openweathermap.org/data/2.5/forecast?id=${CITY_ID}&appid=${WEATHER_API_KEY}`;
let options = {
'method': 'get',
'validateHttpsCertificates': false
};
let response = UrlFetchApp.fetch(url, options);
return JSON.parse(response.getContentText('UTF-8'));
}
/**
* LINEにメッセージを送信する
* @param {String} message メッセージ
*/
function sendLineNotify(message) {
let url = 'https://notify-api.line.me/api/notify';
let options = {
'method': 'post',
'headers': {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Authorization': `Bearer ${LINE_NOTIFY_TOKEN}`
},
'payload': `message=${message}`
};
let response = UrlFetchApp.fetch(url, options);
return JSON.parse(response.getContentText('UTF-8'));
}
SpreadsheetApp.openById
,spreadsheet.getSheetByName
でスプレッドシートの情報を取得しています。getValues()
でセルの値を全て取得しています。天気の内容は英文がAPIから返却されるため、LanguageApp.translate()
で日本文に翻訳しています。
参考リンク
さいごに
ソースコードをGitHubに公開しています。
以上です。