Get Account Changes

Java
// Copyright 2018 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.accountmanagement;

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.v1.errors.GoogleAdsException;
import com.google.ads.googleads.v1.errors.GoogleAdsError;
import com.google.ads.googleads.v1.resources.ChangeStatus;
import com.google.ads.googleads.v1.services.GoogleAdsRow;
import com.google.ads.googleads.v1.services.GoogleAdsServiceClient;
import com.google.ads.googleads.v1.services.GoogleAdsServiceClient.SearchPagedResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Optional;

/** Gets the changes in the account made in the last 7 days. */
public class GetAccountChanges {

  private static class GetAccountChangesParams extends CodeSampleParams {

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

  public static void main(String[] args) {
    GetAccountChangesParams params = new GetAccountChangesParams();
    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("INSERT_CUSTOMER_ID_HERE");
    }

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

    try {
      new GetAccountChanges().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);
      }
    }
  }

  /**
   * Runs the example.
   *
   * @param googleAdsClient the client instance.
   * @param customerId the customerId for which to retrieve change status.
   */
  private void runExample(GoogleAdsClient googleAdsClient, long customerId) {
    String query =
        "SELECT change_status.resource_name, "
            + "change_status.last_change_date_time, "
            + "change_status.resource_type, "
            + "change_status.campaign, "
            + "change_status.ad_group, "
            + "change_status.resource_status, "
            + "change_status.ad_group_ad, "
            + "change_status.ad_group_criterion, "
            + "change_status.campaign_criterion "
            + "FROM change_status "
            + "WHERE change_status.last_change_date_time DURING LAST_7_DAYS "
            + "ORDER BY change_status.last_change_date_time";

    try (GoogleAdsServiceClient client = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
      SearchPagedResponse response = client.search(String.valueOf(customerId), query);

      for (GoogleAdsRow row : response.iterateAll()) {
        Optional<String> resourceNameOfChangedEntity =
            getResourceNameForResourceType(row.getChangeStatus());

        System.out.printf(
            "On '%s', change status '%s' shows a resource type of '%s' "
                + "with resource name '%s' was '%s'.%n",
            row.getChangeStatus().getLastChangeDateTime().getValue(),
            row.getChangeStatus().getResourceName(),
            row.getChangeStatus().getResourceType().name(),
            resourceNameOfChangedEntity.orElse(""),
            row.getChangeStatus().getResourceStatus().name());
      }
    }
  }

  /**
   * Each returned row contains all possible changed fields. This function returns the resource name
   * of the changed field based on the resource type. The changed field's parent is also populated
   * but is not used.
   *
   * @param changeStatus the change status for which to get affected resource name.
   * @return an Optional has a value when one could be obtained for the change resource type.
   */
  private static Optional<String> getResourceNameForResourceType(ChangeStatus changeStatus) {
    String resourceName = null;
    // This is the list of all known resource names but may be subject to change in the future.
    // See https://developers.google.com/google-ads/api/docs/change-status for a description.
    switch (changeStatus.getResourceType()) {
      case AD_GROUP:
        resourceName = changeStatus.getAdGroup().getValue();
        break;
      case AD_GROUP_AD:
        resourceName = changeStatus.getAdGroupAd().getValue();
        break;
      case AD_GROUP_CRITERION:
        resourceName = changeStatus.getAdGroup().getValue();
        break;
      case CAMPAIGN:
        resourceName = changeStatus.getCampaign().getValue();
        break;
      case CAMPAIGN_CRITERION:
        resourceName = changeStatus.getCampaignCriterion().getValue();
        break;
    }
    return Optional.ofNullable(resourceName);
  }
}
C#
// Copyright 2018 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.Ads.GoogleAds.Lib;
using Google.Ads.GoogleAds.V1.Errors;
using Google.Ads.GoogleAds.V1.Services;
using Google.Api.Gax;
using static Google.Ads.GoogleAds.V1.Enums.ChangeStatusResourceTypeEnum.Types;

using System;

namespace Google.Ads.GoogleAds.Examples.V1
{
    /// <summary>
    /// This code example gets the changes in an account during the last 7 days.
    /// </summary>
    public class GetAccountChanges : ExampleBase
    {
        /// <summary>
        /// The page size to be used by default.
        /// </summary>
        private const int PAGE_SIZE = 1_000;

        /// <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)
        {
            GetAccountChanges codeExample = new GetAccountChanges();

            Console.WriteLine(codeExample.Description);

            // The Google Ads customer ID for which the call is made.
            long customerId = long.Parse("INSERT_CUSTOMER_ID_HERE");

            codeExample.Run(new GoogleAdsClient(), customerId);
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description
        {
            get
            {
                return "This code example gets the changes in an account during the last 7 days.";
            }
        }

        /// <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 GoogleAdsService.
            GoogleAdsServiceClient googleAdsService = client.GetService(
                Services.V1.GoogleAdsService);

            string searchQuery = "SELECT change_status.resource_name, " +
                "change_status.last_change_date_time, change_status.resource_type, " +
                "change_status.campaign, change_status.ad_group, change_status.resource_status, " +
                "change_status.ad_group_ad, change_status.ad_group_criterion, " +
                "change_status.campaign_criterion FROM change_status " +
                "WHERE change_status.last_change_date_time DURING LAST_7_DAYS " +
                "ORDER BY change_status.last_change_date_time";

            // Create a request that will retrieve all changes using pages of the specified
            // page size.
            SearchGoogleAdsRequest request = new SearchGoogleAdsRequest()
            {
                PageSize = PAGE_SIZE,
                Query = searchQuery,
                CustomerId = customerId.ToString()
            };

            try
            {
                // Issue the search request.
                PagedEnumerable<SearchGoogleAdsResponse, GoogleAdsRow> searchPagedResponse =
                    googleAdsService.Search(request);

                // Iterate over all rows in all pages and prints the requested field values for the
                // campaign in each row.
                foreach (GoogleAdsRow googleAdsRow in searchPagedResponse)
                {
                    Console.WriteLine("Last change: {0}, Resource type: {1}, " +
                        "Resource name: {2}, Resource status: {3}, Specific resource name: {4}",
                        googleAdsRow.ChangeStatus.LastChangeDateTime,
                        googleAdsRow.ChangeStatus.ResourceType,
                        googleAdsRow.ChangeStatus.ResourceName,
                        googleAdsRow.ChangeStatus.ResourceStatus,
                        SpecificResourceName(googleAdsRow.ChangeStatus.ResourceType,
                            googleAdsRow));
                }
            }
            catch (GoogleAdsException e)
            {
                Console.WriteLine("Failure:");
                Console.WriteLine($"Message: {e.Message}");
                Console.WriteLine($"Failure: {e.Failure}");
                Console.WriteLine($"Request ID: {e.RequestId}");
            }
        }

        /// <summary>
        /// Return the name of the most specific resource that changed.
        /// </summary>
        /// <param name="resourceType">Type of the resource.</param>
        /// <param name="row">Each returned row contains all possible changed fields</param>
        /// <returns>The resource name of the changed field based on the resource type.
        /// The changed field's parent is also populated, but is not used.</returns>
        string SpecificResourceName(ChangeStatusResourceType resourceType, GoogleAdsRow row)
        {
            string resourceName = "";

            switch (resourceType)
            {
                case ChangeStatusResourceType.AdGroup:
                    resourceName = row.ChangeStatus.AdGroup;
                    break;

                case ChangeStatusResourceType.AdGroupAd:
                    resourceName = row.ChangeStatus.AdGroupAd;
                    break;

                case ChangeStatusResourceType.AdGroupCriterion:
                    resourceName = row.ChangeStatus.AdGroupCriterion;
                    break;

                case ChangeStatusResourceType.Campaign:
                    resourceName = row.ChangeStatus.Campaign;
                    break;

                case ChangeStatusResourceType.CampaignCriterion:
                    resourceName = row.ChangeStatus.CampaignCriterion;
                    break;

                case ChangeStatusResourceType.Unknown:
                case ChangeStatusResourceType.Unspecified:
                default:
                    resourceName = "";
                    break;
            }
            return resourceName;
        }
    }
}
PHP
<?php
/**
 * Copyright 2018 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\AccountManagement;

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\V1\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V1\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V1\GoogleAdsException;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\V1\Enums\ChangeStatusOperationEnum\ChangeStatusOperation;
use Google\Ads\GoogleAds\V1\Enums\ChangeStatusResourceTypeEnum\ChangeStatusResourceType;
use Google\Ads\GoogleAds\V1\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V1\Resources\ChangeStatus;
use Google\Ads\GoogleAds\V1\Services\GoogleAdsRow;
use Google\ApiCore\ApiException;

/**
 * This example gets the changes in the account made in the last 7 days.
 */
class GetAccountChanges
{
    const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE';
    const PAGE_SIZE = 1000;

    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)
            ->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
                );
            }
        } catch (ApiException $apiException) {
            printf(
                "ApiException was thrown with message '%s'.%s",
                $apiException->getMessage(),
                PHP_EOL
            );
        }
    }

    /**
     * Runs the example.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the client customer ID without hyphens
     */
    public static function runExample(GoogleAdsClient $googleAdsClient, $customerId)
    {
        $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
        // Creates a query that retrieves all change statuses.
        $query = 'SELECT change_status.resource_name, '
           . 'change_status.last_change_date_time, '
           . 'change_status.resource_type, '
           . 'change_status.campaign, '
           . 'change_status.ad_group, '
           . 'change_status.resource_status, '
           . 'change_status.ad_group_ad, '
           . 'change_status.ad_group_criterion, '
           . 'change_status.campaign_criterion '
           . 'FROM change_status '
           . 'WHERE change_status.last_change_date_time DURING LAST_7_DAYS '
           . 'ORDER BY change_status.last_change_date_time';

        // Issues a search request by specifying page size.
        $response =
            $googleAdsServiceClient->search($customerId, $query, ['pageSize' => self::PAGE_SIZE]);

        // Iterates over all rows in all pages and prints the requested field values for
        // the change status in each row.
        foreach ($response->iterateAllElements() as $googleAdsRow) {
            /** @var GoogleAdsRow $googleAdsRow */
            printf(
                "On %s, change status '%s' shows resource '%s' with type '%s' and status '%s'.%s",
                $googleAdsRow->getChangeStatus()->getLastChangeDateTimeValue(),
                $googleAdsRow->getChangeStatus()->getResourceName(),
                self::getResourceNameForResourceType($googleAdsRow->getChangeStatus()),
                ChangeStatusResourceType::name(
                    $googleAdsRow->getChangeStatus()->getResourceType()
                ),
                ChangeStatusOperation::name($googleAdsRow->getChangeStatus()->getResourceStatus()),
                PHP_EOL
            );
        }
    }

    /**
     * Gets the resource name for the resource type of the change status object.
     *
     * Each returned row contains all possible changed resources, only one of which is populated
     * with the name of the changed resource. This function returns the resource name of the
     * changed resource based on the resource type.
     *
     * @param ChangeStatus $changeStatus the change status object for getting changed resource
     * @return string the name of the resource that changed
     */
    private static function getResourceNameForResourceType(
        ChangeStatus $changeStatus
    ) {
        $resourceType = $changeStatus->getResourceType();
        $resourceName = ''; // Default value for UNSPECIFIED or UNKNOWN resource type.
        switch ($resourceType) {
            case ChangeStatusResourceType::AD_GROUP:
                $resourceName = $changeStatus->getAdGroupValue();
                break;
            case ChangeStatusResourceType::AD_GROUP_AD:
                $resourceName = $changeStatus->getAdGroupAdValue();
                break;
            case ChangeStatusResourceType::AD_GROUP_CRITERION:
                $resourceName = $changeStatus->getAdGroupCriterionValue();
                break;
            case ChangeStatusResourceType::CAMPAIGN:
                $resourceName = $changeStatus->getCampaignValue();
                break;
            case ChangeStatusResourceType::CAMPAIGN_CRITERION:
                $resourceName = $changeStatus->getCampaignCriterionValue();
                break;
        }

        return $resourceName;
    }
}

GetAccountChanges::main();
Python
#!/usr/bin/env python
#
# Copyright 2018 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 gets the changes in the account made in the last 7 days."""

from __future__ import absolute_import

import argparse
import sys

import six

import google.ads.google_ads.client


ADS_PAGE_SIZE = 1000


def resource_name_for_resource_type(resource_type, row):
  """Return the resource name for the resource type.

  Each returned row contains all possible changed fields. This function
  returns the resource name of the changed field based on the
  resource type. The changed field's parent is also populated but is not used.

  Args:
    resource_type: the string equivalent of the resource type
    row: a single row returned from the service

  Returns:
    The resource name of the field that changed.
  """
  resource_name = ''  # default for UNSPECIFIED or UNKNOWN
  if resource_type == 'AD_GROUP':
    resource_name = row.change_status.ad_group.value
  elif resource_type == 'AD_GROUP_AD':
    resource_name = row.change_status.ad_group_ad.value
  elif resource_type == 'AD_GROUP_CRITERION':
    resource_name = row.change_status.ad_group_criterion.value
  elif resource_type == 'CAMPAIGN':
    resource_name = row.change_status.campaign.value
  elif resource_type == 'CAMPAIGN_CRITERION':
    resource_name = row.change_status.campaign_criterion.value
  return resource_name


def main(client, customer_id):
  ads_service = client.get_service('GoogleAdsService', version='v1')
  query = ('SELECT change_status.resource_name, '
           'change_status.last_change_date_time, '
           'change_status.resource_type, '
           'change_status.campaign, '
           'change_status.ad_group, '
           'change_status.resource_status, '
           'change_status.ad_group_ad, '
           'change_status.ad_group_criterion, '
           'change_status.campaign_criterion '
           'FROM change_status '
           'WHERE change_status.last_change_date_time DURING LAST_7_DAYS '
           'ORDER BY change_status.last_change_date_time')

  response = ads_service.search(customer_id, query=query,
                                page_size=ADS_PAGE_SIZE)

  resource_type_enum = (client.get_type(
      'ChangeStatusResourceTypeEnum', version='v1').ChangeStatusResourceType)
  change_status_operation_enum = (client.get_type(
      'ChangeStatusOperationEnum', version='v1').ChangeStatusOperation)

  try:
    for row in response:
      resource_type = (resource_type_enum.Name(row.change_status
                                               .resource_type))
      resource_status = (change_status_operation_enum
                         .Name(row.change_status.resource_status))
      print ('On "%s", change status "%s" shows a resource type of "%s" '
             'with resource name "%s" was "%s".'
             % (row.change_status.last_change_date_time.value,
                row.change_status.resource_name,
                resource_type,
                resource_name_for_resource_type(resource_type, row),
                resource_status))
  except google.ads.google_ads.errors.GoogleAdsException as ex:
    print('Request with ID "%s" failed with status "%s" and includes the '
          'following errors:' % (ex.request_id, ex.error.code().name))
    for error in ex.failure.errors:
      print('\tError with message "%s".' % error.message)
      if error.location:
        for field_path_element in error.location.field_path_elements:
          print('\t\tOn field: %s' % field_path_element.field_name)
    sys.exit(1)


if __name__ == '__main__':
  # GoogleAdsClient will read a google-ads.yaml configuration file in the
  # home directory if none is specified.
  google_ads_client = (google.ads.google_ads.client.GoogleAdsClient
                       .load_from_storage())

  parser = argparse.ArgumentParser(
     description=('Displays account changes that occurred in the last 7 days.'))
  # The following argument(s) should be provided to run the example.
  parser.add_argument('-c', '--customer_id', type=six.text_type,
                      required=True, help='The Google Ads customer ID.')
  args = parser.parse_args()

  main(google_ads_client, args.customer_id)
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 gets the changes in the account made in the last 7 days.

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

def get_account_changes(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

  ga_service = client.service(:GoogleAds)

  query = <<~QUERY
    SELECT
      change_status.resource_name,
      change_status.last_change_date_time,
      change_status.resource_type,
      change_status.campaign,
      change_status.ad_group,
      change_status.resource_status,
      change_status.ad_group_ad,
      change_status.ad_group_criterion,
      change_status.campaign_criterion
    FROM
      change_status
    ORDER BY
      change_status.last_change_date_time
  QUERY

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

  response.each do |row|
    cs = row.change_status
    resource_name = case cs.resource_type
    when :AD_GROUP
      cs.ad_group
    when :AD_GROUP_AD
      cs.ad_group_ad
    when :AD_GROUP_CRITERION
      cs.ad_group_criterion
    when :CAMPAIGN
      cs.campaign
    when :CAMPAIGN_CRITERION
      cs.campaign_criterion
    else
      "UNKNOWN"
    end
    puts "On #{cs.last_change_date_time}, change status #{cs.resource_name} " \
         "shows a resource type of #{cs.resource_type} " \
         "with resource name #{resource_name} was #{cs.resource_status}."
  end
end

if __FILE__ == $PROGRAM_NAME
  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: ruby %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_account_changes(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
  rescue Google::Gax::RetryError => e
    STDERR.printf("Error: '%s'\n\tCause: '%s'\n\tCode: %d\n\tDetails: '%s'\n" \
        "\tRequest-Id: '%s'\n", e.message, e.cause.message, e.cause.code,
                  e.cause.details, e.cause.metadata['request-id'])
  end
end

Send feedback about...

Google Ads API
Google Ads API
Need help? Visit our support page.