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?

PONOSAdvent Calendar 2023

Day 20

ChatGptとGASでSlackのメンバー追加をラクにした話

Last updated at Posted at 2023-12-19

この記事はPONOS Advent Calendar 2023の20日目の記事です。
前回は、@e73ryoさんでした。

はじめに

私は社会人アカペラサークルに所属しており、そこで運営メンバーとして活動しています。
そのサークルでは全体周知事項などがある際にSlackを使用しているのですが、ライブイベント用のチャンネルを作成する際にメンバーの追加がかなり手間になっている問題が起きていました。Slackチャンネルのメンバー追加は、氏名検索や、メールアドレスを一人ずつ入力しなければいけないなど、かなり面倒くさいです。
※一回で80人以上追加することもありますし、サークルではニックネームなどがSlackで使われているため検索がしんどいです。

Slackではワークスペースに参加しているメンバーのリストをcsvで出力することが出来るため「GoogleAppScript(GAS)を使ったらいい感じに出来るんじゃないか?」と考えました。

GASについては完全に素人だったかつ時間が勿体なかったので、ChatGptに要件を伝えながら、実装をしていきました。

事前準備

Slackのメンバーリストをエクスポート

Slackからチームメンバーのcsvリストをワークスペースのデータをエクスポートする
を参考にしてエクスポートします。
以下のようなリストが出力されます。※値は例です。

username email status billing-active has-2fa has-sso userid fullname displayname expiration-timestamp
user1 user1@example.com active true true false 12345 John Doe JohnD 1640995200000
user2 user2@example.com inactive false false true 67890 Jane Smith JaneS 1643673600000
user3 user3@example.com active true true true 54321 Bob Johnson BobJ 1638806400000
user4 user4@example.com active true false true 98765 Alice Brown AliceB 1640995200000
user5 user5@example.com inactive false false false 23456 Mary White MaryW 1638806400000

抽出データ

以下のようなデータをスプレッドシートに用意します。
所属しているサークルでは、Googleフォームでライブに出演するバンドを管理しています。
Googleフォームの回答内容はスプレッドシートに出力されるため、Slackチャンネルに追加する対応もそのスプレッドシートで行えます。

バンド名 出演時間 1人目 2人目 3人目 4人目 5人目 6人目
バンドA 19:00 ギタリストA ドラマーA ベーシストA キーボーディストA ボーカリストA サックスプレイヤA
バンドB 20:30 ドラマーB ベーシストB ギタリストB キーボーディストB サックスプレイヤB トランペッターB
バンドC 22:00 ベーシストC ギタリストC キーボーディストC ドラマーC トランペッターC ボーカリストC

ChatGptに実装してもらったスクリプト

ChatGptに以下の2つのスクリプトを実装してもらいました。
伝え方を間違えるととんでもない実装をしてくるため、要件の言語化はかなり重要です。

抽出した演者のデータから重複排除したリストを新規のシートに貼り付けるスクリプト

function removeDuplicatesAndPaste() {
  // 抽出対象のシート名と貼り付け先のシート名を指定
  var sourceSheetName = "出演バンド一覧"; // 抽出対象のシート名。適宜変更する。
  var targetSheetName = "チャンネル追加対象者"; // 貼り付け先のシート名。適宜変更する。

  // 対象のシート情報を取得
  var sourceSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sourceSheetName);
  var targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(targetSheetName);

  // シートが見つからない場合はエラーメッセージを表示して処理を終了
  if (!sourceSheet || !targetSheet) {
    Browser.msgBox("指定されたシートが見つかりません。");
    return;
  }

  // 抽出対象のB列のデータを取得
  var cellRange = sourceSheet.getRange("A1:G30"); // セル範囲は適宜変更する。
  var cellValues = cellRange.getValues(); // セル範囲の値を取得

  // デバック用のためコメントアウト
  // 取得した値をコンソールに表示する
  // for (var i = 0; i < cellValues.length; i++) {
  //   for (var j = 0; j < cellValues[i].length; j++) {
  //     Logger.log("セル(" + (i + 2) + ", " + (j + 3) + "): " + cellValues[i][j]);
  //   }
  // }

  // 同じメンバーが別のバンドで参加することがあるため、重複を削除したデータを取得
  var uniqueData = removeDuplicates(cellValues);

  // 貼り付ける先のA1セルに「演者」というヘッダーを設定
  var targetRange = targetSheet.getRange("A1");
  targetRange.setValue("演者");

  // 貼り付ける先のA列に一意のデータをセット
  targetRange.offset(1, 0, uniqueData.length, 1).setValues(uniqueData);
}

// 抽出した演者のリストのデータを重複排除する関数
function removeDuplicates(arr) {
  var flattenedArr = arr.flat(); // 2次元の配列を1次元に平坦化
  var uniqueArr = [...new Set(flattenedArr)]; // 重複を削除
  var uniqueValues = [];

  for (var i = 0; i < uniqueArr.length; i++) {
    uniqueValues.push([uniqueArr[i]]);
  }

  return uniqueValues;
}

Slackのメンバーリストのcsvから演者のメールアドレスを取得してコピーするスクリプト

このスクリプトでコピーされたメールアドレスをコピーして、Slackチャンネルのメンバー追加画面にペーストすると、一発で大人数のチャンネル参加を実現できます。

function searchAndCopyData() {
  var sourceSheetName = "slack-members"; // データを検索するシート名。適宜変更する。
  var targetSheetName = "チャンネル追加対象者"; // 結果を出力するシート名。適宜変更する。
  var sourceSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sourceSheetName);
  var targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(targetSheetName);

  if (!sourceSheet || !targetSheet) {
    Browser.msgBox("指定されたシートが見つかりません。");
    return;
  }

  // セルの範囲は適宜変更する。
  // csv出力されたSlackメンバーの氏名があるセル範囲
  var sourceData = sourceSheet.getRange("H2:H" + sourceSheet.getLastRow()).getValues();
  // 重複排除された演者のリストのセル範囲
  var targetData = targetSheet.getRange("A2:A" + targetSheet.getLastRow()).getValues();

  for (var i = 0; i < targetData.length; i++) {
    var targetValue = targetData[i][0];
    var matchedValue = "不明";

    // ハッシュのデータと一致する場合、値を置き換える
    if (data_dict[targetValue]) {
      targetValue = data_dict[targetValue];
    }

    for (var j = 0; j < sourceData.length; j++) {
      var sourceValue = sourceData[j][0];

      if (sourceValue && targetValue && sourceValue.includes(targetValue)) {
        matchedValue = sourceSheet.getRange("B" + (j + 2)).getValue();
        break;
      }
    }

    // B2以降に該当したメールアドレスをコピーしていく
    targetSheet.getRange("B" + (i + 2)).setValue(matchedValue);
  }
}

運用の改善点

  • 対象のシート名についてハードコーディングとなっているため、操作者の入力を受け付けたい
  • 抽出対象とコピー先のセル範囲についてハードコーディングとなっているため、操作者の入力を受け付けたい
  • 全く無知のメンバーが操作した場合、GASの実行までたどり着けない可能性が高いため、実行ボタンなどをシートに貼り付けたい

まとめ

今回はChatGptとGASを使用して、サークル活動時に発生していたSlackチャンネルの大量メンバー追加問題を解決してみました。今後、大量のメンバーをSlackチャンネルに追加する時の運用コストがこれでグッと減ったかなと思います。
最近は、業務でJenkinsも触ることが多く、各サービスから提供されているAPIなどをスクリプトを通じて叩ければ色々な応用が効くんじゃないかなぁと模索しています。
こういった地味な改善が、日々の生産性に寄与していくと信じたいですね。

明日は@ackylaさんの「数年ぶりに自宅サーバーを立ててKubernetesを入れてみる
」です!

0
0
0

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?