0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【GAS】Slackで休暇取得者一覧を自動通知する機能を作った

Posted at

はじめに

弊社では、「⚪︎日は休暇で不在ですよー:whale2:」とお知らせするSlackチャンネルがあります。
(正式な休暇申請のシステムとは別です)
この情報をワークフローで取得し、休暇取得者一覧としてGASで毎朝自動投稿する機能を作成しました。

slack_休暇連絡.png

通知までの流れ

  1. 休暇取得者がSlackのワークフローで情報をフォームに入力
  2. 入力した情報がチャンネルへ投稿&スプレッドシートに追記される
  3. 毎朝、スプレッドシートからその日の休暇取得者情報を取得
  4. チャンネルに自動投稿

使用技術

  • Slackのワークフロー
  • GAS(GoogleAppsScript)
  • incoming webhooks(外部からSlackにメッセージを投稿するための機能)

Slackのワークフローの作成

ワークフローの開始イベント

  • Slack内のリンクから開始

情報をフォームで収集する

  • 申請者:Slackユーザー
  • 休暇開始日:日付
  • 休暇終了日:日付
  • 予定時刻:短い回答
  • 備考:リッチテキスト
  • 休暇申請はしたか:チェックボックス
  • カレンダーに休暇予定を記入したか:チェックボックス

チャンネルへメッセージを送信する

  • ワークフローが使用されたチャンネル

Google Sheets

  • 該当のスプレッドシートを選択

GASで通知機能を作成する

連日取得(例:金と月に取得)に対応するための日付分割.gsと、
Slackに通知するための通知用.gsの2つを作成します。

スプレッドシートの「拡張機能」から「Apps Script」を選択します。

日付を分割する処理

日付を分割してスプレッドシートに追記するとき、入力した日付とずれる現象が発生したため、タイムゾーン関連のコードをしつこく書いてます。

日付分割.gs
function onChange(e) {
  const sheet = e.source.getSheetByName("休暇連絡");
  const notificationSheet = e.source.getSheetByName("通知用");

  // 編集されたシートが「休暇連絡」であることを確認
  if (sheet.getName() === "休暇連絡") {
    const lastRow = sheet.getLastRow();
    const newData = sheet.getRange(lastRow, 1, 1, sheet.getLastColumn()).getValues()[0];
    
    // データの取得
    const username = newData[0];
    const startDate = new Date(newData[1]);
    const endDate = new Date(newData[2]);
    const plannedTime = newData[3];
    const remarks = newData[4];

    // タイムゾーンを適用して日付をローカルタイムゾーンに設定
    const timezone = Session.getScriptTimeZone();
    startDate.setHours(0, 0, 0, 0);
    endDate.setHours(0, 0, 0, 0);

    // startDateをローカルタイムゾーンでの正しい日付に調整
    const startDateLocal = Utilities.formatDate(startDate, timezone, "yyyy-MM-dd");

    let settingDate = new Date(startDateLocal); // startDateLocal を元に settingDate を設定
    let rowIndex = notificationSheet.getLastRow() + 1; // 書き込み開始行

    // 休暇日数分、「通知用」シートにデータを追加
    do {
      // settingDate をローカルタイムゾーンに合わせてフォーマット
      const formattedDate = Utilities.formatDate(settingDate, timezone, "yyyy-MM-dd");

      // 都度書き込み
      notificationSheet.getRange(rowIndex, 1, 1, 4).setValues([[formattedDate, username, plannedTime, remarks]]);
      
      // 次の行へ
      rowIndex++;
      
      // 日付を進める
      settingDate.setDate(settingDate.getDate() + 1); // 日付を進める
      settingDate.setHours(0, 0, 0, 0); // 時間部分をリセット
    } while (settingDate <= endDate);
  }
}

Slackに通知する処理

Slackに通知するためにはincoming webhookのURLを設定する必要があります。
(この記事では設定方法は割愛させていただきます)
平日のみ通知されるようにgetDayメソッドを使っています。

通知用.gs
function sendVacationList() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('通知用');
  var data  = sheet.getDataRange().getValues();
  var today = new Date();
  var month = today.getMonth()+1;
  var date  = today.getDate(); 
  var vacationUsers = [];
  var vacationTimes = [];
  var vacationNotes = [];

  // 今日の休暇取得者を抽出
  for (var i = 1; i < data.length; i++) {
    var vacationDate = new Date(data[i][0]); // 休暇日を1列目から取得
    if (vacationDate.toDateString() == today.toDateString()) {
      vacationUsers.push(data[i][1]); // ユーザー名を2列目から取得
      vacationTimes.push(data[i][2]); // 予定時刻を3列目から取得
      vacationNotes.push(data[i][3]); // 備考を4列目から取得
    }
  }

  // 休暇取得者がいた場合かつ平日であればSlackに送信
  if (today.getDay() === 0 || today.getDay() === 6){ // 0 (日曜日) ~ 6 (土曜日)
    console.log("休日のため通知しない");
  } else {
    if (vacationUsers.length > 0) {
      var message = month + '月' + date + '日の休暇予定の方:\n'
      // ユーザー名とその休暇時間を組み合わせて改行で区切ってリストにする
      for (var i = 0; i < vacationUsers.length; i++) {
      message += vacationUsers[i] + ', ' + vacationTimes[i] + ', ' + vacationNotes[i] + '\n';
      } 
    } else {
      // 休暇取得者がいない場合
      var message = month + '月' + date + '日の休暇予定の方:\n'
      var message = '本日の休暇取得者はいませんでした。';
    }
    
    var webhookUrl = 'Webhook URLをここに入力する';
    var payload = JSON.stringify({text: message});
    var options = { method: 'POST', contentType: 'application/json', payload: payload };

    UrlFetchApp.fetch(webhookUrl, options);
  }
}

まとめ

GASとSlackワークフローで収集した情報を自動投稿する機能を作ることができました。
(知識不足で、var,let,constの使い分けが正しくできていないかも……)

今後は、「朝のお知らせ」としてその日の情報を一覧で通知できるように改良したいです。

完成イメージ
slack_完成イメージ.png

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?