見出し画像

Google WorkspaceとZoomのライセンス数を報告するGoogle Chat bot

前書き

前回の記事の内容を使って、もうちょっと業務に関連したことができないかなーと思ってやってみました。題して、Google WorkspaceとZoonのライセンス数をGoogle Chatに送るbot。そのままですね。

要件やら前提条件やら

弊社では個人のアカウントに特権を持たせず、共有の管理者アカウントを用いて各種アカウント管理周りの作業を行っています。誰がログインしたとか作業したとか分からなくなるからあんまり推奨された行為では無いだろうことは置いといて、思い立ったときにしかログインせず、アカウントの作成などは派遣さんにお願いしていたこともあり、「あれ、あとアカウントいくつ余ってたっけ」ってなることがちょいちょいありました。
というわけで、今のアカウント数がこれくらいで、ライセンス数はこれくらいだから、そろそろ新しいライセンス買わないとね、みたいな話がコンスタントにできるようなシステムを組みたかった背景があります。ついでに言えば、わざわざ見に行かなくても済む形で。
というわけで、前回の内容にちょっと加えて実装してみました。なお、弊社ではSlackやChatworks等といったいい感じのシステムは使ってないため、全てGoogle Workspaceのサービスで完結させてます。必要なものは、Google スプレッドシートとGAS、Google Chatくらいです。

事前作業

①スプレッドシートを作成してIDを取得
スプレッドシートを作成して、URL中のIDを取得(赤枠内)します。
シート1のB1セルに「情報収集日」、C1セルに「アカウント数」と記載します。

画像3

シート2を作成し、B2セルに「Google Workspaceライセンス数」、B3セルに「Zoomライセンス数」と記入、それぞれ購入しているライセンス数を手動で入力します。

画像2

②Zoom JWTの発行
ZoomのAPIを利用できるようにするため、こちらのページを参考にJWTappを有効にします。有効にした際に、APIキーとSecretが表示されますので別途記録しておきます。

③Google ChatのWebhookを発行
Google Chatに対して連携を行うため、Webhookを発行します。

画像4

画像5

Google Chatにて、チャットルームを作成します。

画像6

画像7

Webhookを追加します。

画像8

Webhookが作成されるとURLが発行されますので、コピーしておきます。

④GASにてサービスを追加
GASはスプレッドシート上のスクリプトを編集してください。

画像10

画像9

情報を取得できるようにするため、以下2つのサービス(SDK)を検索して有効にします。
・AdminDirectory
・AdminLicenseManager

ソースコード

ソースは以下参照。素人作成なので所々お見苦しい箇所あるかと思いますがご容赦ください。
初回実行時はGoogleにてアクセス権を求められますので、特権管理者で作成したGASで動かすとよいと思います。

// Google Workspaceのアカウント数を取得。スプレッドシートに記載し、Chatにメッセージ送信する
// 有効にしているサービスは、「AdminDirectory」と「AdminLicenseManager」

//JWT Token の発行関数 参考:https://qiita.com/coticoticotty/items/56ff2a3324fe408b06ca
function getZoomAccessToken() {
 // API KEYを入力
 const ZOOM_API_KEY = '**APIキーを入力**'; 
 // API SECRETを入力
 const ZOOM_API_SECRET = '**Secretを入力**'; 
 // ヘッダー情報の格納 参考:https://techblog.yahoo.co.jp/advent-calendar-2017/jwt/
 const header = { alg: 'HS256', typ: 'JWT' };
 // APIKEYを核に脳したペイロード
 const payload = {
   iss: ZOOM_API_KEY,
   exp: Date.now() + 3600, // 時間設定
 };

 // ヘッダーとペイロードをコード化
 const jsonHeader = JSON.stringify(header);
 const encodedHeader = Utilities.base64Encode(jsonHeader);
 const jsonPayload = JSON.stringify(payload);
 const encodedPayload = Utilities.base64Encode(jsonPayload);

 // 署名を符号化した後にコード化
 const signatureHMAC = Utilities.computeHmacSha256Signature(`${encodedHeader}.${encodedPayload}`, ZOOM_API_SECRET);
 const encodedSignature = Utilities.base64Encode(signatureHMAC);

 // 戻り値にTokenを設定
 const JWT_TOKEN = `${encodedHeader}.${encodedPayload}.${encodedSignature}`;
 //Logger.log(JWT_TOKEN);
 return `${encodedHeader}.${encodedPayload}.${encodedSignature}`;

}


function postChatGoogleWSadnZoomUsersCount() {  
// 今日の日付の取得 
 const date = new Date();

// WebhookのURL
// 参考:https://webree.jp/article/hangouts-webhook/
 const webhookurl = 'https://chat.googleapis.com/v1/spaces/*****';

// 対象スプレッドシートの指定
 const id = "スプレッドシートのID情報"
 const ss = SpreadsheetApp.openById(id)
// シートの名前で指定。シート1に結果、シート2に購入ライセンス数
 const sheet1 = ss.getSheetByName("シート1")
 const sheet2 = ss.getSheetByName("シート2")

// 現在の購入済みライセンス数を確認
 const bayGWS = sheet2.getRange("C2").getValue();
 const bayZoom = sheet2.getRange("C3").getValue();

//頭文字検索に使用する文字列 「charAt()」関数で1文字ずつ呼び出す。大文字と小文字は区別しない
 const searchStrs = "abcdefghijklmnopqrstuvwxyz1234567890";

//この配列に、メールアドレスを格納する
 const allUserMails = new Array();

// 複数ドメインを考慮する
 const domains = ["利用しているドメインを記載"];

// 全体ユーザ数の定義
 const userCounts = 0;

// ドメイン数分forを回す
for(var i = 0;i < domains.length;i ++){
 //頭文字分forを回す
	for(var j = 0;j < searchStrs.length;j ++){
		
		//呼び出すユーザーの条件を指定し、optionalArgsに挿入
		var optionalArgs = {
			domain:domains[i],		 //ドメインを入力
			maxResults:500,				//デフォルトでは100件までなので、500(最大数)を指定
			query:"email:"+ searchStrs.charAt(j) +"*",//メールアドレスの頭文字で検索を行う
			fields:"users/emails"	//メールアドレスの情報のみを限定して取得。グループアドレスは含まれない。
		};
		
		// ユーザー情報の呼び出し
		const userDatas = AdminDirectory.Users.list(optionalArgs);
   // ユーザがいた場合の処理
		if(userDatas.users){
     //ユーザ数の加算(全体ユーザ数の取得)
     userCounts = userCounts+userDatas.users.length;
		}
	}
}

//Zoomの情報収集
const request = UrlFetchApp.fetch('https://api.zoom.us/v2/users/', {
 method: 'GET',
 contentType: 'application/json',
 headers: { Authorization: `Bearer ${getZoomAccessToken()}` }, // JWT Token
});
const users = JSON.parse(request.getContentText());
//Zoomユーザ数の結果
const ZoomusersCounts = users.total_records;

// ユーザアカウント数の記録
// シートのB列の最終行に日付を挿入(yyyy/mm/dd) 列番号1、範囲行数2
 const lastRow = sheet1.getLastRow();
 sheet1.getRange(lastRow + 1, 2).setValue(Utilities.formatDate(date, 'JST', 'yyyy/MM/dd (E) HH:mm'));

// シートのC列にアカウント数を挿入。
 const GoogleUserCounts = "Google Workspaceのアカウント数は"+userCounts+"で、購入済みライセンス数は"+bayGWS+"です。\nZoomのアカウント数は"+ZoomusersCounts+"で、購入済みライセンス数は"+bayZoom+"です。";
 sheet1.getRange(lastRow + 1, 3).setValue(GoogleUserCounts);
	//Logger.log(userCounts);

// 送信内容を生成
// 参考:https://webree.jp/article/gas-hangoutchat/
// セルの値をテキスト形式に変更
 const message = {'text' : GoogleUserCounts}
// おまじない
 const options = {
   'method': 'POST',
   'headers' : {
     'Content-Type': 'application/json; charset=UTF-8'
   },
   'payload':JSON.stringify(message)
 };

// 送信を実行
 const result = UrlFetchApp.fetch(webhookurl, options);

}

結果は以下のような感じになります。
あとはGASの発砲タイミングを調整して、1週間に1回など丁度いい感じに着火するよう設定してあげればよいかと思います。

画像1

画像11

画像12

こんな感じで、JWTの発行関数を先行して動かすように設定しました。毎日飛ばすと休みの日も通知来て鬱陶しいので月一にしてみました。

所感

うまく動いたときは「おお~」となりましたが、ぜいたくを言えば購入済みライセンスまで自動で引っ張ってきたかったところです。Google Workspaceでは購入済みライセンスを引っ張れるAPIはなさそうだったので、手動での更新が必要なところがイケてない箇所かなと。
また、通常のやり方ではGoogle Workspaceで500名以上のアカウントを持つ場合、ユーザ情報を収集する数の上限に引っかかって正確な数値を出すことができません。今回はこちらを参考にソースを組ませて頂きましたが、500名以下ならそこまで難しく考えず通常のユーザ取得スクリプトでよさそうです。



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