Use Cross Account Bidding Strategy

Java

// Copyright 2021 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.advancedoperations;

import static com.google.ads.googleads.examples.utils.CodeSampleHelper.getPrintableDateTime;

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.lib.utils.FieldMasks;
import com.google.ads.googleads.v16.common.TargetSpend;
import com.google.ads.googleads.v16.errors.GoogleAdsError;
import com.google.ads.googleads.v16.errors.GoogleAdsException;
import com.google.ads.googleads.v16.resources.AccessibleBiddingStrategy;
import com.google.ads.googleads.v16.resources.BiddingStrategy;
import com.google.ads.googleads.v16.resources.BiddingStrategyName;
import com.google.ads.googleads.v16.resources.Campaign;
import com.google.ads.googleads.v16.services.BiddingStrategyOperation;
import com.google.ads.googleads.v16.services.BiddingStrategyServiceClient;
import com.google.ads.googleads.v16.services.CampaignOperation;
import com.google.ads.googleads.v16.services.CampaignServiceClient;
import com.google.ads.googleads.v16.services.GoogleAdsRow;
import com.google.ads.googleads.v16.services.GoogleAdsServiceClient;
import com.google.ads.googleads.v16.services.MutateBiddingStrategiesResponse;
import com.google.ads.googleads.v16.services.MutateBiddingStrategyResult;
import com.google.ads.googleads.v16.services.MutateCampaignResult;
import com.google.ads.googleads.v16.services.MutateCampaignsResponse;
import com.google.ads.googleads.v16.services.SearchGoogleAdsStreamRequest;
import com.google.ads.googleads.v16.services.SearchGoogleAdsStreamResponse;
import com.google.ads.googleads.v16.utils.ResourceNames;
import com.google.api.gax.rpc.ServerStream;
import com.google.common.collect.ImmutableList;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * Adds a cross-account bidding strategy to a manager account and attaches it to a client customer's
 * campaign. Also lists all manager-owned and customer accessible bidding strategies.
 */
public class UseCrossAccountBiddingStrategy {

  private static class UseCrossAccountBiddingStrategyParams extends CodeSampleParams {

    @Parameter(names = ArgumentNames.MANAGER_CUSTOMER_ID, required = true)
    private Long managerCustomerId;

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

    @Parameter(names = ArgumentNames.CAMPAIGN_ID, required = true)
    private Long campaignId;
  }

  public static void main(String[] args) {
    UseCrossAccountBiddingStrategyParams params = new UseCrossAccountBiddingStrategyParams();
    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.managerCustomerId = Long.parseLong("INSERT_MANAGER_CUSTOMER_ID_HERE");
      params.customerId = Long.parseLong("INSERT_CUSTOMER_ID_HERE");
      params.campaignId = Long.parseLong("INSERT_CAMPAIGN_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 UseCrossAccountBiddingStrategy()
          .runExample(
              googleAdsClient, params.managerCustomerId, params.customerId, params.campaignId);
    } 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 managerCustomerId the manager customer ID.
   * @param clientCustomerId the client customer ID.
   * @param campaignId the ID of an existing campaign in the client customer's account.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private void runExample(
      GoogleAdsClient googleAdsClient,
      Long managerCustomerId,
      Long clientCustomerId,
      Long campaignId) {
    String biddingStrategyResourceName = createBiddingStrategy(googleAdsClient, managerCustomerId);
    listManagerOwnedBiddingStrategies(googleAdsClient, managerCustomerId);
    listCustomerAccessibleBiddingStrategies(googleAdsClient, clientCustomerId);
    attachCrossAccountBiddingStrategyToCampaign(
        googleAdsClient, clientCustomerId, campaignId, biddingStrategyResourceName);
  }

  /**
   * Creates a new TargetSpend (Maximize Clicks) cross-account bidding strategy in the manager
   * account {@code managerCustomerId}.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param managerCustomerId the manager account's customer ID.
   * @return the resource name of the newly created bidding strategy.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private String createBiddingStrategy(GoogleAdsClient googleAdsClient, long managerCustomerId) {
    try (BiddingStrategyServiceClient biddingStrategyServiceClient =
        googleAdsClient.getLatestVersion().createBiddingStrategyServiceClient()) {
      // Creates a portfolio bidding strategy.
      BiddingStrategy portfolioBiddingStrategy =
          BiddingStrategy.newBuilder()
              .setName("Maximize Clicks #" + getPrintableDateTime())
              .setTargetSpend(TargetSpend.getDefaultInstance())
              // Sets the currency of the new bidding strategy. If not provided, the bidding
              // strategy uses the manager account's default currency.
              .setCurrencyCode("USD")
              .build();
      // Constructs an operation that will create a portfolio bidding strategy.
      BiddingStrategyOperation operation =
          BiddingStrategyOperation.newBuilder().setCreate(portfolioBiddingStrategy).build();
      // Sends the operation in a mutate request.
      MutateBiddingStrategiesResponse response =
          biddingStrategyServiceClient.mutateBiddingStrategies(
              Long.toString(managerCustomerId), ImmutableList.of(operation));

      // Prints the resource name of the created cross-account bidding strategy.
      MutateBiddingStrategyResult mutateBiddingStrategyResult = response.getResults(0);
      String resourceName = mutateBiddingStrategyResult.getResourceName();
      System.out.printf("Created cross-account bidding strategy: '%s'.%n", resourceName);

      return resourceName;
    }
  }

  /**
   * List all cross-account bidding strategies in manager account {@code managerCustomerId}.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param managerCustomerId the manager account's customer ID.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private void listManagerOwnedBiddingStrategies(
      GoogleAdsClient googleAdsClient, long managerCustomerId) throws GoogleAdsException {
    try (GoogleAdsServiceClient googleAdsServiceClient =
        googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
      String query =
          "SELECT bidding_strategy.id, "
              + "bidding_strategy.name, "
              + "bidding_strategy.type, "
              + "bidding_strategy.currency_code "
              + "FROM bidding_strategy";
      // Constructs the SearchGoogleAdsStreamRequest.
      SearchGoogleAdsStreamRequest request =
          SearchGoogleAdsStreamRequest.newBuilder()
              .setCustomerId(Long.toString(managerCustomerId))
              .setQuery(query)
              .build();

      // Creates and issues a search Google Ads stream request that will retrieve all bidding
      // strategies.
      ServerStream<SearchGoogleAdsStreamResponse> stream =
          googleAdsServiceClient.searchStreamCallable().call(request);

      // Iterates through and prints all of the results in the stream response.
      System.out.printf(
          "Cross-account bid strategies in manager account %d: %n", managerCustomerId);
      for (SearchGoogleAdsStreamResponse response : stream) {
        for (GoogleAdsRow googleAdsRow : response.getResultsList()) {
          BiddingStrategy bs = googleAdsRow.getBiddingStrategy();
          System.out.printf("  ID: %d%n", bs.getId());
          System.out.printf("  Name: %s%n", bs.getName());
          System.out.printf("  Strategy type: %s%n", bs.getType());
          System.out.printf("  Currency: %s%n", bs.getCurrencyCode());
          System.out.println();
        }
      }
    }
  }

  /**
   * Lists all bidding strategies available to account {@code clientCustomerId}. This includes both
   * portfolio bidding strategies owned by account {@code clientCustomerId} and cross-account
   * bidding strategies shared by any of its managers.
   *
   * @param googleAdsClient the Google Ads API client.
   * @param clientCustomerId the client account's customer ID.
   * @throws GoogleAdsException if an API request failed with one or more service errors.
   */
  private void listCustomerAccessibleBiddingStrategies(
      GoogleAdsClient googleAdsClient, long clientCustomerId) throws GoogleAdsException {
    try (GoogleAdsServiceClient googleAdsServiceClient =
        googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
      String query =
          "SELECT accessible_bidding_strategy.id, "
              + "accessible_bidding_strategy.name, "
              + "accessible_bidding_strategy.type, "
              + "accessible_bidding_strategy.owner_customer_id, "
              + "accessible_bidding_strategy.owner_descriptive_name "
              + "FROM accessible_bidding_strategy "
          // Uncomment the following WHERE clause to filter results to *only* cross-account bidding
          // strategies shared with the current customer by a manager (and not also include the
          // current customer's portfolio bidding strategies).
          // + "WHERE accessible_bidding_strategy.owner_customer_id != " + clientCustomerId;
          ;

      // Constructs the SearchGoogleAdsStreamRequest.
      SearchGoogleAdsStreamRequest request =
          SearchGoogleAdsStreamRequest.newBuilder()
              .setCustomerId(Long.toString(clientCustomerId))
              .setQuery(query)
              .build();

      // Creates and issues a search Google Ads stream request that will retrieve all accessible
      // bidding strategies.
      ServerStream<SearchGoogleAdsStreamResponse> stream =
          googleAdsServiceClient.searchStreamCallable().call(request);

      // Iterates through and prints all of the results in the stream response.
      System.out.printf("All bid strategies accessible by account %d: %n", clientCustomerId);
      for (SearchGoogleAdsStreamResponse response : stream) {
        for (GoogleAdsRow googleAdsRow : response.getResultsList()) {
          AccessibleBiddingStrategy bs = googleAdsRow.getAccessibleBiddingStrategy();
          System.out.printf("  ID: %d%n", bs.getId());
          System.out.printf("  Name: %s%n", bs.getName());
          System.out.printf("  Strategy type: %s%n", bs.getType());
          System.out.printf("  Owner customer ID: %d%n", bs.getOwnerCustomerId());
          System.out.printf("  Owner description: %s%n", bs.getOwnerDescriptiveName());
          System.out.println();
        }
      }
    }
  }

  /**
   * Attaches the cross-account bidding strategy {@code biddingStrategyId} to campaign {@code
   * campaignId} in client account {@code clientCustomerId}.
   */
  private void attachCrossAccountBiddingStrategyToCampaign(
      GoogleAdsClient googleAdsClient,
      long clientCustomerId,
      long campaignId,
      String biddingStrategyResourceName)
      throws GoogleAdsException {

    try (CampaignServiceClient campaignServiceClient =
        googleAdsClient.getLatestVersion().createCampaignServiceClient()) {
      Campaign campaign =
          Campaign.newBuilder()
              .setResourceName(ResourceNames.campaign(clientCustomerId, campaignId))
              .setBiddingStrategy(biddingStrategyResourceName)
              .build();
      CampaignOperation operation =
          CampaignOperation.newBuilder()
              .setUpdate(campaign)
              .setUpdateMask(FieldMasks.allSetFieldsOf(campaign))
              .build();
      // Sends the operation in a mutate request.
      MutateCampaignsResponse response =
          campaignServiceClient.mutateCampaigns(
              Long.toString(clientCustomerId), ImmutableList.of(operation));

      MutateCampaignResult mutateCampaignResult = response.getResults(0);
      // Prints the resource name of the updated campaign.
      System.out.printf(
          "Updated campaign with resource name: '%s'.%n", mutateCampaignResult.getResourceName());
    }
  }
}

      

C#

// Copyright 2021 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 System;
using System.Collections.Generic;
using System.Linq;
using CommandLine;
using Google.Ads.Gax.Examples;
using Google.Ads.Gax.Util;
using Google.Ads.GoogleAds.Lib;
using Google.Ads.GoogleAds.V16.Common;
using Google.Ads.GoogleAds.V16.Errors;
using Google.Ads.GoogleAds.V16.Resources;
using Google.Ads.GoogleAds.V16.Services;
using static Google.Ads.GoogleAds.V16.Enums.BiddingStrategyTypeEnum.Types;

namespace Google.Ads.GoogleAds.Examples.V16
{
    /// <summary>
    /// This code example adds a cross-account bidding strategy to a manager account and attaches it
    /// to a client customer's campaign. Also lists all the bidding strategies that are owned by the
    /// manager and accessible by the customer.
    /// Please read our guide pages more information on bidding strategies:
    /// https://developers.google.com/google-ads/api/docs/campaigns/bidding/cross-account-strategies
    /// </summary>
    public class UseCrossAccountBiddingStrategy : ExampleBase
    {
        /// <summary>
        /// Command line options for running the <see cref="UseCrossAccountBiddingStrategy"/>
        /// example.
        /// </summary>
        public class Options : OptionsBase
        {
            /// <summary>
            /// The Google Ads client customer ID for which the call is made.
            /// </summary>
            [Option("customerId", Required = true, HelpText =
                "The Google Ads client customer ID for which the call is made.")]
            public long CustomerId { get; set; }

            /// <summary>
            /// The ID of the account that owns the cross-account bidding strategy. This is
            /// typically the ID of the manager account.
            /// </summary>
            [Option("managerCustomerId", Required = true, HelpText =
                "The ID of the account that owns the cross-account bidding strategy. This is" +
                "typically the ID of the manager account.")]
            public long ManagerCustomerId { get; set; }

            /// <summary>
            /// The ID of the campaign owned by the customer ID to which the cross-account bidding
            /// strategy will be attached.
            /// </summary>
            [Option("campaignId", Required = true, HelpText =
                "The ID of the campaign owned by the customer ID to which the cross-account " +
                "bidding strategy will be attached.")]
            public long CampaignId { 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);
            UseCrossAccountBiddingStrategy codeExample = new UseCrossAccountBiddingStrategy();
            Console.WriteLine(codeExample.Description);
            codeExample.Run(new GoogleAdsClient(), options.CustomerId, options.ManagerCustomerId,
                options.CampaignId);
        }

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description =>
            "This code example adds a cross-account bidding strategy to a manager account and " +
            "attaches it to a client customer's campaign. Also lists all the bidding strategies " +
            "that are owned by the manager and accessible by the customer.\n" +
            "Please read our guide pages more information on bidding strategies:" +
            "https://developers.google.com/google-ads/api/docs/campaigns/bidding/cross-account-strategies";

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads client customer ID for which the call is
        /// made.</param>
        /// <param name="managerCustomerId">The manager customer ID.</param>
        /// <param name="campaignId">The ID of the campaign owned by the customer ID to which the
        /// cross-account bidding strategy will be attached.</param>
        public void Run(GoogleAdsClient client, long customerId, long managerCustomerId,
            long campaignId)
        {
            try
            {
                string biddingStrategyResourceName =
                    CreateBiddingStrategy(client, managerCustomerId);
                ListManagerOwnedBiddingStrategies(client, managerCustomerId);
                ListCustomerAccessibleBiddingStrategies(client, customerId);
                AttachCrossAccountBiddingStrategyToCampaign(client, customerId, campaignId,
                    biddingStrategyResourceName);
            }
            catch (GoogleAdsException e)
            {
                Console.WriteLine("Failure:");
                Console.WriteLine($"Message: {e.Message}");
                Console.WriteLine($"Failure: {e.Failure}");
                Console.WriteLine($"Request ID: {e.RequestId}");
                throw;
            }
        }

        /// <summary>
        /// Creates a new TargetSpend (Maximize Clicks) cross-account bidding strategy in the
        /// specified manager account.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="managerCustomerId">The manager customer ID.</param>
        /// <returns>The resource name of the newly created bidding strategy.</returns>
        private string CreateBiddingStrategy(GoogleAdsClient client, long managerCustomerId)
        {
            BiddingStrategyServiceClient biddingStrategyServiceClient =
                client.GetService(Services.V16.BiddingStrategyService);

            // Create a portfolio bidding strategy.
            BiddingStrategy portfolioBiddingStrategy = new BiddingStrategy
            {
                Name = $"Maximize clicks #{ExampleUtilities.GetRandomString()}",
                TargetSpend = new TargetSpend(),
                // Set the currency of the new bidding strategy. If not provided, the bidding
                // strategy uses the manager account's default currency.
                CurrencyCode = "USD"
            };

            // Send a create operation that will create the portfolio bidding strategy.
            MutateBiddingStrategiesResponse mutateBiddingStrategiesResponse =
                biddingStrategyServiceClient.MutateBiddingStrategies(managerCustomerId.ToString(),
                    new[]
                    {
                        new BiddingStrategyOperation
                        {
                            Create = portfolioBiddingStrategy
                        }
                    });

            // Print and return the resource name of the newly created cross-account bidding
            // strategy.
            string biddingStrategyResourceName =
                mutateBiddingStrategiesResponse.Results.First().ResourceName;
            Console.WriteLine("Created cross-account bidding strategy " +
                $"'{biddingStrategyResourceName}'.");

            return biddingStrategyResourceName;
        }

        /// <summary>
        /// Lists all cross-account bidding strategies in a specified manager account.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="managerCustomerId">The manager customer ID.</param>
        private void ListManagerOwnedBiddingStrategies(GoogleAdsClient client,
            long managerCustomerId)
        {
            GoogleAdsServiceClient googleAdsServiceClient =
                client.GetService(Services.V16.GoogleAdsService);

            // Create a GAQL query that will retrieve all cross-account bidding strategies.
            string query = @"
                SELECT
                  bidding_strategy.id,
                  bidding_strategy.name,
                  bidding_strategy.type,
                  bidding_strategy.currency_code
                FROM bidding_strategy";

            // Issue a streaming search request, then iterate through and print the results.
            googleAdsServiceClient.SearchStream(managerCustomerId.ToString(), query,
                delegate(SearchGoogleAdsStreamResponse resp)
                {
                    Console.WriteLine("Cross-account bid strategies in manager account " +
                        $"{managerCustomerId}:");

                    foreach (GoogleAdsRow googleAdsRow in resp.Results)
                    {
                        BiddingStrategy biddingStrategy = googleAdsRow.BiddingStrategy;

                        Console.WriteLine($"\tID: {biddingStrategy.Id}\n" +
                            $"\tName: {biddingStrategy.Name}\n" +
                            "\tStrategy type: " +
                            $"{Enum.GetName(typeof(BiddingStrategyType), biddingStrategy.Type)}\n" +
                            $"\tCurrency: {biddingStrategy.CurrencyCode}\n\n");
                    }
                }
            );
        }

        /// <summary>
        /// Lists all bidding strategies available to specified client customer account. This
        /// includes both portfolio bidding strategies owned by the client customer account and
        /// cross-account bidding strategies shared by any of its managers.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads client customer ID for which the call is
        /// made.</param>
        private void ListCustomerAccessibleBiddingStrategies(GoogleAdsClient client,
            long customerId)
        {
            GoogleAdsServiceClient googleAdsServiceClient =
                client.GetService(Services.V16.GoogleAdsService);

            // Create a GAQL query that will retrieve all accessible bidding strategies.
            string query = @"
                SELECT
                  accessible_bidding_strategy.resource_name,
                  accessible_bidding_strategy.id,
                  accessible_bidding_strategy.name,
                  accessible_bidding_strategy.type,
                  accessible_bidding_strategy.owner_customer_id,
                  accessible_bidding_strategy.owner_descriptive_name
                FROM accessible_bidding_strategy";

            // Uncomment the following WHERE clause addition to the query to filter results to
            // *only* cross-account bidding strategies shared with the current customer by a manager
            // (and not also include the current customer's portfolio bidding strategies).
            // query += $" WHERE accessible_bidding_strategy.owner_customer_id != {customerId}";

            // Issue a streaming search request, then iterate through and print the results.
            googleAdsServiceClient.SearchStream(customerId.ToString(), query,
                delegate(SearchGoogleAdsStreamResponse resp)
                {
                    Console.WriteLine($"All bid strategies accessible by account {customerId}:");

                    foreach (GoogleAdsRow googleAdsRow in resp.Results)
                    {
                        AccessibleBiddingStrategy biddingStrategy =
                            googleAdsRow.AccessibleBiddingStrategy;

                        Console.WriteLine($"\tID: {biddingStrategy.Id}\n" +
                            $"\tName: {biddingStrategy.Name}\n" +
                            $"\tStrategy type: {biddingStrategy.Type.ToString()}\n" +
                            $"\tOwner customer ID: {biddingStrategy.OwnerCustomerId}\n" +
                            $"\tOwner description: {biddingStrategy.OwnerDescriptiveName}\n\n");
                    }
                }
            );
        }

        /// <summary>
        /// Attaches a specified cross-account bidding strategy to a campaign owned by a specified
        /// client customer account.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads client customer ID for which the call is
        /// made.</param>
        /// <param name="campaignId">The ID of the campaign owned by the customer ID to which the
        /// cross-account bidding strategy will be attached.</param>
        /// <param name="biddingStrategyResourceName">A cross-account bidding strategy resource
        /// name.</param>
        private void AttachCrossAccountBiddingStrategyToCampaign(GoogleAdsClient client,
            long customerId, long campaignId, string biddingStrategyResourceName)
        {
            CampaignServiceClient campaignServiceClient =
                client.GetService(Services.V16.CampaignService);

            Campaign campaign = new Campaign
            {
                ResourceName = ResourceNames.Campaign(customerId, campaignId),
                BiddingStrategy = biddingStrategyResourceName
            };

            // Mutate the campaign and print the resource name of the updated campaign.
            MutateCampaignsResponse mutateCampaignsResponse =
                campaignServiceClient.MutateCampaigns(customerId.ToString(), new[]
                {
                    new CampaignOperation
                    {
                        Update = campaign,
                        UpdateMask = FieldMasks.AllSetFieldsOf(campaign)
                    }
                });

            Console.WriteLine("Updated campaign with resource name " +
                $"'{mutateCampaignsResponse.Results.First().ResourceName}'.");
        }
    }
}

      

PHP

<?php

/**
 * Copyright 2021 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\AdvancedOperations;

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\Examples\Utils\Helper;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V16\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V16\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V16\GoogleAdsException;
use Google\Ads\GoogleAds\Lib\V16\GoogleAdsServerStreamDecorator;
use Google\Ads\GoogleAds\Util\FieldMasks;
use Google\Ads\GoogleAds\Util\V16\ResourceNames;
use Google\Ads\GoogleAds\V16\Common\TargetSpend;
use Google\Ads\GoogleAds\V16\Enums\BiddingStrategyTypeEnum\BiddingStrategyType;
use Google\Ads\GoogleAds\V16\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V16\Resources\BiddingStrategy;
use Google\Ads\GoogleAds\V16\Resources\Campaign;
use Google\Ads\GoogleAds\V16\Services\BiddingStrategyOperation;
use Google\Ads\GoogleAds\V16\Services\BiddingStrategyServiceClient;
use Google\Ads\GoogleAds\V16\Services\CampaignOperation;
use Google\Ads\GoogleAds\V16\Services\GoogleAdsRow;
use Google\Ads\GoogleAds\V16\Services\MutateBiddingStrategiesRequest;
use Google\Ads\GoogleAds\V16\Services\MutateCampaignsRequest;
use Google\Ads\GoogleAds\V16\Services\SearchGoogleAdsStreamRequest;
use Google\ApiCore\ApiException;

/**
 * Adds a cross-account bidding strategy to a manager account and attaches it to a client customer's
 * campaign. Also lists all manager-owned and customer accessible bidding strategies.
 */
class UseCrossAccountBiddingStrategy
{
    private const MANAGER_CUSTOMER_ID = 'INSERT_MANAGER_CUSTOMER_ID_HERE';
    private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE';
    private const CAMPAIGN_ID = 'INSERT_CAMPAIGN_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::MANAGER_CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT,
                ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT,
                ArgumentNames::CAMPAIGN_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::MANAGER_CUSTOMER_ID] ?: self::MANAGER_CUSTOMER_ID,
                $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID,
                $options[ArgumentNames::CAMPAIGN_ID] ?: self::CAMPAIGN_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 $managerCustomerId the manager customer ID
     * @param int $clientCustomerId the client customer ID
     * @param int $campaignId the ID of an existing campaign in the client customer's account
     */
    public static function runExample(
        GoogleAdsClient $googleAdsClient,
        int $managerCustomerId,
        int $clientCustomerId,
        int $campaignId
    ) {
        $biddingStrategyResourceName =
            self::createBiddingStrategy($googleAdsClient, $managerCustomerId);
        self::listManagerOwnedBiddingStrategies($googleAdsClient, $managerCustomerId);
        self::listCustomerAccessibleBiddingStrategies($googleAdsClient, $clientCustomerId);
        self::attachCrossAccountBiddingStrategyToCampaign(
            $googleAdsClient,
            $clientCustomerId,
            $campaignId,
            $biddingStrategyResourceName
        );
    }

    /**
     * Creates a new TargetSpend (Maximize Clicks) cross-account bidding strategy in the manager
     * account.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $managerCustomerId the manager account's customer ID
     * @return string the resource name of the newly created bidding strategy
     */
    private static function createBiddingStrategy(
        GoogleAdsClient $googleAdsClient,
        int $managerCustomerId
    ): string {
        // Creates a portfolio bidding strategy.
        $portfolioBiddingStrategy = new BiddingStrategy([
            'name' => 'Maximize Clicks #' . Helper::getPrintableDatetime(),
            'target_spend' => new TargetSpend(),
            // Optional: Sets the currency of the new bidding strategy to match the currency of the
            // client account with which this bidding strategy is shared.
            // If not provided, the bidding strategy uses the manager account's default currency.
            'currency_code' => 'USD'
        ]);

        // Constructs an operation that will create a portfolio bidding strategy.
        $biddingStrategyOperation = new BiddingStrategyOperation();
        $biddingStrategyOperation->setCreate($portfolioBiddingStrategy);

        // Issues a mutate request to create the bidding strategy.
        $biddingStrategyServiceClient = $googleAdsClient->getBiddingStrategyServiceClient();
        $response = $biddingStrategyServiceClient->mutateBiddingStrategies(
            MutateBiddingStrategiesRequest::build($managerCustomerId, [$biddingStrategyOperation])
        );
        /** @var BiddingStrategy $addedBiddingStrategy */
        $addedBiddingStrategy = $response->getResults()[0];

        // Prints out the resource name of the created bidding strategy.
        printf(
            "Created cross-account bidding strategy with resource name: '%s'.%s",
            $addedBiddingStrategy->getResourceName(),
            PHP_EOL
        );

        return $addedBiddingStrategy->getResourceName();
    }

    /**
     * Lists all cross-account bidding strategies in the specified manager account.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $managerCustomerId the manager account's customer ID
     */
    private static function listManagerOwnedBiddingStrategies(
        GoogleAdsClient $googleAdsClient,
        int $managerCustomerId
    ) {
        $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
        // Creates a query that retrieves all bidding strategies.
        $query = 'SELECT bidding_strategy.id, bidding_strategy.name, '
            . 'bidding_strategy.type, bidding_strategy.currency_code '
            . 'FROM bidding_strategy';
        // Issues a search stream request.
        /** @var GoogleAdsServerStreamDecorator $stream */
        $stream = $googleAdsServiceClient->searchStream(
            SearchGoogleAdsStreamRequest::build($managerCustomerId, $query)
        );

        // Iterates over all rows in all messages and prints the requested field values for
        // the bidding strategy in each row.
        printf(
            "Cross-account bid strategies in manager account ID %d:%s",
            $managerCustomerId,
            PHP_EOL
        );
        foreach ($stream->iterateAllElements() as $googleAdsRow) {
            /** @var GoogleAdsRow $googleAdsRow */
            printf(
                '  ID: %1$d%2$s  Name: "%3$s"%2$s  Strategy type: "%4$s"%2$s'
                . '  Currency: "%5$s"%2$s%2$s',
                $googleAdsRow->getBiddingStrategy()->getId(),
                PHP_EOL,
                $googleAdsRow->getBiddingStrategy()->getName(),
                BiddingStrategyType::name($googleAdsRow->getBiddingStrategy()->getType()),
                $googleAdsRow->getBiddingStrategy()->getCurrencyCode()
            );
        }
    }

    /**
     * Lists all bidding strategies available to the specified client customer ID. This includes
     * both portfolio bidding strategies owned by the specified client customer and cross-account
     * bidding strategies shared by any of its managers.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $clientCustomerId the client account's customer ID
     */
    private static function listCustomerAccessibleBiddingStrategies(
        GoogleAdsClient $googleAdsClient,
        int $clientCustomerId
    ) {
        $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
        // Creates a query that retrieves all bidding strategies.
        $query = 'SELECT accessible_bidding_strategy.id, '
              . 'accessible_bidding_strategy.name, '
              . 'accessible_bidding_strategy.type, '
              . 'accessible_bidding_strategy.owner_customer_id, '
              . 'accessible_bidding_strategy.owner_descriptive_name '
              . 'FROM accessible_bidding_strategy '
            // Uncomment the following WHERE clause to filter results to *only* cross-account
            // bidding strategies shared with the current customer by a manager (and not also
            // include the current customer's portfolio bidding strategies).
            // . 'WHERE accessible_bidding_strategy.owner_customer_id != ' . $clientCustomerId
        ;
        // Issues a search stream request.
        /** @var GoogleAdsServerStreamDecorator $stream */
        $stream = $googleAdsServiceClient->searchStream(
            SearchGoogleAdsStreamRequest::build($clientCustomerId, $query)
        );

        // Iterates over all rows in all messages and prints the requested field values for
        // each accessible bidding strategy.
        printf(
            "All bid strategies accessible by the customer ID %d:%s",
            $clientCustomerId,
            PHP_EOL
        );
        foreach ($stream->iterateAllElements() as $googleAdsRow) {
            /** @var GoogleAdsRow $googleAdsRow */
            printf(
                '  ID: %1$d%2$s  Name: "%3$s"%2$s  Strategy type: "%4$s"%2$s'
                . '  Owner customer ID: %5$d%2$s  Owner customer description: "%6$s"%2$s%2$s',
                $googleAdsRow->getAccessibleBiddingStrategy()->getId(),
                PHP_EOL,
                $googleAdsRow->getAccessibleBiddingStrategy()->getName(),
                BiddingStrategyType::name($googleAdsRow->getAccessibleBiddingStrategy()->getType()),
                $googleAdsRow->getAccessibleBiddingStrategy()->getOwnerCustomerId(),
                $googleAdsRow->getAccessibleBiddingStrategy()->getOwnerDescriptiveName()
            );
        }
    }

    /**
     * Attaches the provided cross-account bidding strategy to the specified campaign to the
     * specified client account.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $clientCustomerId the customer ID
     * @param int $campaignId the campaign ID to attach the bidding strategy to
     * @param string $biddingStrategyResourceName the bidding strategy resource name to attach
     */
    private static function attachCrossAccountBiddingStrategyToCampaign(
        GoogleAdsClient $googleAdsClient,
        int $clientCustomerId,
        int $campaignId,
        string $biddingStrategyResourceName
    ) {
        // Creates a campaign using the specified campaign ID and the bidding strategy ID.
        // Note that a cross-account bidding strategy's resource name should use the
        // client's customer ID when attaching it to a campaign, not that of the manager that owns
        // the strategy.
        $campaign = new Campaign([
            'resource_name' => ResourceNames::forCampaign($clientCustomerId, $campaignId),
            'bidding_strategy' => $biddingStrategyResourceName
        ]);

        // Constructs an operation that will update the campaign with the specified resource name,
        // using the FieldMasks utility to derive the update mask. This mask tells the Google Ads
        // API which attributes of the campaign you want to change.
        $campaignOperation = new CampaignOperation();
        $campaignOperation->setUpdate($campaign);
        $campaignOperation->setUpdateMask(FieldMasks::allSetFieldsOf($campaign));

        // Issues a mutate request to update the campaign.
        $campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
        $response = $campaignServiceClient->mutateCampaigns(
            MutateCampaignsRequest::build($clientCustomerId, [$campaignOperation])
        );

        // Prints information about the updated campaign.
        printf(
            "Updated campaign with resource name: '%s'.%s",
            $response->getResults()[0]->getResourceName(),
            PHP_EOL
        );
    }
}

UseCrossAccountBiddingStrategy::main();

      

Python

#!/usr/bin/env python
# Copyright 2021 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.
"""Adds a cross-account bidding strategy to a manager account.

Also attaches the bidding strategy to a client customer's campaign and lists
all manager-owned and customer accessible bidding strategies.
"""


import argparse
import sys
from uuid import uuid4

from google.api_core import protobuf_helpers

from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException


def main(client, customer_id, manager_customer_id, campaign_id):
    """The main method that creates all necessary entities for the example.

    Args:
        client: An initialized GoogleAdsClient instance.
        customer_id: A client customer ID.
        manager_customer_id: A manager customer ID.
        campaign_id: The ID of an existing campaign in the client customer's
            account.
    """
    bidding_strategy_resource_name = create_bidding_strategy(
        client, manager_customer_id
    )
    list_manager_owned_bidding_strategies(client, manager_customer_id)
    list_customer_accessible_bidding_strategies(client, customer_id)
    attach_cross_account_bidding_strategy_to_campaign(
        client, customer_id, campaign_id, bidding_strategy_resource_name
    )


def create_bidding_strategy(client, manager_customer_id):
    """Creates a new cross-account bidding strategy in the manager account.

    The cross-account bidding strategy is of type TargetSpend (Maximize Clicks).

    Args:
        client: An initialized GoogleAdsClient instance.
        manager_customer_id: A manager customer ID.

    Returns:
        The ID of the newly created bidding strategy.
    """
    bidding_strategy_service = client.get_service("BiddingStrategyService")
    # Creates a portfolio bidding strategy.
    # Constructs an operation that will create a portfolio bidding strategy.
    bidding_strategy_operation = client.get_type("BiddingStrategyOperation")
    bidding_strategy = bidding_strategy_operation.create
    bidding_strategy.name = f"Maximize Clicks #{uuid4()}"
    # Sets target_spend to an empty TargetSpend object without setting any
    # of its nested fields.
    bidding_strategy.target_spend = client.get_type("TargetSpend")
    # Sets the currency of the new bidding strategy. If not provided, the
    # bidding strategy uses the manager account's default currency.
    bidding_strategy.currency_code = "USD"

    # Sends the operation in a mutate request.
    response = bidding_strategy_service.mutate_bidding_strategies(
        customer_id=manager_customer_id, operations=[bidding_strategy_operation]
    )

    # Prints the resource name of the created cross-account bidding strategy.
    resource_name = response.results[0].resource_name
    print(f"Created cross-account bidding strategy: '{resource_name}'")

    return resource_name


def list_manager_owned_bidding_strategies(client, manager_customer_id):
    """List all cross-account bidding strategies in the manager account.

    Args:
        client: An initialized GoogleAdsClient instance.
        manager_customer_id: A manager customer ID.
    """
    googleads_service = client.get_service("GoogleAdsService")
    query = """
        SELECT
          bidding_strategy.id,
          bidding_strategy.name,
          bidding_strategy.type,
          bidding_strategy.currency_code
        FROM bidding_strategy"""

    # Creates and issues a search Google Ads stream request that will retrieve
    # all bidding strategies.
    stream = googleads_service.search_stream(
        customer_id=manager_customer_id, query=query
    )

    # Iterates through and prints all of the results in the stream response.
    print(
        "Cross-account bid strategies in manager account: "
        f"{manager_customer_id}"
    )
    for response in stream:
        for row in response.results:
            bs = row.bidding_strategy
            print(
                f"\tID: {bs.id}\n"
                f"\tName: {bs.name}\n"
                f"\tStrategy type: {bs.type_}\n"
                f"\tCurrency: {bs.currency_code}\n\n"
            )


def list_customer_accessible_bidding_strategies(client, customer_id):
    """Lists all bidding strategies available to the client account.

    This includes both portfolio bidding strategies owned by account and
    cross-account bidding strategies shared by any of its managers.

    Args:
        client: An initialized GoogleAdsClient instance.
        customer_id: A client customer ID.
    """
    googleads_service = client.get_service("GoogleAdsService")
    query = """
        SELECT
          accessible_bidding_strategy.id,
          accessible_bidding_strategy.name,
          accessible_bidding_strategy.type,
          accessible_bidding_strategy.owner_customer_id,
          accessible_bidding_strategy.owner_descriptive_name
        FROM accessible_bidding_strategy"""
    # Uncomment the following WHERE clause to filter results to *only*
    # cross-account bidding strategies shared with the current customer by a
    # manager (and not also include the current customer's portfolio
    # bidding strategies).
    #
    # query += f"WHERE accessible_bidding_strategy.owner_customer_id != {customer_id}"

    # Creates and issues a search Google Ads stream request that will retrieve
    # all bidding strategies.
    stream = googleads_service.search_stream(
        customer_id=customer_id, query=query
    )

    # Iterates through and prints all of the results in the stream response.
    print(f"All bid strategies accessible by account '{customer_id}'\n")
    for response in stream:
        for row in response.results:
            bs = row.accessible_bidding_strategy
            print(
                f"\tID: {bs.id}\n"
                f"\tName: {bs.name}\n"
                f"\tStrategy type: {bs.type_}\n"
                f"\tOwner customer ID: {bs.owner_customer_id}\n"
                f"\tOwner description: {bs.owner_descriptive_name}\n\n"
            )


def attach_cross_account_bidding_strategy_to_campaign(
    client, customer_id, campaign_id, bidding_strategy_resource_name
):
    """Attaches the cross-account bidding strategy to the given campaign.

    Args:
        client: An initialized GoogleAdsClient instance.
        customer_id: A client customer ID.
        campaign_id: The ID of an existing campaign in the client customer's
            account.
        bidding_strategy_resource_name: The ID of a bidding strategy
    """
    campaign_service = client.get_service("CampaignService")
    bidding_strategy_service = client.get_service("BiddingStrategyService")
    campaign_operation = client.get_type("CampaignOperation")
    campaign = campaign_operation.update
    campaign.resource_name = campaign_service.campaign_path(
        customer_id, campaign_id
    )
    campaign.bidding_strategy = bidding_strategy_resource_name
    campaign_operation.update_mask = protobuf_helpers.field_mask(
        None, campaign._pb
    )

    # Sends the operation in a mutate request.
    response = campaign_service.mutate_campaigns(
        customer_id=customer_id, operations=[campaign_operation]
    )

    # Prints the resource name of the updated campaign.
    print(
        "Updated campaign with resource name: "
        f"'{response.results[0].resource_name}'"
    )


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

    parser = argparse.ArgumentParser(description=("Creates a Smart campaign."))
    # 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.",
    )
    parser.add_argument(
        "-m",
        "--manager_customer_id",
        type=str,
        required=True,
        help="The Google Ads customer ID for a manager account.",
    )
    parser.add_argument(
        "-i",
        "--campaign_id",
        type=str,
        required=True,
        help="The ID of an existing campaign in the client customer's account",
    )

    args = parser.parse_args()

    try:
        main(
            googleads_client,
            args.customer_id,
            args.manager_customer_id,
            args.campaign_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'Error 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 2021 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 adds a cross-account bidding strategy to a manager account and
# attaches it to a client customer's campaign. Also lists all manager-owned
# and customer accessible bidding strategies.

require "optparse"
require "google/ads/google_ads"

def use_cross_account_bidding_strategy(
  customer_id,
  manager_customer_id,
  campaign_id)
  # GoogleAdsClient will read a config file from
  # ENV['HOME']/google_ads_config.rb when called without parameters

  client = Google::Ads::GoogleAds::GoogleAdsClient.new

  bidding_strategy_resource_name = create_bidding_strategy(
    client,
    manager_customer_id,
  )

  list_manager_owned_bidding_strategies(client, manager_customer_id)

  list_customer_accessible_bidding_strategies(client, customer_id)

  attach_cross_account_bidding_strategy_to_campaign(
    client,
    customer_id,
    campaign_id,
    bidding_strategy_resource_name,
  )
end

# Creates a new TargetSpend (Maximize Clicks) cross-account bidding strategy
# in the manager account.
def create_bidding_strategy(client, manager_customer_id)
  # Constructs an operation that will create a portfolio bidding strategy.
  operation = client.operation.create_resource.bidding_strategy do |b|
    b.name = "Maximize Clicks ##{(Time.new.to_f * 1000).to_i}"
    b.target_spend = client.resource.target_spend
    # Sets the currency of the new bidding strategy. If not provided, the
    # bidding strategy uses the manager account's default currency.
    b.currency_code = "USD"
  end

  # Sends the operation in a mutate request.
  response = client.service.bidding_strategy.mutate_bidding_strategies(
    customer_id: manager_customer_id,
    operations: [operation],
  )

  resource_name = response.results.first.resource_name
  puts "Created cross-account bidding strategy: `#{resource_name}`"

  resource_name
end

# Lists all cross-account bidding strategies in manager account.
def list_manager_owned_bidding_strategies(client, manager_customer_id)
  query = <<~QUERY
    SELECT bidding_strategy.id,
           bidding_strategy.name,
           bidding_strategy.type,
           bidding_strategy.currency_code
    FROM bidding_strategy
  QUERY

  responses = client.service.google_ads.search_stream(
    customer_id: manager_customer_id,
    query: query,
  )

  puts "Cross-account bid strategies in manager account #{manager_customer_id}:"
  responses.each do |response|
    response.results.each do |row|
      b = row.bidding_strategy
      puts "ID: #{b.id}"
      puts "Name: #{b.name}"
      puts "Strategy type: #{b.type}"
      puts "Currency: #{b.currency_code}"
      puts
    end
  end
end

# Lists all bidding strategies available to account. This includes both
# portfolio bidding strategies owned by account and cross-account bidding
# strategies shared by any of its managers.
def list_customer_accessible_bidding_strategies(client, customer_id)
  query = <<~QUERY
    SELECT accessible_bidding_strategy.id,
           accessible_bidding_strategy.name,
           accessible_bidding_strategy.type,
           accessible_bidding_strategy.owner_customer_id,
           accessible_bidding_strategy.owner_descriptive_name
    FROM accessible_bidding_strategy
  QUERY
  # Add the following WHERE clause to filter results to *only*
  # cross-account bidding strategies shared with the current customer by a
  # manager (and not also include the current customer's portfolio bidding
  # strategies).
  # query += <<~QUERY
  #  WHERE accessible_bidding_strategy.owner_customer_id != #{customer_id}
  # QUERY

  responses = client.service.google_ads.search_stream(
    customer_id: customer_id,
    query: query,
  )

  puts "All bid strategies accessible by account #{customer_id}:"
  responses.each do |response|
    response.results.each do |row|
      b = row.accessible_bidding_strategy
      puts "ID: #{b.id}"
      puts "Name: #{b.name}"
      puts "Strategy type: #{b.type}"
      puts "Owner customer ID: #{b.owner_customer_id}"
      puts "Owner description: #{b.owner_descriptive_name}"
      puts
    end
  end
end

# Attaches the cross-account bidding strategy to campaign in client account.
def attach_cross_account_bidding_strategy_to_campaign(
  client,
  customer_id,
  campaign_id,
  bidding_strategy_resource_name)
  operation = client.operation.update_resource.campaign(
    client.path.campaign(customer_id, campaign_id)) do |c|
    c.bidding_strategy = bidding_strategy_resource_name
  end

  # Sends the operation in a mutate request.
  response = client.service.campaign.mutate_campaigns(
    customer_id: customer_id,
    operations: [operation],
  )

  puts "Updated campaign with resource name: " \
    "`#{response.results.first.resource_name}`"
end

if __FILE__ == $PROGRAM_NAME
  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'
  options[:manager_customer_id] = 'INSERT_MANAGER_CUSTOMER_ID_HERE'
  options[:campaign_id] = 'INSERT_CAMPAIGN_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.on('-M', '--manager-customer-id MANAGER-CUSTOMER-ID', String, 'Manager Customer ID') do |v|
      options[:manager_customer_id] = v
    end

    opts.on('-c', '--campaign-id CAMPAIGN-ID', String, 'Campaign ID') do |v|
      options[:campaign_id] = v
    end

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

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

  begin
    use_cross_account_bidding_strategy(
      options.fetch(:customer_id).tr("-", ""),
      options.fetch(:manager_customer_id),
      options.fetch(:campaign_id),
    )
  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 2021, 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.
#
# Demonstrates how to update the bidding strategy for an existing campaign.
#
# This example adds a cross-account bidding strategy to a manager account and
# attaches it to a client customer's campaign. Also lists all the bidding
# strategies that are owned by the manager and accessible by the customer.
# Please read our guide pages more information on bidding strategies:
# https://developers.google.com/google-ads/api/docs/campaigns/bidding/cross-account-strategies

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::SearchStreamHandler;
use Google::Ads::GoogleAds::Utils::FieldMasks;
use Google::Ads::GoogleAds::V16::Resources::BiddingStrategy;
use Google::Ads::GoogleAds::V16::Resources::Campaign;
use Google::Ads::GoogleAds::V16::Common::TargetSpend;
use
  Google::Ads::GoogleAds::V16::Services::GoogleAdsService::SearchGoogleAdsStreamRequest;
use
  Google::Ads::GoogleAds::V16::Services::BiddingStrategyService::BiddingStrategyOperation;
use Google::Ads::GoogleAds::V16::Services::CampaignService::CampaignOperation;
use Google::Ads::GoogleAds::V16::Utils::ResourceNames;

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

# 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";
my $manager_customer_id = "INSERT_MANAGER_CUSTOMER_ID_HERE";
my $campaign_id         = "INSERT_CAMPAIGN_ID_HERE";

sub use_cross_account_bidding_strategy {
  my ($api_client, $customer_id, $manager_customer_id, $campaign_id) = @_;

  my $bidding_strategy_resource_name =
    _create_bidding_strategy($api_client, $manager_customer_id);
  _list_manager_owned_bidding_strategies($api_client, $manager_customer_id);
  _list_customer_accessible_bidding_strategies($api_client, $customer_id);
  _attach_cross_account_bidding_strategy_to_campaign($api_client, $customer_id,
    $campaign_id, $bidding_strategy_resource_name);

  return 1;
}

# Creates a new TargetSpend (Maximize Clicks) cross-account bidding strategy in
# the specified manager account.
sub _create_bidding_strategy {
  my ($api_client, $manager_customer_id) = @_;

  # Create a portfolio bidding strategy.
  my $portfolio_bidding_strategy =
    Google::Ads::GoogleAds::V16::Resources::BiddingStrategy->new({
      name        => "Maximize clicks #" . uniqid(),
      targetSpend => Google::Ads::GoogleAds::V16::Common::TargetSpend->new(),
      # Sets the currency of the new bidding strategy. If not provided, the
      # bidding strategy uses the manager account's default currency.
      currencyCode => "USD"
    });

  # Send a create operation that will create the portfolio bidding strategy.
  my $mutate_bidding_strategies_response =
    $api_client->BiddingStrategyService()->mutate({
      customerId => $manager_customer_id,
      operations => [
        Google::Ads::GoogleAds::V16::Services::BiddingStrategyService::BiddingStrategyOperation
          ->new({
            create => $portfolio_bidding_strategy
          })]});

  my $resource_name =
    $mutate_bidding_strategies_response->{results}[0]{resourceName};

  printf "Created cross-account bidding strategy with resource name '%s'.\n",
    $resource_name;

  return $resource_name;
}

# Lists all cross-account bidding strategies in a specified manager account.
sub _list_manager_owned_bidding_strategies {
  my ($api_client, $manager_customer_id) = @_;

  # Create a GAQL query that will retrieve all cross-account bidding
  # strategies.
  my $query = "SELECT
                 bidding_strategy.id,
                 bidding_strategy.name,
                 bidding_strategy.type,
                 bidding_strategy.currency_code
               FROM bidding_strategy";

  # Issue a streaming search request, then iterate through and print the
  # results.
  my $search_stream_handler =
    Google::Ads::GoogleAds::Utils::SearchStreamHandler->new({
      service => $api_client->GoogleAdsService(),
      request =>
        Google::Ads::GoogleAds::V16::Services::GoogleAdsService::SearchGoogleAdsStreamRequest
        ->new({
          customerId => $manager_customer_id,
          query      => $query
        })});

  printf
    "Cross-account bid strategies in manager account $manager_customer_id:\n";
  $search_stream_handler->process_contents(
    sub {
      my $google_ads_row   = shift;
      my $bidding_strategy = $google_ads_row->{biddingStrategy};
      printf "\tID: $bidding_strategy->{id}\n" .
        "\tName: $bidding_strategy->{name}\n" .
        "\tStrategy type: $bidding_strategy->{type}\n" .
        "\tCurrency: $bidding_strategy->{currencyCode}\n\n";
    });
}

# Lists all bidding strategies available to specified client customer account.
# This includes both portfolio bidding strategies owned by the client customer
# account and cross-account bidding strategies shared by any of its managers.
sub _list_customer_accessible_bidding_strategies {
  my ($api_client, $customer_id) = @_;

  # Create a GAQL query that will retrieve all accessible bidding strategies.
  my $query = "SELECT
                 accessible_bidding_strategy.resource_name,
                 accessible_bidding_strategy.id,
                 accessible_bidding_strategy.name,
                 accessible_bidding_strategy.type,
                 accessible_bidding_strategy.owner_customer_id,
                 accessible_bidding_strategy.owner_descriptive_name
               FROM accessible_bidding_strategy";

  # Uncomment the following WHERE clause addition to the query to filter results
  # to *only* cross-account bidding strategies shared with the current customer
  # by a manager (and not also include the current customer's portfolio bidding
  # strategies).
  # $query .=
  #   " WHERE accessible_bidding_strategy.owner_customer_id != $customer_id";

  # Issue a streaming search request, then iterate through and print the
  # results.
  my $search_stream_handler =
    Google::Ads::GoogleAds::Utils::SearchStreamHandler->new({
      service => $api_client->GoogleAdsService(),
      request =>
        Google::Ads::GoogleAds::V16::Services::GoogleAdsService::SearchGoogleAdsStreamRequest
        ->new({
          customerId => $customer_id,
          query      => $query
        })});

  printf "All bid strategies accessible by account $customer_id:\n";
  $search_stream_handler->process_contents(
    sub {
      my $google_ads_row   = shift;
      my $bidding_strategy = $google_ads_row->{accessibleBiddingStrategy};
      printf "\tID: $bidding_strategy->{id}\n" .
        "\tName: $bidding_strategy->{name}\n" .
        "\tStrategy type: $bidding_strategy->{type}\n" .
        "\tOwner customer ID: $bidding_strategy->{ownerCustomerId}\n" .
        "\tOwner description: $bidding_strategy->{ownerDescriptiveName}\n\n";
    });
}

# Attaches a specified cross-account bidding strategy to a campaign owned by a
# specified client customer account.
sub _attach_cross_account_bidding_strategy_to_campaign {
  my ($api_client, $customer_id, $campaign_id, $bidding_strategy_resource_name)
    = @_;

  my $campaign = Google::Ads::GoogleAds::V16::Resources::Campaign->new({
      resourceName =>
        Google::Ads::GoogleAds::V16::Utils::ResourceNames::campaign(
        $customer_id, $campaign_id
        ),
      biddingStrategy => $bidding_strategy_resource_name
    });

  my $campaign_operation =
    Google::Ads::GoogleAds::V16::Services::CampaignService::CampaignOperation->
    new({
      update     => $campaign,
      updateMask => all_set_fields_of($campaign)});

  my $campaigns_response = $api_client->CampaignService()->mutate({
      customerId => $customer_id,
      operations => [$campaign_operation]});

  printf "Updated campaign with resource name '%s'.\n",
    $campaigns_response->{results}[0]{resourceName};
}

# 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,
  "manager_customer_id=s" => \$manager_customer_id,
  "campaign_id=i"         => \$campaign_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, $manager_customer_id, $campaign_id);

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

=pod

=head1 NAME

use_cross_account_bidding_strategy

=head1 DESCRIPTION

Demonstrates how to update the bidding strategy for an existing campaign.

This example shows updating a search campaign to maximize conversions, although
the same principles apply for other campaign/bidding strategy types.

=head1 SYNOPSIS

use_cross_account_bidding_strategy.pl [options]

    -help                       Show the help message.
    -customer_id                The Google Ads client customer ID.
    -manager_customer_id        The ID of the account that owns the cross-account bidding strategy.
                                This is typically the ID of the manager account.
    -campaign_id                The ID of the campaign owned by the customer ID to which the cross-account
                                bidding strategy will be attached.

=cut