ユーザーの参加グループをPHPで出力(Google Workspace)
前回はGAS(Google Apps Script)でスプレッドシートに出力しましたが、以下の問題がありました。
・管理権限者しか実行できない
・出力が遅い
ですので、今回はAPIを利用して誰でも早く出力することにしました。
前提条件および前準備
Google Workspace Admin SDK > Directory APIにも前提条件として記述されてますが、以下の準備が必要です。
・PHP5.4以上、コマンドライン(CLI)とJSONが利用可能な状態
・Composerのインストール
・Google WorkspaceドメインへのAPIアクセスの有効化
・管理者権限を持つGoogleアカウント
Composerについては、以下のコマンドで作業ディレクトリに設置されます。
# curl -s http://getcomposer.org/installer | php
設置されたcomposer.pharを使用して、Googleクライアントライブラリをインストールします。
# php composer.phar require google/apiclient:^2.0
Google Workspace Admin SDK > Directory APIのページにある『quickstart.php』を土台として利用します。
# php quickstart.php
正常に動作すると『Open the following link in your browser:』が表示されますので、表示されたURLをブラウザを利用してアクセスします。
すると認証画面に遷移し、認証を許可するとコードが表示されますのでコピーしてください。
表示されたコードをコマンドラインの『Enter Verification code:』の場所に貼り付けます。
サンプルコードを修正し、Googleグループの登録状況を出力できるようにする
今回は以下の動作を利用可能としてます
・誰がどのグループ(メーリングリスト)に参加しているかを確認できます。
・どのグループ(メーリングリスト)に誰が参加しているかを確認できます。
WebUIはこんな感じです

[16行目~]利用するスコープを記述します
[22行目]利用するAPIのクライアントIDを、サーバー内に設置し、そのパスとファイル名を記述します
[30行目]前準備にて行った認証成功時に指定のファイルが出力されます。利用するスコープを変更するとこのファイルの再作成が必要です
[70行目~]Google Workspace利用ドメイン(先頭に@つける)を記述
[76行目~]WebUIにて70行目に記述したドメイン以外の入力を受け付けない様にする。
[137行目~]個人(プライベート)アドレスなどが入っていた場合、先頭5文字を伏字にする
<?php
require __DIR__ . '/vendor/autoload.php';
//if (php_sapi_name() != 'cli') {
// throw new Exception('This application must be run on the command line.');
//}
/**
* Returns an authorized API client.
* @return Google_Client the authorized client object
*/
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('G Suite Directory API PHP Quickstart');
$client->setScopes(implode(' ', array(
'https://www.googleapis.com/auth/admin.directory.group.readonly',
'https://www.googleapis.com/auth/admin.directory.group.member.readonly',
'https://www.googleapis.com/auth/admin.directory.user.readonly'
)));
$client->setAuthConfig('OAuth2.0 クライアントIDを記述');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'group_token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
// Get the API client and construct the service object.
$domain = "Google Workspace利用ドメイン(先頭に@つける)";
$eFlag = false; // エラーフラグ
$sFlag = false; // 検索フラグ
$token = ""; // nextPageToken用
$select = $_POST["select"];
$email = $_POST["email"];
if(strpos($email, $domain) != true){
$eFlag = true;
}
if(strlen($email) && strlen($select) && !$eFlag){
switch($select) {
// アドレスから参加グループ(ML)を検索する
case "1":
while(!$endFlag){ // 一度に最大200件しか抽出できないので、[nextPageToken]が出力している間、繰り返す
$client = getClient();
$service = new Google_Service_Directory($client);
$optParams = array(
'userKey' => $email,
'maxResults' => 200,
'pageToken' => $token
);
$group = $service->groups->listGroups($optParams);
for($i = 0; $i < count($group); $i++){
$ml_arr[$i] = $group[$i]["email"];
}
if($group["nextPageToken"] == null){
$endFlag = true;
}else{
$token = $group["nextPageToken"];
}
}
if(count($ml_arr) >= 1){
$sFlag = true;
}else{
$sFlag = false;
}
$msg = "<span id=\"s_address\">".$email."</span>は<span id=\"hit_count\">".count($ml_arr)."</span>個のメーリングリストに参加してます\n";
break;
// グループ(ML)アドレスから参加者を検索する
case "2":
$private_Flag = false;
while(!$endFlag){ // 一度に最大200件しか抽出できないので、[nextPageToken]が出力している間、繰り返す
$client = getClient();
$service = new Google_Service_Directory($client);
$optParams = array(
'maxResults' => 200,
'pageToken' => $token
);
$member = $service->members->listMembers($email,$optParams);
for($i = 0; $i < count($member); $i++){
// Google Workspace利用ドメイン以外は先頭5文字を伏字を入れる
if(strpos($member[$i]["email"], $domain) != true){
$email_arr = explode("@",$member[$i]["email"]);
$email_arr[0] = str_repeat('*',5) . mb_substr($email_arr[0],5,mb_strlen($email_arr[0], 'UTF8'),'UTF8');
$ml_arr[$i] = $email_arr[0]."@".$email_arr[1];
$private_Flag = true;
}else{
$ml_arr[$i] = $member[$i]["email"];
}
}
if($group["nextPageToken"] == null){
$endFlag = true;
}else{
$token = $member["nextPageToken"];
}
}
if(count($ml_arr) >= 1){
$sFlag = true;
}else{
$sFlag = false;
}
$msg = "<span id=\"s_address\">".$email."</span>には<span id=\"hit_count\">".count($ml_arr)."</span>個のメールアドレスが参加してます\n";
if($private_Flag){
$msg .= "
".$domain."以外は伏字にしております"; // 伏字に対する注釈
}
break;
}
}else{
$sFlag = false;
}
?>
WebUIはこんな感じ
<form action="index.php" method="post">
<div id="form_select">
<select name="select">
<option value="1">アドレスから参加グループ(ML)を検索する</option>
<option value="2">グループ(ML)アドレスから参加者を検索する</option>
</select>
</div>
<span id="form_title">検索メールアドレス</span>
<span id="form_data"><input type="text" size="50" name="email" placeholder="メールアドレスを入力してください"></span>
<div id="form_submit"><input type="submit" value="検索"></div>
</form>
<?php
if($sFlag){
echo "
\n";
echo $msg;
echo "
\n";
foreach($ml_arr as $key => $val){
echo $val."
\n";
}
if(count($ml_arr) > 200){
echo "
\n";
echo "最大数(200)を超えましたので、これ以上の表示は管理者に伝えてください\n";
}
}
?>
end





ディスカッション
コメント一覧
まだ、コメントがありません