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で全ユーザーのリストをスプレッドシートに日次取得する方法
ぜひ活用してみてくださいね。