Pub/Sub メッセージの作成とレスポンス

リージョン ID

REGION_ID は、アプリの作成時に選択したリージョンに基づいて Google が割り当てる省略形のコードです。一部のリージョン ID は、一般的に使用されている国や州のコードと類似しているように見える場合がありますが、このコードは国または州に対応するものではありません。2020 年 2 月以降に作成されたアプリの場合、REGION_ID.r は App Engine の URL に含まれています。この日付より前に作成されたアプリの場合、URL のリージョン ID は省略可能です。

詳しくは、リージョン ID をご覧ください。

Pub/Sub は、信頼できる多対多の非同期メッセージングをアプリケーション間で行います。パブリッシャー アプリケーションはメッセージをトピックに送信し、その他のアプリケーションはそのトピックにサブスクライブしてメッセージを受信できます。

このドキュメントでは、Cloud クライアント ライブラリを使用して、App Engine アプリで Pub/Sub メッセージを送受信する方法について説明します。

前提条件

サンプルアプリのクローン作成

サンプルアプリをローカルマシンにコピーし、pubsub ディレクトリに移動します。

Go

git clone https://github.com/GoogleCloudPlatform/golang-samples.git
cd golang-samples/appengine/go11x/pubsub/authenicated_push

Java

このランタイムで使用できる例はありません。

Java 8 と Java 11/17 のデモアプリはフレキシブル環境で利用できることに留意してください。

Node.js

git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples
cd nodejs-docs-samples/appengine/pubsub

PHP

git clone https://github.com/GoogleCloudPlatform/php-docs-samples.git
cd php-docs-samples/pubsub

Python

git clone https://github.com/GoogleCloudPlatform/python-docs-samples
cd python-docs-samples/appengine/standard_python3/pubsub

Ruby

git clone https://github.com/GoogleCloudPlatform/ruby-docs-samples
cd ruby-docs-samples/appengine/pubsub

トピックとサブスクリプションを作成する

トピックとサブスクリプションを作成します。Pub/Sub サーバーがリクエストを送信するエンドポイントも指定します。

Go

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

YOUR_TOKEN は、ランダムなシークレット トークンで置き換えます。push エンドポイントがこれを使用してリクエストを検証します。

Pub/Sub を認証で使用するには、別のサブスクリプションを作成します。

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your Google-managed service account
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

YOUR-SERVICE-ACCOUNT-EMAIL は、サービス アカウントのメールアドレスに置き換えます。

Java

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

YOUR_TOKEN は、ランダムなシークレット トークンで置き換えます。push エンドポイントがこれを使用してリクエストを検証します。

Pub/Sub を認証で使用するには、別のサブスクリプションを作成します。

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your Google-managed service account
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

YOUR-SERVICE-ACCOUNT-EMAIL は、サービス アカウントのメールアドレスに置き換えます。

Node.js

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

YOUR_TOKEN は、ランダムなシークレット トークンで置き換えます。push エンドポイントがこれを使用してリクエストを検証します。

Pub/Sub を認証で使用するには、別のサブスクリプションを作成します。

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your Google-managed service account
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

YOUR-SERVICE-ACCOUNT-EMAIL は、サービス アカウントのメールアドレスに置き換えます。

PHP

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

YOUR_TOKEN は、ランダムなシークレット トークンで置き換えます。push エンドポイントがこれを使用してリクエストを検証します。

Pub/Sub を認証で使用するには、別のサブスクリプションを作成します。

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your Google-managed service account
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

YOUR-SERVICE-ACCOUNT-EMAIL は、サービス アカウントのメールアドレスに置き換えます。

Python

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

YOUR_TOKEN は、ランダムなシークレット トークンで置き換えます。push エンドポイントがこれを使用してリクエストを検証します。

Pub/Sub を認証で使用するには、別のサブスクリプションを作成します。

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your Google-managed service account
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

YOUR-SERVICE-ACCOUNT-EMAIL は、サービス アカウントのメールアドレスに置き換えます。

Ruby

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

YOUR_TOKEN は、ランダムなシークレット トークンで置き換えます。push エンドポイントがこれを使用してリクエストを検証します。

Pub/Sub を認証で使用するには、別のサブスクリプションを作成します。

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your Google-managed service account
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

YOUR-SERVICE-ACCOUNT-EMAIL は、サービス アカウントのメールアドレスに置き換えます。

環境変数を設定する

Go

app.yaml ファイルを編集して、トピックと検証トークンの各環境変数を設定します。

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

runtime: go121
env_variables:
    # This token is used to verify that requests originate from your
    # application. It can be any sufficiently random string.
    PUBSUB_VERIFICATION_TOKEN: check123

Java

app.yaml ファイルを編集して、トピックと検証トークンの各環境変数を設定します。

env_variables:
  PUBSUB_TOPIC: <your-topic-name>
  PUBSUB_VERIFICATION_TOKEN: <your-verification-token>

Node.js

app.yaml ファイルを編集して、トピックと検証トークンの各環境変数を設定します。

env_variables:
  PUBSUB_TOPIC: YOUR_TOPIC_NAME
  # This token is used to verify that requests originate from your
  # application. It can be any sufficiently random string.
  PUBSUB_VERIFICATION_TOKEN: YOUR_VERIFICATION_TOKEN

PHP

index.php ファイルを編集して、トピックとサブスクリプションの環境変数を設定します。

$container->set('topic', 'php-example-topic');
$container->set('subscription', 'php-example-subscription');

Python

app.yaml を編集して、プロジェクト ID、トピック、検証トークンの各環境変数を設定します。

env_variables:
  PUBSUB_TOPIC: '<YOUR_TOPIC>'
  # This token is used to verify that requests originate from your
  # application. It can be any sufficiently random string.
  PUBSUB_VERIFICATION_TOKEN: '<YOUR_VERIFICATION_TOKEN>'

Ruby

app.standard.yaml を編集して、プロジェクト ID、トピック、検証トークンの各環境変数を設定します。

env_variables:
    PUBSUB_TOPIC: gaeflex_net_pubsub_auth_push_1
    # This token is used to verify that requests originate from your
    # application. It can be any sufficiently random string.
    PUBSUB_VERIFICATION_TOKEN: abc123

コードのレビュー

サンプルアプリでは、Pub/Sub クライアント ライブラリを使用しています。

Go

このサンプルアプリでは、構成用として app.yaml ファイルに設定された環境変数(PUBSUB_TOPICPUBSUB_VERIFICATION_TOKEN)を使用します。

このインスタンスが受信したメッセージがスライスに格納されます。

messages   []string

receiveMessagesHandler 関数は、push されたメッセージを受信してトークンを検証し、メッセージを messages スライスに追加します。


// receiveMessagesHandler validates authentication token and caches the Pub/Sub
// message received.
func (a *app) receiveMessagesHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
		return
	}

	// Verify that the request originates from the application.
	// a.pubsubVerificationToken = os.Getenv("PUBSUB_VERIFICATION_TOKEN")
	if token, ok := r.URL.Query()["token"]; !ok || len(token) != 1 || token[0] != a.pubsubVerificationToken {
		http.Error(w, "Bad token", http.StatusBadRequest)
		return
	}

	// Get the Cloud Pub/Sub-generated JWT in the "Authorization" header.
	authHeader := r.Header.Get("Authorization")
	if authHeader == "" || len(strings.Split(authHeader, " ")) != 2 {
		http.Error(w, "Missing Authorization header", http.StatusBadRequest)
		return
	}
	token := strings.Split(authHeader, " ")[1]
	// Verify and decode the JWT.
	// If you don't need to control the HTTP client used you can use the
	// convenience method idtoken.Validate instead of creating a Validator.
	v, err := idtoken.NewValidator(r.Context(), option.WithHTTPClient(a.defaultHTTPClient))
	if err != nil {
		http.Error(w, "Unable to create Validator", http.StatusBadRequest)
		return
	}
	// Please change http://example.com to match with the value you are
	// providing while creating the subscription.
	payload, err := v.Validate(r.Context(), token, "http://example.com")
	if err != nil {
		http.Error(w, fmt.Sprintf("Invalid Token: %v", err), http.StatusBadRequest)
		return
	}
	if payload.Issuer != "accounts.google.com" && payload.Issuer != "https://accounts.google.com" {
		http.Error(w, "Wrong Issuer", http.StatusBadRequest)
		return
	}

	// IMPORTANT: you should validate claim details not covered by signature
	// and audience verification above, including:
	//   - Ensure that `payload.Claims["email"]` is equal to the expected service
	//     account set up in the push subscription settings.
	//   - Ensure that `payload.Claims["email_verified"]` is set to true.
	if payload.Claims["email"] != "test-service-account-email@example.com" || payload.Claims["email_verified"] != true {
		http.Error(w, "Unexpected email identity", http.StatusBadRequest)
		return
	}

	var pr pushRequest
	if err := json.NewDecoder(r.Body).Decode(&pr); err != nil {
		http.Error(w, fmt.Sprintf("Could not decode body: %v", err), http.StatusBadRequest)
		return
	}

	a.messagesMu.Lock()
	defer a.messagesMu.Unlock()
	// Limit to ten.
	a.messages = append(a.messages, pr.Message.Data)
	if len(a.messages) > maxMessages {
		a.messages = a.messages[len(a.messages)-maxMessages:]
	}

	fmt.Fprint(w, "OK")
}

Java

このランタイムで使用できる例はありません。

Java 8 のデモアプリはフレキシブル環境で利用可能です。

Node.js

このサンプルアプリでは、app.yaml ファイルに設定された値を使用して環境変数を構成します。push リクエスト ハンドラは、これらの値を使用して、リクエストが Pub/Sub からのものであり、信頼できる送信元から送信されていることを確認します。

// The following environment variables are set by the `app.yaml` file when
// running on App Engine, but will need to be manually set when running locally.
var PUBSUB_VERIFICATION_TOKEN = process.env.PUBSUB_VERIFICATION_TOKEN;
var pubsub = gcloud.pubsub({
    projectId: process.env.GOOGLE_CLOUD_PROJECT
});
var topic = pubsub.topic(process.env.PUBSUB_TOPIC);

このサンプルアプリは、このインスタンスで受信したメッセージをグローバル リストに保存します。

// List of all messages received by this instance
var messages = [];

このメソッドは、push されたメッセージを受信し、messages グローバル リストに追加します。

app.post('/pubsub/push', jsonBodyParser, (req, res) => {
  if (req.query.token !== PUBSUB_VERIFICATION_TOKEN) {
    res.status(400).send();
    return;
  }

  // The message is a unicode string encoded in base64.
  const message = Buffer.from(req.body.message.data, 'base64').toString(
    'utf-8'
  );

  messages.push(message);

  res.status(200).send();
});

このメソッドは、App Engine ウェブアプリと連携して新しいメッセージを公開し、受信したメッセージを表示します。

app.get('/', (req, res) => {
  res.render('index', {messages, tokens, claims});
});

app.post('/', formBodyParser, async (req, res, next) => {
  if (!req.body.payload) {
    res.status(400).send('Missing payload');
    return;
  }

  const data = Buffer.from(req.body.payload);
  try {
    const messageId = await topic.publishMessage({data});
    res.status(200).send(`Message ${messageId} sent.`);
  } catch (error) {
    next(error);
  }
});

PHP

このサンプルアプリでは、app.yaml ファイルに設定された値を使用して環境変数を構成します。push リクエスト ハンドラは、これらの値を使用して、リクエストが Pub/Sub からのものであり、信頼できる送信元から送信されていることを確認します。

runtime: php81

handlers:
- url: /pubsub\.js
  static_files: pubsub.js
  upload: pubsub\.js

このサンプルアプリは、このインスタンスで受信したメッセージをグローバル リストに保存します。

$messages = [];

pull メソッドは、作成したトピックからメッセージを取得し、メッセージ リストに追加します。

// get PULL pubsub messages
$pubsub = new PubSubClient([
    'projectId' => $projectId,
]);
$subscription = $pubsub->subscription($subscriptionName);
$pullMessages = [];
foreach ($subscription->pull(['returnImmediately' => true]) as $pullMessage) {
    $pullMessages[] = $pullMessage;
    $messages[] = $pullMessage->data();
}
// acknowledge PULL messages
if ($pullMessages) {
    $subscription->acknowledgeBatch($pullMessages);
}

publish メソッドは、新しいメッセージをトピックに公開します。

if ($message = (string) $request->getBody()) {
    // Publish the pubsub message to the topic
    $pubsub = new PubSubClient([
        'projectId' => $projectId,
    ]);
    $topic = $pubsub->topic($topicName);
    $topic->publish(['data' => $message]);
    return $response->withStatus(204);
}

Python

このサンプルアプリでは、app.yaml ファイルに設定された値を使用して環境変数を構成します。push リクエスト ハンドラは、これらの値を使用して、リクエストが Pub/Sub からのものであり、信頼できる送信元から送信されていることを確認します。

app.config['PUBSUB_VERIFICATION_TOKEN'] = \
    os.environ['PUBSUB_VERIFICATION_TOKEN']
app.config['PUBSUB_TOPIC'] = os.environ['PUBSUB_TOPIC']

このサンプルアプリは、このインスタンスで受信したメッセージをグローバル リストに保存します。

MESSAGES = []

receive_messages_handler() メソッドは、push されたメッセージを受信し、MESSAGES グローバル リストに追加します。

@app.route("/pubsub/push", methods=["POST"])
def receive_pubsub_messages_handler():
    # Verify that the request originates from the application.
    if request.args.get("token", "") != current_app.config["PUBSUB_VERIFICATION_TOKEN"]:
        return "Invalid request", 400

    envelope = json.loads(request.data.decode("utf-8"))
    payload = base64.b64decode(envelope["message"]["data"])
    MESSAGES.append(payload)
    # Returning any 2xx status indicates successful receipt of the message.
    return "OK", 200

index() メソッドは、App Engine ウェブアプリと連携して新しいメッセージを公開し、受信したメッセージを表示します。

@app.route("/", methods=["GET", "POST"])
def index():
    if request.method == "GET":
        return render_template(
            "index.html", messages=MESSAGES, tokens=TOKENS, claims=CLAIMS
        )

    data = request.form.get("payload", "Example payload").encode("utf-8")

    # Consider initializing the publisher client outside this function
    # for better latency performance.
    publisher = pubsub_v1.PublisherClient()
    topic_path = publisher.topic_path(
        app.config["GOOGLE_CLOUD_PROJECT"], app.config["PUBSUB_TOPIC"]
    )
    future = publisher.publish(topic_path, data)
    future.result()
    return "OK", 200

Ruby

このサンプルアプリでは、app.standard.yaml ファイルに設定された値を使用して環境変数を構成します。push リクエスト ハンドラは、これらの値を使用して、リクエストが Pub/Sub からのものであり、信頼できる送信元から送信されていることを確認します。

topic = pubsub.topic ENV["PUBSUB_TOPIC"]
PUBSUB_VERIFICATION_TOKEN = ENV["PUBSUB_VERIFICATION_TOKEN"]

このサンプルアプリは、このインスタンスで受信したメッセージをグローバル リストに保存します。

# List of all messages received by this instance
messages = []

このメソッドは、push されたメッセージを受信し、messages グローバル リストに追加します。

post "/pubsub/push" do
  halt 400 if params[:token] != PUBSUB_VERIFICATION_TOKEN

  message = JSON.parse request.body.read
  payload = Base64.decode64 message["message"]["data"]

  messages.push payload
end

このメソッドは、App Engine ウェブアプリと連携して新しいメッセージを公開し、受信したメッセージを表示します。

get "/" do
  @claims = claims
  @messages = messages

  slim :index
end

post "/publish" do
  topic.publish params[:payload]

  redirect "/", 303
end

サンプルのローカルでの実行

ローカルで実行する場合、Google Cloud CLI で Google Cloud APIs を使用するための認証を行うことができます。前提条件に記載されているとおりに環境をセットアップしていれば、この認証のための gcloud init コマンドはすでに実行されています。

Go

アプリケーションを起動する前に環境変数を設定します。

export GOOGLE_CLOUD_PROJECT=[your-project-id]
export PUBSUB_VERIFICATION_TOKEN=[your-token]
export PUBSUB_TOPIC=[your-topic]
go run pubsub.go

Java

アプリケーションを起動する前に環境変数を設定します。

export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]

アプリケーションをローカルで実行するには、いつも使用している開発ツールを使用します。

Node.js

アプリケーションを起動する前に環境変数を設定します。

export GOOGLE_CLOUD_PROJECT=[your-project-id]
export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]
npm install
npm start

PHP

Composer を使用して依存関係をインストールします。

composer install

次に、アプリケーションを起動する前に環境変数を設定します。

export GOOGLE_CLOUD_PROJECT=[your-project-id]
export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]
php -S localhost:8080

Python

可能であれば、依存関係を仮想環境にインストールします。

Mac OS / Linux

  1. 分離された Python 環境を作成します。
    python3 -m venv env
    source env/bin/activate
  2. 現在のディレクトリにサンプルコードが含まれていない場合は、hello_world サンプルコードが含まれるディレクトリに移動します。その後、依存関係をインストールします。
    cd YOUR_SAMPLE_CODE_DIR
    pip install -r requirements.txt

Windows

PowerShell を使用して Python パッケージを実行します。

  1. インストールされた PowerShell を探します。
  2. PowerShell へのショートカットを右クリックし、管理者として PowerShell を起動します。
  3. 分離された Python 環境を作成します。
    python -m venv env
    .\env\Scripts\activate
  4. プロジェクト ディレクトリに移動し、依存関係をインストールします。現在のディレクトリにサンプルコードが含まれていない場合は、hello_world サンプルコードが含まれるディレクトリに移動します。それから依存関係をインストールします。
    cd YOUR_SAMPLE_CODE_DIR
    pip install -r requirements.txt

次に、アプリケーションを起動する前に環境変数を設定します。

export GOOGLE_CLOUD_PROJECT=[your-project-id]
export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]
python main.py

Ruby

依存関係をインストールします。

bundle install

次に、アプリケーションを起動する前に環境変数を設定します。

export GOOGLE_CLOUD_PROJECT=[your-project-id]
export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]
bundle exec ruby app.rb -p 8080

プッシュ通知のシミュレート

アプリケーションは、ローカルでメッセージを送信できますが、push メッセージを受信することはできません。push メッセージをシミュレートするには、ローカルのプッシュ通知エンドポイントに HTTP リクエストを送信します。このサンプルには、sample_message.json というファイルが含まれています。

Go

curl または httpie クライアントを使用して、HTTP POST リクエストを送信できます。

curl -H "Content-Type: application/json" -i --data @sample_message.json "localhost:8080/push-handlers/receive_messages?token=[your-token]"

または

http POST ":8080/push-handlers/receive_messages?token=[your-token]" < sample_message.json

レスポンス:

HTTP/1.1 200 OK
Date: Tue, 13 Nov 2018 16:04:18 GMT
Content-Length: 0

リクエストの完了後、localhost:8080 を更新すると、受信メッセージのリストにメッセージが表示されます。

Java

curl または httpie クライアントを使用して、HTTP POST リクエストを送信できます。

curl -H "Content-Type: application/json" -i --data @sample_message.json "localhost:8080/push-handlers/receive_messages?token=[your-token]"

または

http POST ":8080/push-handlers/receive_messages?token=[your-token]" < sample_message.json

リクエストの完了後、localhost:8080 を更新すると、受信メッセージのリストにメッセージが表示されます。

Node.js

curl または httpie クライアントを使用して、HTTP POST リクエストを送信できます。

curl -H "Content-Type: application/json" -i --data @sample_message.json "localhost:8080/push-handlers/receive_messages?token=[your-token]"

または

http POST ":8080/push-handlers/receive_messages?token=[your-token]" < sample_message.json

レスポンス:

HTTP/1.1 200 OK
Connection: keep-alive
Date: Mon, 31 Aug 2015 22:19:50 GMT
Transfer-Encoding: chunked
X-Powered-By: Express

リクエストの完了後、localhost:8080 を更新すると、受信メッセージのリストにメッセージが表示されます。

PHP

curl または httpie クライアントを使用して、HTTP POST リクエストを送信できます。

curl -i --data @sample_message.json "localhost:4567/push-handlers/receive_messages?token=[your-token]"

または

http POST ":4567/push-handlers/receive_messages?token=[your-token]" < sample_message.json

リクエストの完了後、localhost:8080 を更新すると、受信メッセージのリストにメッセージが表示されます。

Python

curl または httpie クライアントを使用して、HTTP POST リクエストを送信できます。

curl -H "Content-Type: application/json" -i --data @sample_message.json "localhost:8080/pubsub/push?token=[your-token]"

または

http POST ":8080/pubsub/push?token=[your-token]" < sample_message.json

レスポンス:

HTTP/1.0 200 OK
Content-Length: 2
Content-Type: text/html; charset=utf-8
Date: Mon, 10 Aug 2015 17:52:03 GMT
Server: Werkzeug/0.10.4 Python/2.7.10

OK

リクエストの完了後、localhost:8080 を更新すると、受信メッセージのリストにメッセージが表示されます。

Ruby

curl または httpie クライアントを使用して、HTTP POST リクエストを送信できます。

curl -i --data @sample_message.json "localhost:4567/push-handlers/receive_messages?token=[your-token]"

または

http POST ":4567/push-handlers/receive_messages?token=[your-token]" < sample_message.json

レスポンス:

HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Content-Length: 13
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Server: WEBrick/1.3.1 (Ruby/2.3.0/2015-12-25)
Date: Wed, 20 Apr 2016 20:56:23 GMT
Connection: Keep-Alive

Hello, World!

リクエストの完了後、localhost:8080 を更新すると、受信メッセージのリストにメッセージが表示されます。

App Engine で実行する

gcloud コマンドライン ツールを使用してデモアプリを App Engine にデプロイするには:

Go

app.yaml ファイルが配置されているディレクトリから次のコマンドを実行します。

gcloud app deploy

Java

app.yaml ファイルが配置されているディレクトリから gcloud コマンドを実行します。

gcloud app deploy

Maven を使用してアプリをデプロイするには、次のコマンドを実行します。

mvn package appengine:deploy -Dapp.deploy.projectId=PROJECT_ID

PROJECT_ID は、Google Cloud プロジェクトの ID に置き換えます。pom.xml ファイルですでにプロジェクト ID を指定している場合は、実行するコマンドに -Dapp.deploy.projectId プロパティを含める必要はありません。

Node.js

app.yaml ファイルが配置されているディレクトリから次のコマンドを実行します。

gcloud app deploy

PHP

app.yaml ファイルが配置されているディレクトリから次のコマンドを実行します。

gcloud app deploy

Python

app.yaml ファイルが配置されているディレクトリから次のコマンドを実行します。

gcloud app deploy

Ruby

app.yaml ファイルが配置されているディレクトリから次のコマンドを実行します。

gcloud app deploy app.standard.yaml

これで、https://PROJECT_ID.REGION_ID.r.appspot.com のアプリケーションにアクセスできます。フォームを使用してメッセージを送信できますが、アプリケーションのどのインスタンスが通知を受信するかはわかりません。複数のメッセージを送信してページを更新すると、受信メッセージを確認できます。