グループのメンバーをGASで追加・更新・削除する(一括処理・予約処理もあり)

Google Workspaceを使っている人・組織では、ほぼ確実に使われているであろうGoogleグループ
csvファイルによるメンバーの一括登録機能などがありますが、かゆいところには手が届かない印象です。

Google Apps Script(GAS)を使えば、各組織の業務にあわせて自動化することができます。

この記事では、Googleグループのメンバー変更(追加、更新、削除)をGoogle Apps Scriptで実行する方法を解説します。

事前準備:Admin SDK APIの追加

Google Apps ScriptでGoogleグループを扱うには、Admin SDK APIをプロジェクトに追加する必要があります。

「サービス」の + マーク > Admin SDK API を選択 > 追加ボタン

基本:シンプルなメンバー追加・削除・更新

Google公式のコードを参考に、メンバー追加、削除、更新の基本的なコードを作成してみました。

グループにメンバーを追加する

test-group@example.comtaro@example.comをメンバーとして追加する例です。
roleには、MEMBER, MANAGER, OWNERを指定できます。参考

function addGroupMember() {
  const userEmail = 'taro@example.com';
  const groupEmail = 'test-group@example.com';
  const member = {
    email: userEmail,
    role: 'MEMBER'
  };
  try {
    AdminDirectory.Members.insert(member, groupEmail);
    Logger.log('User %s added as a member of group %s.', userEmail, groupEmail);
  } catch (err) {
    Logger.log('Failed with error %s', err.message);
  }
}

グループからメンバーを削除する

test-group@example.comからtaro@example.comを削除する例です。

function removeGroupMember() {
  const userEmail = 'taro@example.com';
  const groupEmail = 'test-group@example.com';
  try {
    AdminDirectory.Members.remove(groupEmail, userEmail);
    Logger.log('User %s removed from group %s.', userEmail, groupEmail);
  } catch (err) {
    Logger.log('Failed with error %s', err.message);
  }
}

メンバーのプロパティを更新する

test-group@example.comのメンバーであるtaro@example.comの役割をMANAGERに変更する例です。

function updateGroupMember() {
  const userEmail = 'taro@example.com';
  const groupEmail = 'test-group@example.com';
  const member = { 
    role: 'MANAGER'
  };
  try {
    AdminDirectory.Members.update(member, groupEmail, userEmail);
    Logger.log('User %s updated in group %s.', userEmail, groupEmail);
  } catch (err) {
    Logger.log('Failed with error %s', err.message);
  }
}

応用1:メンバーの追加・削除・更新を一括処理

スプレッドシートとGoogle Apps Scriptを使って、一括処理用のツールを作ってみました。

A列~D列に処理内容とデータを入力しておく
一括処理実行後は、E列・F列に実行結果と実行日時が登録される

作成したサンプルスクリプトは下記になります。
editGroupMembersを実行すると、シートの内容を元に一括処理が行われます。

// シートを取得
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sh = ss.getActiveSheet();

/**
 * シートに登録されたメンバー編集処理を一括実行する
 */
function editGroupMembers(){
  // 2行目から最終行までループ
  for (let i = 2; i <= sh.getLastRow(); i++){
    // 対象行のセルから値を取得
    const procType = sh.getRange(i, 1).getValue();
    const userEmail = sh.getRange(i, 2).getValue();
    const role = sh.getRange(i, 3).getValue();
    const groupEmail = sh.getRange(i, 4).getValue();
    // 処理実行
    let result;
    switch (procType){
      case 'add':
        result = addGroupMember(userEmail, groupEmail, role);
        break;
      case 'remove':
        result = removeGroupMember(userEmail, groupEmail);
        break;
      case 'update':
        result = updateGroupMember(userEmail, groupEmail, role);
        break;
    }
    // 処理結果を記入
    sh.getRange(i, 5).setValue(result);
    sh.getRange(i, 6).setValue(new Date());
  }
}

// メンバー追加
function addGroupMember(userEmail, groupEmail, role) {
  const member = {
    email: userEmail,
    role: role
  };
  try {
    AdminDirectory.Members.insert(member, groupEmail);
    return "Success"
  } catch (err) {
    return "Error: " + err.message;
  }
}

// メンバー削除
function removeGroupMember(userEmail, groupEmail) {
  try {
    AdminDirectory.Members.remove(groupEmail, userEmail);
    return "Success"
  } catch (err) {
    return "Error: " + err.message;
  }
}

// メンバー更新
function updateGroupMember(userEmail, groupEmail, role) {
  const member = { 
    role: role
  };
  try {
    AdminDirectory.Members.update(member, groupEmail, userEmail);
    return "Success"
  } catch (err) {
    return "Error: " + err.message;
  }
}

応用2:メンバーの一括自動処理を予約する

定期の人事異動のように、多くのメンバー変更が発生する場合、異動日当日の朝にバタバタしちゃいますよね。(もしくは前日の夜に残業して変更作業したり・・・)

そうならないように、メンバー変更を予約して、深夜に自動実行されるようにしてみました。

シートの内容は先述のものと同じです。
ただし、シート名を処理実行日(YYYYMMDD)にしておきます。
例:2022年3月22日に実行する場合 → シート名は 20220322 とする

シートは先ほどのものと同じ。ただし、シート名を処理日付のYYYYMMDDにしておく。

サンプルスクリプトは下記の通りです。
メインの部分は先ほどのスクリプトとほぼ同じですが、処理を呼び出す2つの関数を作成しています。

execActiveSheetアクティブなシートを対象として一括処理する。
任意のタイミングで一括処理したい時に使用する。
execReservedSheet処理日のYYYYMMDDと同名のシートを対象として一括処理する。
トリガーによって日次で自動起動する用。
// シートを取得
const ss = SpreadsheetApp.getActiveSpreadsheet();

/**
 * 随時処理:現在アクティブなシートを対象とする
 */
function execActiveSheet(){
  const sheet = ss.getActiveSheet();
  editGroupMembers(sheet);
}

/**
 * 日時処理:シート名が処理日付のYYYYMMDDと一致するシートを対象とする
 */
function execReservedSheet(){
  // 現在時刻から処理対象シート名(YYYYMMDD)を取得
  const targetSheetName = Utilities.formatDate(new Date(), "JST", "yyyyMMdd");
  // 本日日付名のシートが存在したら処理実行
  const sheets = ss.getSheets();
  for (sheet of sheets){
    if (sheet.getName() === targetSheetName){
      editGroupMembers(sheet);
      return;
    }
  }
}

/**
 * シートに登録されたメンバー編集処理を一括実行する
 */
function editGroupMembers(sh){
  // 2行目から最終行までループ
  for (let i = 2; i <= sh.getLastRow(); i++){
    // 対象行のセルから値を取得
    const procType = sh.getRange(i, 1).getValue();
    const userEmail = sh.getRange(i, 2).getValue();
    const role = sh.getRange(i, 3).getValue();
    const groupEmail = sh.getRange(i, 4).getValue();
    // 処理実行
    let result;
    switch (procType){
      case 'add':
        result = addGroupMember(userEmail, groupEmail, role);
        break;
      case 'remove':
        result = removeGroupMember(userEmail, groupEmail);
        break;
      case 'update':
        result = updateGroupMember(userEmail, groupEmail, role);
        break;
    }
    // 処理結果を記入
    sh.getRange(i, 5).setValue(result);
    sh.getRange(i, 6).setValue(new Date());
  }
}

// メンバー追加
function addGroupMember(userEmail, groupEmail, role) {
  const member = {
    email: userEmail,
    role: role
  };
  try {
    AdminDirectory.Members.insert(member, groupEmail);
    return "Success"
  } catch (err) {
    return "Error: " + err.message;
  }
}

// メンバー削除
function removeGroupMember(userEmail, groupEmail) {
  try {
    AdminDirectory.Members.remove(groupEmail, userEmail);
    return "Success"
  } catch (err) {
    return "Error: " + err.message;
  }
}

// メンバー更新
function updateGroupMember(userEmail, groupEmail, role) {
  const member = { 
    role: role
  };
  try {
    AdminDirectory.Members.update(member, groupEmail, userEmail);
    return "Success"
  } catch (err) {
    return "Error: " + err.message;
  }
}

トリガーは下図のように設定します。
この例では、毎日 午前0時~1時 にexecReserveSheet関数を実行します。

以上でサンプルツールの解説は終わりです。参考になれば幸いです。

コメント