ユーザーの参加グループを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
ディスカッション
コメント一覧
まだ、コメントがありません