🤖

ふり返りのグループ分けをGASで自動化する

2022/11/21に公開

こんにちは!アルダグラムでエンジニアをしている sukechannnn です。

アルダグラムの開発チームはスクラム開発をしており、プラクティスの一環として定期的にKPTを使った振り返りを行っています。
振り返りは KANNA のチャット機能を使って行っています。ユーザーに最も使われる機能のドッグフーディングも兼ねており、定期的に改善案が出てきます。

KANNAチャットで振り返りの様子

そんな振り返りですが、開発チームの人数が増えてきたため、毎回ランダムで2つのグループに分けて行うことになりました。
そこで GAS を使ってグループ分けを自動化してみたので、その方法を紹介してみます。

成果物

以下のような仕様で動くようにしました。

  • 開発チームメンバー(エンジニア + デザイナー + PdM)を毎回ランダムに2つのチームに分ける
  • 開発チームメンバーはスプレッドシートで管理する
  • 隔週で金曜日に行われる振り返りの前に、自動でグループ分けの結果をSlack通知する

金曜日にGASが動くと、以下のようにグループ分けの結果がSlack通知されます。

Slackに通知されるグループ分け

作り方

Google Apps Script の実装

まずは Google Drive から GAS を追加します。会社の Drive でも動きます。

Google App Script

コード.gs に以下のコードを追加します。

// グループ名です。
const groupNames = ['グループA', 'グループB']
const groupNum = groupNames.length;

// 与えられた配列をランダムな順番にします
const shuffle = (array) => {
  for (let i = array.length - 1; i >= 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

// メインの通知処理です
const doPost = () => {
  // スプレッドシートのURLから取得できるIDです
  const spreadSheetById = SpreadsheetApp.openById("xxxxx")
  // 上記スプレッドシートに「開発チームメンバー」というシートを作っておいて、そこにグループ分けしたいメンバーの名前を記入します
  // 以下で「開発チームメンバー」シートを引っ張ってこれます
  const sheetByName = spreadSheetById.getSheetByName("開発チームメンバー")
  const developers = sheetByName.getRange(1, 1, sheetByName.getLastRow(), sheetByName.getLastColumn()).getValues()
  const shuffledDevelopers = shuffle(developers)

  const numPerTeam = Math.ceil(developers.length / groupNum)

  let groups = []
  for (let i = 0; i < groupNum; i++) {
    const order = i + 1
    const start = numPerTeam * (order - 1)
    const end = numPerTeam * order
    if(groupNum === order) {
      groups.push(shuffledDevelopers.slice(start, end))
    } else {
      groups.push(shuffledDevelopers.slice(start, end))
    }
  }

  const groupMessages = groups.map((group, i) => {
    const joined = group.map((member, i) => {
      return `${i + 1}.${member}`
    }).join(' > ')
    return `${groupNames[i]}: ${joined}`
  })

  groupMessages.unshift("今日の振り返りグループは、\n")
  groupMessages.push("\nです!")
  const message = groupMessages.join("\n")

  // Slack に通知するメッセージの内容をログで確認
  Logger.log(message)

  // Slack から取得したトークンを入れる
  const token = "xxxx";
  // ライブラリから導入したSlackAppを定義し、トークンを設定する
  const slackApp = SlackApp.create(token);
  const channelId = "#通知先のチャンネル";
  slackApp.postMessage(channelId, message);

  // HTTPレスポンスを返す(利用しないので空でOK)
  return ContentService.createTextOutput("");
}

GAS で使っている SlackApp ライブラリは、以下のスクリプトIDで検索して追加できます。
1on93YOYfSmV92R5q59NpKmsyWIQD8qnoLYk-gkQBI92C58SPyA2x1-bq

Slackライブラリ

このライブラリを使うことで、簡単に Slack への通知を実装できます。

スプレッドシートの準備

スプレッドシートは以下のように準備しておきます。
スプレッドシートに「開発チームメンバー」というシートを作り、そこにグループ分けしたいメンバーの名前を記入します。

振り返りBot用スプレッドシート

Slack ボットの準備

Slackボットを用意してトークンを取得する必要があります。Slackボットの作り方は、以下の記事が詳しいです。
OAuth Tokens for Your Workspace が GAS に登録するトークンです。
https://qiita.com/odm_knpr0122/items/04c342ec8d9fe85e0fe9

※実行結果を先に確認したい場合は、このステップをスキップしても大丈夫です。

実行してみる

GAS で実行する関数を doPost にして、実行ボタンを押してみてください。毎回ランダムなグループ分けがされたメッセージがログに表示され、指定したSlackチャンネルにメッセージが飛ぶはずです。

※Slackボットの作成を飛ばした場合は、slackApp.postMessage(channelId, message); の行をコメントアウトしてください。

GASログ

Slack と連携する

Slack ボットを作成したら、Slack からスラッシュコマンドで実行できるようにしてみます。

右上のデプロイボタンから「新しいデプロイ」をクリックして、「ウェブアプリ」としてデプロイします。そうするとGASを実行するためのURLが得られるので、これをSlackボットで使います。

作成したSlackボットに Slash Commands を追加します。左のメニューから Slash Commands を選んで「Create New Command」します。

ここで、先程作成したGASのURLを貼り付けます。また、Slashコマンドの名前などを記入します。
今回は /lookback-group コマンドにしました。

これを実行すると、冒頭でお見せした Slack メッセージが表示されます。

スケジュール実行してみる

最後に、スケジュール実行を設定してみます。
私達は振り返りを隔週で金曜日に行っているため、そのスケジュールで振り返りの前にSlackに通知するようにしてみます。

まずは以下のコードを doPost() 関数と同じファイルに追加します。
GAS では「隔週で実行」ということができないので、Googleカレンダーに「振り返り」という予定がある時のみ実行するようにしました。

// Googleカレンダーから予定を取得し「振り返り」という予定が入ってる場合のみ doPost 関数(振り分け通知処理)を実行する
const lookBackTrigger = () => {
  let date = new Date();
  const calendar = CalendarApp.getCalendarById("example@mail.com");
  const events = calendar.getEventsForDay(date);

  const isLookBackDay = events.some(event => (event.getTitle() === '振り返り'))
  Logger.log(isLookBackDay)
  if (isLookBackDay) {
    doPost()
  }
}

そして、左のメニューからトリガーを管理するページに移動します。

右下に「トリガーを追加」ボタンがあるのでそこからトリガーを追加し、実行する関数やどのタイミングで実行するかを選びます。ここでは毎週金曜日の朝に実行するようにしています。

これで設定が完了しました。
試しに実行してみたい場合は「時間ベースのトリガーのタイプを選択」で直近の日時を選択すると、自動でトリガーされるのが確認できると思います。

アルダグラム Tech Blog

Discussion