それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Google Apps AdminApi でユーザーを一括変更する

Google AppsGmailはドット('.') でメアドを増やせないので、とりあえずAliasでまとめて登録しようと思いました。

ドットでメアドを増やせない件

google appsのGmailは ドットでメアドを増やせない件について
Gmailのドットバリエーションを全部作る

このメアドをまとめて登録するのをAPIでやろうと思います。

google apps api の使い方

Google AppsAPIは色々紆余曲折の後、ユーザ管理はProvisioningAPIからDirectoryAPIになって便利になった。RESTFulなAPIをOAuth2で認証して使うと簡単に使うことができる。

写真:機械的にAliasを追加した例

APIをプログラムで使えると、メアドやユーザの管理が便利になります。
もちろん、APIを使えることでそのたのGoogle機能にもアクセスできるようになって世界は広がる。
(01google-apps)


準備

今回はRubyでやります。

  • gem インストール
  • client_secret.json の準備
  • コードサンプルを実行
  • まとめて登録
  • はまったエラー・メッセージについて
  • APIの発見

準備1 gem のインストール

google api を使うRubyモジュールがGoogle@github で公開されているのでソレを活用します。

gem install google-api-client

配布元ページ→ google/google-api-ruby-client · GitHub

ローカルアプリ用のCredentialsを作る

google console で新規プロジェクト作成

Google Developer Console にアクセスして、新規プロジェクトを作ります。

新しいCredentialsを作る

Devloper Consoleから新しいCredentialsを作成します。
今回は、コンソールから使ってバッチ処理するだけなので、Install Apps→Otherを選びました。

(02new-Credentials)


作成できたら一覧に出てきました。
(03Credentials-list)

Secretをダウンロードします。
ダウンロードしたファイル名をclient_secret.jsonで保存しました。
(client-secret)

admin.googme.com でAdminAPIを許可

今回はgoogle apps を触りたいので、 google apps の管理画面でApiを許可します。

(admin api)

コードサンプルを実行して感じをつかむ

サンプルプログラムの作成
client_secret.jsonと同じディレクトリに、ruby プログラムのファイルを作成し、テストしてみます。

このプログラムで、指定したユーザーのAlias.Listを取得します。

require 'pp'
require 'google/api_client'
require 'google/api_client/request'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'

client = Google::APIClient.new(
  :application_name => 'Example Ruby application',
  :application_version => '1.0.0'
)

directory = client.discovered_api('admin',"directory_v1")

client_secrets = Google::APIClient::ClientSecrets.load("./client_secret.json")

flow = Google::APIClient::InstalledAppFlow.new(
  :client_id => client_secrets.client_id,
  :client_secret => client_secrets.client_secret,
  :scope => ['https://www.googleapis.com/auth/admin.directory.user',
                    'https://www.googleapis.com/auth/admin.directory.user.alias']
)
client.authorization = flow.authorize(storage)

req =  Google::APIClient::Request.new({
	  :api_method => directory.users.aliases.list,
  	:parameters => {
  			'userKey' => 'takuyaXXX@XXXXXx',
  			},
	})
req.headers['Content-Type']="application/json"

result = client.execute(req)
pp result.data

コレを実行すると、ブラウザが起動しOAuthのパーミッションを取得を聞いてきました。
Acceptしてプログラムを許可すると、localhost:9292 にリダイレクトされ、auth処理が完了。

APIが実行されUserKeyで指定したユーザーのAlias一覧が出てきます。

他にも幾つかAPIがあるので、それぞれを試して動作チェックしました。

APIのリファレンス

ユーザーの一覧取得、グループ一覧取得、Alias削除などなど。試してみると感じがつかめました。

APIのリファレンスの抜粋

https://developers.google.com/admin-sdk/directory/v1/reference/users/list
https://developers.google.com/admin-sdk/directory/v1/reference/users/aliases/list

APIのリファレンスには、OAuthが必須かどうか、OAuthで権限移譲するパーミッションのURLスコープが書かれているので、APIを利用時に適宜コード中の Scope を追加修正が必要。

GoogleAPIにはOAuthが必要ないものもあるが、AdminAPIのDirectoryはOAuth必須だった。

まとめて登録。

OAuth結果の保存

まとめて登録するときに何度もパーミッションを聞いてくると、面倒なので。

OAuthの結果をファイルに保存してパーミッションが何度も聞かれることのないようにして、
連続処理できるように準備します。

Google::APIClient::FileStorage を使うと簡単にOAuthの状態を保存することが出来ました。MarshalとかJSONにしようと試みたけど、備え付けのライブラリを使うと簡単に出来来たので使うことにしました。

storage = Google::APIClient::FileStorage.new("auth_storage.json")
storage.load_credentials()
if storage.authorization then
	client.authorization  = storage.authorization
else

  client_secrets = Google::APIClient::ClientSecrets.load("./client_secret.json")

  flow = Google::APIClient::InstalledAppFlow.new(
    :client_id => client_secrets.client_id,
    :client_secret => client_secrets.client_secret,
    :scope =>    ['https://www.googleapis.com/auth/admin.directory.user',
                         'https://www.googleapis.com/auth/admin.directory.user.alias']
  )

  client.authorization = flow.authorize(storage)

end

これで連続処理を出来るようになりました。

はまったエラー・メッセージ

invalid Email

POSTでメアド登録時にInvalid Email: alias_emailが何度も出るので、苦労した

req.headers['Content-Type']="application/json"

をつけて、POST時にはPOSTデータがJSONであることを明記しないと動かなった。

googleAppsを管理するGAM・・・

なぜか動かなかった。

APIを発見して指定する。

Api名前空間 discovered_api

Google のサンプルには api がいくつかある。その中でAdmin Directory APIを探すには次のようにした

client.discovered_apis
require 'pp'
require 'google/api_client'
require 'google/api_client/request'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'google/api_client/auth/file_storage'

client = Google::APIClient.new(
  :application_name => 'Example Ruby application',
  :application_version => '1.0.0'
)
client.discovered_apis

client.discovered_apis.select{|e| e.name =~/admin/i}
# => [
#   #<Google::APIClient::API:0x3fdb292044c0 ID:admin:directory_v1>,
#   #<Google::APIClient::API:0x3fdb29203c3c ID:admin:email_migration_v2>,
#   #<Google::APIClient::API:0x3fdb29203444 ID:admin:reports_v1>, 
#   #<Google::APIClient::API:0x3fdb292242fc ID:sqladmin:v1beta1>, 
#   #<Google::APIClient::API:0x3fdb29223ce4 ID:sqladmin:v1beta3>
#  ]

このなかで、directory_v1 がそのまま名前になるのに気づかなくてハマった。