Java
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.ads.googleads.examples.planning; 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.v18.common.DeviceInfo; import com.google.ads.googleads.v18.common.GenderInfo; import com.google.ads.googleads.v18.enums.DeviceEnum.Device; import com.google.ads.googleads.v18.enums.GenderTypeEnum.GenderType; import com.google.ads.googleads.v18.enums.ReachPlanAgeRangeEnum.ReachPlanAgeRange; import com.google.ads.googleads.v18.errors.GoogleAdsError; import com.google.ads.googleads.v18.errors.GoogleAdsException; import com.google.ads.googleads.v18.services.CampaignDuration; import com.google.ads.googleads.v18.services.GenerateReachForecastRequest; import com.google.ads.googleads.v18.services.GenerateReachForecastResponse; import com.google.ads.googleads.v18.services.ListPlannableLocationsRequest; import com.google.ads.googleads.v18.services.ListPlannableLocationsResponse; import com.google.ads.googleads.v18.services.ListPlannableProductsRequest; import com.google.ads.googleads.v18.services.ListPlannableProductsResponse; import com.google.ads.googleads.v18.services.PlannableLocation; import com.google.ads.googleads.v18.services.PlannedProduct; import com.google.ads.googleads.v18.services.PlannedProductReachForecast; import com.google.ads.googleads.v18.services.ProductMetadata; import com.google.ads.googleads.v18.services.ReachForecast; import com.google.ads.googleads.v18.services.ReachPlanServiceClient; import com.google.ads.googleads.v18.services.Targeting; import com.google.common.base.Joiner; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Demonstrates how to interact with the ReachPlanService to find plannable locations and product * codes, build a media plan, and generate a video ads reach forecast. */ public class ForecastReach { private static class ForecastReachParams extends CodeSampleParams { @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true) private Long customerId; } public static void main(String[] args) { ForecastReachParams params = new ForecastReachParams(); 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 ForecastReach().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 Google Ads API client. * @param customerId the customer ID for the reach forecast. */ private void runExample(GoogleAdsClient googleAdsClient, long customerId) { String locationId = "2840"; // US String currencyCode = "USD"; long budgetMicros = 5_000_000L; // $5 USD try (ReachPlanServiceClient reachPlanServiceClient = googleAdsClient.getLatestVersion().createReachPlanServiceClient()) { showPlannableLocations(reachPlanServiceClient); showPlannableProducts(reachPlanServiceClient, locationId); forecastManualMix(reachPlanServiceClient, customerId, locationId, currencyCode, budgetMicros); } } /** * Maps friendly names of plannable locations to location IDs usable with ReachPlanServiceClient. * * @param reachPlanServiceClient instance of Reach Plan Service client. */ private void showPlannableLocations(ReachPlanServiceClient reachPlanServiceClient) { ListPlannableLocationsRequest request = ListPlannableLocationsRequest.newBuilder().build(); ListPlannableLocationsResponse response = reachPlanServiceClient.listPlannableLocations(request); System.out.println("Plannable Locations:"); for (PlannableLocation location : response.getPlannableLocationsList()) { System.out.printf( "Name: %s, ID: %s, ParentCountryId: %s%n", location.getName(), location.getId(), location.getParentCountryId()); } } /** * Lists plannable products for a given location. * * @param reachPlanServiceClient instance of Reach Plan Service client. * @param locationId location ID to plan for. To find a valid location ID, either see * https://developers.google.com/google-ads/api/reference/data/geotargets or call * ReachPlanServiceClient.listPlannableLocations(). */ private void showPlannableProducts( ReachPlanServiceClient reachPlanServiceClient, String locationId) { ListPlannableProductsRequest request = ListPlannableProductsRequest.newBuilder().setPlannableLocationId(locationId).build(); ListPlannableProductsResponse response = reachPlanServiceClient.listPlannableProducts(request); System.out.printf("Plannable Products for location %s:%n", locationId); for (ProductMetadata product : response.getProductMetadataList()) { System.out.printf("%s:%n", product.getPlannableProductCode()); System.out.println("Age Ranges:"); for (ReachPlanAgeRange ageRange : product.getPlannableTargeting().getAgeRangesList()) { System.out.printf("\t- %s%n", ageRange); } System.out.println("Genders:"); for (GenderInfo gender : product.getPlannableTargeting().getGendersList()) { System.out.printf("\t- %s%n", gender.getType()); } System.out.println("Devices:"); for (DeviceInfo device : product.getPlannableTargeting().getDevicesList()) { System.out.printf("\t- %s%n", device.getType()); } } } /** * Creates a base request to generate a reach forecast. * * @param customerId the customer ID for the reach forecast. * @param productMix the product mix for the reach forecast. * @param locationId location ID to plan for. To find a valid location ID, either see * https://developers.google.com/google-ads/api/reference/data/geotargets or call * ReachPlanServiceClient.ListPlannableLocations. * @param currencyCode three-character ISO 4217 currency code. * @return populated GenerateReachForecastRequest object. */ private GenerateReachForecastRequest buildReachRequest( Long customerId, List<PlannedProduct> productMix, String locationId, String currencyCode) { CampaignDuration duration = CampaignDuration.newBuilder().setDurationInDays(28).build(); List<GenderInfo> genders = Arrays.asList( GenderInfo.newBuilder().setType(GenderType.FEMALE).build(), GenderInfo.newBuilder().setType(GenderType.MALE).build()); List<DeviceInfo> devices = Arrays.asList( DeviceInfo.newBuilder().setType(Device.DESKTOP).build(), DeviceInfo.newBuilder().setType(Device.MOBILE).build(), DeviceInfo.newBuilder().setType(Device.TABLET).build()); Targeting targeting = Targeting.newBuilder() .setPlannableLocationId(locationId) .setAgeRange(ReachPlanAgeRange.AGE_RANGE_18_65_UP) .addAllGenders(genders) .addAllDevices(devices) .build(); // See the docs for defaults and valid ranges: // https://developers.google.com/google-ads/api/reference/rpc/latest/GenerateReachForecastRequest return GenerateReachForecastRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setCurrencyCode(currencyCode) .setCampaignDuration(duration) .setTargeting(targeting) .setMinEffectiveFrequency(1) .addAllPlannedProducts(productMix) .build(); } /** * Pulls and prints the reach curve for the given request. * * @param reachPlanServiceClient instance of Reach Plan Service client. * @param request an already-populated reach curve request. */ private void getReachCurve( ReachPlanServiceClient reachPlanServiceClient, GenerateReachForecastRequest request) { GenerateReachForecastResponse response = reachPlanServiceClient.generateReachForecast(request); System.out.println("Reach curve output:"); System.out.println( "Currency, Cost Micros, On-Target Reach, On-Target Imprs, Total Reach, Total Imprs," + " Products"); for (ReachForecast point : response.getReachCurve().getReachForecastsList()) { System.out.printf( "%s, \"", Joiner.on(", ") .join( request.getCurrencyCode(), String.valueOf(point.getCostMicros()), String.valueOf(point.getForecast().getOnTargetReach()), String.valueOf(point.getForecast().getOnTargetImpressions()), String.valueOf(point.getForecast().getTotalReach()), String.valueOf(point.getForecast().getTotalImpressions()))); for (PlannedProductReachForecast product : point.getPlannedProductReachForecastsList()) { System.out.printf("[Product: %s, ", product.getPlannableProductCode()); System.out.printf("Budget Micros: %s]", product.getCostMicros()); } System.out.printf("\"%n"); } } /** * Pulls a forecast for a budget split 15% and 85% between two products. * * @param reachPlanServiceClient instance of Reach Plan Service client. * @param customerId the customer ID for the reach forecast. * @param locationId location ID to plan for. To find a valid location ID, either see * https://developers.google.com/google-ads/api/reference/data/geotargets or call * ReachPlanServiceClient.listPlannableLocations(). * @param currencyCode three-character ISO 4217 currency code. * @param budgetMicros budget in currency to plan for. */ private void forecastManualMix( ReachPlanServiceClient reachPlanServiceClient, long customerId, String locationId, String currencyCode, long budgetMicros) { List<PlannedProduct> productMix = new ArrayList<>(); // Set up a ratio to split the budget between two products. double trueviewAllocation = 0.15; double bumperAllocation = 1 - trueviewAllocation; // See listPlannableProducts on ReachPlanService to retrieve a list // of valid PlannableProductCode's for a given location: // https://developers.google.com/google-ads/api/reference/rpc/latest/ReachPlanService productMix.add( PlannedProduct.newBuilder() .setPlannableProductCode("TRUEVIEW_IN_STREAM") .setBudgetMicros((long) (budgetMicros * bumperAllocation)) .build()); productMix.add( PlannedProduct.newBuilder() .setPlannableProductCode("BUMPER") .setBudgetMicros((long) (budgetMicros * bumperAllocation)) .build()); GenerateReachForecastRequest request = buildReachRequest(customerId, productMix, locationId, currencyCode); getReachCurve(reachPlanServiceClient, request); } }
C#
// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using CommandLine; using Google.Ads.Gax.Examples; using Google.Ads.GoogleAds.Lib; using Google.Ads.GoogleAds.V18.Common; using Google.Ads.GoogleAds.V18.Errors; using Google.Ads.GoogleAds.V18.Services; using System; using System.Collections.Generic; using static Google.Ads.GoogleAds.V18.Enums.DeviceEnum.Types; using static Google.Ads.GoogleAds.V18.Enums.GenderTypeEnum.Types; using static Google.Ads.GoogleAds.V18.Enums.ReachPlanAgeRangeEnum.Types; namespace Google.Ads.GoogleAds.Examples.V18 { /// <summary> /// This example demonstrates how to interact with the ReachPlanService to find plannable /// locations and product codes, build a media plan, and generate a video ads reach forecast. /// </summary> public class ForecastReach : ExampleBase { /// <summary> /// Command line options for running the <see cref="ForecastReach"/> example. /// </summary> public class Options : OptionsBase { /// <summary> /// The Google Ads customer ID for which the call is made. /// </summary> [Option("customerId", Required = true, HelpText = "The Google Ads customer ID for which the call is made.")] public long CustomerId { get; set; } } /// <summary> /// Main method, to run this code example as a standalone application. /// </summary> /// <param name="args">The command line arguments.</param> public static void Main(string[] args) { Options options = ExampleUtilities.ParseCommandLine<Options>(args); ForecastReach codeExample = new ForecastReach(); Console.WriteLine(codeExample.Description); codeExample.Run(new GoogleAdsClient(), options.CustomerId); } /// <summary> /// Returns a description about the code example. /// </summary> public override string Description => "This example demonstrates how to interact with the ReachPlanService to find " + "plannable locations and product codes, build a media plan, and generate a video ads " + "reach forecast."; /// <summary> /// Runs the code example, showing a typical series of calls to the /// <see cref="Services.V18.ReachPlanService"/>. /// </summary> /// <param name="client">The Google Ads API client.</param> /// <param name="customerId">The Google Ads customer ID for which the call is made.</param> public void Run(GoogleAdsClient client, long customerId) { string locationId = "2840"; // US string currencyCode = "USD"; long budgetMicros = 5_000_000L; ReachPlanServiceClient reachPlanService = client.GetService(Services.V18.ReachPlanService); try { ShowPlannableLocations(reachPlanService); ShowPlannableProducts(reachPlanService, locationId); ForecastMix(reachPlanService, customerId.ToString(), locationId, currencyCode, budgetMicros); } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLine($"Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } } /// <summary> /// Maps friendly names of plannable locations to location IDs usable with /// <see cref="ReachPlanServiceClient"/>. /// </summary> /// <param name="reachPlanService">Instance of Reach Plan Service client.</param> public void ShowPlannableLocations(ReachPlanServiceClient reachPlanService) { ListPlannableLocationsRequest request = new ListPlannableLocationsRequest(); ListPlannableLocationsResponse response = reachPlanService.ListPlannableLocations( request); Console.WriteLine("Plannable Locations:"); Console.WriteLine("Name,\tId,\t,ParentCountryId"); foreach (PlannableLocation location in response.PlannableLocations) { Console.WriteLine( $"\"{location.Name}\",\t{location.Id},{location.ParentCountryId}"); } } /// <summary> /// Lists plannable products for a given location. /// </summary> /// <param name="reachPlanService">Instance of Reach Plan Service client.</param> /// <param name="locationId">Location ID to plan for. To find a valid location ID, either /// see https://developers.google.com/google-ads/api/reference/data/geotargets or call /// <see cref="ReachPlanServiceClient.ListPlannableLocations"/>.</param> public void ShowPlannableProducts( ReachPlanServiceClient reachPlanService, string locationId) { ListPlannableProductsRequest request = new ListPlannableProductsRequest { PlannableLocationId = locationId }; ListPlannableProductsResponse response = reachPlanService.ListPlannableProducts( request); Console.WriteLine($"Plannable Products for location {locationId}:"); foreach (ProductMetadata product in response.ProductMetadata) { Console.WriteLine($"{product.PlannableProductCode}:"); Console.WriteLine("Age Ranges:"); foreach (ReachPlanAgeRange ageRange in product.PlannableTargeting.AgeRanges) { Console.WriteLine($"\t- {ageRange}"); } Console.WriteLine("Genders:"); foreach (GenderInfo gender in product.PlannableTargeting.Genders) { Console.WriteLine($"\t- {gender.Type}"); } Console.WriteLine("Devices:"); foreach (DeviceInfo device in product.PlannableTargeting.Devices) { Console.WriteLine($"\t- {device.Type}"); } } } /// <summary> /// Create a base request to generate a reach forecast. /// </summary> /// <param name="customerId">The customer ID for the reach forecast.</param> /// <param name="productMix">The product mix for the reach forecast.</param> /// <param name="locationId">Location ID to plan for. To find a valid location ID, either /// see https://developers.google.com/google-ads/api/reference/data/geotargets or call /// <see cref="ReachPlanServiceClient.ListPlannableLocations"/>.</param> /// <param name="currencyCode">Three-character ISO 4217 currency code.</param> public GenerateReachForecastRequest BuildReachRequest( string customerId, List<PlannedProduct> productMix, string locationId, string currencyCode) { // Valid durations are between 1 and 90 days. CampaignDuration duration = new CampaignDuration { DurationInDays = 28 }; GenderInfo[] genders = { new GenderInfo {Type = GenderType.Female}, new GenderInfo {Type = GenderType.Male} }; DeviceInfo[] devices = { new DeviceInfo {Type = Device.Desktop}, new DeviceInfo {Type = Device.Mobile}, new DeviceInfo {Type = Device.Tablet} }; Targeting targeting = new Targeting { PlannableLocationId = locationId, AgeRange = ReachPlanAgeRange.AgeRange1865Up, }; targeting.Genders.AddRange(genders); targeting.Devices.AddRange(devices); // See the docs for defaults and valid ranges: // https://developers.google.com/google-ads/api/reference/rpc/latest/GenerateReachForecastRequest GenerateReachForecastRequest request = new GenerateReachForecastRequest { CustomerId = customerId, CurrencyCode = currencyCode, CampaignDuration = duration, Targeting = targeting, MinEffectiveFrequency = 1 }; request.PlannedProducts.AddRange(productMix); return request; } /// <summary> /// Retrieves and prints the reach curve for the given request. /// </summary> /// <param name="reachPlanService">Instance of Reach Plan Service client.</param> /// <param name="request">An already-populated reach curve request.</param> public void GetReachCurve(ReachPlanServiceClient reachPlanService, GenerateReachForecastRequest request) { GenerateReachForecastResponse response = reachPlanService.GenerateReachForecast( request); Console.WriteLine("Reach curve output:"); Console.WriteLine( "Currency, Cost Micros, On-Target Reach, On-Target Impressions, Total Reach," + " Total Impressions, Products"); foreach (ReachForecast point in response.ReachCurve.ReachForecasts) { Console.Write($"{request.CurrencyCode}, "); Console.Write($"{point.CostMicros}, "); Console.Write($"{point.Forecast.OnTargetReach}, "); Console.Write($"{point.Forecast.OnTargetImpressions}, "); Console.Write($"{point.Forecast.TotalReach}, "); Console.Write($"{point.Forecast.TotalImpressions}, "); Console.Write("\"["); foreach (PlannedProductReachForecast productReachForecast in point.PlannedProductReachForecasts) { Console.Write($"(Product: {productReachForecast.PlannableProductCode}, "); Console.Write($"Budget Micros: {productReachForecast.CostMicros}), "); } Console.WriteLine("]\""); } } /// <summary> /// Gets a forecast for a budget split 15% and 85% between two products. /// </summary> /// <param name="reachPlanService">Instance of Reach Plan Service client.</param> /// <param name="customerId">The customer ID for the reach forecast.</param> /// <param name="locationId">Location ID to plan for. To find a valid location ID, either /// see https://developers.google.com/google-ads/api/reference/data/geotargets or call /// <see cref="ReachPlanServiceClient.ListPlannableLocations"/>.</param> /// <param name="currencyCode">Three-character ISO 4217 currency code.</param> /// <param name="budgetMicros">Budget in currency to plan for.</param> public void ForecastMix(ReachPlanServiceClient reachPlanService, string customerId, string locationId, string currencyCode, long budgetMicros) { List<PlannedProduct> productMix = new List<PlannedProduct>(); // Set up a ratio to split the budget between two products. double trueviewAllocation = 0.15; double bumperAllocation = 1 - trueviewAllocation; // See listPlannableProducts on ReachPlanService to retrieve a list // of valid PlannableProductCode's for a given location: // https://developers.google.com/google-ads/api/reference/rpc/latest/ReachPlanService productMix.Add(new PlannedProduct { PlannableProductCode = "TRUEVIEW_IN_STREAM", BudgetMicros = Convert.ToInt64(budgetMicros * trueviewAllocation) }); productMix.Add(new PlannedProduct { PlannableProductCode = "BUMPER", BudgetMicros = Convert.ToInt64(budgetMicros * bumperAllocation) }); GenerateReachForecastRequest request = BuildReachRequest(customerId, productMix, locationId, currencyCode); GetReachCurve(reachPlanService, request); } } }
PHP
<?php /** * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace Google\Ads\GoogleAds\Examples\Planning; require __DIR__ . '/../../vendor/autoload.php'; use GetOpt\GetOpt; use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames; use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser; use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder; use Google\Ads\GoogleAds\Lib\V18\GoogleAdsClient; use Google\Ads\GoogleAds\Lib\V18\GoogleAdsClientBuilder; use Google\Ads\GoogleAds\Lib\V18\GoogleAdsException; use Google\Ads\GoogleAds\V18\Common\DeviceInfo; use Google\Ads\GoogleAds\V18\Common\GenderInfo; use Google\Ads\GoogleAds\V18\Enums\DeviceEnum\Device; use Google\Ads\GoogleAds\V18\Enums\GenderTypeEnum\GenderType; use Google\Ads\GoogleAds\V18\Enums\ReachPlanAgeRangeEnum\ReachPlanAgeRange; use Google\Ads\GoogleAds\V18\Errors\GoogleAdsError; use Google\Ads\GoogleAds\V18\Services\CampaignDuration; use Google\Ads\GoogleAds\V18\Services\GenerateReachForecastRequest; use Google\Ads\GoogleAds\V18\Services\ListPlannableLocationsRequest; use Google\Ads\GoogleAds\V18\Services\ListPlannableProductsRequest; use Google\Ads\GoogleAds\V18\Services\PlannableLocation; use Google\Ads\GoogleAds\V18\Services\PlannedProduct; use Google\Ads\GoogleAds\V18\Services\PlannedProductReachForecast; use Google\Ads\GoogleAds\V18\Services\ProductMetadata; use Google\Ads\GoogleAds\V18\Services\ReachForecast; use Google\Ads\GoogleAds\V18\Services\Targeting; use Google\ApiCore\ApiException; /** * This example demonstrates how to interact with the ReachPlanService to find plannable * locations and product codes, build a media plan, and generate a video ads reach forecast. */ class ForecastReach { private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE'; private const CURRENCY_CODE = 'USD'; // You can get a valid location ID from // https://developers.google.com/adwords/api/docs/appendix/geotargeting or by calling // ListPlannableLocations on the ReachPlanService. private const LOCATION_ID = '2840'; // US private const BUDGET_MICROS = 5000000; // 5 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 ); } exit(1); } catch (ApiException $apiException) { printf( "ApiException was thrown with message '%s'.%s", $apiException->getMessage(), PHP_EOL ); exit(1); } } /** * Runs the example. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID */ public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId) { self::showPlannableLocations($googleAdsClient); self::showPlannableProducts($googleAdsClient); self::forecastManualMix($googleAdsClient, $customerId); } /** * Shows map of plannable locations to their IDs. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client */ private static function showPlannableLocations(GoogleAdsClient $googleAdsClient) { $response = $googleAdsClient->getReachPlanServiceClient()->listPlannableLocations( new ListPlannableLocationsRequest() ); printf("Plannable Locations:%sName, Id, ParentCountryId%s", PHP_EOL, PHP_EOL); foreach ($response->getPlannableLocations() as $location) { /** @var PlannableLocation $location */ printf( "'%s', %s, %s%s", $location->getName(), $location->getId(), $location->getParentCountryId(), PHP_EOL ); } } /** * Lists plannable products for a given location. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client */ private static function showPlannableProducts(GoogleAdsClient $googleAdsClient) { $response = $googleAdsClient->getReachPlanServiceClient()->listPlannableProducts( ListPlannableProductsRequest::build(self::LOCATION_ID) ); print 'Plannable Products for Location ID ' . self::LOCATION_ID . ':' . PHP_EOL; foreach ($response->getProductMetadata() as $product) { /** @var ProductMetadata $product */ print $product->getPlannableProductCode() . ':' . PHP_EOL; print 'Age Ranges:' . PHP_EOL; foreach ($product->getPlannableTargeting()->getAgeRanges() as $ageRange) { /** @var ReachPlanAgeRange $ageRange */ printf("\t- %s%s", ReachPlanAgeRange::name($ageRange), PHP_EOL); } print 'Genders:' . PHP_EOL; foreach ($product->getPlannableTargeting()->getGenders() as $gender) { /** @var GenderInfo $gender */ printf("\t- %s%s", GenderType::name($gender->getType()), PHP_EOL); } print 'Devices:' . PHP_EOL; foreach ($product->getPlannableTargeting()->getDevices() as $device) { /** @var DeviceInfo $device */ printf("\t- %s%s", Device::name($device->getType()), PHP_EOL); } } } /** * Retrieves and prints the reach curve for a given product mix. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param array $productMix the product mix for the reach forecast * @param string $locationId the location ID to plan for. You can get a valid location ID from * https://developers.google.com/adwords/api/docs/appendix/geotargeting or * by calling ListPlannableLocations on the ReachPlanService. * @param string $currencyCode three-character ISO 4217 currency code */ private static function getReachCurve( GoogleAdsClient $googleAdsClient, int $customerId, array $productMix, string $locationId, string $currencyCode ) { // Valid durations are between 1 and 90 days. $duration = new CampaignDuration(['duration_in_days' => 28]); $targeting = new Targeting([ 'plannable_location_id' => $locationId, 'age_range' => ReachPlanAgeRange::AGE_RANGE_18_65_UP, 'genders' => [ new GenderInfo(['type' => GenderType::FEMALE]), new GenderInfo(['type' => GenderType::MALE]) ], 'devices' => [ new DeviceInfo(['type' => Device::DESKTOP]), new DeviceInfo(['type' => Device::MOBILE]), new DeviceInfo(['type' => Device::TABLET]) ] ]); // See the docs for defaults and valid ranges: // https://developers.google.com/google-ads/api/reference/rpc/latest/GenerateReachForecastRequest $response = $googleAdsClient->getReachPlanServiceClient()->generateReachForecast( GenerateReachForecastRequest::build($customerId, $duration, $productMix) ->setCurrencyCode($currencyCode) ->setTargeting($targeting) ); printf( "Reach curve output:%sCurrency, Cost Micros, On-Target Reach, On-Target Imprs," . " Total Reach, Total Imprs, Products%s", PHP_EOL, PHP_EOL ); foreach ($response->getReachCurve()->getReachForecasts() as $point) { $products = ''; /** @var ReachForecast $point */ foreach ($point->getPlannedProductReachForecasts() as $plannedProductReachForecast) { /** @var PlannedProductReachForecast $plannedProductReachForecast */ $products .= sprintf( '(Product: %s, Budget Micros: %s)', $plannedProductReachForecast->getPlannableProductCode(), $plannedProductReachForecast->getCostMicros() ); } printf( "%s, %d, %d, %d, %d, %d, %s%s", $currencyCode, $point->getCostMicros(), $point->getForecast()->getOnTargetReach(), $point->getForecast()->getOnTargetImpressions(), $point->getForecast()->getTotalReach(), $point->getForecast()->getTotalImpressions(), $products, PHP_EOL ); } } /** * Gets a forecast for product mix created manually. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID */ private static function forecastManualMix(GoogleAdsClient $googleAdsClient, int $customerId) { // Set up a ratio to split the budget between two products. $trueviewAllocation = floatval(0.15); $bumperAllocation = floatval(1 - $trueviewAllocation); // See listPlannableProducts on ReachPlanService to retrieve a list // of valid PlannableProductCode's for a given location: // https://developers.google.com/google-ads/api/reference/rpc/latest/ReachPlanService $productMix = [ new PlannedProduct([ 'plannable_product_code' => 'TRUEVIEW_IN_STREAM', 'budget_micros' => self::BUDGET_MICROS * $trueviewAllocation ]), new PlannedProduct([ 'plannable_product_code' => 'BUMPER', 'budget_micros' => self::BUDGET_MICROS * $bumperAllocation ]) ]; self::getReachCurve( $googleAdsClient, $customerId, $productMix, self::LOCATION_ID, self::CURRENCY_CODE ); } } ForecastReach::main();
Python
#!/usr/bin/env python # Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """This code example generates a video ads reach forecast.""" import argparse import math import sys from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException ONE_MILLION = 1.0e6 def main(client, customer_id): """The main method that creates all necessary entities for the example. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. """ # You can review a list of valid location IDs by visiting: # https://developers.google.com/google-ads/api/reference/data/geotargets # or by calling the ListPlannableLocations method on ReachPlanService. location_id = "2840" # US currency_code = "USD" budget = 500000 show_plannable_locations(client) show_plannable_products(client, location_id) forecast_manual_mix(client, customer_id, location_id, currency_code, budget) def show_plannable_locations(client): """Shows map of plannable locations to their IDs. Args: client: an initialized GoogleAdsClient instance. """ reach_plan_service = client.get_service("ReachPlanService") response = reach_plan_service.list_plannable_locations() print("Plannable Locations") print("Name,\tId,\tParentCountryId") for location in response.plannable_locations: print( f"'{location.name}',\t{location.id},\t{location.parent_country_id}" ) def show_plannable_products(client, location_id): """Lists plannable products for a given location. Args: client: an initialized GoogleAdsClient instance. location_id: The location ID to plan for. """ reach_plan_service = client.get_service("ReachPlanService") response = reach_plan_service.list_plannable_products( plannable_location_id=location_id ) print(f"Plannable Products for Location ID {location_id}") for product_metadata in response.product_metadata: print( f"{product_metadata.plannable_product_code} : " f"{product_metadata.plannable_product_name}" ) print("Age Ranges:") for age_range in product_metadata.plannable_targeting.age_ranges: print(f"\t- {age_range.name}") print("Genders:") for gender in product_metadata.plannable_targeting.genders: print(f"\t- {gender.type_.name}") print("Devices:") for device in product_metadata.plannable_targeting.devices: print(f"\t- {device.type_.name}") def request_reach_curve( client, customer_id, product_mix, location_id, currency_code ): """Creates a sample request for a given product mix. Args: client: an initialized GoogleAdsClient instance. customer_id: The customer ID for the reach forecast. product_mix: The product mix for the reach forecast. location_id: The location ID to plan for. currency_code: Three-character ISO 4217 currency code. """ # See the docs for defaults and valid ranges: # https://developers.google.com/google-ads/api/reference/rpc/latest/GenerateReachForecastRequest request = client.get_type("GenerateReachForecastRequest") request.customer_id = customer_id # Valid durations are between 1 and 90 days. request.campaign_duration.duration_in_days = 28 request.currency_code = currency_code request.cookie_frequency_cap = 0 request.min_effective_frequency = 1 request.planned_products = product_mix request.targeting.plannable_location_id = location_id request.targeting.age_range = ( client.enums.ReachPlanAgeRangeEnum.AGE_RANGE_18_65_UP ) # Add gender targeting to the request. for gender_type in [ client.enums.GenderTypeEnum.FEMALE, client.enums.GenderTypeEnum.MALE, ]: gender = client.get_type("GenderInfo") gender.type_ = gender_type request.targeting.genders.append(gender) # Add device targeting to the request. for device_type in [ client.enums.DeviceEnum.DESKTOP, client.enums.DeviceEnum.MOBILE, client.enums.DeviceEnum.TABLET, ]: device = client.get_type("DeviceInfo") device.type_ = device_type request.targeting.devices.append(device) reach_plan_service = client.get_service("ReachPlanService") response = reach_plan_service.generate_reach_forecast(request=request) print( "Currency, Cost, On-Target Reach, On-Target Imprs, Total Reach," " Total Imprs, Products" ) for point in response.reach_curve.reach_forecasts: product_splits = [] for p in point.planned_product_reach_forecasts: product_splits.append( {p.plannable_product_code: p.cost_micros / ONE_MILLION} ) print( [ currency_code, point.cost_micros / ONE_MILLION, point.forecast.on_target_reach, point.forecast.on_target_impressions, point.forecast.total_reach, point.forecast.total_impressions, product_splits, ] ) def forecast_manual_mix( client, customer_id, location_id, currency_code, budget ): """Pulls a forecast for product mix created manually. Args: client: an initialized GoogleAdsClient instance. customer_id: The customer ID for the reach forecast. product_mix: The product mix for the reach forecast. location_id: The location ID to plan for. currency_code: Three-character ISO 4217 currency code. budget: Budget to allocate to the plan. """ product_mix = [] trueview_allocation = 0.15 bumper_allocation = 1 - trueview_allocation product_splits = [ ("TRUEVIEW_IN_STREAM", trueview_allocation), ("BUMPER", bumper_allocation), ] for product, split in product_splits: planned_product = client.get_type("PlannedProduct") planned_product.plannable_product_code = product planned_product.budget_micros = math.trunc(budget * ONE_MILLION * split) product_mix.append(planned_product) request_reach_curve( client, customer_id, product_mix, location_id, currency_code ) if __name__ == "__main__": parser = argparse.ArgumentParser( description="Generates video ads reach forecast." ) # The following argument(s) should be provided to run the example. parser.add_argument( "-c", "--customer_id", type=str, required=True, help="The Google Ads customer ID.", ) args = parser.parse_args() # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client = GoogleAdsClient.load_from_storage(version="v18") try: main(googleads_client, args.customer_id) except GoogleAdsException as ex: print( 'Request with ID "{}" failed with status "%s" and includes the ' "following errors:".format(ex.request_id, ex.error.code().name) ) for error in ex.failure.errors: print('\tError with message "{}".'.format(error.message)) if error.location: for field_path_element in error.location.field_path_elements: print( "\t\tOn field: {}".format(field_path_element.field_name) ) sys.exit(1)
Ruby
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example demonstrates how to interact with the ReachPlanService to find # plannable locations and product codes, build a media plan, and generate a # video ads reach forecast. require 'optparse' require 'google/ads/google_ads' def forecast_reach(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 reach_plan_service = client.service.reach_plan show_plannable_locations(reach_plan_service) show_plannable_products(reach_plan_service) forecast_manual_mix(client, reach_plan_service, customer_id) end # Shows map of plannable locations to their IDs. def show_plannable_locations(reach_plan_service) response = reach_plan_service.list_plannable_locations() puts "Plannable Locations:" puts "Name, Id, ParentCountryId" response.plannable_locations.each do |location| puts "'#{location.name}', #{location.id}, #{location.parent_country_id}" end end # Lists plannable products for a given location. def show_plannable_products(reach_plan_service) response = reach_plan_service.list_plannable_products( plannable_location_id: LOCATION_ID, ) puts "Plannable Products for Location ID #{LOCATION_ID}:" response.product_metadata.each do |product| puts "#{product.plannable_product_code}:" puts "Age Ranges:" product.plannable_targeting.age_ranges.each do |age_range| puts "\t- #{age_range}" end puts "Genders:" product.plannable_targeting.genders.each do |gender| puts "\t- #{gender.type}" end puts "Devices:" product.plannable_targeting.devices.each do |device| puts "\t- #{device.type}" end end end # Retrieves and prints the reach curve for a given product mix. def get_reach_curve( client, reach_plan_service, customer_id, product_mix, location_id, currency_code) duration = client.resource.campaign_duration do |d| # Valid durations are between 1 and 90 days. d.duration_in_days = 28 end targeting = client.resource.targeting do |t| t.plannable_location_id = location_id t.age_range = :AGE_RANGE_18_65_UP t.genders << client.resource.gender_info do |gender| gender.type = :FEMALE end t.genders << client.resource.gender_info do |gender| gender.type = :MALE end t.devices << client.resource.device_info do |device| device.type = :DESKTOP end t.devices << client.resource.device_info do |device| device.type = :MOBILE end t.devices << client.resource.device_info do |device| device.type = :TABLET end end # See the docs for defaults and valid ranges: # https://developers.google.com/google-ads/api/reference/rpc/latest/GenerateReachForecastRequest response = reach_plan_service.generate_reach_forecast( customer_id: customer_id, campaign_duration: duration, planned_products: product_mix, currency_code: currency_code, targeting: targeting, ) puts "Reach curve output:" puts "Currency, Cost Micros, On-Target Reach, On-Target Imprs, " \ "Total Reach, Total Imprs, Products" response.reach_curve.reach_forecasts.each do |point| products = "" point.planned_product_reach_forecasts.each do |product| products += "(Product: #{product.plannable_product_code}, "\ "Cost Micros: #{product.cost_micros})" end puts "#{currency_code}, #{point.cost_micros}, " \ "#{point.forecast.on_target_reach}, " \ "#{point.forecast.on_target_impressions}, " \ "#{point.forecast.total_reach}, " \ "#{point.forecast.total_impressions}, " \ "#{products}" end end # Gets a forecast for product mix created manually. def forecast_manual_mix(client, reach_plan_service, customer_id) # Set up a ratio to split the budget between two products. trueview_allocation = 0.15 bumper_allocation = 1 - trueview_allocation # See listPlannableProducts on ReachPlanService to retrieve a list # of valid PlannableProductCode's for a given location: # https://developers.google.com/google-ads/api/reference/rpc/latest/ReachPlanService product_mix = [] product_mix << client.resource.planned_product do |p| p.plannable_product_code = 'TRUEVIEW_IN_STREAM' p.budget_micros = BUDGET_MICROS * trueview_allocation end product_mix << client.resource.planned_product do |p| p.plannable_product_code = 'BUMPER' p.budget_micros = BUDGET_MICROS * bumper_allocation end get_reach_curve( client, reach_plan_service, customer_id, product_mix, LOCATION_ID, CURRENCY_CODE, ) end if __FILE__ == $0 CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE'; CURRENCY_CODE = 'USD'; # You can get a valid location ID from # https://developers.google.com/adwords/api/docs/appendix/geotargeting # or by calling list_plannable_locations on the reach_plan service. LOCATION_ID = '2840'; # US BUDGET_MICROS = 5_000_000; # 5 options = {} # The following parameter(s) should be provided to run the example. You can # either specify these by changing the INSERT_XXX_ID_HERE values below, or on # the command line. # # Parameters passed on the command line will override any parameters set in # code. # # Running the example with -h will print the command line usage. options[:customer_id] = 'INSERT_CUSTOMER_ID_HERE' OptionParser.new do |opts| opts.banner = sprintf('Usage: %s [options]', File.basename(__FILE__)) opts.separator '' opts.separator 'Options:' opts.on('-C', '--customer-id CUSTOMER-ID', String, 'Customer ID') do |v| options[:customer_id] = v end opts.separator '' opts.separator 'Help:' opts.on_tail('-h', '--help', 'Show this message') do puts opts exit end end.parse! begin forecast_reach(options.fetch(:customer_id).tr("-", "")) rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e e.failure.errors.each do |error| STDERR.printf("Error with message: %s\n", error.message) if error.location error.location.field_path_elements.each do |field_path_element| STDERR.printf("\tOn field: %s\n", field_path_element.field_name) end end error.error_code.to_h.each do |k, v| next if v == :UNSPECIFIED STDERR.printf("\tType: %s\n\tCode: %s\n", k, v) end end raise end end
Perl
#!/usr/bin/perl -w # # Copyright 2019, Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example demonstrates how to interact with the ReachPlanService to find # plannable locations and product codes, build a media plan, and generate a video # ads reach forecast. 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::V18::Common::GenderInfo; use Google::Ads::GoogleAds::V18::Common::DeviceInfo; use Google::Ads::GoogleAds::V18::Enums::ReachPlanAdLengthEnum qw(FIFTEEN_OR_TWENTY_SECONDS); use Google::Ads::GoogleAds::V18::Enums::GenderTypeEnum qw(MALE FEMALE); use Google::Ads::GoogleAds::V18::Enums::DeviceEnum qw(DESKTOP MOBILE TABLET); use Google::Ads::GoogleAds::V18::Enums::ReachPlanAgeRangeEnum qw(AGE_RANGE_18_65_UP); use Google::Ads::GoogleAds::V18::Services::ReachPlanService::PlannedProduct; use Google::Ads::GoogleAds::V18::Services::ReachPlanService::CampaignDuration; use Google::Ads::GoogleAds::V18::Services::ReachPlanService::Targeting; use Google::Ads::GoogleAds::V18::Services::ReachPlanService::GenerateReachForecastRequest; use Getopt::Long qw(:config auto_help); use Pod::Usage; use Cwd qw(abs_path); # The following parameter(s) should be provided to run the example. You can # either specify these by changing the INSERT_XXX_ID_HERE values below, or on # the command line. # # Parameters passed on the command line will override any parameters set in # code. # # Running the example with -h will print the command line usage. my $customer_id = "INSERT_CUSTOMER_ID_HERE"; sub forecast_reach { my ($api_client, $customer_id) = @_; # Location ID to plan for. You can get a valid location ID from # https://developers.google.com/google-ads/api/reference/data/geotargets or by # calling list_plannable_locations on the ReachPlanService. # Location ID 2840 is for USA. my $location_id = "2840"; my $currency_code = "USD"; my $budget_micros = 500_000_000_000; my $reach_plan_service = $api_client->ReachPlanService(); show_plannable_locations($reach_plan_service); show_plannable_products($reach_plan_service, $location_id); forecast_mix( $reach_plan_service, $customer_id, $location_id, $currency_code, $budget_micros ); return 1; } # Maps friendly names of plannable locations to location IDs usable with # ReachPlanService. sub show_plannable_locations { my ($reach_plan_service) = @_; my $response = $reach_plan_service->list_plannable_locations(); print "Plannable Locations:\n"; print "Name,\tId,\tParentCountryId\n"; foreach my $location (@{$response->{plannableLocations}}) { printf "'%s',\t%s,\t%d\n", $location->{name}, $location->{id}, $location->{parentCountryId} ? $location->{parentCountryId} : 0; } } # Lists plannable products for a given location. sub show_plannable_products { my ($reach_plan_service, $location_id) = @_; my $response = $reach_plan_service->list_plannable_products({ plannableLocationId => $location_id }); printf "Plannable Products for location %d:\n", $location_id; foreach my $product (@{$response->{productMetadata}}) { printf "%s : '%s'\n", $product->{plannableProductCode}, $product->{plannableProductName}; print "Age Ranges:\n"; foreach my $age_range (@{$product->{plannableTargeting}{ageRanges}}) { printf "\t- %s\n", $age_range; } print "Genders:\n"; foreach my $gender (@{$product->{plannableTargeting}{genders}}) { printf "\t- %s\n", $gender->{type}; } print "Devices:\n"; foreach my $device (@{$product->{plannableTargeting}{devices}}) { printf "\t- %s\n", $device->{type}; } } } # Pulls a forecast for a budget split 15% and 85% between two products. sub forecast_mix { my ( $reach_plan_service, $customer_id, $location_id, $currency_code, $budget_micros ) = @_; my $product_mix = []; # Set up a ratio to split the budget between two products. my $trueview_allocation = 0.15; my $bumper_allocation = 1 - $trueview_allocation; # See list_plannable_products on ReachPlanService to retrieve a list of valid # plannable product codes for a given location: # https://developers.google.com/google-ads/api/reference/rpc/latest/ReachPlanService push @$product_mix, Google::Ads::GoogleAds::V18::Services::ReachPlanService::PlannedProduct-> new({ plannableProductCode => "TRUEVIEW_IN_STREAM", budgetMicros => int($budget_micros * $trueview_allocation)}); push @$product_mix, Google::Ads::GoogleAds::V18::Services::ReachPlanService::PlannedProduct-> new({ plannableProductCode => "BUMPER", budgetMicros => int($budget_micros * $bumper_allocation)}); my $reach_request = build_reach_request($customer_id, $product_mix, $location_id, $currency_code); pull_reach_curve($reach_plan_service, $reach_request); } # Create a base request to generate a reach forecast. sub build_reach_request { my ($customer_id, $product_mix, $location_id, $currency_code) = @_; # Valid durations are between 1 and 90 days. my $duration = Google::Ads::GoogleAds::V18::Services::ReachPlanService::CampaignDuration-> new({ durationInDays => 28 }); my $genders = [ Google::Ads::GoogleAds::V18::Common::GenderInfo->new({ type => FEMALE } ), Google::Ads::GoogleAds::V18::Common::GenderInfo->new({ type => MALE })]; my $devices = [ Google::Ads::GoogleAds::V18::Common::DeviceInfo->new({ type => DESKTOP } ), Google::Ads::GoogleAds::V18::Common::DeviceInfo->new({ type => MOBILE } ), Google::Ads::GoogleAds::V18::Common::DeviceInfo->new({ type => TABLET })]; my $targeting = Google::Ads::GoogleAds::V18::Services::ReachPlanService::Targeting->new({ plannableLocationId => $location_id, ageRange => AGE_RANGE_18_65_UP, genders => $genders, devices => $devices }); # See the docs for defaults and valid ranges: # https://developers.google.com/google-ads/api/reference/rpc/latest/GenerateReachForecastRequest return Google::Ads::GoogleAds::V18::Services::ReachPlanService::GenerateReachForecastRequest ->new({ customerId => $customer_id, currencyCode => $currency_code, campaignDuration => $duration, cookieFrequencyCap => 0, minEffectiveFrequency => 1, targeting => $targeting, plannedProducts => $product_mix }); } # Pulls and prints the reach curve for the given request. sub pull_reach_curve { my ($reach_plan_service, $reach_request) = @_; my $response = $reach_plan_service->generate_reach_forecast($reach_request); print "Reach curve output:\n"; print "Currency,\tCost Micros,\tOn-Target Reach,\tOn-Target Imprs,\t" . "Total Reach,\tTotal Imprs,\tProducts\n"; foreach my $point (@{$response->{reachCurve}{reachForecasts}}) { printf "%s,\t%d,\t%d,\t%d,\t%d,\t%d,\t'[", $reach_request->{currencyCode}, $point->{costMicros}, $point->{forecast}{onTargetReach}, $point->{forecast}{onTargetImpressions}, $point->{forecast}{totalReach}, $point->{forecast}{totalImpressions}; foreach my $productReachForecast (@{$point->{plannedProductReachForecasts}}) { printf "(Product: %s, Budget Micros: %d), ", $productReachForecast->{plannableProductCode}, $productReachForecast->{costMicros}; } print "]'\n"; } } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) { return 1; } # Get Google Ads Client, credentials will be read from ~/googleads.properties. my $api_client = Google::Ads::GoogleAds::Client->new(); # By default examples are set to die on any server returned fault. $api_client->set_die_on_faults(1); # Parameters passed on the command line will override any parameters set in code. GetOptions("customer_id=s" => \$customer_id); # Print the help message if the parameters are not initialized in the code nor # in the command line. pod2usage(2) if not check_params($customer_id); # Call the example. forecast_reach($api_client, $customer_id =~ s/-//gr); =pod =head1 NAME forecast_reach =head1 DESCRIPTION This example demonstrates how to interact with the ReachPlanService to find plannable locations and product codes, build a media plan, and generate a video ads reach forecast. =head1 SYNOPSIS forecast_reach.pl [options] -help Show the help message. -customer_id The Google Ads customer ID. =cut