😎

朝会当番を Slack + GAS でガラガラ・ポン!

2022/12/01に公開

実現したかったこと

  • 朝会の司会役を属人化させず、皆んなに経験してもらいたい
  • 単純に当番制にしてもよいが、遊びゴコロも欲しい

→ Slack でボットに朝会の司会役を指名させよう!毎日ランダムに!

出来たもの

ボットによる朝会の司会指名

Google Apps Script

function handler() {
  const { isWorkingDay, hours, minutes } = getDate();
  if (! isWorkingDay) {
    // 営業日でない
    return;
  }

  // 工夫①
  // 毎朝 9 時 40 分台に投稿する
  const is朝会 = hours === 9  && 40 <= minutes && minutes <= 49;
  if (! is朝会) {
    return;
  }

  // Slack の "username" を指定する
  const members = [
    "taro.yamada", 
    "hanako.suzuki", 
    "......", 
    "new.member1", // 新入社員1
    "new.member2", // 新入社員2
    // 工夫②
    // 新入社員ボーナス
    "new.member1", 
    "new.member2"
  ];
  
  // 司会役(ランダムに選出)
  const facilitator = members[Math.floor(Math.random() * members.length)];
  
  const text = 
`
まもなく朝会です。進行は <@${facilitator}> さんお願いします!
https://meet.google.com/xxxxxx

朝会開始(10時)まで朝会会場は自由に使ってね!
`;

  const incomingWebhookUrl = "〇〇〇〇〇〇";
  // Slack に投稿
  UrlFetchApp.fetch(incomingWebhookUrl, {
    "method": "post",
    "contentType": "application/json",
    "payload": JSON.stringify(
      {
        "text": text,
      }
    )
  });
}

/**
 * 日時情報を取得する
 *
 * - isWorkingDay: 営業日かどうか
 * - hours: 時
 * - minutes: 分
 */
function getDate() {
  const date = new Date();

  return {
    isWorkingDay: 1 <= date.getDay() && date.getDay() <= 5 // 月(1)〜金(5)
    // 工夫③
    // 土日だけでなく、祝日も起動タイミングから除外する
      && !isHoliday(date.getFullYear(), date.getMonth() + 1, date.getDate()), 
    hours: date.getHours(),
    minutes: date.getMinutes()
  };
}

/**
 * 指定された日付が休日かどうか判定する
 */
function isHoliday(year, month, day) {
  const res = UrlFetchApp.fetch(`https://holidays-jp.github.io/api/v1/${year}/date.json`);
  const holidays = JSON.parse(res.getContentText());
  const key = `${year}-${month <= 9 ? '0' + month : month}-${day}`;
  return !!holidays[key];
}

工夫したこと

① GAS を「分ベースのタイマー」トリガーで起動させるための時刻判定

GAS のトリガー設定では「毎日◯時◯分」という指定ができないため、10分おきに起動するタイマーで、希望する時間帯にのみ、スクリプトが実行されるように起動時刻の判定処理を実装しました。

  const { isWorkingDay, hours, minutes } = getDate();
  if (! isWorkingDay) {
    // 営業日でない
    return;
  }

  // 工夫①
  // 毎朝 9 時 40 分台に投稿する
  const is朝会 = hours === 9  && 40 <= minutes && minutes <= 49;
  if (! is朝会) {
    return;
  }

② 新入社員を当たりやすくして、オンボーディングを促進

今年、開発組織が急拡大(※前年比で開発組織の人員数が 3 倍に!)するなか、在宅勤務者も多い環境で、新入社員が前に出る機会を増やしてチームに馴染みやすくすることをねらって、入社直後の約 1 ヶ月間くらいは新入社員が朝会の司会役に当たりやすくなるよう調整しました。

  const members = [
    "taro.yamada", 
    "hanako.suzuki", 
    "......", 
    "new.member1", // 新入社員1
    "new.member2", // 新入社員2
    // 工夫②
    // 新入社員ボーナス
    "new.member1", 
    "new.member2"
  ];
  
  const facilitator = members[Math.floor(Math.random() * members.length)];

③ 祝日のボット投稿を抑制するため、祝日判定処理をお手軽実装

ボットの誤投稿はノイズになるため、祝日にボットが起動しないように祝日の判定処理を実装しました。

    isWorkingDay: 1 <= date.getDay() && date.getDay() <= 5 // 月(1)〜金(5)
    // 工夫③
    // 土日だけでなく、祝日も起動タイミングから除外する
      && !isHoliday(date.getFullYear(), date.getMonth() + 1, date.getDate()), 
/**
 * 指定された日付が休日かどうか判定する
 */
function isHoliday(year, month, day) {
  const res = UrlFetchApp.fetch(`https://holidays-jp.github.io/api/v1/${year}/date.json`);
  const holidays = JSON.parse(res.getContentText());
  const key = `${year}-${month <= 9 ? '0' + month : month}-${day}`;
  return !!holidays[key];
}

最後に

このボットを実装するために初めて GAS を実装・運用したのですが、かんたんに・なんでも実現できそうで GAS めちゃくちゃ便利だと思いました 👍

BABYJOB テックブログ

Discussion