获取产品类别常量

Java

// Copyright 2019 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.ads.googleads.examples.shoppingads;

import com.beust.jcommander.Parameter;
import com.google.ads.googleads.examples.utils.ArgumentNames;
import com.google.ads.googleads.examples.utils.CodeSampleParams;
import com.google.ads.googleads.lib.GoogleAdsClient;
import com.google.ads.googleads.v17.errors.GoogleAdsError;
import com.google.ads.googleads.v17.errors.GoogleAdsException;
import com.google.ads.googleads.v17.resources.ProductCategoryConstant;
import com.google.ads.googleads.v17.resources.ProductCategoryConstant.ProductCategoryLocalization;
import com.google.ads.googleads.v17.services.GoogleAdsRow;
import com.google.ads.googleads.v17.services.GoogleAdsServiceClient;
import com.google.ads.googleads.v17.services.GoogleAdsServiceClient.SearchPagedResponse;
import com.google.ads.googleads.v17.services.SearchGoogleAdsRequest;
import com.google.api.client.util.Preconditions;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** Fetches the set of all ProductCategoryConstants. */
public class GetProductCategoryConstants {

  private static class GetProductCategoryConstantParams extends CodeSampleParams {

    @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true)
    Long customerId;
  }

  public static void main(String args[]) {
    GetProductCategoryConstantParams params = new GetProductCategoryConstantParams();
    if (!params.parseArguments(args)) {
      // Either pass the required parameters for this example on the command line, or insert them
      // into the code here. See the parameter class definition above for descriptions.
      params.customerId = Long.parseLong("ENTER_CUSTOMER_ID_HERE");
    }

    GoogleAdsClient googleAdsClient = null;
    try {
      googleAdsClient = GoogleAdsClient.newBuilder().fromPropertiesFile().build();
    } catch (FileNotFoundException fnfe) {
      System.err.printf(
          "Failed to load GoogleAdsClient configuration from file. Exception: %s%n", fnfe);
      System.exit(1);
    } catch (IOException ioe) {
      System.err.printf("Failed to create GoogleAdsClient. Exception: %s%n", ioe);
      System.exit(1);
    }

    try {
      new GetProductCategoryConstants().runExample(googleAdsClient, params.customerId);
    } catch (GoogleAdsException gae) {
      // GoogleAdsException is the base class for most exceptions thrown by an API request.
      // Instances of this exception have a message and a GoogleAdsFailure that contains a
      // collection of GoogleAdsErrors that indicate the underlying causes of the
      // GoogleAdsException.
      System.err.printf(
          "Request ID %s failed due to GoogleAdsException. Underlying errors:%n",
          gae.getRequestId());
      int i = 0;
      for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) {
        System.err.printf("  Error %d: %s%n", i++, googleAdsError);
      }
      System.exit(1);
    }
  }

  /**
   * Runs the example.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param customerId the client customer ID.
   */
  private void runExample(GoogleAdsClient googleAdsClient, long customerId) {
    // Creates the query.
    String query =
        "SELECT "
            + "product_category_constant.localizations, "
            + "product_category_constant.product_category_constant_parent "
            + "FROM "
            + "product_category_constant";

    // Creates the request.
    SearchGoogleAdsRequest request =
        SearchGoogleAdsRequest.newBuilder()
            .setCustomerId(Long.toString(customerId))
            .setQuery(query)
            .build();

    // Creates the Google Ads Service Client.
    try (GoogleAdsServiceClient googleAdsServiceClient =
        googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {

      // Creates a list of top level category nodes.
      List<CategoryNode> rootCategories = new ArrayList<>();
      // Creates a map of category resource name to category node for all categories found in the
      // results. This Map is a convenience lookup to enable fast retrieval of existing nodes.
      Map<String, CategoryNode> biddingCategories = new HashMap<>();

      // Performs the search request.
      SearchPagedResponse response = googleAdsServiceClient.search(request);
      for (GoogleAdsRow googleAdsRow : response.iterateAll()) {
        // Gets the product category constant from the row.
        ProductCategoryConstant productCategory = googleAdsRow.getProductCategoryConstant();

        // Finds the US-en localized name in the localizations list.
        String localizedName =
            productCategory.getLocalizationsList().stream()
                .filter(
                    localization ->
                        "US".equals(localization.getRegionCode())
                            && "en".equals(localization.getLanguageCode()))
                // Gets the name from the product category localization.
                .map(ProductCategoryLocalization::getValue)
                .findAny()
                .orElse(null);
        String resourceName = productCategory.getResourceName();
        CategoryNode node = biddingCategories.get(resourceName);
        if (node == null) {
          // Adds a node for the resource name to the map.
          node = new CategoryNode(resourceName, localizedName);
          biddingCategories.put(resourceName, node);
        } else if (node.getLocalizedName() == null) {
          // Ensures that the name attribute for the node is set. Name will be null for nodes added
          // to biddingCategories as a result of being a parentNode below.
          node.setLocalizedName(localizedName);
        }

        if (productCategory.hasProductCategoryConstantParent()) {
          // Looks for the parent category's node in the map and adds it if it is not present.
          String parentResourceName = productCategory.getProductCategoryConstantParent();
          CategoryNode parentNode = biddingCategories.get(parentResourceName);
          if (parentNode == null) {
            parentNode = new CategoryNode(parentResourceName);
            biddingCategories.put(parentResourceName, parentNode);
          }
          parentNode.children.add(node);
        } else {
          // The category has no parent, so adds the category's node to the list of root categories
          // encountered.
          rootCategories.add(node);
        }
      }
      displayCategories(rootCategories, "");
    }
  }

  /**
   * Recursively prints out each category node and its children.
   *
   * @param categories the categories to print.
   * @param prefix the string to print at the beginning of each line of output.
   */
  private static void displayCategories(List<CategoryNode> categories, String prefix) {
    for (CategoryNode category : categories) {
      System.out.printf("%s%s [%s]%n", prefix, category.localizedName, category.resourceName);
      displayCategories(
          category.children, String.format("%s%s > ", prefix, category.localizedName));
    }
  }

  /** Node that tracks a product bidding category's id, name, and child nodes. */
  private static class CategoryNode {
    private final String resourceName;
    private String localizedName;
    private final List<CategoryNode> children;

    /**
     * Gets the localized name of the category.
     *
     * @return the name of the category.
     */
    public String getLocalizedName() {
      return this.localizedName;
    }

    /**
     * Sets the localized name of the category.
     *
     * @param localizedName the new name of the category.
     */
    public void setLocalizedName(String localizedName) {
      this.localizedName = localizedName;
    }

    /**
     * Constructor for categories first encountered as non-parent elements in the results.
     *
     * @param resourceName the resource name = of the category
     * @param localizedName the name of the category
     */
    CategoryNode(String resourceName, String localizedName) {
      this.children = new ArrayList<>();
      this.resourceName = Preconditions.checkNotNull(resourceName);
      this.localizedName = localizedName;
    }

    /**
     * Constructor for categories first encountered as a parent category, in which case only the
     * resource name is available.
     *
     * @param resourceName the resource name of the category
     */
    CategoryNode(String resourceName) {
      this(resourceName, null);
    }
  }
}

      

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 CommandLine;
using Google.Ads.Gax.Examples;
using Google.Ads.GoogleAds.Extensions.Config;
using Google.Ads.GoogleAds.Lib;
using Google.Ads.GoogleAds.V17.Errors;
using Google.Ads.GoogleAds.V17.Resources;
using Google.Ads.GoogleAds.V17.Services;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Google.Ads.GoogleAds.Examples.V17
{
    /// <summary>
    /// This code example fetches the set of valid ProductCategories.
    /// </summary>
    public class GetProductCategoryConstants : ExampleBase
    {
        /// <summary>
        /// Command line options for running the <see cref="GetProductCategoryConstants"/>
        /// example.
        /// </summary>
        public class Options : OptionsBase
        {
            /// <summary>
            /// The Google Ads customer ID for which the call is made.
            /// </summary>
            [Option("customerId", Required = true, HelpText =
                "The Google Ads customer ID for which the call is made.")]
            public long CustomerId { get; set; }
        }

        /// <summary>
        /// Main method, to run this code example as a standalone application.
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        public static void Main(string[] args)
        {
            Options options = ExampleUtilities.ParseCommandLine<Options>(args);

            GetProductCategoryConstants codeExample = new GetProductCategoryConstants();
            Console.WriteLine(codeExample.Description);
            codeExample.Run(new GoogleAdsClient(), options.CustomerId);
        }

        /// <summary>
        /// Node that tracks a product category's id, name, and child nodes.
        /// </summary>

        public class CategoryNode
        {
            /// <summary>
            /// The resource name of the category.
            /// </summary>
            public string ResourceName
            {
                get;
                private set;
            }

            /// <summary>
            /// Gets or sets the localized name of the category.
            /// </summary>
            public string LocalizedName
            {
                get;
                set;
            }

            /// <summary>
            /// Gets the list of child.
            /// </summary>
            public List<CategoryNode> Children
            {
                get;
            } = new List<CategoryNode>();

            /// <summary>
            /// Constructor for categories first encountered as non-parent elements in the results.
            /// </summary>
            /// <param name="resourceName">The resource name of the category.</param>
            /// <param name="localizedName">The name of the category.</param>
            public CategoryNode(string resourceName, string localizedName)
            {
                if (string.IsNullOrEmpty(resourceName))
                {
                    throw new ArgumentNullException();
                }
                this.ResourceName = resourceName;
                this.LocalizedName = localizedName;
            }

            /// <summary>
            /// Constructor for categories first encountered as a parent category, in which case
            /// only the ID is available.
            /// </summary>
            /// <param name="resourceName">The resource name of the category.</param>
            public CategoryNode(string resourceName) : this(resourceName, null) { }
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description =>
            "This code example fetches the set of valid ProductCategories.";

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads customer ID for which the call is made.</param>
        public void Run(GoogleAdsClient client, long customerId)
        {
            // Get the GoogleAdsServiceClient .
            GoogleAdsServiceClient googleAdsService =
                client.GetService(Services.V17.GoogleAdsService);

            // Creates the query.
            string query = "SELECT product_category_constant.localizations, " +
                "product_category_constant.product_category_constant_parent " +
                "FROM product_category_constant";

            // Creates the request.
            SearchGoogleAdsRequest request = new SearchGoogleAdsRequest()
            {
                CustomerId = customerId.ToString(),
                Query = query
            };

            // Creates a list of top level category nodes.
            List<CategoryNode> rootCategories = new List<CategoryNode>();

            // Creates a map of category ID to category node for all categories found in the
            // results.
            // This Map is a convenience lookup to enable fast retrieval of existing nodes.
            Dictionary<string, CategoryNode> productCategories =
                new Dictionary<string, CategoryNode>();

            try
            {
                // Performs the search request.
                foreach (GoogleAdsRow googleAdsRow in googleAdsService.Search(request))
                {
                    ProductCategoryConstant productCategory =
                        googleAdsRow.ProductCategoryConstant;

                    string localizedName = productCategory.Localizations
                        .Where(item => item.RegionCode == "US" && item.LanguageCode == "en")
                        .Select(item => item.Value.ToString())
                        .First();
                    string resourceName = productCategory.ResourceName;

                    CategoryNode node = null;
                    if (productCategories.ContainsKey(resourceName))
                    {
                        node = productCategories[resourceName];
                    }
                    else
                    {
                        node = new CategoryNode(resourceName, localizedName);
                        productCategories[resourceName] = node;
                    }

                    if (string.IsNullOrEmpty(node.LocalizedName))
                    {
                        // Ensures that the name attribute for the node is set. Name will be null for
                        //nodes added to productCategories as a result of being a parentNode below.
                        node.LocalizedName = localizedName;
                    }

                    if (!string.IsNullOrEmpty(
                        productCategory.ProductCategoryConstantParent))
                    {
                        string parentResourceName =
                            productCategory.ProductCategoryConstantParent;
                        CategoryNode parentNode = null;

                        if (productCategories.ContainsKey(parentResourceName))
                        {
                            parentNode = productCategories[parentResourceName];
                        }
                        else
                        {
                            parentNode = new CategoryNode(parentResourceName);
                            productCategories[parentResourceName] = parentNode;
                        }
                        parentNode.Children.Add(node);
                    }
                    else
                    {
                        rootCategories.Add(node);
                    }
                }
                DisplayCategories(rootCategories, "");
            }
            catch (GoogleAdsException e)
            {
                Console.WriteLine("Failure:");
                Console.WriteLine($"Message: {e.Message}");
                Console.WriteLine($"Failure: {e.Failure}");
                Console.WriteLine($"Request ID: {e.RequestId}");
                throw;
            }
        }

        /// <summary>
        /// Recursively prints out each category node and its children.
        /// </summary>
        /// <param name="categories">The categories to print.</param>
        /// <param name="prefix">The string to print at the beginning of each line of output.
        /// </param>
        private static void DisplayCategories(IEnumerable<CategoryNode> categories,
            string prefix)
        {
            foreach (CategoryNode category in categories)
            {
                Console.WriteLine($"{prefix}{category.LocalizedName}" +
                    $" [{category.ResourceName}]");
                DisplayCategories(category.Children, $"{prefix}{category.LocalizedName} > ");
            }
        }
    }
}

      

PHP

<?php

/**
 * Copyright 2019 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\GoogleAds\Examples\ShoppingAds;

require __DIR__ . '/../../vendor/autoload.php';

use GetOpt\GetOpt;
use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames;
use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V17\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V17\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V17\GoogleAdsException;
use Google\Ads\GoogleAds\V17\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V17\Resources\ProductCategoryConstant;
use Google\Ads\GoogleAds\V17\Resources\ProductCategoryConstant\ProductCategoryLocalization;
use Google\Ads\GoogleAds\V17\Services\GoogleAdsRow;
use Google\Ads\GoogleAds\V17\Services\SearchGoogleAdsRequest;
use Google\ApiCore\ApiException;

/** Fetches the set of all ProductCategoryConstants. */
class GetProductCategoryConstants
{
    private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE';

    public static function main()
    {
        // Either pass the required parameters for this example on the command line, or insert them
        // into the constants above.
        $options = (new ArgumentParser())->parseCommandArguments([
            ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT
        ]);

        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct a Google Ads client configured from a properties file and the
        // OAuth2 credentials above.
        $googleAdsClient = (new GoogleAdsClientBuilder())
            ->fromFile()
            ->withOAuth2Credential($oAuth2Credential)
            // We set this value to true to show how to use GAPIC v2 source code. You can remove the
            // below line if you wish to use the old-style source code. Note that in that case, you
            // probably need to modify some parts of the code below to make it work.
            // For more information, see
            // https://developers.devsite.corp.google.com/google-ads/api/docs/client-libs/php/gapic.
            ->usingGapicV2Source(true)
            ->build();

        try {
            self::runExample(
                $googleAdsClient,
                $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID
            );
        } catch (GoogleAdsException $googleAdsException) {
            printf(
                "Request with ID '%s' has failed.%sGoogle Ads failure details:%s",
                $googleAdsException->getRequestId(),
                PHP_EOL,
                PHP_EOL
            );
            foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) {
                /** @var GoogleAdsError $error */
                printf(
                    "\t%s: %s%s",
                    $error->getErrorCode()->getErrorCode(),
                    $error->getMessage(),
                    PHP_EOL
                );
            }
            exit(1);
        } catch (ApiException $apiException) {
            printf(
                "ApiException was thrown with message '%s'.%s",
                $apiException->getMessage(),
                PHP_EOL
            );
            exit(1);
        }
    }

    /**
     * Runs the example.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     */
    public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId)
    {
        $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
        // Creates the query.
        $query = "SELECT product_category_constant.localizations, "
            . "product_category_constant.product_category_constant_parent "
            . "FROM product_category_constant ";

        // Performs the search request.
        $response =
            $googleAdsServiceClient->search(SearchGoogleAdsRequest::build($customerId, $query));

        // Creates a map of top level categories.
        $rootCategories = [];
        // Creates a map of all categories found in the results.
        // This is a convenience lookup to enable fast retrieval of existing categories.
        $biddingCategories = [];

        // Iterates over all rows in all pages to extract the result.
        foreach ($response->iterateAllElements() as $googleAdsRow) {
            /**
             * @var GoogleAdsRow $googleAdsRow
             * @var ProductCategoryConstant $productBiddingCategory
             */
            // Gets the product category constant from the row.
            $productBiddingCategory = $googleAdsRow->getProductCategoryConstant();

            // Finds the US-en localized name in the localizations list.
            /** @var ProductCategoryLocalization[] $filteredLocalizations */
            $filteredLocalizations = array_filter(
                iterator_to_array($productBiddingCategory->getLocalizations()->getIterator()),
                function (ProductCategoryLocalization $productCategoryLocalization) {
                    return $productCategoryLocalization->getRegionCode() === 'US'
                        && $productCategoryLocalization->getLanguageCode() === 'en';
                }
            );
            // Fetches the first value in the filtered array, which is supposed to contain only
            // one member or none at all.
            $localizedName = empty($filteredLocalizations)
                ? null : array_shift($filteredLocalizations)->getValue();
            $resourceName = $productBiddingCategory->getResourceName();

            // Adds the category in the map if new.
            if (!array_key_exists($resourceName, $biddingCategories)) {
                $biddingCategories[$resourceName] = [];
            }

            // Sets the localized name attribute if not already set.
            if (!array_key_exists('localizedName', $biddingCategories[$resourceName])) {
                $biddingCategories[$resourceName]['localizedName'] = $localizedName;
            }
            if ($productBiddingCategory->getProductCategoryConstantParent() === '') {
                // Adds the category as a root category if having no parent.
                $rootCategories[$resourceName] = &$biddingCategories[$resourceName];
            } else {
                // Links the category to the parent category if any.
                $parentResourceName =
                    $productBiddingCategory->getProductCategoryConstantParent();
                // Adds the parent category in the map if new.
                if (!array_key_exists($parentResourceName, $biddingCategories)) {
                    $biddingCategories[$parentResourceName] = [];
                }
                // Adds the category as a child category of the parent category.
                $biddingCategories[$parentResourceName]['children'][$resourceName] =
                    &$biddingCategories[$resourceName];
            }
        }
        // Prints the result.
        self::displayCategories($rootCategories, '');
    }



    /**
     * Recursively prints out each category and its children.
     *
     * @param array $categories the map of categories to print
     * @param string $prefix the string to print at the beginning of each line of output
     */
    private static function displayCategories(
        array $categories,
        string $prefix
    ) {
        foreach ($categories as $categoryKey => $categoryValue) {
            $localizedName = $categoryValue['localizedName'];
            printf(
                '%s%s [%s]%s',
                $prefix,
                $localizedName,
                $categoryKey,
                PHP_EOL
            );
            if (array_key_exists('children', $categoryValue)) {
                self::displayCategories(
                    $categoryValue['children'],
                    sprintf('%s%s > ', $prefix, $localizedName)
                );
            }
        }
    }
}

GetProductCategoryConstants::main();

      

Python

#!/usr/bin/env python
# Copyright 2019 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.
"""This example fetches the set of all ProductCategoryConstants."""


import argparse
import collections
import sys
from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException


def display_categories(categories, prefix=""):
    """Recursively prints out each category and its children.

    Args:
      categories: the map of categories to print
      prefix: the string to print at the beginning of each line of output

    Returns: None
    """
    for category in categories:
        print(f"{prefix} {category.localized_name} [{category.resource_name}]")
        if category.children:
            display_categories(
                category.children, prefix=f"{prefix} {category.localized_name}"
            )


def main(client, customer_id):
    """Fetches the set of valid ProductBiddingCategories."""

    class Category:
        def __init__(
            self, localized_name=None, resource_name=None, children=None
        ):
            self.localized_name = localized_name
            self.resource_name = resource_name
            if children is None:
                self.children = []
            else:
                self.children = children

    ga_service = client.get_service("GoogleAdsService")
    query = """
        SELECT
            product_category_constant.localizations,
            product_category_constant.product_category_constant_parent
        FROM product_category_constant"""

    search_request = client.get_type("SearchGoogleAdsStreamRequest")
    search_request.customer_id = customer_id
    search_request.query = query
    stream = ga_service.search_stream(search_request)

    all_categories = collections.defaultdict(lambda: Category())

    # Creates a map of top level categories.
    root_categories = []

    for batch in stream:
        for row in batch.results:
            # Gets the product category constant from the row.
            product_category = row.product_category_constant

            localized_name = ""
            for localization in product_category.localizations:
                region = localization.region_code
                lang = localization.language_code
                if region == "US" and lang == "en":
                    # Gets the name from the product category localization.
                    localized_name = localization.value
                    break

            category = Category(
                localized_name=localized_name,
                resource_name=product_category.resource_name,
            )

            all_categories[category.resource_name] = category
            parent_resource_name = (
                product_category.product_category_constant_parent
            )

            # Links the category to the parent category if any.
            if parent_resource_name:
                # Adds the category as a child category of the parent
                # category.
                all_categories[parent_resource_name].children.append(category)
            else:
                # Otherwise adds the category as a root category.
                root_categories.append(category)

    display_categories(root_categories)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Get Product Bidding Category Constant"
    )
    # The following argument(s) should be provided to run the example.
    parser.add_argument(
        "-c",
        "--customer_id",
        type=str,
        required=True,
        help="The Google Ads customer ID.",
    )
    args = parser.parse_args()

    # GoogleAdsClient will read the google-ads.yaml configuration file in the
    # home directory if none is specified.
    googleads_client = GoogleAdsClient.load_from_storage(version="v17")

    try:
        main(googleads_client, args.customer_id)
    except GoogleAdsException as ex:
        print(
            f'Request with ID "{ex.request_id}" failed with status '
            f'"{ex.error.code().name}" and includes the following errors:'
        )
        for error in ex.failure.errors:
            print(f'\tError with message "{error.message}".')
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print(f"\t\tOn field: {field_path_element.field_name}")
        sys.exit(1)

      

Ruby

#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright 2019 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.
#
# This example fetches the set of all ProductCategoryConstants.

require 'optparse'
require 'google/ads/google_ads'

def display_categories(categories, prefix: '')
  categories.each do |c|
    puts "#{prefix}#{c.fetch(:name)} [#{c.fetch(:id)}]"
    unless c.fetch(:children).empty?
      display_categories(
        c.fetch(:children),
        prefix: "#{prefix}#{c.fetch(:name)} > "
      )
    end
  end
end

def get_product_category_constant(customer_id)
  # GoogleAdsClient will read a config file from
  # ENV['HOME']/google_ads_config.rb when called without parameters
  client = Google::Ads::GoogleAds::GoogleAdsClient.new

  query = <<~EOD
    SELECT
      product_category_constant.localizations,
      product_category_constant.product_category_constant_parent
    FROM
      product_category_constant
  EOD

  ga_service = client.service.google_ads
  response = ga_service.search(
      customer_id: customer_id,
      query: query,
      page_size: PAGE_SIZE,
  )

  # Default the values in the hash to have an Array of children, so that
  # we can push children in before we've discovered all the data for the
  # parent category.
  all_categories = Hash.new do |h, k|
    h[k] = {children: []}
  end
  root_categories = Set.new

  response.each do |row|
    product_category = row.product_category_constant

    localized_product = product_category.localizations.detect{ |l|
      l.region_code == "US" && l.language_code == 'en'
    }

    category = {
      name: localized_product.value,
      id: product_category.resource_name,
      children: []
    }

    all_categories[category.fetch(:id)] = category
    parent_id = product_category.product_category_constant_parent

    if parent_id
      all_categories[parent_id][:children] << category
    else
      root_categories.add(category)
    end
  end

  display_categories(root_categories)
end

if __FILE__ == $0
  PAGE_SIZE = 1000

  options = {}
  # The following parameter(s) should be provided to run the example. You can
  # either specify these by changing the INSERT_XXX_ID_HERE values below, or on
  # the command line.
  #
  # Parameters passed on the command line will override any parameters set in
  # code.
  #
  # Running the example with -h will print the command line usage.
  options[:customer_id] = 'INSERT_CUSTOMER_ID_HERE'

  OptionParser.new do |opts|
    opts.banner = sprintf('Usage: %s [options]', File.basename(__FILE__))

    opts.separator ''
    opts.separator 'Options:'

    opts.on('-C', '--customer-id CUSTOMER-ID', String, 'Customer ID') do |v|
      options[:customer_id] = v
    end

    opts.separator ''
    opts.separator 'Help:'

    opts.on_tail('-h', '--help', 'Show this message') do
      puts opts
      exit
    end
  end.parse!

  begin
    get_product_category_constant(
      options.fetch(:customer_id).tr("-", "")
    )
  rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e
    e.failure.errors.each do |error|
      STDERR.printf("Error with message: %s\n", error.message)
      if error.location
        error.location.field_path_elements.each do |field_path_element|
          STDERR.printf("\tOn field: %s\n", field_path_element.field_name)
        end
      end
      error.error_code.to_h.each do |k, v|
        next if v == :UNSPECIFIED
        STDERR.printf("\tType: %s\n\tCode: %s\n", k, v)
      end
    end
    raise
  end
end

      

Perl

#!/usr/bin/perl -w
#
# Copyright 2019, 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.
#
# This example fetches the set of all ProductCategoryConstants.

use strict;
use warnings;
use utf8;

use FindBin qw($Bin);
use lib "$Bin/../../lib";
use Google::Ads::GoogleAds::Client;
use Google::Ads::GoogleAds::Utils::GoogleAdsHelper;
use Google::Ads::GoogleAds::Utils::SearchGoogleAdsIterator;
use
  Google::Ads::GoogleAds::V17::Services::GoogleAdsService::SearchGoogleAdsRequest;

use Getopt::Long qw(:config auto_help);
use Pod::Usage;
use Cwd qw(abs_path);

# The following parameter(s) should be provided to run the example. You can
# either specify these by changing the INSERT_XXX_ID_HERE values below, or on
# the command line.
#
# Parameters passed on the command line will override any parameters set in
# code.
#
# Running the example with -h will print the command line usage.
my $customer_id = "INSERT_CUSTOMER_ID_HERE";

sub get_product_category_constants {
  my ($api_client, $customer_id) = @_;

  # Create the search query.
  my $search_query =
    "SELECT product_category_constant.localizations, " .
    "product_category_constant.product_category_constant_parent " .
    "FROM product_category_constant";

  # Create a search Google Ads request that will retrieve all product
  # categories using pages of the specified page size.
  my $search_request =
    Google::Ads::GoogleAds::V17::Services::GoogleAdsService::SearchGoogleAdsRequest
    ->new({
      customerId => $customer_id,
      query      => $search_query
    });

  # Get the GoogleAdsService.
  my $google_ads_service = $api_client->GoogleAdsService();

  my $iterator = Google::Ads::GoogleAds::Utils::SearchGoogleAdsIterator->new({
    service => $google_ads_service,
    request => $search_request
  });

  # Default the values in the hash to have an array of children, so that
  # we can push children in before we've discovered all the data for the
  # parent category.
  my $all_categories  = {};
  my $root_categories = [];

  while ($iterator->has_next) {
    my $google_ads_row   = $iterator->next;
    my $product_category = $google_ads_row->{productCategoryConstant};

    # Find the US-en localized name in the localizations list.
    my @localizations =
      grep { $_->{regionCode} eq "US" and $_->{languageCode} eq "en" }
      @{$product_category->{localizations}};
    my $localized_name = @localizations ? @localizations[0]->{value} : undef;
    my $category       = {
      name     => $localized_name,
      id       => $product_category->{resourceName},
      children => []};

    $all_categories->{$category->{id}} = $category;

    my $parent_id = $product_category->{productCategoryConstantParent};
    if ($parent_id) {
      push @{$all_categories->{$parent_id}{children}}, $category;
    } else {
      push @$root_categories, $category;
    }
  }

  display_categories($root_categories, "");

  return 1;
}

# Recursively prints out each category node and its children.
sub display_categories {
  my ($categories, $prefix) = @_;
  foreach my $category (@$categories) {
    printf "%s%s [%s]\n", $prefix, $category->{name}, $category->{id};
    display_categories($category->{children},
      sprintf("%s%s > ", $prefix, $category->{name}));
  }
}

# Don't run the example if the file is being included.
if (abs_path($0) ne abs_path(__FILE__)) {
  return 1;
}

# Get Google Ads Client, credentials will be read from ~/googleads.properties.
my $api_client = Google::Ads::GoogleAds::Client->new();

# By default examples are set to die on any server returned fault.
$api_client->set_die_on_faults(1);

# Parameters passed on the command line will override any parameters set in code.
GetOptions("customer_id=s" => \$customer_id);

# Print the help message if the parameters are not initialized in the code nor
# in the command line.
pod2usage(2) if not check_params($customer_id);

# Call the example.
get_product_category_constants($api_client, $customer_id =~ s/-//gr);

=pod

=head1 NAME

get_product_category_constants

=head1 DESCRIPTION

This example fetches the set of all ProductCategoryConstants.

=head1 SYNOPSIS

get_product_category_constants.pl [options]

    -help                       Show the help message.
    -customer_id                The Google Ads customer ID.

=cut