見出し画像

Googleグループの設定と管理

G Suiteを導入し、Googleグループをメーリングリストとして使用している企業も多いかと思いますが、Googleグループ作成時に「デフォルトのままでいいや」と設定を誤ると「グループ外の人たちがメールを見れる状態になっていた」「メールの取りこぼしが起きていた」といったことも起こり得るのでので、Googleグループの設定について改めて整理してみました。
2019年5月にGoogleグループの仕様変更もありましたので、その変更内容も踏まえています。
また、GAMを利用してGoogleグループを管理するスクリプトを以前Qiitaに投稿しましたが、そちらを少し手直しした物も改めて紹介します。

なお、Googleグループの仕様変更により、各画面・文言・プロパティは今後変更になる可能性もありますのでご了承ください。

■Googleグループ上でのトピックの表示

あまり知られていないかもしれませんが、Googleグループは単なるメーリングリストではなく、フォーラム機能を持っているので、Webから過去のメールを閲覧可能です。(フォーラム機能の説明は長くなるので割愛します)

G Suiteのランチャーメニューから「グループ」を選択すると、「Googleグループ」の画面が開きます。

「マイグループ」をクリックすると、自身が所属するGoogleグループの閲覧が、「すべてのグループ」をクリックすると、自身は所属していないが組織内で公開されているグループの一覧が表示されます。

各グループの画面では、所属するメンバーや過去に届いたメールが「トピック」として表示されます。

つまり、Googleグループの設定を誤っていると、この画面から見えてはいけないグループやメールが見えてしまう可能性があります。
そういった自体を防ぐために、Googleグループの各設定を確認しておきましょう。

■Googleグループの管理画面

G Suite管理コンソールからGoogleグループの作成・設定変更を行いますが、
「Googleグループの管理画面(簡易版)」
「ビジネス向けGoogleグループ管理画面」
の2種類の画面があります。

Googleグループの管理画面(簡易版)
G Suite管理コンソールで「グループ」をクリックした際に最初に表示される画面です。この画面で設定できる項目は、以下の画像の項目のみです。

G Suite Admin SDKのリファレンスをご覧頂きたいのですが、Googleグループのプロパティは、この画面の設定項目以外にも大量にあります。
これらのプロパティをGUIから設定するには、「ビジネス向けGoogleグループ管理画面」から操作する必要があります。

ビジネス向けGoogleグループ管理画面
通常のGoogleグループ管理画面から「ビジネス向けGoogleグループ管理画面」へは、Googleグループ設定画面の「設定」を展開した下の方の「管理の設定」「詳細設定」のリンクから遷移できます。(見つけづらいので、改修してほしい…)


以下の画面のように、通常のグループ設定画面に比べ、設定できる項目が非常に多いです。


なお、「ビジネス向けGoogleグループ」はG Suite無償版では使用できず、Basic以上である必要があります。(つまり無償版で設定できるGoogleグループの設定項目は非常に限られています)

Googleグループで設定可能な主なプロパティと推奨設定について説明して行きます。なお、推奨設定はあくまで私個人の経験則によるものなので、自社のルールや運用を踏まえた上で適切な設定を判断するようにお願いします。

■Googleグループのプロパティ(基本)

改めて、「Googleグループの管理画面(簡易版)」を見てみましょう。

この画面で設定できるプロパティは、以下の通り。
・オーナーに連絡(whoCanContactOwner)
・メンバーを表示(whoCanViewMembership)
・トピックを表示(whoCanViewGroup)
・投稿を公開(whoCanPostMessage)
・メンバーを管理(whoCanModerateMembers)
 ※2019年5月のアップデート以前は以下のプロパティでそれぞれ設定が
 分かれていましたが、[whoCanModerateMembers]にマージされました
 ・whoCanAdd
 ・whoCanInvite
 ・whoCanApproveMembers
 ・whoCanBanUsers
 ・whoCanModifyMembers

・グループに参加できるユーザー(whoCanJoin)
・組織外メンバーの許可(allowExternalMembers)

上記の中で、特に重要なプロパティについて説明して行きます。

・メンバーを表示(whoCanViewMembership)
「グループのメンバー」を推奨。
「組織全体」に設定すると、このグループに参加していない組織内ユーザー全員がグループのメンバーを閲覧できるようになります。

・トピックを表示(whoCanViewGroup)
「グループのメンバー」を推奨。
「トピック」というのは、Googleグループ宛に送られたメールのことだと思ってください。
「組織全体」に設定すると、このグループに参加していない組織内ユーザーでも、Googleグループの画面から対象のグループ宛に送られたメールを閲覧できてしまいます。
役員や労務など機密性の高いメーリングリストも存在するかと思いますので、「組織全体」になっている場合は危険です。
なお、「外部」を選択するとインターネット上の誰でもトピックを閲覧できる状態になってしまいますので、WebフォーラムとしてGoogleグループを外部公開して運用したい場合以外は選択しないようにしましょう。
また、「外部」を選択してインターネット公開するには、Googleグループビジネス自体の共有設定を変更する必要があります。詳細はGoogleの以下のドキュメントをご確認ください。
ビジネス向け Google グループの共有オプションの設定

・投稿を公開(whoCanPostMessage)
「外部」を推奨。
日本語が分かりづらいですが、英語のプロパティ名の通り、「Googleグループに投稿できる人」を指定します。
社外からのメールを受け付けるメーリングリストであれば、「外部」にしておかないと機能しません。
※逆に社内でのみ使用したいメーリングリストであれば「組織全体」でも大丈夫です

・メンバーを管理(whoCanModerateMembers)
これは会社の運用ルールによって推奨設定が変わってきます。
Googleグループのメンバー管理をシステム管理者で完全にコントロールしたい場合は「グループの管理者」にし、グループ内のメンバーを全員の権限を「メンバー」としておき「管理者」を設定しなければOKです。
逆にグループのメンバー管理を各グループの管理者に移譲したい場合は、グループ内のメンバーのうちの数名を「管理者」にしておけば実現できます。

・グループに参加できるユーザー(whoCanJoin)
「組織内のすべてのユーザーがリクエストできる」を推奨。
こちらもメンバー管理の運用次第ですが、メンバー内で管理者を設定しなければリクエストが来ても誰も承認はできないので、結果的にシステム管理者のみがメンバー設定可能となります。

・組織外メンバーの許可(allowExternalMembers)
「OFF」を推奨。
「ON」にすると、グループに社外ドメインのメールアドレスを追加できます。自社ドメイン以外を転送先に含むメーリングリストのみ「ON」にするのがいいでしょう。

■Googleグループのプロパティ(詳細)

続いて、「ビジネス向けGoogleグループ管理画面」でしか編集できませんがデフォルトから変更しておいた方が良いプロパティを紹介します。

・アーカイブオプション(isArchived) [情報] > [コンテンツ管理]
false→trueへの変更を推奨。
trueに設定すると、Googleグループ宛に受信したメールがGoogleグループのトピック上に永続的に保存されるようになります。falseの場合は、各メンバーにメールが転送されるだけでトピックは残りません。
なお、trueに設定することは「後からグループに参加したメンバーが、過去に受信したメールを見れるようになる」ということでもあるので、善し悪しを判断して設定してください。

・スパムメッセージ(spamModerationLevel) [設定] > [管理]
「管理キューに送信し、モデレーターに通知(MODERATE)」から
「管理キューをスキップしてグループに投稿(ALLOW)」 への変更を推奨。
これもあまり知られていませんが、Googleグループ自体にもスパムフィルタがあり、スパム判定されたメールはGoogleグループの「保留中のメッセージ」というキューに溜まります。
「保留中のメッセージ」の中のスパムメールは7日間しか保存されず、7日を過ぎたメールは自動削除されます。
厄介なのが、このスパムフィルタの感度が高すぎて誤検知が多いということ。そして、各Googleグループに管理者を設定していない場合は、スパム検知メールも飛ばないので、メールの取りこぼしが発生します
@icloud.com などのドメインはスパム判定される率が高いので、カスタマサポート用のメーリングリストのなどは特に要注意です。
Googleグループ側のスパムフィルタをバイパスしても、Gmail側で改めてフィルタがかかるので、メールの取りこぼしリスクの方が影響が大きい場合はALLOWに変更しておくことを推奨します。
※スパムフィルタが一段減ることになるので、社内のセキュリティレベルを踏まえた上で判断してください

・グループディレクトリ(showInGroupDirectory) [情報] > [ディレクトリ]
「組織のすべてのメンバー」に設定していると、Googleグループの利用者画面の「すべてのグループ」で表示されるようになります。
存在自体を知られたくないメーリングリストについては、「グループのすべてのメンバー」に変更しておくのがいいでしょう。

・whoCanLeaveGroup ※画面上の設定箇所なし
これもあまり知られていませんが、Googleグループの画面で「このグループから退会」をユーザーがポチッと押すだけで簡単に退会できてしまいます
社内連絡用メーリングリストを漏れなく運用していたつもりが、気付いたら一部メンバーが退会していたというケースが発生する可能性もあるので、デフォルトの「ALL_MEMBERS_CAN_LEAVE」から「NONE_CAN_LEAVE」に変更しておくことをおすすめします。
管理画面上に設定箇所がないので、後述のGAMやAPIから設定変更が必要です。(昔は設定箇所があった気もする…)

■GAMについて

ここまで解説してきた通り、Googleグループで設定すべきプロパティは沢山ありますが、G Suite管理コンソールでのGoogleグループ関連の設定は操作性が悪い上にレスポンスも遅く、大量のグループの作成・設定変更を行うのはかなり苦痛です。

G Suite Admin SDKのAPIを使用すればGoogleグループに対する一通りの操作は可能ですが、GASでは実行時間6分以内に収まらなかったり、コーディングに慣れていない方がAPIをコールするプログラムを作成するのも大変だと思います。
オフィシャルなツールではないですが、GAM(GoogleAppsManager)というG Suiteの管理用コマンドのライブラリが開発されているので、こちらを利用してGoogleグループの管理を楽にするサンプルをいくつか紹介します。

GAMのインストール方法やドキュメント、リファレンスもGitHubのwikiで公開されていますので、今回の記事での説明は割愛させて頂きます。

■GAMを使ったサンプルスクリプト

1.全Googleグループのメンバー・設定をCSVに出力する
GAMのインストール・設定が完了していれば、以下のコマンドを実行するだけで全Googleグループのメンバー・プロパティをCSVに出力できます。

gam print groups name description admincreated id aliases members owners managers settings > groups.csv

出力されたCSVをフィルタして、各Googleグループのプロパティ設定に差異が無いか確認しておくと安心です。
特に、途中から入った現場では「前任者が作成していた既存のGoogleグループの設定が、好ましい設定ではなかった」というケースも少なくないので、一度全グループの設定を確認しておくことをオススメします。

2.Googleグループの一括作成・設定変更
Googleグループを一括作成して必要な初期設定をするPowerShellのサンプルスクリプトです。
「Email」「Name」の2カラムを持った以下のフォーマットのCSVに、作成したいGoogleグループを列挙しておきます。

|Email|Name|
|gam-test1@yourdomain.com|GAMテストグループ1|
|gam-test2@yourdomain.com|GAMテストグループ2|
...

作成したCSVをGAMの実行ファイルと同じフォルダに配置し、以下のPowerShellスクリプトを実行すれば、グループの作成とプロパティの更新が実行されていきます。

$GAM_Path = "C:\GAM"
cd $GAM_Path

# インポートCSVファイルのパス
$CSVFile = "C:\GAM\CreateGoogleGroup.csv"
$InputCSV = ipcsv $CSVFile -Encoding default

ForEach($r in $InputCSV)
{
   ./gam.exe create group $($r.Email) name $($r.Name)

   # Create直後にUpdateを実行するとエラーになる場合があるのでインターバルを置く
   Start-Sleep -s 1

   ./gam.exe update group $($r.Email) who_can_view_membership all_members_can_view
   ./gam.exe update group $($r.Email) who_can_view_group all_members_can_view
   ./gam.exe update group $($r.Email) who_can_post_message anyone_can_post
   
   ./gam.exe update group $($r.Email) who_can_moderate_members owners_and_managers
   ./gam.exe update group $($r.Email) who_can_join can_request_to_join
   ./gam.exe update group $($r.Email) who_can_leave_group none_can_leave
   ./gam.exe update group $($r.Email) show_in_group_directory false

   ./gam.exe update group $($r.Email) is_archived true
   ./gam.exe update group $($r.Email) spam_moderation_level allow
}

設定するプロパティを変更したい場合は、G Suite Admin SDKのリファレンスを参照してください。
1点注意があり、「GAMでupdate groupを実行しても、エラーが返ってこず正常終了したように見えてプロパティが更新されていない」ということが稀にあります。(これはGAMの不具合なのかG Suite Admin SDKの問題なのか不明ですが、G Suite Admin SDKのAPIを直接叩いた際も同じような現象が起きていた気がするので、API側の問題かもしれません)
スクリプト実行後は、先述のGoogleグループ一括出力等でプロパティを出力して、他のグループと設定の差異が無いかどうかチェックした方が安全です。

3.Googleグループのメンバーを一括変更する
組織変更などで各Googleグループのメンバーを大量かつ短時間で変更したい場合には、一括変更のスクリプトを用意しておくと便利です。

まず、インポートCSVを以下のフォーマットで作成します。
グループのメンバーを追加したい場合は、arg1~2に"add" "member"を、
グループからメンバーを削除したい場合は、arg1~2に"remove" "user"を、
セットしてください。

|Group|arg1|arg2|Member|
|group-a@yourdomain.com|remove|user|user-1@yourdomain.com|
|group-b@yourdomain.com|add|member|user-1@yourdomain.com|
|group-b@yourdomain.com|add|member|user-2@yourdomain.com|
...

作成したCSVをGAMの実行ファイルと同じフォルダに配置し、以下のPowerShellスクリプトを実行すれば、メンバーが変更されていきます。

$GAM_Path = "C:\GAM"
cd $GAM_Path

# インポートCSVファイルのパス
$CSVFile = "C:\GAM\ModifyGoogleGroupMember.csv"
$InputCSV = ipcsv $CSVFile -Encoding default

ForEach($r in $InputCSV)
{
   ./gam.exe update group $($r.Group) $r.arg1 $r.arg2 $($r.Member)
}


■GASのサンプル(2019/8/14追記)

どうもGAMの挙動が不安定なのと、ブラウザだけで実行できる環境がほしかったので、スプレッドシート&GAS(Google Apps Script)版のスクリプトも作成しました。
GASもG Suite Businessであれば実行時間が30分まで延びるようなので、それなりの量のデータを扱えるはずです。

なお、いずれのスクリプトも「リソース」→「Googleの拡張サービス」から「Admin Directory API」と「Groups Settings API」を追加し、グループの管理権限を有するユーザーで実行する必要があるので注意してください。

1.全Googleグループの設定をスプレッドシートに出力する
以下のスクリプトを実行すると、スプレッドシートに対象ドメインの全Googleグループの情報が列挙されます。
(出力するプロパティは、必要そうな物だけに絞っています)

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];

//実行メニューを作成
function onOpen() {
 var ui = SpreadsheetApp.getUi();
 var menu = ui.createMenu("GAS実行");
 menu.addItem("Googleグループ一括出力", "exportGoogleGroup");
 menu.addToUi();
}

function exportGoogleGroup() {
 //対象ドメイン
 var domainName = 'example.com';
 
 //取得するグループの最大数(デフォルトは200)
 var maxResults = 500;

 //シートをクリア
 sheet.clear();
  
 var values = [];
 
 //ヘッダー追加
 values.push([
   "メールアドレス",
   "グループ名",
   "説明",
   "メンバー数",
   "WhoCanJoin",
   "whoCanViewMembership",
   "whoCanViewGroup",
   "whoCanInvite",
   "whoCanAdd",
   "allowExternalMembers",
   "whoCanPostMessage",
   "allowWebPosting",
   "maxMessageBytes",
   "isArchived",
   "archiveOnly",
   "messageModerationLevel",
   "spamModerationLevel",
   "showInGroupDirectory",
   "whoCanLeaveGroup",
   "whoCanContactOwner",
   "whoCanApproveMembers",
   "whoCanBanUsers",
   "whoCanModifyMembers",
   "whoCanApproveMessages",
   "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); //説明
     value.push(groupsList.groups[i].directMembersCount); //メンバー数

     //グループのプロパティを取得
     var group = AdminGroupsSettings.Groups.get(groupsList.groups[i].email);
     value.push(group["whoCanJoin"]);
     value.push(group["whoCanViewMembership"]);
     value.push(group["whoCanViewGroup"]);
     value.push(group["whoCanInvite"]);
     value.push(group["whoCanAdd"]);
     value.push(group["allowExternalMembers"]);
     value.push(group["whoCanPostMessage"]);
     value.push(group["allowWebPosting"]);
     value.push(group["maxMessageBytes"]);
     value.push(group["isArchived"]);
     value.push(group["archiveOnly"]);
     value.push(group["messageModerationLevel"]);
     value.push(group["spamModerationLevel"]);
     value.push(group["showInGroupDirectory"]);
     value.push(group["whoCanLeaveGroup"]);
     value.push(group["whoCanContactOwner"]);
     value.push(group["whoCanApproveMembers"]);
     value.push(group["whoCanBanUsers"]);
     value.push(group["whoCanModifyMembers"]);
     value.push(group["whoCanApproveMessages"]);
     value.push(group["whoCanDiscoverGroup"]);

     values.push(value); 
   }
   
   //取得したデータをスプレッドシートにセット
   sheet.getRange(1, 1, groupsList.groups.length + 1 , 25).setValues(values);
 } 
}

出力結果はこんな感じです。


2.Googleグループの一括作成・設定変更
以下のようなカラムを持ったスプレッドシートに、作成するグループの情報を列挙しておきます。
(Result列はブランクにしておく)

以下のスクリプトを実行すると、Googleグループの作成とプロパティ設定の処理が走り、Result欄に実行結果がセットされます。(プロパティ設定はお好みで変更してください)

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];

//実行メニューを作成
function onOpen() {
 var ui = SpreadsheetApp.getUi();
 var menu = ui.createMenu("GAS実行");
 menu.addItem("Googleグループ一括作成", "createGoogleGroup");
 menu.addToUi();
}

function createGoogleGroup() {
 var lastColum = sheet.getLastColumn();
 var lastRow = sheet.getLastRow();
 var startRow = 2;  
 var numRows = lastRow - 1;     
 var dataRange = sheet.getRange(startRow, 1, numRows, lastColum);
 var data = dataRange.getValues();

 for (var i = 0; i < data.length; ++i) {
   var row = data[i];
   
   row.rowNumber = i + 2;
   
   //Result列がブランクであれば処理を実行    
   if (!row[3]) { 
     var result = "";
     
     try
     {
       //Groupの作成(コメントアウトすることでGroupのプロパティ更新のみ実行可能)
       AdminDirectory.Groups.insert({email: row[0], name: row[1], description: row[2]});     
       
       //Groupのプロパティ更新
       var group = AdminGroupsSettings.Groups.get(row[0]);
       group.whoCanViewMembership = "ALL_MEMBERS_CAN_VIEW";
       group.whoCanViewGroup = "ALL_MEMBERS_CAN_VIEW";
       group.whoCanPostMessage = "ANYONE_CAN_POST";
       group.whoCanModerateMembers = "OWNERS_AND_MANAGERS";
       group.whoCanJoin = "CAN_REQUEST_TO_JOIN";
       group.whoCanLeaveGroup = "NONE_CAN_LEAVE";
       group.whoCanDiscoverGroup = "ALL_MEMBERS_CAN_DISCOVER";
       group.isArchived = "true";
       group.spamModerationLevel = "ALLOW";
       AdminGroupsSettings.Groups.patch(group, row[0]);
       
       result = "Success"; 
     }catch(e){
       result = "Error:" + e;
     }
     
     //実行結果をResult列にセット
     sheet.getRange(row.rowNumber, 4).setValue(result); 

   }
 }  
}


3.Googleグループのメンバーを一括変更する
以下のようなカラムを持ったスプレッドシートに、変更対象のグループとメンバーの情報を列挙しておきます。
(Result列はブランクにしておく)

以下のスクリプトを実行すると、各Googleグループのメンバ追加・削除の処理が走り、Result欄に実行結果がセットされます。

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];

//実行メニューを作成
function onOpen() {
 var ui = SpreadsheetApp.getUi();
 var menu = ui.createMenu("GAS実行");
 menu.addItem("Googleグループメンバー変更", "modifyGoogleGroupMember");
 menu.addToUi();
}

function modifyGoogleGroupMember(){
 var lastColum = sheet.getLastColumn();
 var lastRow = sheet.getLastRow();
 var startRow = 2;  
 var numRows = lastRow - 1;     
 var dataRange = sheet.getRange(startRow, 1, numRows, lastColum);
 var data = dataRange.getValues();
 
   for (var i = 0; i < data.length; ++i) {
   var row = data[i];
   
   row.rowNumber = i + 2;
   
   //Result列がブランクであれば処理を実行    
   if (!row[3]) { 
     var result = "";
     
     try
     {

       if(row[1] == "add")
       {
         result = AdminDirectory.Members.insert({email: row[2], role: "MEMBER"}, row[0]);
         result = "Success"; 
       }else if(row[1] == "remove")
       {
         result = AdminDirectory.Members.remove(row[0], row[2]);
         result = "Success"; 
       }else{
         result = "Error:Actionパラメータに誤りがあります。add/removeのいずれかをセットしてください。"
       }
     }catch(e){
       result = "Error:" + e;
     }
     
     //実行結果をResult列にセット
     sheet.getRange(row.rowNumber, 4).setValue(result); 

   }
 }  
}


■おわりに

Googleグループはメンテナンス頻度が高い上に、G Suite管理コンソールだけで設定変更するのは非常に辛く、オペレーションミスが発生する可能性も高いです。
APIやGAMを駆使して、スクリプト化できる部分はスクリプト化しておいた方が、今後の運用はぐっと楽になるでしょう。

また、Googleグループに限らずG Suiteはアップデートや仕様変更が激しいので、各プロパティは今後も変わって行く可能性が高いです。
今回紹介した推奨設定についてもベストプラクティスという訳ではないので、実際の環境や運用に適した設定を行うようにしてください。



この記事が気に入ったらサポートをしてみませんか?