LoginSignup
7
2

More than 1 year has passed since last update.

はじめに

LINE Notifyを使用して天気予報を通知するBOTを作成しました。
IMG_5276_1.PNG

GoogleAppsScript(GAS)にて1日1回通知プログラムを実行します。そのプログラムでは、天気予報APIからその日の天気予報を取得して、LINE Notifyに通知します。

機能としては下記の通りです。

  • スプレッドシートに記録
  • 当日雨が降る場合は「※今日は傘を持っていきましょう!!」を表示する
  • 前日より最高気温が3℃高い場合は「※今日は暑くなります!!」を表示する
  • 前日より最低気温が3℃低い場合は「※今日は寒くなります!!」を表示する

天気予報API

OpenWeatherMapは、Webやモバイルアプリケーションの開発者に、現在の天候や予測履歴を含む各種気象データの無料APIを提供するオンラインサービスです。有料プランもあります。詳しくは下記の記事に詳細が記載されています。

LINE Notify

GoogleAppsScript

  1. GoogleAppsScriptを開いて、以下のスクリプトを実装します。LINE_NOTIFY_TOKENにLINE Notifyで発行したトークンを指定する。
  2. SSID_WEATHERにスプレッドシートのIDとSSN_WEATHERにシート名を指定する。
  3. 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に公開しています。

以上です。

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2