【Google】GCPのPub/Subを使ってリアルタイムデベロッパー通知をプルする
以前、Google Play Billing の月額課金(サブスクリプション)の状態は、「リアルタイムデベロッパー通知をトリガーに管理・制御すると楽ですよ」という話をしました。
しかし残念ながら、通知を受信するには GCP(Google Cloud Platform)の Cloud Pub/Sub のサービスを経由することになり、GooglePlay から直接 http(s)などで通知が受けれるわけではありません。
今回は、この GCP の Cloud Pub/Sub についてまとめたいと思います。
GCPの環境設定
GCP の Cloud Pub/Sub を利用するには GCP のサービス登録が必要になります。
AWS と同様、初めて契約する場合は無料枠があるので、まずは利用してみましょう。
$300 相当が無料になる、12 か月間の無料トライアルにご登録ください。トライアル期間が終わっても、Always Free プロダクトは引き続きご利用いただけます。
GCP(Google Cloud Platform)
Cloud Pub/Sub は AWS で言うところの SNS(Amazon Simple Notification Service)がサービスとしては近いでしょうか。
Cloud Pub/Sub は、Google Cloud Platform 上や外部でホストされているシステムをデベロッパーが速やかに統合できるようにするため、低レイテンシで耐久性のあるメッセージングを提供します。
Cloud Pub/Sub とは
Android のサブスクリプションの状態を管理する場合は、Cloud Pub/Sub で以下を作成する必要があります。
・トピック(TOPIC)
・サブスクリプション(SUBSCRIPTION)
GooglePlay Console 上のアプリの設定で、作成したトピックを Publish(パブリッシュ)対象とします。
Cloud Pub/Sub ではトピックとサブスクリプションを紐つけて、トピックに対してパブリッシュされたものをどのように扱うか決めます。
通常だと、メッセージをどこかのサーバへそのまま転送したり(プッシュ)、メッセージを溜め込んでおき Cloud Pub/Sub 側に取得しに来てもらう(プル)パターンになります。
この辺りは、各プログラム言語に対応したクライアントライブラリも用意されているので、活用すればすぐに試すことができます。
Pub/Sub の設定は以下のページの方がわかりやすいかもしれませんね。
Cloud Pub/Sub を使用するには、Cloud Pub/Sub API が有効化されている Google Cloud Platform(GCP)上にプロジェクトが存在する必要があります。
Cloud Pub/Sub をセットアップする
GCPのサービスアカウント
Pub/Sub へ外部からアクセスするには、認証鍵(サービスアカウントキー)が必要になります。
また、Pub/Sub で作成したトピックやサブスクリプションに対しても、GCP のプロジェクトアカウントに以下の権限を付与します。
・Pub/Sub パブリッシャー
・Pub/Sub サブスクライバー
権限付与は「IAMと管理 – IAM」メニューで、認証鍵は「IAMと管理 – サービスアカウント」でアカウントを作成してから鍵の発行(JSON)を行います。
トピックの作成
トピックを作成します。最終的なトピック ID のフルパスは以下の形式になります。
projects/[プロジェクトID]/topics/[トピックID]
これを Android アプリを管理する GooglePlay Console 上の「開発ツール – サービスとAPI」のリアルタイムデベロッパー通知で設定します。
サブスクリプションの作成
サブスクリプションを作成します。最終的なサブスクリプション ID のフルパスは以下の形式になります。
projects/[プロジェクトID]/subscriptions/[サブスクリプションID]
連携するトピックや配信タイプなどを設定します。
今回は配信タイプを「プル」としますが、ドメイン認証が簡単にできる環境であれば「プッシュ」の方が運用は楽かもしれませんね。
トピックへのパブリッシュ
すぐにネイティブアプリが用意できない場合は、直接トピックにパブリッシュしてみましょう。
ここでは試しに PHP のクライアントライブラリを利用してみます。
言語に縛りはないので好きな言語で実装してください。
This simple command-line application demonstrates how to invoke Google Pub\Sub from PHP.
Google Pub\Sub CLI for PHP
$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
$ php composer-setup.php
$ php -r "unlink('composer-setup.php');"
$ php composer.phar install
composer がインストールされたら、以下のどちらかの方法でライブラリをセットアップします。
composer の方が楽ですかね。
composer require google/cloud-pubsub
GitHub から落としてきてもいいと思います。
$ git clone https://github.com/GoogleCloudPlatform/php-docs-samples
$ cd php-docs-samples/pubsub/api
サービスアカウントキーの指定方法
このライブラリを実行するには、サービスアカウントキーのパスを環境変数に指定する必要があるので、export するか .bashrc などに定義しておきましょう。
export GOOGLE_APPLICATION_CREDENTIALS=/foo/bar/key.json
ただ、動作確認をする分にはキーをローカルに保持していてもいいと思うのですが、git では管理したくないので、ここはファイルパス指定ではなく、json ファイルの中身を base64 エンコードなどして文字列で定義できるといいですね。
もちろん、その中身もソースコード上には定義せず、データベースなり別のところから取得できるようにしておくと実運用でも活用できそうです。
ライブラリを使ってパブリッシュする
まずは、このライブラリのヘルプを確認してみます。
$ php pubsub.php
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
help Displays help for a command
iam Manage IAM for Pub\Sub
list Lists commands
subscription Manage subscriptions for Pub\Sub
topic Manage topics for Pub\Sub
topic に対する操作は topic、subscroption なら subscription を指定すれば良さそうですね。
topic に対するヘルプは以下の通り。
$ php pubsub.php topic --help
Usage:
topic [options] [--] <project> [<topic>] [<message>]
Arguments:
project Your Google Cloud project ID
topic The topic name
message A message to publish to the topic
Arguments に「project」「topic」「message」が用意されているので、これらを指定すればトピックに対してメッセージをパブリッシュできそうです。
GCP のサービスアカウントのところで「Pub/Sub で作成したトピックやサブスクリプションに対しても、GCP のプロジェクトアカウントに以下の権限を付与します」と説明した通り、権限がない場合は 403 のステータスコードでエラーになるので注意が必要です。
ではパブリッシュしてみます。
$ php pubsub.php topic [GCPのプロジェクトID] [トピックID] [メッセージ]
Message published
サブスクリプションを作成する際にプル型にしている場合は、サブスクリプション側にメッセージが溜まっていますのでチェックしてみましょう。
サブスクリプションからのプル
では、コマンドからメッセージを受信してみましょう。まずは subscription のヘルプから。
$ php pubsub.php subscription --help
Usage:
subscription [options] [--] <project> [<subscription>]
Arguments:
project Your Google Cloud project ID
subscription The subscription name
Options:
--create Create the subscription.
--topic=TOPIC The topic for the subscription (when using --create).
--endpoint=ENDPOINT An optional endpoint for push subscriptions.
--delete Delete the subscription.
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
こちらは Arguments に「project」「subscription」だけの指定で一気に受信できそうなイメージです。
$ php pubsub.php subscription [GCPのプロジェクトID] [サブスクリプションID]
Message:[メッセージの中身]
ただし、Pub/Sub から受信するメッセージは順序が保証されていなかったり、重複するケースも想定しておかないといけないので、通知を受け取った後の処理で冪等に扱うなうなど考慮が必要になります。
まとめ
PHP のライブラリを利用して、GCP の Pub/Sub の簡単な操作を紹介しました。
Java など他の言語もそうですが、このライブラリでは認証用のファイルのパスを環境変数(GOOGLE_APPLICATION_CREDENTIALS)に指定する必要があります。
ただ、このファイルを GitHub(GHE含む)で管理するなんてあり得ないですし、プログラムの構成に悩むところです。
私は結果的に、認証ファイルのバイトストリームをライブラリにセットするように調整しましたが、もう少しライブラリ側もデフォルトの設定について考慮してくれると嬉しいですね。
普段 AWS を使う機会が多いので、少しでも GCP のサービスを触れたのは良かったと思います。