66
34

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.

ZOZOテクノロジーズ #1Advent Calendar 2019

Day 3

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

Last updated at Posted at 2019-12-02

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。JavaScriptが動きます。「トリガー」という機能で定期実行できます。(知らなかった!)

手順

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();
  var tomorrow = new Date();
  tomorrow.setDate(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’で指定できます。

sendToSlackで送りたいチャンネルも引数として受け取ってペイロードで指定すればOKです。
こんな感じでmainとsendToSlackを書き換えましょう。

function main() {
  const today = new Date();
  var tomorrow = new Date();
  tomorrow.setDate(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 = '取得したWebhook URL';
  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便利!
これでもうPC忘れない…!

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

スペシャルサンクス

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

参考リンク

66
34
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
66
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?