LINEに旅行当日の目的地の天気と今日の現在地の天気を伝えるメッセージを送るアプリケーションを作成している。
その過程で、OPEN WEATHER MAP APIというものを使って天気を取得するのだが、そのバージョン3.0についてのスクリプトがネット上にあまりなかったので一例を載っける。
バージョン2.5も無料であるが、3.0も一日に1000回までのリクエストなら無料である。したがって、多くの人にとって使いやすいAPIの一つであろう。
中身は至ってシンプルで地域の名前と日付の引数を持たせて、getWeatherMessageを動かすと、天気や、最低気温、最高気温を配列形式で
返してくれるものである。
私自身は、日付をどうしても指定してデータを取りたかったので、引数に渡したらそれをyyyy-mm-ddの形式に変換するための関数にdataを渡し、また天気がjsonのデータ内になかったので雲の支配率と降雨量から天気を簡単に出すという判別も行っている。そして、地名ではデータが取ってこれないので地名から経度と緯度を割り出す関数も用意している。
この経度と緯度割り出す段階で日本語でもほとんど成功するのだがスクリプトの変更をするとたまにエラーが発生するのでローマ字でregionを送ることをおすすめする。
そして、APIの取得するURL内で関数を呼び出して実行するスクリプトを書いているが、重複する処理をしているため無駄な演算が生じている可能性がある。
やはり、重複する演算を生じさせないために呼び出す前にletなどでその情報を定義しておくほうが良いのだろうか?
有識者の方がいたら教えてほしい。
それでは以上。
const OPEN_WEATHER_MAP_API_KEY = "OPEN_WEATHER_MAP_API_KEY";
function main() {
let region = "Sapporo";
let date = new Date();
console.log(getWeatherMessage(region, date)):
};
function getWeatherMessage(region, date) {
var response = UrlFetchApp.fetch(`https://api.openweathermap.org/data/3.0/onecall/day_summary?lat=${getGeocode(region)[0]}&lon=${getGeocode(region)[1]}&date=${formatDate(date)}&appid=${OPEN_WEATHER_MAP_API_KEY}&units=metric&lang=ja`);
var weatherData = JSON.parse(response.getContentText());
var cloud_cover = weatherData.cloud_cover.afternoon;
return [judgeWeather(cloud_cover, weatherData.precipitation.total), `${Math.round(weatherData.temperature.min)}℃`, `${Math.round(weatherData.temperature.max)}℃`]
}
//地名を経度、緯度へ変換
function getGeocode(address) {
var response = Maps.newGeocoder().geocode(address);
// 結果の確認
if (response.status == 'OK') {
var result = response.results[0];
var latitude = result.geometry.location.lat;
var longitude = result.geometry.location.lng;
return [latitude, longitude];
} else {
return [null, null];
}
}
//dateのフォーマットを変換
function formatDate(date) {
const year = date.getFullYear();
const month = ('0' + (date.getMonth() + 1)).slice(-2);
const day = ('0' + date.getDate()).slice(-2);
return `${year}-${month}-${day}`;
}
//天気を判別
function judgeWeather(cloudCover, precipitationTotal){
if(precipitationTotal > 5.0){
return "雨";
}else if(cloudCover > 80){
return "曇り";
}else {
return "晴れ"
}
}