（要管理者権限）Google Workspaceでグループを一括管理するGAS

Google Workspace（for Education）の管理者がグループを管理する際の不便な点として、
1. グループの一括管理ができない
2. 管理コンソールで設定できる権限では不十分である
ことが挙げられます。

GASの勉強がてらこれを解消するものを作成しました。自己責任で使ってください。

# 使い方
初回のみ以下の1〜6を実行して下さい。
1. （要Google Workspace管理者権限）[editGoogleGroup](http://bit.ly/3v9M5LG)をクリックし「コピーを作成」
2. スプレッドシート「コピー ～ editGoogleGroup」が開くので、メニューバー「ツール」→「スクリプトエディタ」
3. コード.gsの13行目に管理しているドメイン名を記入
4. 「onOpen」関数が選択されていることを確認して「実行」
5. 承認を求められるので、管理者アカウントを選択の上で「許可」
6. 再度「実行」を押した上で、スプレッドシートに戻る

## グループ一覧の取得
1. メニューバー「グループ操作」→「グループ一括出力」を実行
2. 「グループ一覧」シートへ管理しているグループの一覧が表示
![スクリーンショット 2021-03-09 午後8.39.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558740/a29e4955-9433-4772-18ba-6db99ebcd6ad.png)

## グループの新規追加
1. 「グループ追加・変更」シートに必要な情報を追加。B列「メールアドレス」に新規追加したいグループのメールアドレスを記入。A列は記入せず、D列「説明」以外は必ず入力。グループの各プロパティ（E列「WhoCanJoin」以降）で設定可能なステータスについては、[Groups Settings API
](https://developers.google.com/admin-sdk/groups-settings/v1/reference/groups)を参照のこと。最初は既存のグループの設定を援用するのがおすすめ。各行にグループ毎の設定を記入することで、複数のグループを一括で追加することも可能。![スクリーンショット 2021-03-09 午後8.44.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558740/daccd12b-cf81-79ed-f266-f6a56a56fc26.png)

2. メニューバー「グループ操作」→「グループ追加・変更」を実行
3. 「グループ一覧」シートへ追加したグループを含めた最新の一覧が自動で表示されている。

## グループの設定変更（メールアドレスも変更可能）
1. グループの新規追加と基本的には同様で、B列「メールアドレス」に既存のグループのメールアドレスを指定し、その他変更しない項目も含めて「説明」以外の全ての項目を埋める。もしグループのメールアドレスも変更したい場合には、A列「変更後のメールアドレス」欄も指定する。
2. メニューバー「グループ操作」→「グループ追加・変更」を実行
3. 「グループ一覧」シートへ追加したグループを含めた最新の一覧が自動で表示されている。

# スクリプトの説明
GASの勉強中なので、少しずつ今回書いたスクリプトの説明も加えていく予定(2021/3/9)。

管理コンソール上からグループを作成した場合、「primaryLanguage」は空欄で作成されるため、スクリプトから「primaryLanguage」の項目を削除。グループの詳細設定ではprimaryLanguageも設定でき、日本語を指定するなら「ja」。

以下のスクリプトにないリソースを[Groups Settings API](https://developers.google.com/admin-sdk/groups-settings/v1/reference/groups)から見つけ、使用したい場合にはそれぞれのシートの最後列にその項目を加えた上で、スクリプトのl.43、l.74、l.117、l.146に当該リソースについての記述を追加する。

特殊な使い方なため公開しているコードには加えていないが、私自身のコードには加えているものに「includeInGlobalAddressList」がある。

「includeInGlobalAddressList」はそのグループメールアドレスをオートコンプリート候補に加えるかどうかに影響する。デフォルトはTRUE、つまりオートコンプリート候補に加えるが、FALSEにすることでオートコンプリートに表示されなくなる。個人のメールアドレスについては、ディレクトリ設定で組織部門毎にグループ単位でオートコンプリートへの表示、非表示を制御できるが、実はグループメールアドレスそのものはここでは制御できない（グループAの中に個人アドレスB, Cがあったとして、BとCのアドレスは見えなくできるが、Aのアドレス自体は見える）。

特に匿名性を高めたいグループメールアドレスについては、この設定も考えると良いだろう。もちろんFALSEにすると初回はそのメールアドレスをベタ打ちしないといけない。

## スクリプト
```javascript
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("グループ一覧");

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  var menu = ui.createMenu("グループ操作");
  menu.addItem("グループ一括出力", "exportGoogleGroup");
  menu.addItem("グループ追加・変更", "modifyGoogleGroup");
  menu.addToUi();
}

function exportGoogleGroup() {
  var domainName = '管理しているドメイン名'; 
  var maxResults = 500;

  sheet.clear();
  
  var values = [];

  values.push([
    "メールアドレス",
    "グループ名",
    "説明",
    "WhoCanJoin",
    "whoCanViewMembership",
    "whoCanViewGroup",
    "allowExternalMembers",
    "whoCanPostMessage",
    "allowWebPosting",
    "isArchived",
    "archiveOnly",
    "messageModerationLevel",
    "spamModerationLevel",
    "replyTo",
    "membersCanPostAsTheGroup",
    "whoCanLeaveGroup",
    "whoCanContactOwner",
    "whoCanApproveMembers",
    "whoCanBanUsers",
    "whoCanModerateMembers",
    "whoCanModerateContent",
    "whoCanDiscoverGroup",
  ]);
 
  var groupsList = AdminDirectory.Groups.list({domain: domainName, maxResults: maxResults});
  if(groupsList) {
    for(var i = 0; i < groupsList.groups.length; i++){
      var value = [];
    
      value.push(groupsList.groups[i].email);
      value.push(groupsList.groups[i].name);
      value.push(groupsList.groups[i].description);

      var group = AdminGroupsSettings.Groups.get(groupsList.groups[i].email);
      value.push(group["whoCanJoin"]);
      value.push(group["whoCanViewMembership"]);
      value.push(group["whoCanViewGroup"]);
      value.push(group["allowExternalMembers"]);
      value.push(group["whoCanPostMessage"]);
      value.push(group["allowWebPosting"]);
      value.push(group["isArchived"]);
      value.push(group["archiveOnly"]);
      value.push(group["messageModerationLevel"]);
      value.push(group["spamModerationLevel"]);
      value.push(group["replyTo"]);
      value.push(group["membersCanPostAsTheGroup"]);
      value.push(group["whoCanLeaveGroup"]);
      value.push(group["whoCanContactOwner"]);
      value.push(group["whoCanApproveMembers"]);
      value.push(group["whoCanBanUsers"]);
      value.push(group["whoCanModerateMembers"]);
      value.push(group["whoCanModerateContent"]);
      value.push(group["whoCanDiscoverGroup"]);

      values.push(value); 
    }

    sheet.getRange(1, 1, values.length, value.length).setValues(values);
  } 
}

function modifyGoogleGroup(){
  const sheet2 = ss.getSheetByName('グループ追加・変更');
  var lastrow = sheet2.getLastRow();
  var lastcolumn = sheet2.getLastColumn();
  
  var data = sheet2.getRange(1, 1, lastrow, lastcolumn).getValues();
  for(var i = 1;i < lastrow;i++){
    var result = true;
    try{
      var group = AdminGroupsSettings.Groups.get(data[i][1]);
    }catch(e){
      result = false;
    }
    if (result){
      group.name = data[i][2];
      group.description = data[i][3];
      group.whoCanJoin = data[i][4];
      group.whoCanViewMembership = data[i][5];
      group.whoCanViewGroup = data[i][6];
      group.allowExternalMembers = data[i][7];
      group.whoCanPostMessage = data[i][8];
      group.allowWebPosting = data[i][9];
      group.isArchived = data[i][10];
      group.archiveOnly = data[i][11];
      group.messageModerationLevel = data[i][12];
      group.spamModerationLevel = data[i][13];
      group.replyTo = data[i][14];
      group.membersCanPostAsTheGroup = data[i][15];
      group.whoCanLeaveGroup = data[i][16];
      group.whoCanContactOwner = data[i][17];
      group.whoCanApproveMembers = data[i][18];
      group.whoCanBanUsers = data[i][19];
      group.whoCanModerateMembers = data[i][20];
      group.whoCanModerateContent = data[i][21];
      group.whoCanDiscoverGroup = data[i][22];

      AdminGroupsSettings.Groups.patch(group, data[i][1]);
      // メールアドレスも更新する場合
      if (data[i][0]){
        AdminDirectory.Groups.patch({"email": data[i][0]}, data[i][1]);
        AdminDirectory.Groups.Aliases.remove(data[i][0], data[i][1]);
      }
    }else{
      AdminDirectory.Groups.insert({email: data[i][1], name: data[i][2], description: data[i][3]});   
      var group1 = AdminGroupsSettings.Groups.get(data[i][1]);
      group1.whoCanJoin = data[i][4];
      group1.whoCanViewMembership = data[i][5];
      group1.whoCanViewGroup = data[i][6];
      group1.allowExternalMembers = data[i][7];
      group1.whoCanPostMessage = data[i][8];
      group1.allowWebPosting = data[i][9];
      group1.isArchived = data[i][10];
      group1.archiveOnly = data[i][11];
      group1.messageModerationLevel = data[i][12];
      group1.spamModerationLevel = data[i][13];
      group1.replyTo = data[i][14];
      group1.membersCanPostAsTheGroup = data[i][15];
      group1.whoCanLeaveGroup = data[i][16];
      group1.whoCanContactOwner = data[i][17];
      group1.whoCanApproveMembers = data[i][18];
      group1.whoCanBanUsers = data[i][19];
      group1.whoCanModerateMembers = data[i][20];
      group1.whoCanModerateContent = data[i][21];
      group1.whoCanDiscoverGroup = data[i][22];

      AdminGroupsSettings.Groups.patch(group1, data[i][1]);
    }
  }
  exportGoogleGroup();
}
```