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

リージョン ID

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

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

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

このドキュメントでは、Cloud クライアント ライブラリ

前提条件

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

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

Go

v1.18 以降

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git
    cd golang-samples/appengine_flexible/pubsub

v1.15 以前

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git
    cd golang-samples/appengine_flexible/go115_and_earlier/pubsub

Java

バージョン 11 / 17

git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/flexible/java-11/pubsub/

バージョン 8

git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/flexible/java-8/pubsub/

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

v3.8 以降

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

v3.7 以前

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

Ruby

バージョン 3.2

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

バージョン 3.1 以前

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

.NET

バージョン 6

git clone  https://github.com/GoogleCloudPlatform/dotnet-docs-samples
cd dotnet-docs-samples/appengine/flexible/Pubsub/Pubsub.Sample

バージョン 3.1 以前

git clone https://github.com/GoogleCloudPlatform/dotnet-docs-samples
git checkout flex-dotnet3-and-earlier
cd dotnet-docs-samples/appengine/flexible/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 は、サービス アカウントのメールアドレスに置き換えます。

.NET

# 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 ファイルを編集して、トピックと検証トークンの各環境変数を設定します。

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-token

Java

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>

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: 1234abc

Ruby

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

env_variables:
    PUBSUB_TOPIC: <pubsub-topic-name>
    # This token is used to verify that requests originate from your
    # application. It can be any sufficiently random string.
    PUBSUB_VERIFICATION_TOKEN: <verification-token>

.NET

バージョン 6

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

runtime: aspnetcore
env: flex

runtime_config:
  operating_system: ubuntu22

env_variables:
  TEST_PROJECT_ID: your-project-id
  TEST_VERIFICATION_TOKEN: your-token
  TEST_TOPIC_ID: your-topic
  TEST_SUBSCRIPTION_ID: your-sub
  TEST_AUTH_SUBSCRIPTION_ID: your-auth-sub
  TEST_SERVICE_ACCOUNT_EMAIL: your-service-account-email

バージョン 3.1 以前

appsettings.json ファイルを編集して、プロジェクト ID を設定します。

{
  "Pubsub": {
    "ProjectId": "your-project-id",
    "VerificationToken": "your-secret-token",
    "TopicId": "your-topic",
    "SubscriptionId": "your-subscription",
    "AuthSubscriptionId": "your-auth-subscription",
    "ServiceAccountEmail": "your-service-account-email"
  },

  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

コードのレビュー

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

Go

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

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

messages   []string

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


func pushHandler(w http.ResponseWriter, r *http.Request) {
	// Verify the token.
	if r.URL.Query().Get("token") != token {
		http.Error(w, "Bad token", http.StatusBadRequest)
		return
	}
	msg := &pushRequest{}
	if err := json.NewDecoder(r.Body).Decode(msg); err != nil {
		http.Error(w, fmt.Sprintf("Could not decode body: %v", err), http.StatusBadRequest)
		return
	}

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

publishHandler 関数は、新しいメッセージをトピックに公開します。


func publishHandler(w http.ResponseWriter, r *http.Request) {
	ctx := context.Background()

	msg := &pubsub.Message{
		Data: []byte(r.FormValue("payload")),
	}

	if _, err := topic.Publish(ctx, msg).Get(ctx); err != nil {
		http.Error(w, fmt.Sprintf("Could not publish message: %v", err), 500)
		return
	}

	fmt.Fprint(w, "Message published.")
}

Java

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

String pubsubVerificationToken = System.getenv("PUBSUB_VERIFICATION_TOKEN");

このサンプルアプリでは、メッセージを格納する Cloud Datastore データベース インスタンスを保守します。サーブレット PubSubPush は、push されたメッセージを受信して、messageRepository データベース インスタンスに追加します。

バージョン 11 / 17

@WebServlet(value = "/pubsub/push")
@MultipartConfig()
public class PubSubPush extends HttpServlet {

  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    String pubsubVerificationToken = System.getenv("PUBSUB_VERIFICATION_TOKEN");
    // Do not process message if request token does not match pubsubVerificationToken
    if (pubsubVerificationToken == null
        || pubsubVerificationToken.compareTo(req.getParameter("token")) != 0) {
      resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
      return;
    }
    // parse message object from "message" field in the request body json
    // decode message data from base64
    Message message = getMessage(req);
    try {
      messageRepository.save(message);
      // 200, 201, 204, 102 status codes are interpreted as success by the Pub/Sub system
      resp.setStatus(HttpServletResponse.SC_OK);
    } catch (Exception e) {
      System.out.println(e);
      resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
  }

バージョン 8

@WebServlet(value = "/pubsub/push")
public class PubSubPush extends HttpServlet {

  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    String pubsubVerificationToken = System.getenv("PUBSUB_VERIFICATION_TOKEN");
    // Do not process message if request token does not match pubsubVerificationToken
    if (req.getParameter("token").compareTo(pubsubVerificationToken) != 0) {
      resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
      return;
    }
    // parse message object from "message" field in the request body json
    // decode message data from base64
    Message message = getMessage(req);
    try {
      messageRepository.save(message);
      // 200, 201, 204, 102 status codes are interpreted as success by the Pub/Sub system
      resp.setStatus(HttpServletResponse.SC_OK);
    } catch (Exception e) {
      resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
  }

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

@WebServlet(name = "Publish with PubSub", value = "/pubsub/publish")
public class PubSubPublish extends HttpServlet {

  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    Publisher publisher = this.publisher;
    try {
      String topicId = System.getenv("PUBSUB_TOPIC");
      // create a publisher on the topic
      if (publisher == null) {
        publisher = Publisher.newBuilder(
            ProjectTopicName.of(ServiceOptions.getDefaultProjectId(), topicId))
            .build();
      }
      // construct a pubsub message from the payload
      final String payload = req.getParameter("payload");
      PubsubMessage pubsubMessage =
          PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8(payload)).build();

      publisher.publish(pubsubMessage);
      // redirect to home page
      resp.sendRedirect("/");
    } catch (Exception e) {
      resp.sendError(HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage());
    }
  }

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: php
env: flex

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

$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 = []

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

@app.route("/pubsub/push", methods=["POST"])
def pubsub_push():
    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)

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

    # publisher = pubsub_v1.PublisherClient()
    topic_path = publisher.topic_path(
        current_app.config["PROJECT"], current_app.config["PUBSUB_TOPIC"]
    )

    publisher.publish(topic_path, data=data)

    return "OK", 200

Ruby

このサンプルアプリでは、app.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

.NET

バージョン 6

[HttpGet]
[HttpPost]
public async Task<IActionResult> IndexAsync(MessageForm messageForm)
{
    var model = new MessageList();
    if (!_options.HasGoodProjectId())
    {
        model.MissingProjectId = true;
        return View(model);
    }
    if (!string.IsNullOrEmpty(messageForm.Message))
    {
        // Publish the message.
        var pubsubMessage = new PubsubMessage()
        {
            Data = ByteString.CopyFromUtf8(messageForm.Message)
        };
        pubsubMessage.Attributes["token"] = _options.VerificationToken;
        await _publisher.PublishAsync(pubsubMessage);
        model.PublishedMessage = messageForm.Message;
    }
    // Render the current list of messages.
    model.Messages = s_receivedMessages.ToArray();
    model.AuthMessages = s_authenticatedMessages.ToArray();
    return View(model);
}

バージョン 3.1 以前

[HttpGet]
[HttpPost]
public IActionResult Index(MessageForm messageForm)
{
    var model = new MessageList();
    if (!_options.HasGoodProjectId())
    {
        model.MissingProjectId = true;
        return View(model);
    }
    if (!string.IsNullOrEmpty(messageForm.Message))
    {
        // Publish the message.
        var pubsubMessage = new PubsubMessage()
        {
            Data = ByteString.CopyFromUtf8(messageForm.Message)
        };
        pubsubMessage.Attributes["token"] = _options.VerificationToken;
        _publisher.PublishAsync(pubsubMessage);
        model.PublishedMessage = messageForm.Message;
    }
    // Render the current list of messages.
    model.Messages = s_receivedMessages.ToArray();
    model.AuthMessages = s_authenticatedMessages.ToArray();
    return View(model);
}

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

ローカルで実行する場合、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

mvn clean package

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

export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]
mvn jetty:run

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

.NET

アプリケーションのルート ディレクトリから次のコマンドを実行します。

    dotnet restore
    dotnet run

ウェブブラウザに「http://localhost:5000/」と入力します。ウェブサーバーを終了するには、ターミナル ウィンドウで Ctrl+C キーを押します。

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

アプリケーションは、ローカルでメッセージを送信できますが、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

レスポンス:

HTTP/1.1 200 OK
Date: Wed, 26 Apr 2017 00:03:28 GMT
Content-Length: 0
Server: Jetty(9.3.8.v20160314)

リクエストの完了後、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 を更新すると、受信メッセージのリストにメッセージが表示されます。

.NET

HTTP POST リクエストを送信するには、次のコマンドを実行します。

Get-Content -Raw .\sample_message.json | Invoke-WebRequest -Uri
http://localhost:5000/Push?token=your-secret-token -Method POST -ContentType
'text/json' -OutFile out.txt

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

App Engine で実行する

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

Go

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

gcloud app deploy

Java

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.yaml

.NET

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

gcloud app deploy

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