🐣

Googleカレンダーと連携してslackのステータスを変更する

2023/05/02に公開

背景・概要

休みの日にSlackのstatusの変更を忘れがちなので、statusの変更を自動化しようと思いたちました。
GASで、Googleカレンダーから今日の予定を取得し、それに応じてSlackのステータスを更新させる流れです。

カレンダーに「全休」「午後休」「午前休」のタイトルが含まれる予定がある場合、Slackのステータスをそれに応じて更新させます。
たとえば、「全休」の場合、ステータスを「お休み」に設定し、「:yasumi:」というアイコンを表示させます。

「:yasumi:」というアイコンはあらかじめ作成して登録しておくか、別の休み用のアイコンを指定してください。
「午前休」や「午後休」の場合は、その時間帯に応じてステータスを更新させます。

slackTokenとcalendarIdを入力

slackToken の取得方法

  • Slack APIのページ に進み、「Create an app」をクリック
  • 「From scratch」をクリック
  • 「App Nameへ入力」と「Select a workspace」を選択
  • 左側メニューの「OAuth & Permissions」をクリック
  • 少し画面をスクロールして、「Scopes」見出しを探してください
  • その中にある「User Token Scopes」小見出しを探してください
  • 「Add an OAth Scope」をクリック
  • 「users.profile:write」を選択
  • 同じく、左側メニューの「OAuth & Permissions」の中にある
  • 「Building Apps for Slack」見出しの
  • 「Install your app」
  • 「OAuth Tokens for Your Workspace」の「Install to Workspace」をクリックし、「許可」
  • すると、「xoxp-」から始まる「User OAuth Token」をコピーできます。

calendarId の取得方法

取得したいGoogleカレンダー個別の「カレンダーの設定」から取得します。

表示される名前を入力

「全休、午後休、午前休」はカレンダータイトルを「部分一致」で取得していますので、
たとえば、他のメンバーがカレンダーを閲覧した時にわかりやすいように、「田中全休、佐藤午後休、鈴木午前休」というタイトルにしても動作します。

GASのトリガー

自分はこのような時間で設定しましたが、午後半休のタイミングは就業規則で異なるかと思いますので、実情に合わせてください。

  • 時間主導型、日付ベースのタイマー 午前5時〜6時
  • 時間主導型、日付ベースのタイマー 午後1時〜2時

slackの休みアイコン

":yasumi:として、「休」を○で囲った赤いアイコンを登録しています。

GAS

function updateSlackStatusFromCalendar() {
  // Slack APIの設定
  var slackToken = "slackTokenを入力";
  var slackApiUrl = "https://slack.com/api/users.profile.set";
  var slackProfile = {
    "status_text": "",
    "status_emoji": "",
    "status_expiration": 0
  };
  var slackOptions = {
    "method": "post",
    "headers": {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + slackToken
    },
    "payload": JSON.stringify({"profile": slackProfile})
  };
  
  // GoogleカレンダーAPIの設定
  // var calendarId = "c_de3iu5gksvo9enams87of6tqfo@group.calendar.google.com";
  var calendarId = "nakano@flymee.co.jp";
  var calendar = CalendarApp.getCalendarById(calendarId);
  var events = calendar.getEventsForDay(new Date());
  
  // Googleカレンダーの予定情報をSlackのステータスに反映させる
  var isVacation = false;
  for (var i = 0; i < events.length; i++) {
    var event = events[i];
    var eventTitle = event.getTitle();
    if (eventTitle.indexOf("全休") != -1) {
      slackProfile.status_text = "お休み";
      slackProfile.status_emoji = ":yasumi:";
      slackProfile.status_expiration = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 23, 59).getTime() / 1000;
      slackOptions.payload = JSON.stringify({"profile": slackProfile});
      UrlFetchApp.fetch(slackApiUrl, slackOptions);
      isVacation = true;
      break;
    } else if (eventTitle.indexOf("午後休") != -1) {
      var now = new Date();
      if (now.getHours() >= 13) {
        slackProfile.status_text = "午後休";
        slackProfile.status_emoji = ":yasumi:";
        slackProfile.status_expiration = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 23, 59).getTime() / 1000;
        slackOptions.payload = JSON.stringify({"profile": slackProfile});
        UrlFetchApp.fetch(slackApiUrl, slackOptions);
        isVacation = true;
      } else { // 午後休の場合、ステータスを変更するだけでなく、23:59に削除する
        slackProfile.status_text = "";
        slackProfile.status_emoji = "";
        slackProfile.status_expiration = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 23, 59).getTime() / 1000;
        slackOptions.payload = JSON.stringify({"profile": slackProfile});
        UrlFetchApp.fetch(slackApiUrl, slackOptions);
        isVacation = true;
        break;
      }
    } else if (eventTitle.indexOf("午前休") != -1) {
      var now = new Date();
      if (now.getHours() >= 13 && now.getMinutes() >= 30) {
        slackProfile.status_text = "午前休";
        slackProfile.status_emoji = ":yasumi:";
        slackProfile.status_expiration = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 23, 59).getTime() / 1000;
        slackOptions.payload = JSON.stringify({"profile": slackProfile});
        UrlFetchApp.fetch(slackApiUrl, slackOptions);
        isVacation = true;
      } else { // 午後休の場合、ステータスを変更するだけでなく、23:59に削除する
        slackProfile.status_text = "午前休";
        slackProfile.status_emoji = ":yasumi:";
        slackProfile.status_expiration = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 13, 30).getTime() / 1000;
        slackOptions.payload = JSON.stringify({"profile": slackProfile});
        UrlFetchApp.fetch(slackApiUrl, slackOptions);
        isVacation = true;
        break;
      }
    }
  }
}

おわりに

Slackのステータスを変更しておかないと、普段どおりに、問い合わせのSlack連絡が届きます。
急いでいる時など、ステータスの変更を忘れてしまいがちなので、ITヘルプデスクに限らず、多数の方に地味に助かる便利な機能だと思います。
そして、こういった忘れがちなタスクが自動化できるのは楽しいです。

GitHubで編集を提案

Discussion