Google Groupsのメンバー一覧を取得するGAS

Google Groupsのメンバー一覧を取得するGoogle Apps Scriptをご紹介します。

概要

こちらのビジネス向け Google グループの機能 という記事で、企業向けのGoogle Groupsを利用して、Google Driveなど様々なGoogleサービスの権限を管理することができることを紹介しました。

この機能は非常に便利で、Google Drive、Google SitesなどのGoogle Workspaceの各サービスの他、Goole Cloud での権限管理などにも利用でき、部門や部署ごとなどの利用のほかに、プロジェクト単位や役職単位など様々な場面に合わせて利用することができます。

使い始めると、細かいグループが増えていき、どのグループに誰が入っているのかを一つづつ開いて確認するのは手間がかかります。
そういった場合に、スプレッドシートにて確認が必要なグループの一覧を作成し、最新のメンバー一覧を作ると管理がしやすくなります。

今回ご紹介するGASは、スプレッドシートにGroup一覧を作成し、メンバー一覧を取り込む機能の実装を紹介したいと思います。

今回のGASでは、Google GroupsへのURLをGASのソースで作成しています。Google GroupsのURLは、企業向けのGoogle WorkspaceとGmailでURLの形式が変わります。今回ご紹介するGASは、企業向けのGoogle Groupsを前提としていますので注意して下さい。

想定する機能

今回紹介するツールは、2つの機能を構築します。

  • 管理対象のGroupを追加した際に追加Group用のメンバーリストを取得する為の新規シートを作成する
  • 追加済みのシートに対して、Groupから最新のメンバー一覧を取得し反映する

GroupsAppの紹介

Google Groupsの情報を取得するには、GASの標準ライブラリにある GroupsApp を利用します。
公式サイトは、こちらです。
https://developers.google.com/apps-script/reference/groups/groups-app

このライブラリには2つのメソッドが用意されています。

メソッド内容
getGroupByEmail(email)Groupsのメールアドレスを指定して1件のGroupを取得
getGroups()直接メンバー(または保留中のメンバー)であるすべてのグループを取得します。

今回使用するのは getGroupByEmail(email) です。
このメソッドを利用すると Groupという型のオブジェクトが返ってきます。
公式サイトは、こちらです。
https://developers.google.com/apps-script/reference/groups/group

Groupには、公式サイトにあるように操作用のメソッドが用意されています。いくつかピックアップして紹介します。

メソッド内容
getEmail()このグループに割り当てられているメールアドレスを取得します。
getGroups()このグループに参加しているグループ(子グループ)を取得します。
getRole(user)引数で渡したGoogleアカウントに割り当てられている権限を取得します。
getUsers()このグループに参加しているGoogleアカウントを取得します。

今回は、getUsers() を利用してユーザーの一覧を取得します。

準備

管理対象とするGoogle Groupsのアカウントとスプレッドシートを用意します。

(1) Google Groupsでグループを用意します

今回は、こちらの2つのアカウントを用意します。

  • groupe-test-1@[domain]
  • groupe-test-2@[domain]

※ [domain] は、ご自身の組織のドメインに置き換えてください。

(2) スプレッドシートを用意します

まずは2つのシートを作成します。

1シート目は、管理対象のGroupsのアカウントを入力します。

  • グループ一覧 という名前のシートを作成
  • C1: 組織のドメインを入力
  • B4,B5: groupsのアカウントの@の前部分(xxxx@example.com の xxxxx 部分のみ)を入力
  • C4,C5: 「使用目的」は、グループの目的がわかる内容を入力(必須ではありません)
  • 「シート追加」「全メンバー再取得」のボタンを作成し、今回作成する関数を割り当てる ※

補足) D4,D5の「グループ設定画面へ」は、GASを実行すると自動でリンクが入る項目です。ここでは何も入力する必要はありません。

※ こちらのボタンの作り方は、Googleスプレッドシート上でのGASプログラムの実行方法 で紹介しています。割り当てる関数は、ソースコードの解説の中で再度説明します。

グループ一覧シートでのボタンの役割は以下のとおりです。

ボタン名割り当てる関数機能
シート追加addSheet「groupsアカウント」の項目に新しいGroupsが追加された場合に、templateシートをコピーして「groupsアカウント」をシート名にします。
全メンバー再取得allGroupsReplaceMember追加済みの各シートに、最新のGroupsのメンバーを取得しメンバーリストを更新します。

2シート目に、groupsのアカウントごとのメンバー一覧シートを作成する際にtemplateを作成します。
メンバー取得時にはこのシートをコピーして使用します。

  • template という名前のシート名を作成
  • B3 のセルから下に入力欄を用意

ソースコードの解説

GASのソースコードは、スプレッドシートに書いていきます。

今回は、3つの関数に分けて作成していきます。
上で挙げた2つの機能の実装を解説していきます。

(1) 変数を定義

最初に、関数をまたいで使用する変数を定義します。
実際に一からコーディングをする際には、他の関数と共通で使う値 最初に設定をまとめておくとあとからメンテナンスしやすくなる値 などを少しずつ最初に出していくといった進め方をして頂ければと思います。

// グループ一覧シートのデータ取得用変数設定
var group_list_sheet_name = 'グループ一覧';
var domain_cell = "グループ一覧!c1";

var group_list_first_row = 4;
var group_list_first_col = 2;
var group_list_max_row = 500;

// templateシートのデータ取得用変数設定
var templete_sheet_name = 'template';

var template_first_row = 3;
var template_first_col = 2;
var template_max_row = 500;


// 処理対象スプレッドシート取得
var spreadsheetObj = SpreadsheetApp.getActiveSpreadsheet();
// インデックスシート取得
var sheetObj = spreadsheetObj.getSheetByName(group_list_sheet_name);
// 対象ドメイン取得
var domain = sheetObj.getRange(domain_cell).getValue();

ここで定義しているのは、データを取得するセルの位置、範囲、スプレッドシートのオブジェクトの取得などです。 var group_list_max_row = 500; と var template_max_row = 500; は、データの最大行数を取得するコードを書くこともできますが、コードが複雑になること、内部利用のツールであることから十分大きな数字を直接設定しています。

(2) シート追加機能の実装

グループ一覧を取得して、Groupのメンバーリストを更新するシートを追加する機能を実装していきます。

1) 関数の作成

まずは、シートを追加する関数 addSheet() を実装していきます。

/**
 * シートを追加する。
 */
function addSheet() {
  
}

2) groups一覧取得

作成した、addSheet()の関数内に以下の実装を進めていきます。

「グループ一覧」シートの groupsアカウント の項目を取得します。

ソースコードはこちらのようになります。

  // 対象のグループ名取得
  var range = group_list_sheet.getRange(group_list_first_row, group_list_first_col, group_list_max_row, 3);
  var range_values = range.getValues();

  // templateシート取得
  var template_sheet = ss.getSheetByName(templete_sheet_name);

  // 內部リンク用のURL作成
  var spreadsheetID = ss.getId();
  var spreadsheetURL = "https://docs.google.com/spreadsheets/d/"+ spreadsheetID + "/edit"
  

2行目: スプレッドシートの範囲を読み込んでいます。
group_list_sheet.getRange(group_list_first_row, group_list_first_col, group_list_max_row, 3) として、最後の引数に 3 を設定するのはD列 グループ設定画面 へのリンクを更新するためです。 3である理由はセルの開始位置から3列目のためです。

3行目: var range_values = range.getValues(); で、セルの範囲の値を取得します。

6行目: 「template」シートをシート名を指定して取得しています。

9行目: ここからは、利便性の向上のためスプレッドシート内で内部リンクを行うために対象のシートへのURLを作成しています。
実際のスプレッドシートのURLを確認して頂くのがわかりやすいと思いますが、以下のような形式になっています。

https://docs.google.com/spreadsheets/d/[spreadsheetID]/edit

3) 「template」シートをコピーしメンバーリストを更新するシートを作成

ここからは、実際にシートをコピーし、メンバーリストを更新するためのシートを作成し、「グループ一覧」シートに作成したシートへの内部リンクの追加、および、Groupsへのリンクの追加を行っていきます。

ソースコードはこちらのようになります。

  for (var i=0; i < range_values.length; i++){
    // データが無くなったらそこで終了
    if (range_values[i][0] == ''){
      return
    }
    // 対象のシートがあるか確認
    var mamber_list_sheet = ss.getSheetByName(range_values[i][0]);
    // なければシート追加
    if (!mamber_list_sheet){
      // templateシートをコピー
      var mamber_sheet = template_sheet.copyTo(ss);
      // シート名変更
      mamber_sheet.setName(range_values[i][0]);
      // タイトル横にGroupsへのリンクを追加
      var group_hyperlink = 'https://groups.google.com/a/' + domain +'/g/' + range_values[i][0] + '/members';
      mamber_sheet.getRange("C2").getCell(1, 1).setFormula('=HYPERLINK("' + group_hyperlink + '","groupsへ")');

      // 一覧にシートへのリンクを追加
      var sheetURL = spreadsheetURL + "#gid=" + mamber_sheet.getSheetId();
      range.getCell(i+1, 1).setFormula('=HYPERLINK("' + sheetURL +'","'+ range_values[i][0] + '")');
      // google groupsへのリンクを追加
      range.getCell(i+1, 3).setFormula('=HYPERLINK("' + group_hyperlink + '","groupsへ")');  
    }  
  }

1行目: このfor文は、「グループ一覧」から取得したgroupsアカウントのリストを利用して繰り返しを行います。

3行目: データが無くなったときにfor文を終了し関数自体を終了するようにしています。処理を終了する処理などは、ソースの最初の方で抜けるようにするとソースが見やすくなります。

7行目: group名で既存のシートの存在を確認し、存在しないときにシート追加のロジックを実行します。

11行目: template_sheet.copyTo(ss) これで「templateシート」をコピーして今開いているスプレッドシートに追加します。

13行目: 追加したシートのシート名を group名に変更します。

15行目: Groupのメンバーリストへのリンクを作成しています。リンクの形式は以下のようになりますので、それに合わせて作成します。

https://groups.google.com/a/[domain]/g/[グループ名]/members

19行目: 作成したリンクを新しく作ったシートの C2のセルに HYPERLINK としてセットしています。これによりセルにリンクを埋め込むことができます。

20行目: ここからは「グループ一覧」シートのgroupsアカウントにシートへのリンクを埋め込みます。こちらのリンクの形式は以下のようになりますので、それに合わせてURLを作成します。

https://docs.google.com/spreadsheets/d/[spreadsheetID]/edit#gid=[シートID]

22行目: メンバーリストのシートに埋め込んだGroupへのリンクをグループ設定画面へ の項目に埋め込むため 15行目で作成したURLを埋め込みます。

4) ボタンへの関数の割り当て

実装した addSheet() を「グループ一覧」シートの「シート追加」ボタンへ割り当てます。

5) 実行結果のイメージ

作成した関数を実行すると、スプレッドシートには、以下のような内容が反映されます。

「グループ一覧」シートには、groupアカウントにリンクが挿入され、メンバーリストのシートへのリンクが入ります。グループ設定画面 にgroupsのメンバー一覧へのリンクが追加されます。

「template」シートからコピーしたメンバー一覧更新用のシートはこちらのようになります。

※ この時点では、メンバー一覧の取得はされません。次の関数でメンバー一覧を取得する関数を実装していきます。

(3) 全メンバー再取得機能の実装

ここでは、2つの関数に分けて実装していきたいと思います。

2つに分ける理由としては、

  • シート毎にループする部分とGroupsのメンバーを取得する部分を切り分ける
  • 全Groupsのメンバー更新と、個別の更新をできるようにする

今回は、個別にGroupsのメンバーを更新する機能は実装しませんが、今後の拡張を考え、関数を分けておきます。

1) 全シートを取得しfor文で繰り返し処理を実装

全Groupsのアカウントを対象とするため、「グループ一覧」シートの groupsアカウント のリストを取得します。

/**
 * 全シートのメンバーを取得する
 */
function allGroupsReplaceMember(){
  // 処理対象スプレッドシート取得
  var range_values = group_list_sheet.getRange(group_list_first_row, group_list_first_col, group_list_max_row).getValues();
  
  // インデックスシート取得
  for (var i=0; i < range_values.length; i++){
    // データが無くなったらそこで終了
    if (range_values[i][0] == ''){
      return
    }
    
    // メンバー一覧のシートを取得
    var mamber_sheet = ss.getSheetByName(range_values[i][0]);
    
    // 1シート分の更新用関数呼び出し
    replaceMember(mamber_sheet);
  }
}

6行目: groupsアカウント の一覧を取得し、値を取得します。

9行目: 上記で取得したリストを利用してfor文で、繰り返し処理を行います。

11行目: シート作成時と同様、データが無くなったところで処理を終了します。

16行目: メンバー一覧のシートを取得しています。

19行目: replaceMember は、次に紹介する関数の呼び出しを行っています。詳しくは次の項目で解説しますが、Groupsのメンバー一覧を取得して、シートに反映する処理を行います。

2) 対象とするシートのGroupsメンバー一覧を取得し更新する機能を実装

こちらの関数で、処理対象のシートを引数で受け取り、GroupsAppを使用して、groupsのメンバー一覧を取得し、シートに反映します。

/**
 * 1シート分のgroupのメンバーを取得し直す
 * (allGroupsReplaceMemberから呼び出される関数)
 */
function replaceMember(mamber_sheet){

  // シート名(グループ名取得)
  var sheetName = mamber_sheet.getSheetName()
  // group名作成
  var group_mail = sheetName + "@" + domain
  
  // groupメンバー取得
  var users = GroupsApp.getGroupByEmail(group_mail).getUsers();
  
  // 既存データ削除
  mamber_sheet.getRange(template_first_row, template_first_col, template_max_row).clear();

  // 最新メンバー一覧反映
  var member_list = [];
  for (var i = 0; i < users.length; i++) {
    member_list.push([users[i].getEmail()]);
  }
  
  // セルに反映
  var update_range = mamber_sheet.getRange(template_first_row, template_first_col, member_list.length)
  update_range.setValues(member_list);
  // 罫線設定
  update_range.setBorder(true, true, true, true, true, true);
  
}

8行目: group名として利用するため、引数で受け取った変数(シートの情報)からシート名を取得します。

10行目: group名とdomainを組み合わせて、groupsのメールアドレスを作成ます。

13行目: GroupsAppを利用して、作成したメールアドレスを利用して、メンバー一覧を取得します。

16行目: 取得したメンバー一覧を反映するため、既存のデータをクリアします。

19行目: 取得したメンバー一覧の中から、ユーザーのメールアドレスのみ抽出し配列に入れます。

25行目: 更新対象のセルの範囲を取得します。

26行目: 取得したセルの範囲に作成したメールアドレスの一覧を更新します。

28行目: 15行目でクリアした際に、罫線もクリアされるため、罫線を設定します。

3) ボタンへの関数の割り当て

実装した allGroupsReplaceMember() を「グループ一覧」シートの「全メンバー再取得」ボタンへ割り当てます。

4) 実行結果のイメージ

作成した関数を実行すると、スプレッドシートには、以下のような内容が反映されます。

全体のソースコード

最後に、ソースコード全体を紹介しておきます。

// グループ一覧シートのデータ取得用変数設定
var group_list_sheet_name = 'グループ一覧';
var domain_cell = "グループ一覧!c1";

var group_list_first_row = 4;
var group_list_first_col = 2;
var group_list_max_row = 500;

// templateシートのデータ取得用変数設定
var templete_sheet_name = 'template';

var template_first_row = 3;
var template_first_col = 2;
var template_max_row = 500;


// 処理対象スプレッドシート取得
var ss = SpreadsheetApp.getActiveSpreadsheet();
// インデックスシート取得
var group_list_sheet = ss.getSheetByName(group_list_sheet_name);
// 対象ドメイン取得
var domain = group_list_sheet.getRange(domain_cell).getValue();
Logger.log(domain);

/**
 * シートを追加する。
 */
function addSheet() {

  // 対象のグループ名取得
  var range = group_list_sheet.getRange(group_list_first_row, group_list_first_col, group_list_max_row, 3);
  var range_values = range.getValues();

  // templateシート取得
  var template_sheet = ss.getSheetByName(templete_sheet_name);

  // 內部リンク用のURL作成
  var spreadsheetID = ss.getId();
  var spreadsheetURL = "https://docs.google.com/spreadsheets/d/"+ spreadsheetID + "/edit"
  
  for (var i=0; i < range_values.length; i++){
    // データが無くなったらそこで終了
    if (range_values[i][0] == ''){
      return
    }
    // 対象のシートがあるか確認
    var mamber_list_sheet = ss.getSheetByName(range_values[i][0]);
    // なければシート追加
    if (!mamber_list_sheet){
      // templateシートをコピー
      var mamber_sheet = template_sheet.copyTo(ss);
      // シート名変更
      mamber_sheet.setName(range_values[i][0]);
      // タイトル横にGroupsへのリンクを追加
      var group_hyperlink = 'https://groups.google.com/a/' + domain +'/g/' + range_values[i][0] + '/members';
      mamber_sheet.getRange("C2").getCell(1, 1).setFormula('=HYPERLINK("' + group_hyperlink + '","groupsへ")');

      // 一覧にシートへのリンクを追加
      var sheetURL = spreadsheetURL + "#gid=" + mamber_sheet.getSheetId();
      range.getCell(i+1, 1).setFormula('=HYPERLINK("' + sheetURL +'","'+ range_values[i][0] + '")');
      // google groupsへのリンクを追加
      range.getCell(i+1, 3).setFormula('=HYPERLINK("' + group_hyperlink + '","groupsへ")');  
    }  
  }
}

/**
 * 全シートのメンバーを取得する
 */
function allGroupsReplaceMember(){
  // 処理対象スプレッドシート取得
  var range_values = group_list_sheet.getRange(group_list_first_row, group_list_first_col, group_list_max_row).getValues();
  
  // インデックスシート取得
  for (var i=0; i < range_values.length; i++){
    // データが無くなったらそこで終了
    if (range_values[i][0] == ''){
      return
    }

    var mamber_sheet = ss.getSheetByName(range_values[i][0]);
    
    // 1シート分の更新用関数呼び出し
    replaceMember(mamber_sheet);
  }
}

/**
 * 1シート分のgroupのメンバーを取得し直す
 * (allGroupsReplaceMemberから呼び出される関数)
 */
function replaceMember(mamber_sheet){

  // シート名(グループ名取得)
  var sheetName = mamber_sheet.getSheetName()
  // group名作成
  var group_mail = sheetName + "@" + domain
  
  // groupメンバー取得
  var users = GroupsApp.getGroupByEmail(group_mail).getUsers();
  
  // 既存データ削除
  mamber_sheet.getRange(template_first_row, template_first_col, template_max_row).clear();

  // 最新メンバー一覧反映
  var member_list = [];
  for (var i = 0; i < users.length; i++) {
    member_list.push([users[i].getEmail()]);
  }
  
  // セルに反映
  var update_range = mamber_sheet.getRange(template_first_row, template_first_col, member_list.length);
  update_range.setValues(member_list);
  // 罫線設定
  update_range.setBorder(true, true, true, true, true, true);
  
}

まとめ

1行ずつ説明をすると少し長くなってしまいますが、全体のソースコードを見ると比較的短めのソースコードになっているのではないかと思います。
内部で利用するツールを想定しているので、ご紹介した内容でも十分使えると思いますが、エラーチェックや個別にグループを指定してメンバー一覧を取得するなど、より便利に利用する方法も検討できると思います。

ぜひ、実際に使ってみて利用シーンに合わせて機能を拡張して使ってみてください。

Google Cloudの導入は当社にご相談ください

ITディストリビューターであるTD SYNNEXはGoogle Cloud™ Partner Award を受賞するなど、長年にわたりGoogle™のグローバル認定ディストリビューターとして、総合的な Googleソリューションを提供しています。お客様にとって最適なソリューションの提案や導入、活用をサポートします。

製品・サービスについてのお問合せ

情報収集中の方へ

導入事例やソリューションをまとめた資料をご提供しております。

資料ダウンロード
導入をご検討中の方へ

折り返し詳細のご案内を差し上げます。お問い合わせお待ちしております。

お問い合わせ