🐣

SlackのステータスとGカレンダーを連携してリモート時にステータスを変更する

2023/05/12に公開

背景・概要

リモートで定期的にしておりますが、会社に在籍していると思われて、Slackで連絡が来る場合があります。
Slackのステータスをしておけば防げることなので、Gカレンダーと連携してステータスを変更しようと思います。

カレンダーに「リモート」「午後リモート」「午前リモート」のタイトルが含まれる予定がある場合、Slackのステータスをそれに応じて更新させます。
ただし、ステータス変更を予約する機能はありませんので、午前8時と午後2時にトリガーを動かす必要があります。
午後リモートがある場合だけ、14時まで変更しないようにスキップさせます。

slackTokenとcalendarIdを入力

YOUR_SLACK_TOKEN の取得方法

  • 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」をコピーできます。

YOUR_CALENDAR_ID の取得方法

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

表示される名前を入力

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

GASのトリガー

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

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

GAS

// Replace with your calendar ID and Slack API token
var CALENDAR_ID = 'YOUR_CALENDAR_ID';
var SLACK_API_TOKEN = 'YOUR_SLACK_TOKEN';

// Define the slack status configurations
var SLACK_STATUS_CONFIG = {
  'リモート': {
    text: 'リモート',
    emoji: ':house_with_garden:',
    expirationHours: 19
  },
  '午後リモート': {
    text: '午後リモート',
    emoji: ':house_with_garden:',
    expirationHours: 19
  },
  '午前リモート': {
    text: '午前リモート',
    emoji: ':house_with_garden:',
    expirationHours: 14
  }
}

function updateSlackStatus() {
  var now = new Date();
  var events = CalendarApp.getCalendarById(CALENDAR_ID).getEventsForDay(now);

  var statusText = '';
  var statusEmoji = '';
  var statusExpiration = '';

  for (var i = 0; i < events.length; i++) {
    var title = events[i].getTitle();

    Object.keys(SLACK_STATUS_CONFIG).forEach(function(key) {
      if (title === key) {
        if (key == '午後リモート' && now.getHours() < 14) {
          // Do nothing until 14:00
          return;
        }
        statusText = SLACK_STATUS_CONFIG[key].text;
        statusEmoji = SLACK_STATUS_CONFIG[key].emoji;
        statusExpiration = new Date(now.getFullYear(), now.getMonth(), now.getDate(), SLACK_STATUS_CONFIG[key].expirationHours, 0, 0);
      }
    });
  }

  // Only update the status if a matching event was found and the expiration time is valid
  if (statusText && statusEmoji && statusExpiration instanceof Date) {
    var payload = {
      'profile': {
        'status_text': statusText,
        'status_emoji': statusEmoji,
        'status_expiration': Math.floor(statusExpiration.getTime() / 1000)
      }
    };

    var options = {
      'method': 'post',
      'headers': {
        'Authorization': 'Bearer ' + SLACK_API_TOKEN,
        'Content-type': 'application/json'
      },
      'payload': JSON.stringify(payload)
    };

    UrlFetchApp.fetch('https://slack.com/api/users.profile.set', options);
  }
}

おわりに

こういった少し気になるタスクを減らすことは、チリツモですが、すごく大切かなと思います。
他にも自動化できることを見つけたいと思います。

GitHubで編集を提案

Discussion