GASでGoogleグループのメンバー一覧を取得するコードと解説

  • このエントリーをはてなブックマークに追加
  • LINEで送る

0.はじめに

GoogleWorkspaceを管理されている方々なら
「Googleグループを一覧化したい、マスタ管理したい」
そう思う事が絶対にあると思います。

そんな方に向けて、グループメンバーを一覧化するコードをご紹介します。
簡単に解説もしていきますので、ぜひ参考にしてみてくださいね。

1.コード

サンプルコードです。


//メイン処理
function getGroupListAll(){  
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sh = ss.getSheetByName('test');

  let domainList = ["ドメインを入力","ドメインを入力"];
  let output = ([["グループ名", "メールアドレス", "メンバー数", "グループメンバー"]]);

  //outputに対して一気にグループ情報とメンバー情報を付加
  domainList.forEach(x=> pushArray(output,getGroupInfo(x)));

  //2次元配列で貼り付けるための整形
  inputSpace(output);

  //シートクリア
  sh.clear();

  //貼り付け
  sh.getRange(1,1,output.length,output[0].length).setValues(output);
}


//ドメインのグループを全件取得する
function getGroupInfo(domain){
  let maxResults = 200;  
  let token = '';
  let result = []
  do{
    if(token==""){
      var groupsList = AdminDirectory.Groups.list({domain: domain, maxResults: maxResults})
    }else{
      var groupsList = AdminDirectory.Groups.list({domain: domain, maxResults: maxResults, pageToken: token})
    }
    if(groupsList.groups) {
      for(let i in groupsList.groups){
        let groupName = groupsList.groups[i].name//グループ名
        let groupMail = groupsList.groups[i].email//メールアドレス
        let groupNumber = groupsList.groups[i].directMembersCount//メンバー数
        let groupMember = getMemb(groupsList.groups[i].email)
        let forPush = [groupName,groupMail,groupNumber]
        result.push(forPush.concat(groupMember))
        }
      }
      token = groupsList.nextPageToken
    }while(token)
  return result
}


//addressのメンバーを1次元配列で取得
function getMemb(address){
  let rv = [];
  let member = ''
  let token = '';

  do{
    if(token == ''){
      member = AdminDirectory.Members.list(address,{maxResults:200});
    }else{
      member = AdminDirectory.Members.list(address,{maxResults:200, pageToken: token});
    }
    if(member.members){
      member.members.forEach(x => rv.push(x.email));
    }
  token = member.nextPageToken;
  }while(token)

  return rv;
}


//破壊的に二次元配列に二次元配列を結合する
function pushArray(array1, array2){
  for(let arr2 of array2){
    array1.push(arr2);
  }
}


//長さの違う2次元配列に空白を入力する
function inputSpace(array){
  let wide = 0;
  for(let arr of array){
    if(arr.length>wide){
      wide = arr.length;
    }
  }
  for(let arr of array){
    while(arr.length<wide){
      arr.push('');
    }
  }
}

多分もっと分かりやすく、綺麗に書く事もできると思います。
ちなみにAIチャットボットChatGPTに書いてもらうとこんな感じになります。
AIチャットボットにGASを書いてもらったら実用レベルで絶望した件

2.出力結果

こんな感じにスプレッドシートに出力されます。
メンバーリストの出力結果画像

3.解説

3-1.AdminDirectory

グループ情報取得、メンバー情報取得の両方の処理でAdminDirectoryを使用します。
エディタ左側の「サービス」から「AdminSDK」を追加しないと使えません。

Groups.listの公式リファレンス
Members.listの公式リファレンス

3-2.構成

大きな流れとしては、こんな感じになっています。

貼り付け用の二次元配列とヘッダを用意

各ドメインをループし全グループを取得
└ループ内で各グループのメンバーを取得

行ごとに長さの違うジャグ配列になっているため、
列数を揃えるためにinputSpace()で整形

シートをクリアして貼り付け

3-3.ポイント

Groups.list、Members.list両方とも1リクエスト当たりの上限があります。
200件が上限のため200件以上の場合はトークンを取得して
次ページ分の情報取得へ進んでいく必要があります。

コード内で.nextPageToken()してトークンを取得、
do while(token)でトークンがある場合は次のページを取得しています。

4.注意点

4-1.セル数上限に注意

「3000人入っているグループが5000件ある・・・」等、
ボリュームがある場合はスプレッドシートのセル数上限に注意してください。

セル数上限は昨年引き上げられてスプレッドシート当たり1000万になりましたが、
人数分、右方向にセルを使う仕様のため要注意です。

対策したい場合、1行100列までにして次の行に折り返す工夫などが必要です。

4-2.タイムアウトに注意

グループを全件取得し、更にメンバーを全件取得しています。
グループ2000×メンバー3000だと単純に掛け算して6,000,000。
処理数が多くなるので時間がかかります。

対策としては、ループをラムダ式に置き換え高速化を図るか、
タイムアウトしそうになったら一度処理を終了して
続きから実行するトリガーを設定するような手法が必要になります。

何にせよ、一度ご自身の環境で実行して対策の要否を検討してみてください。
私の環境では2000グループ×2000名ほどですが、何とかなっています。

5.さいごに

いかがでしたでしょうか。
これがあると、Admin画面を見られない方にも参照して頂けます。
メンバーをユーザー名で表示したい場合、
こちらの記事も参照してユーザーリストと照合する仕組みにしてください。
GASで全ユーザーのリストをスプレッドシートに日次取得する方法
ぜひ活用してみてくださいね。

  • このエントリーをはてなブックマークに追加
  • LINEで送る

コメントを残す

*