5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

はじめてのGASアプリ – 天気予報SlackBot

Last updated at Posted at 2021-02-28

はじめに

Google Apps Scriptをやってみますか?
ここでは、0からGASでSlackに天気予報を投稿するBotの作成方法を共有していきます。
基本的には、他のブログから学び、初めてのGASの作成の模様を自分用メモとして書きました。

0.作業環境を用意する

僕の環境は以下の通りです。

  1. Windows 10 Pro 64 bit
  2. Google Chrome
  3. 自分用のGoogleアカウント
  4. 管理権限を持っているSlackアカウント

1.Slackアプリを作成する

【初心者向けGAS×Slack】はじめてのSlackアプリを作成しよう
そんなに難しくない、手順通りで大丈夫と思います。

2.Incoming Webhooksを導入する

【初心者向けGAS】Slackにメッセージを投稿するIncoming Webhooksの最初の一歩
生成したWebhook URLのメモが必要です。後ほど、postMessageに使います。

3.Google Apps Scriptを新規作成する

  1. Googleドライブは、Googleトップページ右上のアプリ一覧から開き、「ドライブ」をクリックする。
    image.png

  2. Googleドライブの左上の[:heavy_plus_sign: 新規]から[その他]→[Google Apps Script]の順に進みます。
    image.png

  3. 「無題のプロジェクト」を新規作成しました。
    image.png

4.天気予報SlackBotの実装

###4.1.天気予報API「OpenWeatherMap」について
現時点、完全制限なしの天気予報APIがほとんどないので、今回は認証が必要なAPI: OpenWeatherMapを使うことに決めました。

無料版で利用可能な以下の2つをAPIで実行します。
・指定した都市の現在の天気を取得する。(http://api.openweathermap.org/data/2.5/weather?q={city}&appid={key}&lang=ja&units=metric)
・指定した都市の先5日間の3時間ごとの天気を取得する。(http://api.openweathermap.org/data/2.5/forecast?q={city}&appid={key}&lang=ja&units=metric)
**q={city}&appid={key}**を自分の天気を取得したい都市名、APIキーにセットすることが必要です。

###4.2.天気予報APIからのJSONを文字列に変換する

app.gs
function main() {
  // get from > https://home.openweathermap.org/api_keys
  // *current weather api*
  var URL = 'http://api.openweathermap.org/data/2.5/weather?q=Shinagawa-ku,JP&appid={your API key}&lang=ja&units=metric';
  var res = UrlFetchApp.fetch(URL);
  var data = JSON.parse(res.getContentText());

  // *every 3 hours for the last 5 days weather api*
  var futureURL = 'http://api.openweathermap.org/data/2.5/forecast?q=Shinagawa-ku,JP&appid={your API key}&lang=ja&units=metric';
  var futureResponse = UrlFetchApp.fetch(futureURL);
  var futureData = JSON.parse(futureResponse.getContentText());

  // send message text
  var strBody = "";

  if(data.cod == 200 && futureData.cod == 200){
    var city = data.name;

    // current data
    var summary = data.weather[0].description;
    var temp = Math.floor(data.main.temp);
    var date = new Date(data.dt*1000);

    // tomorrow data
    const tomorrowHour = 9;
    var tomorrowData = futureData.list.find(s => new Date(s.dt*1000).getHours() == tomorrowHour);
    var tomorrowSummary = tomorrowData.weather[0].description;
    var tomorrowTemp = Math.floor(tomorrowData.main.temp);
    var tomorrowDate = new Date(tomorrowData.dt*1000);
    var ary = ["", "", "", "", "", "", ""];
    var week_num = tomorrowDate.getDay();
    var week = "("+ary[week_num]+")";
    var time = Utilities.formatDate(tomorrowDate, "Asia/Tokyo", "M/d");
    var tomorrowDateText = time + week;

    var todayWeather = "*【今日 " + date.getHours() + "時発表の天気予報" + getEmoji(data) + "】*\n> " + city + "" + summary + " " + temp + "";
    var tomorrowWeather = "*【明日 " + tomorrowDateText + " 午前" + String(tomorrowHour) + "時の天気" + getEmoji(tomorrowData) + "】*\n> " + city + "" + tomorrowSummary + " " + tomorrowTemp + "";

    strBody = todayWeather + "\n" + tomorrowWeather;
  }
  else{
    strBody = "データを取得できません。ご確認ください。";
  }

  post(strBody);
}

###4.3.Incoming Webhooksの機能を使って、Slackにメッセージを送る

post.gs
function post(text) {
  // *Slack Webhook URL*
  var url = 'your Webhook URL';
  var params = {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify({text: text}),
  };
  UrlFetchApp.fetch(url, params);
}

###4.4.天気に応じた天気アイコンを表示させる

getEmoji.gs
function getEmoji(json) {
  switch (json.weather[0].main){
    case 'Clouds':
    return ":cloud:";
    case 'Snow':
    return ":snowflake:";
    case 'Rain':
    return ":rain_cloud:";
    case 'Clear':
    return ":sun_with_face:";
    case 'Fog':
    case 'Haze':
    return ":fog:";
    case 'Mist':
    return ":barely_sunny:";
    default:
    return ":mostly_sunny:";
  }
}

###4.5.天気予報をSlackに送る動作確認
プロジェクト編集画面の「:arrow_forward: 実行」ボタンをクリックして、Incoming Webhooksで設定したチャンネルに以下のように投稿が行われます。
image.png

###4.6.祝日・休日判定処理の追加(FIX:06/27)
6月27日現時点、出勤日のみメッセージを届けたいので、以下のように祝日・休日判定処理を追加する。
戻り値がTRUEの場合、メッセージ送信を行う。

workday.gs
function workday(date) {
  // check today is working day
  let dateInt = date.getDay();
  if (dateInt == 0 || dateInt == 6) {
    return false;
  }
  // check today is holiday
  let calendarId = "ja.japanese#holiday@group.v.calendar.google.com";
  let calendar = CalendarApp.getCalendarById(calendarId);
  let todayEvents = calendar.getEventsForDay(date);
  if (todayEvents.length > 0) {
    return false;
  }
  return true;
}

5.デプロイ

1、画面右上にある「デプロイ」ボタン→「新しいデプロイ」で、作成済みのAPPをデプロイする。
image.png
2、Googleアカウントを選択して、データへのアクセスを承認する。
(「アクセスを承認」ボタン→「詳細」リンク→プロジェクト名(安全ではないページ)に移動→「許可」ボタン→「完了」ボタン)
image.png

6.トリガー

画面左側にある「:alarm_clock: トリガー」メニュー→[:heavy_plus_sign: トリガーを追加]ボタン、APP実行したい時間帯を選択すると、「保存」ボタンをクリックする。
僕の方は、毎日退勤する前、現在の気温とあす朝の天気を知りたい、午後6-7時を選択しました。
image.png

7.自動的に投稿を実行される

選択した時間帯通りに知りたい情報を投稿しました!
image.png

8.Source Code (GitHub)

まとめ

GASの初心者として天気予報Botを作れました。定期ジョブ、デプロイ作業は意外に親しみやすい、マウスを数回クリックするだけです。APIから取得のデータを活用して、投稿内容のカスタマイズを簡単にできます。

参照サイト

5
5
1

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
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?