Slackの雨通知botを爆速で作る【メッ●●】

ZOZOテクノロジーズのむーさん@murs313です。

ZOZOテクノロジーズでは8月にフルリモート・フルフレックスが始まり、各チームで相談しながら利用しています。
うちのチームも気軽に利用できる雰囲気なのですが、しばしばこんなことが…。

~とある平日の夜~
むー「あーーー、明日雨じゃん」
むー「明日自宅リモートにしよ……」
むー「……PC持って帰ってきてないじゃん!!!無理じゃん!!!」

というわけで、翌日が雨予報だったらSlack通知をしてくれるbotをつくりました。もちろんメッ●●でね。

できたもの

翌日が雨予報だったら、17時に通知してPCを持って帰ることを促してくれます。

使うもの

天気予報の公開API
こちらからlivedoorを選びました。
[2019] 公開されているAPI一覧まとめ

SlackのIncoming WebHook
SlackのApp。チャンネルに設定するとWebhook URLが発行されて、このURLにPOSTすると該当チャンネルに投稿できる。
https://slack.com/intl/ja-jp/help/articles/115005265063

Google Apps Script
通称GAS。定期実行できる「トリガー」という機能がある。(知らなかった!)

手順

1. Incoming WebHooksの設定

Slack左上のメニューから「Slackをカスタマイズ」を選択

ブラウザが開いたら、サイドメニューから「App管理」を選択

「Appディレクトリを検索…」の検索窓で検索して「Incoming WebHook」を選択

「Slackに追加」をクリック

投稿したいチャンネルを選択して、「Incoming WebHookインテグレーションの追加」をクリック

これでWebhook URLが発行されました。あとで使います。このURLにPOSTすると該当チャンネルに投稿できてしまうので、むやみに公開しないように注意してください。

「セットアップの手順」にリンクの付け方やペイロードの説明が書かれているので読んでおくと良いでしょう。
「インテグレーションの設定」でアイコンの名前や画像を設定できるので、メッ●●にしておきましょう。こんなふうにね。

2. GASの設定

2-1. スクリプトを書く

Googleドライブの「新規」から、「Google Apps Script」を選択

下記のコードから、2箇所書き換える必要があります。

function main() {
  const today = new Date();
  const tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate()+1);
  if (isHoliday(today)) return; // 今日が休日なら処理しない
  if (isHoliday(tomorrow)) return; // 明日が休日なら処理しない

  const cityId = 120010; // http://weather.livedoor.com/forecast/rss/primary_area.xml

  const forecast = getForecast(cityId);
  if (forecast.indexOf('') !== -1) { // 雨のときだけSlack通知する
    sendToSlack(forecast);
  }
}

function getForecast(cityId) {
  const response = UrlFetchApp.fetch('http://weather.livedoor.com/forecast/webservice/json/v1?city=' + cityId);
  const obj = JSON.parse(response.getContentText()); 

  const forecast = '明日の' + obj['location']['city'] + '' + obj['forecasts'][1]['telop'] + 'です。';
  return forecast;
}

function sendToSlack(message) {
  const webhookUrl = '取得したWebhook URL';
  const jsonData = {
    'text' : message
  };
  const payload = JSON.stringify(jsonData);
  const options = {
    'method' : 'post',
    'contentType' : 'application/json',
    'payload' : payload
  };
  UrlFetchApp.fetch(webhookUrl, options);
}

function isHoliday(date) {
  // 土日ならtrue
  const weekInt = date.getDay();
  if(weekInt == 0 || weekInt == 6) return true;

  // 国民の祝日に該当していたらtrue
  const holidays = CalendarApp.getCalendarsByName('日本の祝日');
  const todayholidays = holidays[0].getEventsForDay(date).length;
  if(todayholidays.length > 0) return true;

  return false;
}

2-2. 動作確認

一度正しく動作するか確認します。ヘッダーの「▶︎」で実行できます。
このままのコードでは、翌日が祝日だったり雨じゃなかったりするとメッセージが届かないので、都合が悪ければコメントアウトしましょう。メッ●●からメッセージが来ればOKです。

2-3. トリガーの設定

ヘッダーの時計マークをクリックすると、トリガー設定画面に遷移するので、「トリガーを追加」をクリック。

実行する関数をmainにして、好みの設定にすれば完成です!

2-4. (オマケ)複数チャンネルに召喚したいとき

「うちにもメッ●●置いてよ!」と言われて、「何度もWebhook URLを発行しなきゃいけないのか…」と絶望しますが、そんな必要はありません。
ペイロードにチャンネル名を記述して、メッセージの宛先を変更することができます。
パブリックチャンネルは‘channel’: ‘#channel-name’、ダイレクトメッセージは‘channel’: ‘@username’で指定できます。
mainとsendToSlackを下記のように書き換えます。

function main() {
  const today = new Date();
  const tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate()+1);
  if (isHoliday(today)) return; // 今日が休日なら処理しない
  if (isHoliday(tomorrow)) return; // 明日が休日なら処理しない

  const firstChannelName = '#first-channel'
  const secondChannelName = '#second-channel'
  const thirdChannelName = '@hanako.yamada'
  const cityId = 120010; // http://weather.livedoor.com/forecast/rss/primary_area.xml

  const forecast = getForecast(cityId);
  if (forecast.indexOf('') !== -1) { // 雨のときだけSlack通知する
    sendToSlack(firstChannelName, forecast);
    sendToSlack(secondChannelName, forecast);
    sendToSlack(thirdChannelName, forecast);
  }
}

function sendToSlack(channelName, message) {
  const webhookUrl = 'https://hooks.slack.com/services/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';
  const jsonData = {
    'channel': channelName,
    'text' : message
  };
  const payload = JSON.stringify(jsonData);
  const options = {
    'method' : 'post',
    'contentType' : 'application/json',
    'payload' : payload
  };
  UrlFetchApp.fetch(webhookUrl, options);
}

感想

数時間でできました…。GAS便利!
先人とGASに感謝です。
これでもうPC忘れない…!

リモートでWEARの開発をしたい方はJOIN US!!!
https://tech.zozo.com/recruit/mid-career/detail59/

スペシャルサンクス

  • GASでコードの定期実行できるよって教えてくれたできる後輩田島(https://twitter.com/kaz_tch)
    (「slackbotだ!!!」と言いながらbotkitを使い、定期実行で困っていた私には天啓でした。ありがとう!!)
  • メッ●●の鳴き声が分からず聞いたら、めちゃめちゃ調べて音声ファイルまで送ってくれたポケモン女子まゆちゃん

参考リンク

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account