बिड करने वालों के लिए क्रिएटिव मैनेज करना

बिडिंग करने वाले के तौर पर, ये काम किए जा सकते हैं:

सबमिट किए गए क्रिएटिव की सूची बनाएं

सबमिट किए गए क्रिएटिव की सूची देखने के दो तरीके हैं:

  • bidders.creatives.list: इसमें, फ़िल्टर करने के बेहतर विकल्प उपलब्ध हैं.
  • Pub/Sub इंटिग्रेशन: इसमें क्रिएटिव की सबसे नई स्थिति शामिल है.

सूची बनाने का तरीका

यहां बताया गया है कि bidders.creatives.list की मदद से, बिडिंग करने वाले किसी खास व्यक्ति के लिए, क्रिएटिव की सूची कैसे हासिल की जा सकती है.

इस तरीके से, सूची फ़िल्टर की जा सकती है. अगर फ़िल्टर का इस्तेमाल नहीं किया जाता है, तो buyers.creatives.list बिड करने वाले के खाते से जुड़े सभी खरीदारों के सभी क्रिएटिव दिखाता है.

जब तक view पैरामीटर को FULL के तौर पर न बताया गया हो, तब तक रिस्पॉन्स में creativeServingDecision के अलावा, ज़्यादातर फ़ील्ड शामिल नहीं होते.

बड़ी संख्या में क्रिएटिव के लिए इस कॉल को पूरा होने में कई घंटे लग सकते हैं. ओपन बिडिंग के लिए यह आम बात है. आपको इस कॉल के लिए एक लंबा टाइम आउट कॉन्फ़िगर करना पड़ सकता है, 5 मिनट तक.

यह तरीका अनुरोध करने पर क्रिएटिव का एक स्नैपशॉट दिखाता है. बड़े और पेजों में नंबर वाले अनुरोधों के लिए, पहले पेज के लिए अनुरोध करते समय स्नैपशॉट लिया जाता है. बड़े और पेजों वाले अनुरोधों को प्रोसेस करने में लगने वाले समय की वजह से, आपको जवाब मिलने तक, क्रम में चलने वाले पेजों पर creativeServingDecision और lastStatusUpdate फ़ील्ड बदल सकते हैं.

स्नैपशॉट के बाद होने वाले अपडेट, रिस्पॉन्स के तौर पर कैप्चर नहीं किए जाते. इसका मतलब है कि शायद इस जवाब में बड़े और कई पेजों वाले अनुरोधों के लिए नई जानकारी शामिल न हो. अगर आपको creativeServingDecision और lastStatusUpdate की नई वैल्यू की ज़रूरत है, तो हमारा सुझाव है कि Google Cloud Pub/Sub के साथ इंटिग्रेट करें.

यहां bidders.creatives.list कॉल के कुछ सैंपल दिए गए हैं:

आराम

अनुरोध

GET https://realtimebidding.googleapis.com/v1/bidders/<INSERT_ACCOUNT_ID_HERE>/creatives?filter=creativeServingDecision.networkPolicyCompliance.status%3DAPPROVED+AND+creativeFormat%3DHTML&view=FULL&pageSize=3&alt=json
Authorization: Bearer <INSERT_ACCESS_TOKEN_HERE>
Content-Type: application/json

जवाब

{
  "creatives": [
    {
      "name": "buyers/<ACCOUNT_ID1>/creatives/HTML_Creative_89d53648-1e9d-428e-bd60-06f8f81d8a0d",
      "accountId": "<ACCOUNT_ID1>",
      "creativeId": "HTML_Creative_89d53648-1e9d-428e-bd60-06f8f81d8a0d",
      "html": {
        "snippet": "<iframe marginwidth=0 marginheight=0 height=600 frameborder=0 width=160 scrolling=no src=\\\"https://test.com/ads?id=123456&curl=%%CLICK_URL_ESC%%&wprice=%%WINNING_PRICE_ESC%%\\\"></iframe>",
        "width": 300,
        "height": 250
      },
      "creativeFormat": "HTML",
      "declaredClickThroughUrls": [
        "http://test.com"
      ],
      "declaredAttributes": [
        "CREATIVE_TYPE_HTML"
      ],
      "advertiserName": "Test",
      "apiUpdateTime": "2020-07-17T23:34:48.072475Z",
      "activityMetrics": {
        "yesterday": {
          "spend": {
            "currencyCode": "USD"
          },
          "forgoneSpend": {
            "currencyCode": "USD"
          }
        },
        "last7Days": {
          "spend": {
            "currencyCode": "USD"
          },
          "forgoneSpend": {
            "currencyCode": "USD"
          }
        }
      },
      "previewUrl": "https://storage.googleapis.com/g-authorized-buyers-creative-previews/lVljTKfc2vIA0JiMoEawKsslu5cWrXgD_tuFwRADsyinpD5J2XYMX7eNAwQ",
      "creativeServingDecision": {
        "detectedProductCategories": [
          10016,
          10019,
          10141,
          10168,
          10754,
          10885,
          12206
        ],
        "detectedLanguages": [
          "en"
        ],
        "detectedAttributes": [
          "CREATIVE_TYPE_HTML"
        ],
        "lastStatusUpdate": "2020-07-18T08:24:46.847935Z",
        "dealsPolicyCompliance": {
          "status": "APPROVED"
        },
        "networkPolicyCompliance": {
          "status": "APPROVED"
        },
        "platformPolicyCompliance": {
          "status": "APPROVED"
        },
        "chinaPolicyCompliance": {
          "status": "DISAPPROVED"
        },
        "russiaPolicyCompliance": {
          "status": "DISAPPROVED"
        }
      }
    },
    {
      "name": "buyers/<ACCOUNT_ID2>/creatives/HTML_Creative_ac0770fa-5294-4571-856e-9ec6f613e590",
      "accountId": "<ACCOUNT_ID2>",
      "creativeId": "HTML_Creative_ac0770fa-5294-4571-856e-9ec6f613e590",
      "html": {
        "snippet": "<iframe marginwidth=0 marginheight=0 height=600 frameborder=0 width=160 scrolling=no src=\"https://test.com/ads?id=123456&curl=%%CLICK_URL_ESC%%&wprice=%%WINNING_PRICE_ESC%%\"></iframe>",
        "width": 300,
        "height": 250
      },
      "creativeFormat": "HTML",
      "declaredClickThroughUrls": [
        "test.com"
      ],
      "declaredAttributes": [
        "CREATIVE_TYPE_HTML"
      ],
      "advertiserName": "Test",
      "apiUpdateTime": "2020-07-15T21:24:10.269378Z",
      "activityMetrics": {
        "yesterday": {
          "spend": {
            "currencyCode": "USD"
          },
          "forgoneSpend": {
            "currencyCode": "USD"
          }
        },
        "last7Days": {
          "spend": {
            "currencyCode": "USD"
          },
          "forgoneSpend": {
            "currencyCode": "USD"
          }
        }
      },
      "previewUrl": "https://storage.googleapis.com/g-authorized-buyers-creative-previews/hedyN-6bCXEA0JiMoD8I704lPjLIl_-GXo7AOqBnWQJaOnuH6w6hUWzre2A",
      "creativeServingDecision": {
        "detectedProductCategories": [
          10016,
          10019,
          10141,
          10168,
          10754,
          10885,
          12206
        ],
        "detectedLanguages": [
          "en"
        ],
        "detectedAttributes": [
          "CREATIVE_TYPE_HTML"
        ],
        "lastStatusUpdate": "2020-07-15T22:02:39.925606Z",
        "dealsPolicyCompliance": {
          "status": "APPROVED"
        },
        "networkPolicyCompliance": {
          "status": "APPROVED"
        },
        "platformPolicyCompliance": {
          "status": "APPROVED"
        },
        "chinaPolicyCompliance": {
          "status": "APPROVED"
        },
        "russiaPolicyCompliance": {
          "status": "APPROVED"
        }
      }
    },
    {
      "name": "buyers/<ACCOUNT_ID3>/creatives/HTML_Creative_83fb53fa-e8be-42f8-88cd-30453f04ab9b",
      "accountId": "<ACCOUNT_ID3>",
      "creativeId": "HTML_Creative_83fb53fa-e8be-42f8-88cd-30453f04ab9b",
      "html": {
        "snippet": "<iframe marginwidth=0 marginheight=0 height=600 frameborder=0 width=160 scrolling=no\n    src=\"https://test.com/ads?id=123456&curl=%%CLICK_URL_ESC%%&wprice=%%WINNING_PRICE_ESC%%\">\n</iframe>\n",
        "width": 300,
        "height": 250
      },
      "creativeFormat": "HTML",
      "declaredClickThroughUrls": [
        "http://test.com"
      ],
      "declaredAttributes": [
        "CREATIVE_TYPE_HTML"
      ],
      "advertiserName": "Test",
      "version": 1,
      "apiUpdateTime": "2020-07-23T20:41:48.420172Z",
      "activityMetrics": {
        "yesterday": {
          "spend": {
            "currencyCode": "USD"
          },
          "forgoneSpend": {
            "currencyCode": "USD"
          }
        },
        "last7Days": {
          "spend": {
            "currencyCode": "USD"
          },
          "forgoneSpend": {
            "currencyCode": "USD"
          }
        }
      },
      "previewUrl": "https://storage.googleapis.com/g-authorized-buyers-creative-previews/vm8sg3ISJRsA0JiMoAT89KJdex1E9Bq9dPyRUSL9g9pu4P73NbwJOUM_G2U",
      "creativeServingDecision": {
        "detectedProductCategories": [
          10016,
          10019,
          10141,
          10168,
          10754,
          10885,
          12206
        ],
        "detectedLanguages": [
          "en"
        ],
        "detectedAttributes": [
          "CREATIVE_TYPE_HTML"
        ],
        "lastStatusUpdate": "2020-07-23T21:29:31.105040Z",
        "dealsPolicyCompliance": {
          "status": "APPROVED"
        },
        "networkPolicyCompliance": {
          "status": "APPROVED"
        },
        "platformPolicyCompliance": {
          "status": "APPROVED"
        },
        "chinaPolicyCompliance": {
          "status": "APPROVED"
        },
        "russiaPolicyCompliance": {
          "status": "APPROVED"
        }
      }
    }
  ],
  "nextPageToken": "CnkKTPcAAAAA_____4AA__8AAP__AAD__wAA__8AAP__AAD__wAA__8AAP8B__5zbi01MzcyODQxMC03NTc4NzQ1OTI4MDI0NTAwODAxAAEQAyEEJCN6EliW_DkAAAAA_____0gDUABaCwntdJgOpe997BADYNmu5KoFGlhjcmVhdGl2ZVNlcnZpbmdEZWNpc2lvbi5vcGVuQXVjdGlvblNlcnZpbmdTdGF0dXMuc3RhdHVzPUFQUFJPVkVEIEFORCBjcmVhdGl2ZUZvcm1hdD1IVE1MII6l_Yzxh-sC",
  "totalSize": 25
}

C#

/* 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
 *
 *     http://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.
 */

using Google.Apis.RealTimeBidding.v1;
using Google.Apis.RealTimeBidding.v1.Data;
using Mono.Options;

using System;
using System.Collections.Generic;

namespace Google.Apis.RealTimeBidding.Examples.v1.Bidders.Creatives
{
    /// <summary>
    /// Lists creatives for a given bidder account ID.
    /// </summary>
    public class ListCreatives : ExampleBase
    {
        private RealTimeBiddingService rtbService;

        /// <summary>
        /// Constructor.
        /// </summary>
        public ListCreatives()
        {
            rtbService = Utilities.GetRealTimeBiddingService();
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get => "This code example lists all creatives for a given bidder account.";
        }

        /// <summary>
        /// Parse specified arguments.
        /// </summary>
        protected override Dictionary<string, object> ParseArguments(List<string> exampleArgs) {
            string[] requiredOptions = new string[] {"account_id"};
            bool showHelp = false;
            string defaultFilter = "creativeServingDecision.networkPolicyCompliance.status=" +
                                   "APPROVED AND creativeFormat=HTML";
            string accountId = null;
            string filter = null;
            int? pageSize = null;
            string view = null;

            OptionSet options = new OptionSet {
                "List creatives for the given buyer account.",
                {
                    "h|help",
                    "Show help message and exit.",
                    h => showHelp = h != null
                },
                {
                    "a|account_id=",
                    ("[Required] The resource ID of the bidders resource under which the " +
                     "creatives were created. This will be used to construct the parent used as " +
                     "a path parameter for the creatives.list request."),
                    a => accountId = a
                },
                {
                    "p|page_size=",
                    ("The number of rows to return per page. The server may return fewer rows " +
                     "than specified."),
                    (int p) => pageSize =  p
                },
                {
                    "f|filter=",
                    ("Query string to filter creatives. If no filter is specified, all active " +
                     "creatives will be returned. To demonstrate usage, the default behavior of" +
                     "this sample is to filter such that only approved HTML snippet creatives " +
                     "are returned."),
                    f => filter = f
                },
                {
                    "v|view=",
                    ("Controls the amount of information included in the response. By default, " +
                     "the creatives.list method only includes creativeServingDecision. This " +
                     "sample configures the view to return the full contents of the creatives " +
                     @"by setting this to ""FULL""."),
                    v => view = v
                },
            };

            List<string> extras = options.Parse(exampleArgs);
            var parsedArgs = new Dictionary<string, object>();

            // Show help message.
            if(showHelp == true)
            {
                options.WriteOptionDescriptions(Console.Out);
                Environment.Exit(0);
            }
            // Set arguments.
            parsedArgs["account_id"] = accountId;
            parsedArgs["page_size"] = pageSize ?? Utilities.MAX_PAGE_SIZE;
            parsedArgs["filter"] = filter ?? defaultFilter;
            parsedArgs["view"] = view ?? "FULL";
            // Validate that options were set correctly.
            Utilities.ValidateOptions(options, parsedArgs, requiredOptions, extras);

            return parsedArgs;
        }

        /// <summary>
        /// Run the example.
        /// </summary>
        /// <param name="parsedArgs">Parsed arguments for the example.</param>
        protected override void Run(Dictionary<string, object> parsedArgs)
        {
            string accountId = (string) parsedArgs["account_id"];
            string parent = $"bidders/{accountId}";
            string pageToken = null;

            Console.WriteLine(@"Listing creatives for bidder account ""{0}""", parent);
            do
            {
                BiddersResource.CreativesResource.ListRequest request =
                   rtbService.Bidders.Creatives.List(parent);
                request.Filter = (string) parsedArgs["filter"];
                request.PageSize = (int) parsedArgs["page_size"];
                request.PageToken = pageToken;
                request.View = (BiddersResource.CreativesResource.ListRequest.ViewEnum) Enum.Parse(
                    typeof(BiddersResource.CreativesResource.ListRequest.ViewEnum),
                    (string) parsedArgs["view"],
                    false);

                ListCreativesResponse page = null;

                try
                {
                    page = request.Execute();
                }
                catch (System.Exception exception)
                {
                    throw new ApplicationException(
                        $"Real-time Bidding API returned error response:\n{exception.Message}");
                }

                var creatives = page.Creatives;
                pageToken = page.NextPageToken;

                if(creatives == null)
                {
                    Console.WriteLine("No creatives found for buyer account.");
                }
                else
                {
                    foreach (Creative creative in creatives)
                        {
                            Utilities.PrintCreative(creative);
                        }
                }
            }
            while(pageToken != null);
        }
    }
}

Java

/*
 * 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.
 */

package com.google.api.services.samples.authorizedbuyers.realtimebidding.v1.bidders.creatives;

import com.google.api.services.realtimebidding.v1.RealTimeBidding;
import com.google.api.services.realtimebidding.v1.model.Creative;
import com.google.api.services.realtimebidding.v1.model.ListCreativesResponse;
import com.google.api.services.samples.authorizedbuyers.realtimebidding.Utils;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.List;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;

/**
 * This sample illustrates how to list Creatives for a given bidder account ID.
 *
 * <p>Note that unless filtered, this will include creatives from all buyer accounts under the
 * bidder.
 */
public class ListCreatives {

  public static void execute(RealTimeBidding client, Namespace parsedArgs) throws IOException {
    Long accountId = parsedArgs.getLong("account_id");
    Integer pageSize = parsedArgs.getInt("page_size");
    String parentBuyerName = String.format("bidders/%s", accountId);
    String pageToken = null;

    System.out.printf("Found Creatives for bidder Account ID '%d':\n", accountId);

    do {
      List<Creative> creatives = null;

      ListCreativesResponse response =
          client
              .bidders()
              .creatives()
              .list(parentBuyerName)
              .setFilter(parsedArgs.getString("filter"))
              .setView(parsedArgs.getString("view"))
              .setPageSize(pageSize)
              .setPageToken(pageToken)
              .execute();

      creatives = response.getCreatives();
      pageToken = response.getNextPageToken();

      if (creatives == null) {
        System.out.println("No creatives found.");
      } else {
        for (Creative creative : creatives) {
          Utils.printCreative(creative);
        }
      }
    } while (pageToken != null);
  }

  public static void main(String[] args) {
    ArgumentParser parser =
        ArgumentParsers.newFor("ListCreatives")
            .build()
            .defaultHelp(true)
            .description(("Lists creatives for the given bidder account."));
    parser
        .addArgument("-a", "--account_id")
        .help(
            "The resource ID of the bidders resource under which the creatives were created by"
                + " buyers. This will be used to construct the parent used as a path parameter for"
                + " the creatives.list request.")
        .required(true)
        .type(Long.class);
    parser
        .addArgument("-p", "--page_size")
        .help(
            "The resource ID of the buyers resource under which the user lists were created. "
                + "This will be used to construct the parent used as a path parameter for the "
                + "userLists.list request.")
        .setDefault(Utils.getMaximumPageSize())
        .type(Integer.class);
    parser
        .addArgument("-f", "--filter")
        .help(
            "Query string to filter creatives. If no filter is specified, all active creatives will"
                + " be returned. To demonstrate usage, the default behavior of this sample is to"
                + " filter such that only approved HTML snippet creatives are returned.")
        .setDefault(
            "creativeServingDecision.networkPolicyCompliance.status=APPROVED "
                + "AND creativeFormat=HTML");
    parser
        .addArgument("-v", "--view")
        .help(
            "Controls the amount of information included in the response. By default, the"
                + " creatives.list method only includes creativeServingDecision. This sample"
                + " configures the view to return the full contents of the creatives by setting"
                + " this to 'FULL'.")
        .choices("FULL", "SERVING_DECISION_ONLY")
        .setDefault("FULL");

    Namespace parsedArgs = null;
    try {
      parsedArgs = parser.parseArgs(args);
    } catch (ArgumentParserException ex) {
      parser.handleError(ex);
      System.exit(1);
    }

    RealTimeBidding client = null;
    try {
      client = Utils.getRealTimeBiddingClient();
    } catch (IOException ex) {
      System.out.printf("Unable to create RealTimeBidding API service:\n%s", ex);
      System.out.println("Did you specify a valid path to a service account key file?");
      System.exit(1);
    } catch (GeneralSecurityException ex) {
      System.out.printf("Unable to establish secure HttpTransport:\n%s", ex);
      System.exit(1);
    }

    try {
      execute(client, parsedArgs);
    } catch (IOException ex) {
      System.out.printf("RealTimeBidding API returned error response:\n%s", ex);
      System.exit(1);
    }
  }
}

PHP

<?php

/**
 * 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.
 */

namespace Google\Ads\AuthorizedBuyers\RealTimeBidding\Examples\V1\Bidders_Creatives;

use Google\Ads\AuthorizedBuyers\RealTimeBidding\ExampleUtil\BaseExample;
use Google\Ads\AuthorizedBuyers\RealTimeBidding\ExampleUtil\Config;

/**
 * This example illustrates how to list creatives for the given bidder's account ID.
 *
 * Note that unless filtered, this will include creatives from all buyer accounts under the
 * bidder.
 */
class ListCreatives extends BaseExample
{

    public function __construct($client)
    {
        $this->service = Config::getGoogleServiceRealTimeBidding($client);
    }

    /**
     * @see BaseExample::getInputParameters()
     */
    protected function getInputParameters()
    {
        return [
            [
                'name' => 'account_id',
                'display' => 'Bidder account ID',
                'required' => true,
                'description' =>
                    'The resource ID of the bidders resource under which the creatives were ' .
                    'created. This will be used to construct the parent used as a path ' .
                    'parameter for the creatives.list request.'
            ],
            [
                'name' => 'filter',
                'display' => 'Filter',
                'required' => false,
                'description' =>
                    'Query string to filter creatives. If no filter is specified, all active ' .
                    'creatives will be returned. To demonstrate usage, the default behavior of ' .
                    'this sample is to filter such that only approved HTML snippet creatives ' .
                    'are returned.',
                'default' =>
                    'creativeServingDecision.networkPolicyCompliance.status=APPROVED ' .
                    'AND creativeFormat=HTML'
            ],
            [
                'name' => 'view',
                'display' => 'View',
                'required' => false,
                'description' =>
                    'Controls the amount of information included in the response. By default, ' .
                    'the creatives.list method only includes creativeServingDecision. This ' .
                    'sample configures the view to return the full contents of the creatives by ' .
                    'setting this to "FULL".',
                'default' => 'FULL'
            ]
        ];
    }

    /**
     * @see BaseExample::run()
     */
    public function run()
    {
        $values = $this->formValues;

        $parentName = "bidders/$values[account_id]";

        $queryParams = [
            'filter' => $values['filter'],
            'pageSize' => 10,
            'view' => $values['view']
        ];

        $result = $this->service->bidders_creatives->listBiddersCreatives($parentName, $queryParams);

        print "<h2>Creatives found for '$parentName':</h2>";
        if (empty($result['creatives'])) {
            print '<p>No Creatives found</p>';
        } else {
            foreach ($result['creatives'] as $creative) {
                $this->printResult($creative);
            }
        }
    }

    /**
     * @see BaseExample::getName()
     */
    public function getName()
    {
        return 'List Bidder Creatives';
    }
}

Python

#!/usr/bin/python
#
# Copyright 2020 Google Inc. All Rights Reserved.
#
# 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
#
#      http://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.

"""Lists creatives for the given bidder's account ID.

Note that unless filtered, this will include creatives from all buyer accounts
under the bidder.
"""


import argparse
import os
import pprint
import sys

sys.path.insert(0, os.path.abspath('../../..'))

from googleapiclient.errors import HttpError

import util


_BIDDER_NAME_TEMPLATE = 'bidders/%s'

DEFAULT_BIDDER_RESOURCE_ID = 'ENTER_BIDDER_RESOURCE_ID_HERE'


def main(realtimebidding, args):
  account_id = args.account_id
  list_filter = args.filter
  view = args.view
  page_size = args.page_size

  page_token = None
  more_pages = True

  print(f'Listing creatives for bidder account: "{account_id}".')
  while more_pages:
    try:
      # Construct and execute the request.
      response = realtimebidding.bidders().creatives().list(
          parent=_BIDDER_NAME_TEMPLATE % account_id, pageToken=page_token,
          filter=list_filter, view=view, pageSize=page_size).execute()
    except HttpError as e:
      print(e)
      sys.exit(1)

    pprint.pprint(response)

    page_token = response.get('nextPageToken')
    more_pages = bool(page_token)


if __name__ == '__main__':
  try:
    service = util.GetService(version='v1')
  except IOError as ex:
    print(f'Unable to create realtimebidding service - {ex}')
    print('Did you specify the key file in util.py?')
    sys.exit(1)

  default_list_filter = (
      'creativeServingDecision.networkPolicyCompliance.status=APPROVED '
      'AND creativeFormat=HTML')

  parser = argparse.ArgumentParser(
      description=('Lists creatives for the given bidder account.'))
  # Required fields.
  parser.add_argument(
      '-a', '--account_id', default=DEFAULT_BIDDER_RESOURCE_ID,
      help=('The resource ID of the bidders resource under which the '
            'creatives were created by a buyer. This will be used to '
            'construct the parent used as a path parameter for the '
            'creatives.list request.'))
  parser.add_argument(
      '-p', '--page_size', default=util.MAX_PAGE_SIZE,
      help=('The number of rows to return per page. The server may return '
            'fewer rows than specified.'))
  # Optional fields.
  parser.add_argument(
      '-f', '--filter', default=default_list_filter,
      help=('Query string to filter creatives. If no filter is specified, all '
            'active creatives will be returned. To demonstrate usage, the '
            'default behavior of this sample is to filter such that only '
            'approved HTML snippet creatives are returned.'))
  parser.add_argument(
      '-v', '--view', default='FULL',
      help=('Controls the amount of information included in the response. By '
            'default, the creatives.list method only includes '
            'creativeServingDecision. This sample configures the view to '
            'return the full contents of the creatives by setting this to '
            '"FULL".'))

  args = parser.parse_args()

  main(service, args)


Ruby

#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright:: Copyright 2020 Google LLC
#
# License:: 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
#
#           http://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.
#
# Lists creatives for the given bidder's account ID.
#
# Note that unless filtered, this will include creatives from all buyer
# accounts under the bidder.

require 'optparse'

require_relative '../../../util'


def list_creatives(realtimebidding, options)
  parent = "bidders/#{options[:account_id]}"
  filter = options[:filter]
  view = options[:view]
  page_size = options[:page_size]

  page_token = nil

  puts "Listing creatives for bidder account '#{parent}'"
  begin
    response = realtimebidding.list_bidder_creatives(
        parent, filter: filter, view: view, page_size: page_size, page_token: page_token
    )

    page_token = response.next_page_token

    unless response.creatives.nil?
      response.creatives.each do |creative|
        print_creative(creative)
      end
    else
      puts 'No creatives found for buyer account'
    end
  end until page_token == nil
end


if __FILE__ == $0
  begin
    # Retrieve the service used to make API requests.
    service = get_service()
  rescue ArgumentError => e
    raise 'Unable to create service, with error message: #{e.message}'
  rescue Signet::AuthorizationError => e
    raise 'Unable to create service, was the KEY_FILE in util.rb set? Error message: #{e.message}'
  end

  default_list_filter = 'creativeServingDecision.networkPolicyCompliance'\
                        '.status=APPROVED AND creativeFormat=HTML'

  # Set options and default values for fields used in this example.
  options = [
    Option.new(
      'account_id',
      'The resource ID of the bidders resource under which the creatives were created, This will be used to '\
      'construct the parent used as a path parameter for the creatives.list request.',
      type: Integer, short_alias: 'a', required: true, default_value: nil
    ),
    Option.new(
      'filter',
      'Query string to filter creatives. If no filter is specified, all active creatives will be returned. To '\
      'demonstrate usage, the default behavior of this sample is to filter such that only approved HTML snippet '\
      'creatives are returned.',
      short_alias: 'f', required: false, default_value: default_list_filter
    ),
    Option.new(
      'view',
      'Controls the amount of information included in the response. By default, the creatives.list method only '\
      'includes creativeServingDecision. This sample configures the view to return the full contents of creatives by '\
      'setting this to FULL.',
      short_alias: 'v', required: false, default_value: 'FULL'
    ),
    Option.new(
      'page_size', 'The number of rows to return per page. The server may return fewer rows than specified.',
      type: Array, short_alias: 'u', required: false, default_value: MAX_PAGE_SIZE
    ),
  ]

  # Parse options.
  parser = Parser.new(options)
  opts = parser.parse(ARGV)

  begin
    list_creatives(service, opts)
  rescue Google::Apis::ServerError => e
    raise "The following server error occured:\n#{e.message}"
  rescue Google::Apis::ClientError => e
    raise "Invalid client request:\n#{e.message}"
  rescue Google::Apis::AuthorizationError => e
    raise "Authorization error occured:\n#{e.message}"
  end
end

Pub/Sub इंटिग्रेशन

creativeServingDecision और lastStatusUpdate जैसे कुछ फ़ील्ड समय के साथ बदलते रहते हैं. अगर आपको सबमिट किए गए क्रिएटिव की हाल की स्थिति के बारे में जानना है, तो Google Cloud Pub/Sub का इस्तेमाल करें.

अपने Authorized Buyers समाधान को Google Cloud Pub/Sub के साथ इंटिग्रेट करके, आप क्रिएटिव स्थिति में हुए बदलावों को रीयल टाइम में ट्रैक कर सकते हैं.

ज़्यादा जानकारी के लिए, स्टेटस में हुए बदलावों को देखने और देखने का तरीका जानने के लिए, यहां दिए गए सेक्शन देखें.

स्टेटस में हुए बदलावों को देखें

यहां यह बताया गया है कि bidders.creatives.watch की मदद से क्रिएटिव स्टेटस में हुए बदलावों को देखने के लिए, बिड करने वाले के खाते को कैसे कॉन्फ़िगर किया जा सकता है. कॉन्फ़िगर किए जाने के बाद, Authorized Buyers, बिडिंग करने वाले के लिए Google Cloud Pub/Sub की सदस्यता बनाएंगे. साथ ही, बिड करने वाले के खाते में खरीदारों के लिए, क्रिएटिव की स्थिति में हुए हर बदलाव के लिए उसे मैसेज भेजेंगे.

आराम

अनुरोध

POST https://realtimebidding.googleapis.com/v1/bidders/<INSERT_ACCOUNT_ID_HERE>/creatives:watch?alt=json
Authorization: Bearer <INSERT_ACCESS_TOKEN_HERE>
Content-Type: application/json

जवाब

{
  "topic": "projects/realtimebidding-pubsub/topics/topic<ACCOUNT_ID>",
  "subscription": "projects/realtimebidding-pubsub/subscriptions/subscription<ACCOUNT_ID>"
}

C#

/* 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
 *
 *     http://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.
 */

using Google.Apis.RealTimeBidding.v1;
using Google.Apis.RealTimeBidding.v1.Data;
using Mono.Options;

using System;
using System.Collections.Generic;

namespace Google.Apis.RealTimeBidding.Examples.v1.Bidders.Creatives
{
    /// <summary>
    /// Enables monitoring of changes in creative statuses for a given bidder.
    ///
    /// Watched creatives will have changes to their status posted to Google Cloud Pub/Sub. For
    /// more details on Google Cloud Pub/Sub, see: https://cloud.google.com/pubsub/docs
    ///
    /// For an example of pulling creative status changes from a Google Cloud Pub/Sub subscription,
    /// see PullWatchedCreativesSubscription.cs.
    /// </summary>
    public class WatchCreatives : ExampleBase
    {
        private RealTimeBiddingService rtbService;

        /// <summary>
        /// Constructor.
        /// </summary>
        public WatchCreatives()
        {
            rtbService = Utilities.GetRealTimeBiddingService();
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get => "Enables watching creative status changes for the given bidder account.";
        }

        /// <summary>
        /// Parse specified arguments.
        /// </summary>
        protected override Dictionary<string, object> ParseArguments(List<string> exampleArgs) {
            string[] requiredOptions = new string[] {"account_id"};
            bool showHelp = false;

            string accountId = null;

            OptionSet options = new OptionSet {
                "Patches the specified creative.",
                {
                    "h|help",
                    "Show help message and exit.",
                    h => showHelp = h != null
                },
                {
                    "a|account_id=",
                    ("[Required] The resource ID of the buyers resource under which the " +
                     "creatives were created. This will be used to construct the name used as " +
                     "a path parameter for the creatives.get request."),
                    a => accountId = a
                }
            };

            List<string> extras = options.Parse(exampleArgs);
            var parsedArgs = new Dictionary<string, object>();

            // Show help message.
            if(showHelp == true)
            {
                options.WriteOptionDescriptions(Console.Out);
                Environment.Exit(0);
            }
            // Set arguments.
            parsedArgs["account_id"] = accountId;
            // Validate that options were set correctly.
            Utilities.ValidateOptions(options, parsedArgs, requiredOptions, extras);

            return parsedArgs;
        }

        /// <summary>
        /// Run the example.
        /// </summary>
        /// <param name="parsedArgs">Parsed arguments for the example.</param>
        protected override void Run(Dictionary<string, object> parsedArgs)
        {
            var accountId = (string) parsedArgs["account_id"];
            var parentBidderName = $"bidders/{accountId}";

            WatchCreativesRequest body = new WatchCreativesRequest();

            BiddersResource.CreativesResource.WatchRequest request =
                rtbService.Bidders.Creatives.Watch(body, parentBidderName);

            WatchCreativesResponse response = null;

            Console.WriteLine("Watching creative status changes for bidder account with name: {0}",
                              parentBidderName);

            try
            {
                response = request.Execute();
            }
            catch (System.Exception exception)
            {
                throw new ApplicationException(
                    $"Real-time Bidding API returned error response:\n{exception.Message}");
            }

            Console.WriteLine("- Topic: {0}", response.Topic);
            Console.WriteLine("- Subscription: {0}", response.Subscription);
        }
    }
}

Java

/*
 * 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.
 */

package com.google.api.services.samples.authorizedbuyers.realtimebidding.v1.bidders.creatives;

import com.google.api.services.realtimebidding.v1.RealTimeBidding;
import com.google.api.services.realtimebidding.v1.model.WatchCreativesRequest;
import com.google.api.services.realtimebidding.v1.model.WatchCreativesResponse;
import com.google.api.services.samples.authorizedbuyers.realtimebidding.Utils;
import java.io.IOException;
import java.security.GeneralSecurityException;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;

/**
 * Enables monitoring of changes of a creative status for a given bidder.
 *
 * <p>Watched creatives will have changes to their status posted to Google Cloud Pub/Sub. For more
 * details on Google Cloud Pub/Sub, see: https://cloud.google.com/pubsub/docs
 *
 * <p>For an example of pulling creative status changes from a Google Cloud Pub/Sub subscription,
 * see PullWatchedCreativesSubscription.java.
 */
public class WatchCreatives {

  public static void execute(RealTimeBidding client, Namespace parsedArgs) throws IOException {
    Long accountId = parsedArgs.getLong("account_id");
    String parentBidderName = String.format("bidders/%s", accountId);

    WatchCreativesResponse response =
        client.bidders().creatives().watch(parentBidderName, new WatchCreativesRequest()).execute();

    System.out.printf("Watching creative status changes for bidder account '%s'.':\n", accountId);
    System.out.printf("- Topic: %s\n", response.getTopic());
    System.out.printf("- Subscription: %s\n", response.getSubscription());
  }

  public static void main(String[] args) {
    ArgumentParser parser =
        ArgumentParsers.newFor("WatchCreatives")
            .build()
            .defaultHelp(true)
            .description(
                ("Enables watching creative status changes for the given bidder account."));
    parser
        .addArgument("-a", "--account_id")
        .help(
            "The resource ID of a bidder account. This will be used to construct the parent "
                + "used as a path parameter for the creatives.watch request.")
        .required(true)
        .type(Long.class);

    Namespace parsedArgs = null;
    try {
      parsedArgs = parser.parseArgs(args);
    } catch (ArgumentParserException ex) {
      parser.handleError(ex);
      System.exit(1);
    }

    RealTimeBidding client = null;
    try {
      client = Utils.getRealTimeBiddingClient();
    } catch (IOException ex) {
      System.out.printf("Unable to create RealTimeBidding API service:\n%s", ex);
      System.out.println("Did you specify a valid path to a service account key file?");
      System.exit(1);
    } catch (GeneralSecurityException ex) {
      System.out.printf("Unable to establish secure HttpTransport:\n%s", ex);
      System.exit(1);
    }

    try {
      execute(client, parsedArgs);
    } catch (IOException ex) {
      System.out.printf("RealTimeBidding API returned error response:\n%s", ex);
      System.exit(1);
    }
  }
}

PHP

<?php

/**
 * 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.
 */

namespace Google\Ads\AuthorizedBuyers\RealTimeBidding\Examples\V1\Bidders_Creatives;

use Google\Ads\AuthorizedBuyers\RealTimeBidding\ExampleUtil\BaseExample;
use Google\Ads\AuthorizedBuyers\RealTimeBidding\ExampleUtil\Config;
use Google_Service_RealTimeBidding_WatchCreativesRequest;

/**
 * Enables monitoring of changes in status of a given bidder's creatives.
 *
 * Watched creatives will have changes to their status posted to Google Cloud Pub/Sub. For more
 * details on Google Cloud Pub/Sub, see:
 * https://cloud.google.com/pubsub/docs
 *
 * For an example of pulling creative status changes from a Google Cloud Pub/Sub subscription, see
 * PullWatchedCreativesSubscription.php.
 */
class WatchCreatives extends BaseExample
{

    public function __construct($client)
    {
        $this->service = Config::getGoogleServiceRealTimeBidding($client);
    }

    /**
     * @see BaseExample::getInputParameters()
     */
    protected function getInputParameters()
    {
        return [
            [
                'name' => 'account_id',
                'display' => 'Bidder account ID',
                'required' => true,
                'description' =>
                    'The resource ID of a bidder account. This will be used to construct the ' .
                    'parent used as a path parameter for the creatives.watch request.'
            ]
        ];
    }

    /**
     * @see BaseExample::run()
     */
    public function run()
    {
        $values = $this->formValues;

        $parentName = "bidders/$values[account_id]";

        $watch_request = new Google_Service_RealTimeBidding_WatchCreativesRequest();

        try {
            $response = $this->service->bidders_creatives->watch($parentName, $watch_request);
            print "<h2>Watching creative status for bidder '$parentName'.</h2>";
            $this->printResult($response);
        } catch (Google_Service_Exception $ex) {
            if ($ex->getCode() === 404 || $ex->getCode() === 403) {
                print '<h1>Bidder not found or can\'t access account.</h1>';
            } else {
                throw $ex;
            }
        }
    }

    /**
     * @see BaseExample::getName()
     */
    public function getName()
    {
        return 'Watch Bidder Creatives';
    }
}

Python

#!/usr/bin/python
#
# Copyright 2020 Google Inc. All Rights Reserved.
#
# 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
#
#      http://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.

"""Enables monitoring of changes of a creative status for a given bidder.

Watched creatives will have changes to their status posted to Google Cloud
Pub/Sub. For more details on Google Cloud Pub/Sub, see:
https://cloud.google.com/pubsub/docs

For an example of pulling creative status changes from a Google Cloud Pub/Sub
subscription, see pull_watched_creatives_subscription.py.
"""


import argparse
import os
import pprint
import sys

sys.path.insert(0, os.path.abspath('../../..'))

from googleapiclient.errors import HttpError

import util


_BIDDER_NAME_TEMPLATE = 'bidders/%s'

DEFAULT_BIDDER_RESOURCE_ID = 'ENTER_BIDDER_RESOURCE_ID_HERE'


def main(realtimebidding, args):
  account_id = args.account_id

  print(f'Watching creative status changes for bidder account "{account_id}":')

  try:
    # Construct and execute the request.
    response = realtimebidding.bidders().creatives().watch(
        parent=_BIDDER_NAME_TEMPLATE % account_id).execute()
  except HttpError as e:
    print(e)
    sys.exit(1)

  pprint.pprint(response)


if __name__ == '__main__':
  try:
    service = util.GetService(version='v1')
  except IOError as ex:
    print(f'Unable to create realtimebidding service - {ex}')
    print('Did you specify the key file in util.py?')
    sys.exit(1)

  parser = argparse.ArgumentParser(
      description=('Enables watching creative status changes for the given '
                   'bidder account.'))
  # Required fields.
  parser.add_argument(
      '-a', '--account_id', default=DEFAULT_BIDDER_RESOURCE_ID,
      help=('The resource ID of a bidder account. This will be used to '
            'construct the parent used as a path parameter for the '
            'creatives.watch request.'))

  args = parser.parse_args()

  main(service, args)


Ruby

#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright:: Copyright 2020 Google LLC
#
# License:: 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
#
#           http://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.
#
# Enables monitoring of changes of a creative status for a given bidder.
#
# Watched creatives will have changes to their status posted to Google Cloud Pub/Sub. For more details on Google Cloud
# Pub/Sub, see: https://cloud.google.com/pubsub/docs
#
# For an example of pulling creative status changes from the Google Cloud Pub/Sub subscription, see
# pull_watched_creatives_subscription.rb.

require 'optparse'

require_relative '../../../util'


def watch_creatives(realtimebidding, options)
  parent = "bidders/#{options[:account_id]}"

  puts "Watching creative status changes for bidder account '#{parent}':"

  response = realtimebidding.watch_creatives(parent)

  puts "\tTopic: #{response.topic}"
  puts "\tSubscription: #{response.subscription}"
end


if __FILE__ == $0
  begin
    # Retrieve the service used to make API requests.
    service = get_service()
  rescue ArgumentError => e
    raise 'Unable to create service, with error message: #{e.message}'
  rescue Signet::AuthorizationError => e
    raise 'Unable to create service, was the KEY_FILE in util.rb set? Error message: #{e.message}'
  end

  # Set options and default values for fields used in this example.
  options = [
    Option.new(
      'account_id',
      'The resource ID of the bidder account. This will be used to construct the parent used as a path parameter for '\
      'the creatives.watch request.',
      type: Integer, short_alias: 'a', required: true, default_value: nil
    ),
  ]

  # Parse options.
  parser = Parser.new(options)
  opts = parser.parse(ARGV)

  begin
    watch_creatives(service, opts)
  rescue Google::Apis::ServerError => e
    raise "The following server error occured:\n#{e.message}"
  rescue Google::Apis::ClientError => e
    raise "Invalid client request:\n#{e.message}"
  rescue Google::Apis::AuthorizationError => e
    raise "Authorization error occured:\n#{e.message}"
  end
end

स्थिति में हुए बदलाव देखें

यहां यह बताया गया है कि Google Cloud Pub/Sub API के projects.subscriptions.pull और projects.subscriptions.acknowledge तरीकों का इस्तेमाल करके, बिड करने वाले के क्रिएटिव स्टेटस में हुए बदलावों के लिए, मैसेज को कैसे हासिल किया जा सकता है और उन्हें स्वीकार किया जा सकता है.

क्रिएटिव की पहचान करने के लिए, मिलने वाले हर message में creativeFormat, creativeId, और accountId एट्रिब्यूट शामिल होंगे. data फ़ील्ड में, क्रिएटिव के creativeServingDecision का base64-एन्कोडेड JSON प्रतिनिधित्व शामिल है. ackId का इस्तेमाल करके यह स्वीकार किया जा सकता है कि subscriptions.acknowledge एपीआई कॉल से मैसेज मिला है.

आराम

पुल का अनुरोध

POST https://pubsub.googleapis.com/v1/projects/realtimebidding-pubsub/subscriptions/subscription<INSERT_ACCOUNT_ID_HERE>:pull?alt=json
Authorization: Bearer <INSERT_ACCESS_TOKEN_HERE>
Content-Type: application/json
 
{
  "maxMessages": 5
}

पुल का जवाब

{
  "receivedMessages": [
    {
      "ackId": "TgQhIT4wPkVTRFAGFixdRkhRNxkIaFEOT14jPzUgKEUSAAgUBXx9ckRLdV4zdQdRDRlzemInYwxAVFNCW3RfURsfWVx-VQZVDRh6eGR2a1IWCABGVnp3qPT2zoHmIB1tNfaZ_6hASoL904h0Zhs9XxJLLD5-Jz1FQV5AEkwsCERJUytDCypYEQ",
      "message": {
        "data": "eyJkZXRlY3RlZENsaWNrVGhyb3VnaFVybHMiOlsiaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS8iLCJodHRwczovL3d3dy5nb29nbGUuY29tLyNzcGZcdTAwM2QxNTk0ODUwNjEyNzEwIl0sImRldGVjdGVkUHJvZHVjdENhdGVnb3JpZXMiOlsxMDAwMywxMDAwNywxMDAxMCwxMDAxMywxMDAxNiwxMDAxOSwxMDA0MiwxMDA4MiwxMDEwMywxMDE0MSwxMDE2OCwxMDc1NCwxMDg4NSwxMjIwNiwxMzQxOF0sImRldGVjdGVkTGFuZ3VhZ2VzIjpbImVuIl0sImRldGVjdGVkRG9tYWlucyI6WyJnb29nbGUuY29tIl0sImRldGVjdGVkQXR0cmlidXRlcyI6WyJDUkVBVElWRV9UWVBFX0hUTUwiXSwibGFzdFN0YXR1c1VwZGF0ZSI6IjIwMjAtMDctMTVUMjI6MjY6MzQuNzk2WiIsImRlYWxzUG9saWN5Q29tcGxpYW5jZSI6eyJzdGF0dXMiOiJBUFBST1ZFRCJ9LCJuZXR3b3JrUG9saWN5Q29tcGxpYW5jZSI6eyJzdGF0dXMiOiJBUFBST1ZFRCJ9LCJwbGF0Zm9ybVBvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiQVBQUk9WRUQifSwiY2hpbmFQb2xpY3lDb21wbGlhbmNlIjp7InN0YXR1cyI6IkFQUFJPVkVEIn0sInJ1c3NpYVBvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiQVBQUk9WRUQifX0=",
        "attributes": {
          "creativeFormat": "ADX_FORMAT_NATIVE",
          "creativeId": "Native_Creative_7eb070ce-7268-4dd2-9640-15e28fd16892",
          "accountId": "<ACCOUNT_ID1>"
        },
        "messageId": "1401855318592354",
        "publishTime": "2020-08-04T15:00:27.410Z"
      }
    },
    {
      "ackId": "TgQhIT4wPkVTRFAGFixdRkhRNxkIaFEOT14jPzUgKEUSAAgUBXx9ckRLdV4zdQdRDRlzemInYwxAVFNCW3RfURofWVx-VQZVDRh6dGFxYlMWAgpFW393qPT2zoHmIB1tNfaZ_6hASoL904h0Zhs9XxJLLD5-Jz1FQV5AEkwsCERJUytDCypYEQ",
      "message": {
        "data": "eyJkZXRlY3RlZENsaWNrVGhyb3VnaFVybHMiOlsiaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS8iXSwiZGV0ZWN0ZWRQcm9kdWN0Q2F0ZWdvcmllcyI6WzEwMDAzLDEwMDA3LDEwMDEwLDEwMDEzLDEwMDE2LDEwMDE5LDEwMDQyLDEwMDgyLDEwMTAzLDEwMTQxLDEwMTY4LDEwNzU0LDEwODg1LDEyMjA2LDEzNDE4XSwiZGV0ZWN0ZWRMYW5ndWFnZXMiOlsiZW4iXSwiZGV0ZWN0ZWREb21haW5zIjpbImdvb2dsZS5jb20iXSwiZGV0ZWN0ZWRBdHRyaWJ1dGVzIjpbIk5BVElWRV9FTElHSUJJTElUWV9FTElHSUJMRSJdLCJsYXN0U3RhdHVzVXBkYXRlIjoiMjAyMC0wNy0xOFQxMTozNDozMy41MTVaIiwiZGVhbHNQb2xpY3lDb21wbGlhbmNlIjp7InN0YXR1cyI6IkFQUFJPVkVEIn0sIm5ldHdvcmtQb2xpY3lDb21wbGlhbmNlIjp7InN0YXR1cyI6IkFQUFJPVkVEIn0sInBsYXRmb3JtUG9saWN5Q29tcGxpYW5jZSI6eyJzdGF0dXMiOiJBUFBST1ZFRCJ9LCJjaGluYVBvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiQVBQUk9WRUQifSwicnVzc2lhUG9saWN5Q29tcGxpYW5jZSI6eyJzdGF0dXMiOiJBUFBST1ZFRCJ9fQ==",
        "attributes": {
          "creativeFormat": "ADX_FORMAT_NATIVE",
          "creativeId": "Native_Creative_10fdd7a1-8f3d-4026-a12b-3fb823dff23e",
          "accountId": "<ACCOUNT_ID2>"
        },
        "messageId": "1401890489538081",
        "publishTime": "2020-08-04T15:00:27.410Z"
      }
    },
    {
      "ackId": "ISE-MD5FU0RQBhYsXUZIUTcZCGhRDk9eIz81IChFEgAIFAV8fXBCU3VfXndoUQ0Zcn1gcmkIFghRRFF3XVEZB2hObXUlcQwdcn9ncm5bGwUFRFR_WVgz_oen-qi9BBclSpKK96NvM9nsl9lPZiU9XxJLLD5-Jz1FQV5AEkwsCERJUytDCypYEU4E",
      "message": {
        "data": "eyJkZXRlY3RlZFByb2R1Y3RDYXRlZ29yaWVzIjpbMTAwMTYsMTAwMTksMTAxNDEsMTAxNjgsMTA3NTQsMTA4ODUsMTIyMDZdLCJkZXRlY3RlZExhbmd1YWdlcyI6WyJlbiJdLCJkZXRlY3RlZEF0dHJpYnV0ZXMiOlsiQ1JFQVRJVkVfVFlQRV9WQVNUX1ZJREVPIl0sImxhc3RTdGF0dXNVcGRhdGUiOiIyMDIwLTA3LTMwVDIyOjU3OjI0LjgxMFoiLCJkZWFsc1BvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiQVBQUk9WRUQifSwibmV0d29ya1BvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiRElTQVBQUk9WRUQiLCJ0b3BpY3MiOlt7InBvbGljeVRvcGljIjoiVklERU9fQURTX09USEVSIiwiaGVscENlbnRlclVybCI6Imh0dHBzOi8vc3VwcG9ydC5nb29nbGUuY29tL2Fkc3BvbGljeS9hbnN3ZXIvMjY3OTk0MCIsImV2aWRlbmNlcyI6W3sidmFzdCI6eyJwYXJzaW5nRXJyb3JzIjpbIklOVkFMSURfWE1MX1NZTlRBWCJdfX1dfV19LCJwbGF0Zm9ybVBvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiQVBQUk9WRUQifSwiY2hpbmFQb2xpY3lDb21wbGlhbmNlIjp7InN0YXR1cyI6IkRJU0FQUFJPVkVEIn0sInJ1c3NpYVBvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiRElTQVBQUk9WRUQifX0=",
        "attributes": {
          "creativeId": "Video_Creative_1193239f-a5dd-40c2-8472-34913a3f202c",
          "creativeFormat": "ADX_FORMAT_VIDEO_VAST",
          "accountId": "<ACCOUNT_ID3>"
        },
        "messageId": "1402674184717163",
        "publishTime": "2020-08-04T20:18:11.890Z"
      }
    },
    {
      "ackId": "ISE-MD5FU0RQBhYsXUZIUTcZCGhRDk9eIz81IChFEgAIFAV8fXBCU3VfXndoUQ0Zcn1gcmkIFghRRFF3XVEZB2lObXUlcQwdcn9nfG5eGwYKTVp_WVMz_oen-qi9BBclSpKK96NvM9nsl9lPZiU9XxJLLD5-Jz1FQV5AEkwsCERJUytDCypYEU4E",
      "message": {
        "data": "eyJkZXRlY3RlZEF0dHJpYnV0ZXMiOlsiQ1JFQVRJVkVfVFlQRV9IVE1MIl0sImxhc3RTdGF0dXNVcGRhdGUiOiIyMDIwLTA3LTMwVDIzOjM0OjQzLjAxOVoiLCJkZWFsc1BvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiQVBQUk9WRUQifSwibmV0d29ya1BvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiRElTQVBQUk9WRUQiLCJ0b3BpY3MiOlt7InBvbGljeVRvcGljIjoiREVTVElOQVRJT05fTk9UX0NSQVdMQUJMRSIsImhlbHBDZW50ZXJVcmwiOiJodHRwczovL3N1cHBvcnQuZ29vZ2xlLmNvbS9hZHNwb2xpY3kvYW5zd2VyLzYzNjg2NjEiLCJldmlkZW5jZXMiOlt7ImRlc3RpbmF0aW9uTm90Q3Jhd2xhYmxlIjp7ImNyYXdsZWRVcmwiOiJodHRwczovL3Rlc3QuY2xpY2t1cmwuY29tLzA0YWUxM2Y0LTM2OGEtNDYwNS05NGNhLWM2OWVmNzE4MDVjOSIsInJlYXNvbiI6IlVOUkVBQ0hBQkxFX1JPQk9UUyIsImNyYXdsVGltZSI6IjIwMjAtMDgtMDRUMDA6MTU6MjFaIn19LHsiZGVzdGluYXRpb25Ob3RDcmF3bGFibGUiOnsiY3Jhd2xlZFVybCI6Imh0dHBzOi8vdGVzdC5jbGlja3VybC5jb20vOGU2NDQwOTYtYWEwOC00OTEzLTkyMDgtZTJlYThkOTkxZDEzIiwicmVhc29uIjoiVU5SRUFDSEFCTEVfUk9CT1RTIiwiY3Jhd2xUaW1lIjoiMjAyMC0wOC0wM1QyMzo0ODo0MloifX0seyJkZXN0aW5hdGlvbk5vdENyYXdsYWJsZSI6eyJjcmF3bGVkVXJsIjoiaHR0cHM6Ly90ZXN0LmNsaWNrdXJsLmNvbS9mYmVmMDdjNC02ZGM1LTRlMmYtYjM5Yi1mYjc4OGE3YTFlNGMiLCJyZWFzb24iOiJVTlJFQUNIQUJMRV9ST0JPVFMiLCJjcmF3bFRpbWUiOiIyMDIwLTA4LTA0VDAwOjE1OjIwWiJ9fV19XX0sInBsYXRmb3JtUG9saWN5Q29tcGxpYW5jZSI6eyJzdGF0dXMiOiJBUFBST1ZFRCJ9LCJjaGluYVBvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiQVBQUk9WRUQifSwicnVzc2lhUG9saWN5Q29tcGxpYW5jZSI6eyJzdGF0dXMiOiJBUFBST1ZFRCJ9fQ==",
        "attributes": {
          "creativeId": "HTML_Creative_5e230148-2a6a-4ac7-b8a6-024ca06e3305",
          "accountId": "<ACCOUNT_ID2>",
          "creativeFormat": "ADX_FORMAT_HTML_SNIPPET"
        },
        "messageId": "1402694487889168",
        "publishTime": "2020-08-04T20:18:11.890Z"
      }
    },
    {
      "ackId": "ISE-MD5FU0RQBhYsXUZIUTcZCGhRDk9eIz81IChFEgAIFAV8fXBCU3VdXHdoUQ0Zcn1gcmkLRgMHQwErW1EaB2hObXUlcQwdcn9nfW5dFAcKQ1J3X1Iz_oen-qi9BBclSpKK96NvM9nsl9lPZiU9XxJLLD5-Jz1FQV5AEkwsCERJUytDCypYEU4E",
      "message": {
        "data": "eyJkZXRlY3RlZFByb2R1Y3RDYXRlZ29yaWVzIjpbMTAwMTYsMTAwMTksMTAxNDEsMTAxNjgsMTA3NTQsMTA4ODUsMTIyMDZdLCJkZXRlY3RlZExhbmd1YWdlcyI6WyJlbiJdLCJkZXRlY3RlZEF0dHJpYnV0ZXMiOlsiQ1JFQVRJVkVfVFlQRV9IVE1MIl0sImxhc3RTdGF0dXNVcGRhdGUiOiIyMDIwLTA3LTIyVDIzOjUyOjE4Ljk0N1oiLCJkZWFsc1BvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiQVBQUk9WRUQifSwibmV0d29ya1BvbGljeUNvbXBsaWFuY2UiOnsic3RhdHVzIjoiQVBQUk9WRUQifSwicGxhdGZvcm1Qb2xpY3lDb21wbGlhbmNlIjp7InN0YXR1cyI6IkFQUFJPVkVEIn0sImNoaW5hUG9saWN5Q29tcGxpYW5jZSI6eyJzdGF0dXMiOiJBUFBST1ZFRCJ9LCJydXNzaWFQb2xpY3lDb21wbGlhbmNlIjp7InN0YXR1cyI6IkFQUFJPVkVEIn19",
        "attributes": {
          "creativeFormat": "ADX_FORMAT_HTML_SNIPPET",
          "creativeId": "HTML_Creative_3e250341-3b6f-daf8-c3b4-131bd09e4217",
          "accountId": "<ACCOUNT_ID1>"
        },
        "messageId": "1402684776861909",
        "publishTime": "2020-08-04T20:18:12.095Z"
      }
    }
  ]
}

अनुरोध स्वीकार करें

POST https://pubsub.googleapis.com/v1/projects/realtimebidding-pubsub/subscriptions/subscription<INSERT_ACCOUNT_ID_HERE>:acknowledge?alt=json
Authorization: Bearer <INSERT_ACCESS_TOKEN_HERE>
Content-Type: application/json
 
{
  "ackIds": [
    "TgQhIT4wPkVTRFAGFixdRkhRNxkIaFEOT14jPzUgKEUSAAgUBXx9ckRLdV4zdQdRDRlzemInYwxAVFNCW3RfURsfWVx-VQZVDRh6eGR2a1IWCABGVnp3qPT2zoHmIB1tNfaZ_6hASoL904h0Zhs9XxJLLD5-Jz1FQV5AEkwsCERJUytDCypYEQ",
    "TgQhIT4wPkVTRFAGFixdRkhRNxkIaFEOT14jPzUgKEUSAAgUBXx9ckRLdV4zdQdRDRlzemInYwxAVFNCW3RfURofWVx-VQZVDRh6dGFxYlMWAgpFW393qPT2zoHmIB1tNfaZ_6hASoL904h0Zhs9XxJLLD5-Jz1FQV5AEkwsCERJUytDCypYEQ",
    "ISE-MD5FU0RQBhYsXUZIUTcZCGhRDk9eIz81IChFEgAIFAV8fXBCU3VfXndoUQ0Zcn1gcmkIFghRRFF3XVEZB2hObXUlcQwdcn9ncm5bGwUFRFR_WVgz_oen-qi9BBclSpKK96NvM9nsl9lPZiU9XxJLLD5-Jz1FQV5AEkwsCERJUytDCypYEU4E",
    "ISE-MD5FU0RQBhYsXUZIUTcZCGhRDk9eIz81IChFEgAIFAV8fXBCU3VfXndoUQ0Zcn1gcmkIFghRRFF3XVEZB2lObXUlcQwdcn9nfG5eGwYKTVp_WVMz_oen-qi9BBclSpKK96NvM9nsl9lPZiU9XxJLLD5-Jz1FQV5AEkwsCERJUytDCypYEU4E",
    "ISE-MD5FU0RQBhYsXUZIUTcZCGhRDk9eIz81IChFEgAIFAV8fXBCU3VdXHdoUQ0Zcn1gcmkLRgMHQwErW1EaB2hObXUlcQwdcn9nfW5dFAcKQ1J3X1Iz_oen-qi9BBclSpKK96NvM9nsl9lPZiU9XxJLLD5-Jz1FQV5AEkwsCERJUytDCypYEU4E"
  ]
}

जवाब को स्वीकार करें

{}

C#

/* 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
 *
 *     http://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.
 */

using Google.Apis.Pubsub.v1;
using Google.Apis.Pubsub.v1.Data;
using Mono.Options;

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;

namespace Google.Apis.RealTimeBidding.Examples.v1.Bidders.Creatives
{
    /// <summary>
    /// Pulls creative status changes from a Google Cloud Pub/Sub subscription.
    ///
    /// Note that messages do not expire until they are acknowledged; set the acknowledgement
    /// argument to "true" to acknowledge receiving all messages sent in the response.
    ///
    /// To learn more about Google Cloud Pub/Sub, read the developer documentation:
    /// https://cloud.google.com/pubsub/docs/overview
    /// https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/list
    /// https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/acknowledge
    /// </summary>
    public class PullWatchedCreativesSubscription : ExampleBase
    {
        private PubsubService pubSubService;

        /// <summary>
        /// Constructor.
        /// </summary>
        public PullWatchedCreativesSubscription()
        {
            pubSubService = Utilities.GetPubSubService();
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get => "This code example pulls creative status changes (if any) from a specified " +
                   "Google Cloud Pub/Sub subscription.";
        }

        /// <summary>
        /// Parse specified arguments.
        /// </summary>
        protected override Dictionary<string, object> ParseArguments(List<string> exampleArgs) {
            string[] requiredOptions = new string[] {"subscription_name"};
            bool showHelp = false;

            string subscriptionName = null;
            int? maxMessages  = null;
            bool? acknowledge = null;

            OptionSet options = new OptionSet {
                ("Pulls creative status changes (if any) from a specified Google Cloud Pub/Sub " +
                 "subscription."),
                {
                    "h|help",
                    "Show help message and exit.",
                    h => showHelp = h != null
                },
                {
                    "s|subscription_name=",
                    ("[Required] The Google Cloud Pub/Sub subscription to be pulled. This value " +
                     "would be returned in the response from the bidders.creatives.watch " +
                     "method, and should be provided as-is in the form: " +
                     @"""projects/realtimebidding-pubsub/subscriptions/{subscription_id}"""),
                    s => subscriptionName = s
                },
                {
                    "m|max_messages=",
                    "The maximum number of messages to be returned in a single pull.",
                    (int m) => maxMessages =  m
                },
                {
                    "a|acknowledge",
                    ("Specify this argument to indicate that you want to acknowledge messages " +
                     "pulled from the subscription. Acknowledged messages won't appear in the " +
                     "subsequent responses to pulls from the subscription. By default, messages " +
                     "will not be acknowledged."),
                    a => acknowledge = a != null
                }
            };

            List<string> extras = options.Parse(exampleArgs);
            var parsedArgs = new Dictionary<string, object>();

            // Show help message.
            if(showHelp == true)
            {
                options.WriteOptionDescriptions(Console.Out);
                Environment.Exit(0);
            }
            // Set arguments.
            parsedArgs["subscription_name"] = subscriptionName;
            parsedArgs["max_messages"] = maxMessages ?? Utilities.MAX_PAGE_SIZE;
            parsedArgs["acknowledge"] = acknowledge ?? false;
            // Validate that options were set correctly.
            Utilities.ValidateOptions(options, parsedArgs, requiredOptions, extras);

            return parsedArgs;
        }

        /// <summary>
        /// Run the example.
        /// </summary>
        /// <param name="parsedArgs">Parsed arguments for the example.</param>
        protected override void Run(Dictionary<string, object> parsedArgs)
        {
            string subscriptionName = (string) parsedArgs["subscription_name"];

            Console.WriteLine(@"Retrieving messages from subscription: ""{0}""", subscriptionName);

            PullRequest pullRequest = new PullRequest();
            pullRequest.MaxMessages = (int?) parsedArgs["max_messages"];

            PullResponse response = null;

            try
            {
                response = pubSubService.Projects.Subscriptions.Pull(
                    pullRequest, subscriptionName).Execute();
            }
            catch (System.Exception exception)
            {
                throw new ApplicationException(
                    $"Google Cloud Pub/Sub API returned error response:\n{exception.Message}");
            }

            var ackIds = new List<string>();
            IList<ReceivedMessage> receivedMessages = response.ReceivedMessages;

            if(receivedMessages.Count == 0)
            {
                Console.Out.WriteLine("No messages received from the subscription.");
            }
            else
            {
                var options = new JsonSerializerOptions();
                options.WriteIndented = true;

                foreach(ReceivedMessage receivedMessage in receivedMessages)
                {
                ackIds.Add(receivedMessage.AckId);
                PubsubMessage message = receivedMessage.Message;
                IDictionary<string, string> messageAttributes = message.Attributes;
                var accountId = messageAttributes["accountId"];
                var creativeId = messageAttributes["creativeId"];

                Console.Out.WriteLine(@"* Creative found for buyer account ID ""{0}"" with " +
                                      @"creative ID ""{1}"" has been updated with the following " +
                                      "creative status:\n", accountId, creativeId);

                byte[] data = Convert.FromBase64String(message.Data);
                var decodedString = Encoding.UTF8.GetString(data);
                JsonElement jsonData = JsonSerializer.Deserialize<JsonElement>(decodedString);

                Console.Out.WriteLine(JsonSerializer.Serialize(jsonData, options));
                }

                if((bool) parsedArgs["acknowledge"])
                {
                    AcknowledgeRequest acknowledgeRequest = new AcknowledgeRequest();
                    acknowledgeRequest.AckIds = ackIds;

                    Console.Out.WriteLine(
                        "Acknowledging all {0} messages pulled from the subscription.",
                        ackIds.Count);

                    try
                    {
                        pubSubService.Projects.Subscriptions.Acknowledge(acknowledgeRequest,
                                                                         subscriptionName);
                    }
                    catch (System.Exception exception)
                    {
                        throw new ApplicationException(
                            "Google Cloud Pub/Sub API returned error response:\n" +
                            $"{exception.Message}");
                    }
                }
            }

        }
    }
}

Java

/*
 * 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.
 */

package com.google.api.services.samples.authorizedbuyers.realtimebidding.v1.bidders.creatives;

import static net.sourceforge.argparse4j.impl.Arguments.storeTrue;

import com.google.api.services.pubsub.Pubsub;
import com.google.api.services.pubsub.model.AcknowledgeRequest;
import com.google.api.services.pubsub.model.PubsubMessage;
import com.google.api.services.pubsub.model.PullRequest;
import com.google.api.services.pubsub.model.PullResponse;
import com.google.api.services.pubsub.model.ReceivedMessage;
import com.google.api.services.samples.authorizedbuyers.realtimebidding.Utils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;

/**
 * Pulls creative status updates from a Google Cloud Pub/Sub subscription.
 *
 * <p>Note that messages do not expire until they are acknowledged; set the acknowledged argument to
 * True to acknowledge receiving all messages sent in the response.
 *
 * <p>To learn more about Google Cloud Pub/Sub, read the developer documentation:
 * https://cloud.google.com/pubsub/docs/overview
 * https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/list
 * https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/acknowledge
 */
public class PullWatchedCreativesSubscription {

  public static void execute(Pubsub client, Namespace parsedArgs) throws IOException {
    String subscriptionName = parsedArgs.getString("subscription_name");

    System.out.printf("Retrieving messages from subscription: '%s'\n", subscriptionName);

    PullRequest pullRequest = new PullRequest();
    pullRequest.setMaxMessages(parsedArgs.getInt("max_messages"));

    PullResponse response =
        client.projects().subscriptions().pull(subscriptionName, pullRequest).execute();

    List<String> ackIds = new ArrayList<>();
    List<ReceivedMessage> receivedMessages = response.getReceivedMessages();
    if (receivedMessages.isEmpty()) {
      System.out.println("No messages received from the subscription.");
    } else {
      Gson gson = new GsonBuilder().setPrettyPrinting().create();

      for (ReceivedMessage receivedMessage : receivedMessages) {
        ackIds.add(receivedMessage.getAckId());
        PubsubMessage message = receivedMessage.getMessage();
        Map<String, String> messageAttributes = message.getAttributes();
        String accountId = messageAttributes.get("accountId");
        String creativeId = messageAttributes.get("creativeId");

        System.out.printf(
            "* Creative found for buyer account ID '%s' with creative ID '%s' "
                + "has been updated with the following creative status:\n",
            accountId, creativeId);

        String decodedData = new String(message.decodeData());
        JsonElement jsonElement = JsonParser.parseString(decodedData);
        System.out.printf("%s\n\n", gson.toJson(jsonElement));
      }

      if (parsedArgs.getBoolean("acknowledge")) {
        AcknowledgeRequest acknowledgeRequest = new AcknowledgeRequest();
        acknowledgeRequest.setAckIds(ackIds);

        System.out.printf(
            "Acknowledging all %d messages pulled from the subscription.", ackIds.size());

        client
            .projects()
            .subscriptions()
            .acknowledge(subscriptionName, acknowledgeRequest)
            .execute();
      }
    }
  }

  public static void main(String[] args) {
    ArgumentParser parser =
        ArgumentParsers.newFor("PullWatchedCreativesSubscription")
            .build()
            .defaultHelp(true)
            .description(
                ("Pulls creative status changes (if any) from a specified Google Cloud "
                    + "Pub/Sub subscription."));
    parser
        .addArgument("-s", "--subscription_name")
        .help(
            "The Google Cloud Pub/Sub subscription to be pulled. This value would be returned "
                + "in the response from the bidders.creatives.watch method, and should be provided "
                + "as-is in the form: "
                + "\"projects/realtimebidding-pubsub/subscriptions/{subscription_id}\"")
        .required(true);
    parser
        .addArgument("-m", "--max_messages")
        .help("The maximum number of messages to be returned in a single pull.")
        .type(Integer.class)
        .setDefault(Utils.getMaximumPageSize());
    parser
        .addArgument("-a", "--acknowledge")
        .help(
            "'Whether to acknowledge the messages pulled from the subscription. Acknowledged "
                + "messages won't appear in subsequent responses to pulls from the subscription.'")
        .type(Boolean.class)
        .action(storeTrue())
        .setDefault(false);

    Namespace parsedArgs = null;
    try {
      parsedArgs = parser.parseArgs(args);
    } catch (ArgumentParserException ex) {
      parser.handleError(ex);
      System.exit(1);
    }

    Pubsub client = null;
    try {
      client = Utils.getPubsubClient();
    } catch (IOException ex) {
      System.out.printf("Unable to create Pubsub API service:\n%s", ex);
      System.out.println("Did you specify a valid path to a service account key file?");
      System.exit(1);
    } catch (GeneralSecurityException ex) {
      System.out.printf("Unable to establish secure HttpTransport:\n%s", ex);
      System.exit(1);
    }

    try {
      execute(client, parsedArgs);
    } catch (IOException ex) {
      System.out.printf("PubSub API returned error response:\n%s", ex);
      System.exit(1);
    }
  }
}

PHP

<?php

/**
 * 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.
 */

namespace Google\Ads\AuthorizedBuyers\RealTimeBidding\Examples\V1\Bidders_Creatives;

use Google\Ads\AuthorizedBuyers\RealTimeBidding\ExampleUtil\BaseExample;
use Google\Ads\AuthorizedBuyers\RealTimeBidding\ExampleUtil\Config;
use Google_Service_Pubsub_AcknowledgeRequest;
use Google_Service_Pubsub_PullRequest;

/**
 * Enables monitoring of changes in status of a given bidder's creatives.
 *
 * Watched creatives will have changes to their status posted to Google Cloud Pub/Sub. For more
 * details on Google Cloud Pub/Sub, see:
 * https://cloud.google.com/pubsub/docs
 *
 * For an example of pulling creative status changes from a Google Cloud Pub/Sub subscription, see
 * PullWatchedCreativesSubscription.php.
 */
class PullWatchedCreativesSubscription extends BaseExample
{

    public function __construct($client)
    {
        $this->service = Config::getGoogleServicePubSub($client);
    }

    /**
     * @see BaseExample::getInputParameters()
     */
    protected function getInputParameters()
    {
        return [
            [
                'name' => 'subscription_name',
                'display' => 'Subscription name',
                'required' => true,
                'description' =>
                    'The Google Cloud Pub/Sub subscription to be pulled. This value would be ' .
                    'returned in the response from the bidders.creatives.watch method, and ' .
                    'should be provided as-is in the form:</br>' .
                    '"projects/realtimebidding-pubsub/subscriptions/{subscription_id}"'
            ],
            [
                'name' => 'acknowledge',
                'display' => 'Acknowledge',
                'required' => false,
                'description' =>
                    'A boolean describing whether to acknowledge the messages pulled from the ' .
                    'subscription. Acknowledged messages won\'t appear in subsequent responses ' .
                    'to pulls from the subscription.',
                'default' => 'false'
            ]
        ];
    }

    /**
     * @see BaseExample::run()
     */
    public function run()
    {
        $values = $this->formValues;

        $subscriptionName = $values['subscription_name'];
        $acknowledge = filter_var($values['acknowledge'], FILTER_VALIDATE_BOOLEAN);

        $pullRequest = new Google_Service_Pubsub_PullRequest();
        $pullRequest->maxMessages = 10;

        $ackIds = [];

        try {
            $response = $this->service->projects_subscriptions->pull($subscriptionName, $pullRequest);
            print "<h2>Pulled subscription '$subscriptionName' with results:</h2>";

            if (empty($response['receivedMessages'])) {
                print '<p>No messages received from the subscription.</p>';
                return;
            } else {
                print '<ul>';
                foreach ($response['receivedMessages'] as $receivedMessage) {
                    $ackIds[] = $receivedMessage['ackId'];
                    $message = $receivedMessage['message'];
                    $accountId = $message['attributes']['accountId'];
                    $creativeId = $message['attributes']['creativeId'];
                    $creativeServingDecision = $this->getPrettyPrintCreativeServingDecision(
                        $message['data']
                    );

                    print "<li>Creative found for buyer account ID '$accountId' with creative " .
                        "ID '$creativeId' has been updated with the following creative status:";

                    print '</br>';
                    print "<pre>$creativeServingDecision</pre>";
                    print '</li>';
                }
                print '</ul>';
            }
        } catch (Google_Service_Exception $ex) {
            if ($ex->getCode() === 404 || $ex->getCode() === 403) {
                print '<h1>Subscription not found or don\'t have access.</h1>';
            } else {
                throw $ex;
            }
        }

        if ($acknowledge) {
            $ackRequest = new Google_Service_Pubsub_AcknowledgeRequest();
            $ackRequest->ackIds = $ackIds;

            try {
                $ackResponse = $this->service->projects_subscriptions->acknowledge(
                    $subscriptionName,
                    $ackRequest
                );
                printf('Acknowledged %d messages pulled from the subscription.', count($ackIds));
                print '</br></br>';
            } catch (Google_Service_Exception $ex) {
                if ($ex->getCode() === 404 || $ex->getCode() === 403) {
                    print '<h1>AckIDs not found or do not have access.</h1>';
                } else {
                    throw $ex;
                }
            }
        }
    }

    /**
     * @see BaseExample::getName()
     */
    public function getName()
    {
        return 'Pull Watched Creatives Subscription';
    }

    public function getPrettyPrintCreativeServingDecision($data)
    {
        return json_encode(json_decode(base64_decode($data)), JSON_PRETTY_PRINT);
    }
}

Python

#!/usr/bin/python
#
# Copyright 2020 Google Inc. All Rights Reserved.
#
# 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
#
#      http://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.

"""Pulls creative status updates from a Google Cloud Pub/Sub subscription.

Note that messages do not expire until they are acknowledged; set the
acknowledged argument to True to acknowledge receiving all messages sent in the
response.

To learn more about Google Cloud Pub/Sub, read the developer documentation:
https://cloud.google.com/pubsub/docs/overview
https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/list
https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/acknowledge
"""


import argparse
import base64
import json
import os
import pprint
import sys

sys.path.insert(0, os.path.abspath('../../..'))

from googleapiclient.errors import HttpError
import util


def main(pubsub, args):
  subscription_name = args.subscription_name

  print(f'Retrieving messages from subscription: "{subscription_name}"')

  body = {'maxMessages': args.max_messages}

  subscriptions = pubsub.projects().subscriptions().pull(
      subscription=subscription_name, body=body).execute()

  pprint.pprint(subscriptions)

  if 'receivedMessages' in subscriptions:
    ack_ids = []

    for received_message in subscriptions['receivedMessages']:
      ack_ids.append(received_message['ackId'])
      message = received_message['message']
      account_id = message['attributes']['accountId']
      creative_id = message['attributes']['creativeId']

      print(f'* Creative found for buyer account ID "{account_id}" with '
            f'creative ID "{creative_id}" has been updated with the following '
            'creative status:')
      creative_serving_decision = parse_creative_serving_decision(
          message['data'])
      pprint.pprint(creative_serving_decision)
      print()

    if args.acknowledge:
      body = {'ackIds': ack_ids}

      print(f'Acknowledging all {len(ack_ids)} messages pulled from the '
            'subscription.')

      pubsub.projects().subscriptions().acknowledge(
          subscription=subscription_name, body=body).execute()
  else:
    print('No messages received from the subscription.')


def parse_creative_serving_decision(data):
  """Parses the Creative Serving Decision from the Cloud Pub/Sub response.

  Args:
    data: a base64-encoded JSON string representing a creative's
          CreativeServingDevision.

  Returns:
    A JSON representation of the creative's CreativeServingDecision.
  """
  return json.loads(base64.b64decode(data))


if __name__ == '__main__':
  try:
    service = util.GetCloudPubSubService(version='v1')
  except IOError as ex:
    print(f'Unable to create pubsub service - {ex}')
    print('Did you specify the key file in util.py?')
    sys.exit(1)

  parser = argparse.ArgumentParser(
      description=('Pulls creative status changes (if any) from a specified '
                   'Google Cloud Pub/Sub subscription.'))

  # Required fields.
  parser.add_argument(
      '-s', '--subscription_name', required=True, type=str,
      help=('The Google Cloud Pub/Sub subscription to be pulled. This value '
            'would be returned in the response from the '
            'bidders.creatives.watch method, and should be provided as-is in '
            'the form: "projects/realtimebidding-pubsub/subscriptions/'
            '{subscription_id}"))'))
  parser.add_argument(
      '-m', '--max_messages', default=100, type=int,
      help='The maximum number of messages to be returned in a single pull.')
  parser.add_argument(
      '-a', '--acknowledge', default=False, type=bool,
      help=('Whether to acknowledge the messages pulled from the '
            'subscription. Acknowledged messages won\'t appear in subsequent '
            'responses to pulls from the subscription.'))

  args = parser.parse_args()

  main(service, args)


Ruby

#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright:: Copyright 2020 Google LLC
#
# License:: 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
#
#           http://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.
#
# Pulls creative status updates from a Google Cloud Pub/Sub subscription.
#
# Note that messages do not expire until they are acknowledged; set the acknowledged argument to true to acknowledge
# receiving all messages sent in the response.
#
# To learn more about Google Cloud Pub/Sub, read the developer documentation:
# https://cloud.google.com/pubsub/docs/overview
# https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/list
# https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/acknowledge

require 'base64'
require 'json'
require 'optparse'

require_relative '../../../util'


def pull_watched_creatives_subscription(pubsub, options)
  subscription_name = options[:subscription_name]
  pull_request_object = Google::Apis::PubsubV1::PullRequest.new(max_messages: options[:max_messages])

  puts "Retrieving messages from subscription '#{subscription_name}':"

  response = pubsub.pull_subscription(subscription_name, pull_request_object)

  unless response.received_messages.nil?
    ack_ids = []
    response.received_messages.each do |received_message|
      message = received_message.message
      account_id = message.attributes['accountId']
      creative_id = message.attributes['creativeId']
      ack_ids << received_message.ack_id
      creative_serving_decision = JSON.parse(message.data)

      puts "* Creative found for buyer account ID '#{account_id}' with creative ID '#{creative_id}' has been "\
           "updated with the following creative status:"
      puts JSON.pretty_generate(creative_serving_decision)

      if options[:acknowledge]
        ack_req_object = Google::Apis::PubsubV1::AcknowledgeRequest.new(ack_ids: ack_ids)

        puts "Acknowledging all #{ack_ids.length} messages pulled from the subscription."

        pubsub.acknowledge_subscription(subscription_name, ack_req_object)
      end
    end
  else
    puts 'No messages received from the subscription.'
  end
end


if __FILE__ == $0
  begin
    # Retrieve the service used to make API requests.
    service = get_cloud_pub_sub_service()
  rescue ArgumentError => e
    raise 'Unable to create service, with error message: #{e.message}'
  rescue Signet::AuthorizationError => e
    raise ('Unable to create service, was the KEY_FILE in util.rb set? ' +
           'Error message: #{e.message}')
  end

  # Set options and default values for fields used in this example.
  options = [
    Option.new(
      'subscription_name',
      'The Google Cloud Pub/Sub subscription to be pulled. This value would be returned in the response from the '\
      'bidders.creatives.watch method, and should be provided as-is in the form:'\
      'projects/realtimebidding-pubsub/subscriptions/{subscription_id}',
      short_alias: 's', required: true, default_value: nil
    ),
    Option.new(
      'max_messages',
      'The maximum number of messages to be returned in a single pull.',
      type: Integer, short_alias: 'm', required: false, default_value: 100
    ),
    Option.new(
      'acknowledge',
      'Whether to acknowledge the messages pulled from the subscription. Acknowledged messages won\'t appear in '\
      'subsequent responses to pulls from the subscription. By default, this sample will not acknowledge messages '\
      'pulled from the subscription.',
      type: FalseClass, short_alias: 'a', required: false, default_value: false
    ),
  ]

  # Parse options.
  parser = Parser.new(options)
  opts = parser.parse(ARGV)

  begin
    pull_watched_creatives_subscription(service, opts)
  rescue Google::Apis::ServerError => e
    raise "The following server error occured:\n#{e.message}"
  rescue Google::Apis::ClientError => e
    raise "Invalid client request:\n#{e.message}"
  rescue Google::Apis::AuthorizationError => e
    raise "Authorization error occured:\n#{e.message}"
  end
end