【GoogleAppsScript】朝に雨が降っていたら傘を持って帰るのを忘れないようにSlackに教えてもらう

(最近SlackとGASの記事ばっか書いてる気がする...)

はじめに

以下を解消するのが目的です

  • 朝に雨が降ってると退勤時に雨が降ってようが降ってまいが、会社の傘立てに傘を忘れる確率が100%(降ってるときは傘立てが事務所にあるから取りに戻る必要がある)
  • 傘を一つしか持ってないから2日連続で雨のときに無事死亡する

2つ目はずぶ濡れ出勤すれば済む問題なので1つ目を解消します:)

あと、スマホと傘を常時一緒に持っているわけではないのでスマートタグは使いません

どうしたか

弊社では退勤時、Slackの#timecardに「お先に失礼します。」という投稿をする慣習があります。
その慣習を使って、投稿された「お先に失礼します。」のメッセージのスレッドに傘を持ち帰る旨の投稿をして傘の置き忘れを防ぎます。

チャンネルではなくスレッドに書き込む理由は、投稿された自動メッセージがリモートワークの方など他の社員にとって邪魔な情報になる可能性があるからです。

「お先に失礼します。」に関しての自動化は過去記事に記載していますのでよければ以下もご覧ください :) iliiliiiliili.hatenablog.jp

手順

1. SlackBotの作成

1-1. Event Subscriptionsの設定

https://api.slack.com/apps/からSlackBotを作成します。
この辺りの作成手順はググれば出てくるので割愛します。

メッセージの投稿をトリガーとしてWebhookを使用するのでEvent Subscriptionsをオンにします。

Webhook先のURLをVerifiedにするために一旦GASを以下のコードでデプロイしておきます。

const params = JSON.parse(e.postData.getDataAsString());
if (params.challenge) {
  return ContentService.createTextOutput(params.challenge);
}

SlackのEvent Subscriptionsの設定画面

Request URLVerifiedになればOK

eventは以下を設定しました。(チャンネルのみで使用するのであればmessage.channelsだけでOK。多分。)

1-2. OAuth & Permissions の設定

次に、傘を忘れないようにするメッセージを投稿するためにOAuth & Permissionsを設定します

SlackのOAuth & Permissionsの設定画面

今回はメッセージの書き込みとアプリBotの表示のカスタマイズをしたいのでScopesには以下を設定

アプリBotを使うのでBot User OAuth Tokenに表示されているトークンをメモっておく

2. GASの作成

2-1. パラメータの確認

doPost()でSlackからの投稿を受け取って処理します。

function doPost(e) {
  if (params.event.user !== SLACK_USER_ID) {
    return;
  }
  if (
    params.event.type === "message" &&
    params.event.text === "お先に失礼します。"
  ) {
    checkBringBackUmbrella(params.event.ts);
  }
}

やってること

  • 自分以外のSlackUserIdの場合は何もしない
  • テキストが「お先に失礼します。」の時にのみ天気予報のチェック(+Slackへの投稿)を行う

2-2. 天気予報のAPIを叩く

次に、天気予報のAPIを叩いて当日の雨量を取得します。
天気予報を取得するためのAPIにはOpen-Meteoを使用しました。

open-meteo.com

const date = new Date().toLocaleDateString();
// YYYY-MM-DDのformatに整形
const format = date.split("/").map((row) => (row.length === 1 ? "0" + row : row));
const formattedDate = [format[2], format[0], format[1]].join("-");

const LONGTIDE = 雨量を取得したい地域の経度;
const LATITUDE = 雨量を取得したい地域の緯度;
const res = UrlFetchApp.fetch(
  "https://api.open-meteo.com/v1/forecast?timezone=Asia/Tokyo&latitude=" +
    LATITUDE +
    "&longitude=" +
    LONGTIDE +
    "&hourly=rain&start_date=" +
    formattedDate +
    "&end_date=" +
    formattedDate
);

new Date().toLocaleDateString()の戻りが2022/9/22じゃなくて9/22/2022になるのなんでなん...?
ちなGASのタイムゾーンは東京にしてるし、appsscript.jsontimeZoneAsia/Tokyoになってる)

2-3. Slackにメッセージを投稿する

午前7~9時のいずれかの雨量が0.1以上だったら会社に傘を持ってきているとみなして「お先に失礼します。」のメッセージのスレッドに対して投稿する。
(なお、会社用の鞄に常時折りたたみ傘が入ってるので、10時以降に雨が降った場合は傘立てには傘は入っていないものとしています。)

const src = JSON.parse(res);
// 7,8,9時の雨量
const morningRains = src.hourly.rain.slice(7, 10);
// すべて0.0の場合は雨が降っていなかった
if (morningRains.every((rain) => rain === 0.0)) {
  return;
}
// 雨が降っている場合はSlackのスレッドに書き込む
const SLACK_TOKEN = "SlackのAppBotのトークン";
const SLACK_CHANNEL_NAME = "チャンネル名";
UrlFetchApp.fetch("https://api.slack.com/api/chat.postMessage", {
  method: "post",
  payload: {
    token: SLACK_TOKEN,
    channel: SLACK_CHANNEL_NAME,
    text: "<@"+SLACK_USER_ID+">今日は午前中の雨量が0.1以上でした。傘があれば持って帰りましょう。",
    icon_emoji: ":umbrella:",
    username: "放置傘警察",
    thread_ts: ts,
    reply_broadcast: false,
  },
});

これで雨のときにはSlackが教えてくれるようになりました:)

Slackのスレッド画面

コード全文

最後に

会社以外の傘立てに忘れたらおしまいだね!!

参考

open-meteo.com