Add Local Campaign

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

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.v8.common.AdImageAsset;
import com.google.ads.googleads.v8.common.AdTextAsset;
import com.google.ads.googleads.v8.common.AdVideoAsset;
import com.google.ads.googleads.v8.common.ImageAsset;
import com.google.ads.googleads.v8.common.LocalAdInfo;
import com.google.ads.googleads.v8.common.MaximizeConversionValue;
import com.google.ads.googleads.v8.common.YoutubeVideoAsset;
import com.google.ads.googleads.v8.enums.AdGroupAdStatusEnum.AdGroupAdStatus;
import com.google.ads.googleads.v8.enums.AdGroupStatusEnum.AdGroupStatus;
import com.google.ads.googleads.v8.enums.AdvertisingChannelSubTypeEnum.AdvertisingChannelSubType;
import com.google.ads.googleads.v8.enums.AdvertisingChannelTypeEnum.AdvertisingChannelType;
import com.google.ads.googleads.v8.enums.AssetTypeEnum.AssetType;
import com.google.ads.googleads.v8.enums.BudgetDeliveryMethodEnum.BudgetDeliveryMethod;
import com.google.ads.googleads.v8.enums.CampaignStatusEnum.CampaignStatus;
import com.google.ads.googleads.v8.enums.LocationSourceTypeEnum.LocationSourceType;
import com.google.ads.googleads.v8.enums.OptimizationGoalTypeEnum.OptimizationGoalType;
import com.google.ads.googleads.v8.errors.GoogleAdsError;
import com.google.ads.googleads.v8.errors.GoogleAdsException;
import com.google.ads.googleads.v8.resources.Ad;
import com.google.ads.googleads.v8.resources.AdGroup;
import com.google.ads.googleads.v8.resources.AdGroupAd;
import com.google.ads.googleads.v8.resources.Asset;
import com.google.ads.googleads.v8.resources.Campaign;
import com.google.ads.googleads.v8.resources.Campaign.LocalCampaignSetting;
import com.google.ads.googleads.v8.resources.Campaign.OptimizationGoalSetting;
import com.google.ads.googleads.v8.resources.CampaignBudget;
import com.google.ads.googleads.v8.services.AdGroupAdOperation;
import com.google.ads.googleads.v8.services.AdGroupAdServiceClient;
import com.google.ads.googleads.v8.services.AdGroupOperation;
import com.google.ads.googleads.v8.services.AdGroupServiceClient;
import com.google.ads.googleads.v8.services.AssetOperation;
import com.google.ads.googleads.v8.services.AssetServiceClient;
import com.google.ads.googleads.v8.services.CampaignBudgetOperation;
import com.google.ads.googleads.v8.services.CampaignBudgetServiceClient;
import com.google.ads.googleads.v8.services.CampaignOperation;
import com.google.ads.googleads.v8.services.CampaignServiceClient;
import com.google.ads.googleads.v8.services.MutateAdGroupAdsResponse;
import com.google.ads.googleads.v8.services.MutateAdGroupsResponse;
import com.google.ads.googleads.v8.services.MutateAssetsResponse;
import com.google.ads.googleads.v8.services.MutateCampaignBudgetsResponse;
import com.google.ads.googleads.v8.services.MutateCampaignsResponse;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;
import com.google.protobuf.ByteString;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;

/**
 * Adds an Local campaign.
 *
 * <p>Prerequisite: To create a Local campaign, you need to define the store locations you want to
 * promote by linking your Google My Business account or selecting affiliate locations. More
 * information about Local campaigns can be found at:
 * https://support.google.com/google-ads/answer/9118422.
 */
public class AddLocalCampaign {

  private static final String MARKETING_IMAGE_URL = "https://gaagl.page.link/Eit5";
  private static final String LOGO_IMAGE_URL = "https://gaagl.page.link/bjYi";
  private static final String YOUTUBE_VIDEO_ID = "ECpDzH9gXh8";

  private static class AddLocalCampaignParams extends CodeSampleParams {

    @Parameter(names = ArgumentNames.CUSTOMER_ID)
    private long customerId;
  }

  public static void main(String[] args) throws IOException {
    AddLocalCampaignParams params = new AddLocalCampaignParams();
    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 = 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 AddLocalCampaign().runExample(googleAdsClient, params.customerId);
    } catch (GoogleAdsException gae) {
      // GoogleAdsException is the base class for most exceptions thrown by an API request.
      // Instances of this exception have a message and a GoogleAdsFailure that contains a
      // collection of GoogleAdsErrors that indicate the underlying causes of the
      // GoogleAdsException.
      System.err.printf(
          "Request ID %s failed due to GoogleAdsException. Underlying errors:%n",
          gae.getRequestId());
      int i = 0;
      for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) {
        System.err.printf("  Error %d: %s%n", i++, googleAdsError);
      }
      System.exit(1);
    }
  }

  /** Runs the example. */
  private void runExample(GoogleAdsClient googleAdsClient, long customerId) throws IOException {
    // Creates a budget for the campaign.
    String budgetResourceName = createCampaignBudget(googleAdsClient, customerId);

    // Creates a local campaign.
    String campaignResourceName =
        createLocalCampaign(googleAdsClient, customerId, budgetResourceName);

    // Creates a local campaign ad group.
    String adGroupResourceName = createAdGroup(googleAdsClient, customerId, campaignResourceName);

    // Creates a local ad.
    createLocalAd(googleAdsClient, customerId, adGroupResourceName);
  }

  /** Creates a campaign budget. */
  private String createCampaignBudget(GoogleAdsClient googleAdsClient, long customerId) {
    // Creates a CampaignBudget object.
    CampaignBudget budget =
        CampaignBudget.newBuilder()
            .setAmountMicros(50000000)
            .setName("Interplanetary Cruise Budget #" + getPrintableDateTime())
            .setDeliveryMethod(BudgetDeliveryMethod.STANDARD)
            // A Local campaign cannot use a shared campaign budget.
            .setExplicitlyShared(false)
            .build();

    // Creates an operation to add the campaign.
    CampaignBudgetOperation operation =
        CampaignBudgetOperation.newBuilder().setCreate(budget).build();

    // Connects to the API.
    try (CampaignBudgetServiceClient campaignBudgetServiceClient =
        googleAdsClient.getLatestVersion().createCampaignBudgetServiceClient()) {
      // Issues the mutate request.
      MutateCampaignBudgetsResponse response =
          campaignBudgetServiceClient.mutateCampaignBudgets(
              String.valueOf(customerId), ImmutableList.of(operation));

      // Prints some debugging information.
      String resourceName = response.getResults(0).getResourceName();
      System.out.printf("Created campaign budget with resource name: '%s'.%n", resourceName);
      return resourceName;
    }
  }

  /** Creates a local campaign. */
  private String createLocalCampaign(
      GoogleAdsClient googleAdsClient, long customerId, String budgetResourceName) {
    // Creates a Campaign object.
    Campaign campaign =
        Campaign.newBuilder()
            .setName("Interplanetary Cruise Budget #" + getPrintableDateTime())
            .setCampaignBudget(budgetResourceName)
            // Recommendation: Set the campaign to PAUSED when creating it to prevent the ads from
            // immediately serving. Set to ENABLED once you've added targeting and the ads are ready
            // to serve.
            .setStatus(CampaignStatus.PAUSED)
            // Sets the advertisingChannelType to LOCAL and advertisingChannelSubType to
            // LOCAL_CAMPAIGN.
            .setAdvertisingChannelType(AdvertisingChannelType.LOCAL)
            .setAdvertisingChannelSubType(AdvertisingChannelSubType.LOCAL_CAMPAIGN)
            // Sets the bidding strategy. Note that this must be set directly on the campaign.
            //   - Setting a portfolio bidding strategy by resource name is not supported.
            //   - Maximize conversion value is the only strategy supported for Local
            //     campaigns.
            //   - An optional ROAS (Return on Advertising Spend) can be set for
            //     MaximizeConversionValue.
            //   - Specify the ROAS value must as a ratio. It is calculated by
            //     dividing "total value" by "total spend". For example, to target 350% ROAS, set
            //     targetRoas=3.5.
            //   - For more information on maximize conversion value, see the support article:
            //     http://support.google.com/google-ads/answer/7684216.
            .setMaximizeConversionValue(
                MaximizeConversionValue.newBuilder().setTargetRoas(3.5).build())
            // Configures the Local campaign setting.
            .setLocalCampaignSetting(
                LocalCampaignSetting.newBuilder()
                    // Use the locations associated with the customer's linked Google My Business
                    // account.
                    .setLocationSourceType(LocationSourceType.GOOGLE_MY_BUSINESS))
            .setOptimizationGoalSetting(
                OptimizationGoalSetting.newBuilder()
                    // Optimization goal setting is mandatory for Local campaigns. This example
                    // selects driving directions and call clicks as goals.
                    .addOptimizationGoalTypes(OptimizationGoalType.CALL_CLICKS)
                    .addOptimizationGoalTypes(OptimizationGoalType.DRIVING_DIRECTIONS)
                    .build())
            .build();

    // Creates a operation to add the campaign.
    CampaignOperation operation = CampaignOperation.newBuilder().setCreate(campaign).build();

    // Connects to the API.
    try (CampaignServiceClient client =
        googleAdsClient.getLatestVersion().createCampaignServiceClient()) {
      // Sends the mutate request.
      MutateCampaignsResponse response =
          client.mutateCampaigns(String.valueOf(customerId), ImmutableList.of(operation));

      // Prints some debugging information.
      String resourceName = response.getResults(0).getResourceName();
      System.out.printf("Created Local campaign with resource name: '%s'.%n", resourceName);
      return resourceName;
    }
  }

  /** Creates a local campaign ad-group. */
  private String createAdGroup(
      GoogleAdsClient googleAdsClient, long customerId, String campaignResourceName) {
    // Creates an ad group. Note that the ad group type must not be set.
    // Also, since the advertisingChannelSubType is LOCAL_CAMPAIGN:
    //   1. you cannot override bid settings at the ad group level.
    //   2. you cannot add ad group criteria.
    AdGroup adGroup =
        AdGroup.newBuilder()
            .setName("Earth to Mars Cruises #" + getPrintableDateTime())
            .setStatus(AdGroupStatus.ENABLED)
            .setCampaign(campaignResourceName)
            .build();

    // Creates an operation to add the ad group.
    AdGroupOperation operation = AdGroupOperation.newBuilder().setCreate(adGroup).build();

    // Connects to the API.
    try (AdGroupServiceClient client =
        googleAdsClient.getLatestVersion().createAdGroupServiceClient()) {
      // Issues the mutate request.
      MutateAdGroupsResponse response =
          client.mutateAdGroups(String.valueOf(customerId), ImmutableList.of(operation));

      // Prints some debugging information.
      String resourceName = response.getResults(0).getResourceName();
      System.out.printf("Created ad group with resource name: '%s'.%n", resourceName);
      return resourceName;
    }
  }

  /** Creates a local ad. */
  private void createLocalAd(
      GoogleAdsClient googleAdsClient, long customerId, String adGroupResourceName)
      throws IOException {
    // Creates the local ad object.
    Ad ad =
        Ad.newBuilder()
            .addFinalUrls("https://www.example.com")
            .setLocalAd(
                LocalAdInfo.newBuilder()
                    // Adds headline text to the ad.
                    .addHeadlines(createTextAsset("Best Space Cruise Line"))
                    .addHeadlines(createTextAsset("Experience the Stars"))

                    // Adds description text to the ad.
                    .addDescriptions(createTextAsset("Buy your tickets now"))
                    .addDescriptions(createTextAsset("Visit the Red Planet"))

                    // Adds a call to action text to the ad.
                    .addCallToActions(createTextAsset("Shop Now"))

                    // Adds various rich media types to the ad.
                    .addMarketingImages(
                        createImageAsset(
                            googleAdsClient, customerId, MARKETING_IMAGE_URL, "Marketing Image"))
                    .addLogoImages(
                        createImageAsset(
                            googleAdsClient, customerId, LOGO_IMAGE_URL, "Square Marketing Image"))
                    .addVideos(
                        createYoutubeVideoAsset(
                            googleAdsClient, customerId, YOUTUBE_VIDEO_ID, "Local Campaigns"))
                    .build())
            .build();

    // Creates the ad group ad object.
    AdGroupAd adGroupAd =
        AdGroupAd.newBuilder()
            .setAdGroup(adGroupResourceName)
            .setStatus(AdGroupAdStatus.ENABLED)
            .setAd(ad)
            .build();

    // Creates an operation to add the AdGroupAd.
    AdGroupAdOperation operation = AdGroupAdOperation.newBuilder().setCreate(adGroupAd).build();

    // Connects to the API.
    try (AdGroupAdServiceClient client =
        googleAdsClient.getLatestVersion().createAdGroupAdServiceClient()) {
      // Issues the mutate request.
      MutateAdGroupAdsResponse response =
          client.mutateAdGroupAds(String.valueOf(customerId), ImmutableList.of(operation));

      // Prints some debugging information.
      String resourceName = response.getResults(0).getResourceName();
      System.out.printf("Created ad group ad with resource name: '%s'.%n", resourceName);
    }
  }

  // --------------------------------- Utility functions -------------------------------------------

  /** Converts a String to a {@link AdTextAsset}. */
  private AdTextAsset createTextAsset(String s) {
    return AdTextAsset.newBuilder().setText(s).build();
  }

  /** Creates an {@link AdImageAsset}. */
  private static AdImageAsset createImageAsset(
      GoogleAdsClient googleAdsClient, long customerId, String imageUrl, String imageName)
      throws IOException {
    // Creates a media file.
    byte[] assetBytes = ByteStreams.toByteArray(new URL(imageUrl).openStream());
    Asset asset =
        Asset.newBuilder()
            .setName(imageName)
            .setType(AssetType.IMAGE)
            .setImageAsset(ImageAsset.newBuilder().setData(ByteString.copyFrom(assetBytes)).build())
            .build();

    // Creates an asset operation.
    AssetOperation operation = AssetOperation.newBuilder().setCreate(asset).build();

    // Creates the asset service client.
    try (AssetServiceClient assetServiceClient =
        googleAdsClient.getLatestVersion().createAssetServiceClient()) {
      // Adds the image asset.
      MutateAssetsResponse response =
          assetServiceClient.mutateAssets(Long.toString(customerId), ImmutableList.of(operation));
      String imageResourceName = response.getResults(0).getResourceName();
      System.out.printf("Created image asset with resource name '%s'.%n", imageResourceName);

      // Wraps the asset resource name in AdImageAsset.
      return AdImageAsset.newBuilder().setAsset(imageResourceName).build();
    }
  }

  /** Creates a {@link AdVideoAsset}. */
  private AdVideoAsset createYoutubeVideoAsset(
      GoogleAdsClient googleAdsClient, long customerId, String youtubeVideoId, String videoName) {
    // Creates an Asset object.
    Asset asset =
        Asset.newBuilder()
            .setName(videoName)
            .setType(AssetType.YOUTUBE_VIDEO)
            .setYoutubeVideoAsset(YoutubeVideoAsset.newBuilder().setYoutubeVideoId(youtubeVideoId))
            .build();

    // Creates an operation to add the asset.
    AssetOperation operation = AssetOperation.newBuilder().setCreate(asset).build();

    // Connects to the API.
    try (AssetServiceClient assetServiceClient =
        googleAdsClient.getLatestVersion().createAssetServiceClient()) {
      // Issues the mutate request.
      MutateAssetsResponse response =
          assetServiceClient.mutateAssets(String.valueOf(customerId), ImmutableList.of(operation));

      // Prints some debugging information.
      String resourceName = response.getResults(0).getResourceName();
      System.out.printf(
          "A new YouTube video asset has been added with resource name: '%s'.%n", resourceName);

      // Wraps the result in an AdVideoAsset.
      return AdVideoAsset.newBuilder().setAsset(resourceName).build();
    }
  }
}

      

C#

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using CommandLine;
using Google.Ads.GoogleAds.Lib;
using Google.Ads.GoogleAds.Util;
using Google.Ads.GoogleAds.V8.Common;
using Google.Ads.GoogleAds.V8.Errors;
using Google.Ads.GoogleAds.V8.Resources;
using Google.Ads.GoogleAds.V8.Services;
using Google.Protobuf;
using System;
using System.Collections.Generic;
using System.Linq;
using static Google.Ads.GoogleAds.V8.Enums.AdGroupAdStatusEnum.Types;
using static Google.Ads.GoogleAds.V8.Enums.AdGroupStatusEnum.Types;
using static Google.Ads.GoogleAds.V8.Enums.AdvertisingChannelSubTypeEnum.Types;
using static Google.Ads.GoogleAds.V8.Enums.AdvertisingChannelTypeEnum.Types;
using static Google.Ads.GoogleAds.V8.Enums.AssetTypeEnum.Types;
using static Google.Ads.GoogleAds.V8.Enums.BudgetDeliveryMethodEnum.Types;
using static Google.Ads.GoogleAds.V8.Enums.CampaignStatusEnum.Types;
using static Google.Ads.GoogleAds.V8.Enums.LocationSourceTypeEnum.Types;
using static Google.Ads.GoogleAds.V8.Enums.OptimizationGoalTypeEnum.Types;

namespace Google.Ads.GoogleAds.Examples.V8
{
    /// <summary>
    /// This example adds an Local campaign.
    /// Prerequisite: To create a Local campaign, you need to define the store locations you want
    /// to promote by linking your Google My Business account or selecting affiliate locations.
    /// More information about Local campaigns can be found at:
    /// https: //support.google.com/google-ads/answer/9118422.
    /// </summary>
    public class AddLocalCampaign : ExampleBase
    {
        /// <summary>
        /// Command line options for running the <see cref="AddLocalCampaign"/> example.
        /// </summary>
        public class Options : OptionsBase
        {
            /// <summary>
            /// The Google Ads customer ID.
            /// </summary>
            [Option("customerId", Required = true, HelpText =
                "The Google Ads customer ID.")]
            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 = new Options();
            CommandLine.Parser.Default.ParseArguments<Options>(args).MapResult(
                delegate (Options o)
                {
                    options = o;
                    return 0;
                }, delegate (IEnumerable<Error> errors)
                {
                    // The Google Ads customer ID.
                    options.CustomerId = long.Parse("INSERT_CUSTOMER_ID_HERE");

                    return 0;
                });

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

        private const string MARKETING_IMAGE_URL = "https://gaagl.page.link/Eit5";
        private const string LOGO_IMAGE_URL = "https://gaagl.page.link/bjYi";
        private const string YOUTUBE_VIDEO_ID = "ECpDzH9gXh8";

        /// <summary>
        /// Returns a description about the code example.
        /// </summary>
        public override string Description =>
            "This example adds an Local campaign.\nPrerequisite: To create a Local campaign, " +
            "you need to define the store locations you want to promote by linking your " +
            "Google My Business account or selecting affiliate locations. More information " +
            "about Local campaigns can be found at: " +
            "https://support.google.com/google-ads/answer/9118422.";

        /// <summary>
        /// Runs the code example.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads customer ID.</param>
        public void Run(GoogleAdsClient client, long customerId)
        {
            try
            {
                // Create a budget for the campaign.
                string budgetResourceName = CreateCampaignBudget(client, customerId);

                // Create a campaign.
                string campaignResourceName = CreateCampaign(client, customerId,
                    budgetResourceName);

                // Create an ad group.
                string adGroupResourceName =
                    CreateAdGroup(client, customerId, campaignResourceName);

                // Create a Local ad.
                CreateLocalAd(client, customerId, adGroupResourceName);
            }
            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 campaign budget.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads customer ID.</param>
        /// <returns>The resource name of the newly created campaign budget.</returns>
        private string CreateCampaignBudget(GoogleAdsClient client, in long customerId)
        {
            // Get the CampaignBudgetService client.
            CampaignBudgetServiceClient campaignBudgetServiceClient =
                client.GetService(Services.V8.CampaignBudgetService);

            // Create a campaign budget object.
            CampaignBudget campaignBudget = new CampaignBudget
            {
                Name = $"Interplanetary Cruise Budget #{ExampleUtilities.GetRandomString()}",
                AmountMicros = 50000000,
                DeliveryMethod = BudgetDeliveryMethod.Standard,
                // A Local campaign cannot use a shared campaign budget.
                ExplicitlyShared = false
            };

            // Create a campaign budget operation.
            CampaignBudgetOperation campaignBudgetOperation = new CampaignBudgetOperation
            {
                Create = campaignBudget
            };

            // Issue a mutate request to add the campaign budget, then print and return the
            // resulting budget's resource name.
            MutateCampaignBudgetsResponse campaignBudgetsResponse =
                campaignBudgetServiceClient.MutateCampaignBudgets(customerId.ToString(),
                    new[] { campaignBudgetOperation });

            string campaignBudgetResourceName =
                campaignBudgetsResponse.Results.First().ResourceName;
            Console.WriteLine(
                $"Created campaign budget with resource name '{campaignBudgetResourceName}'.");

            return campaignBudgetResourceName;
        }

        /// <summary>
        /// Creates a Local campaign.
        /// </summary>
        /// <param name="client">The Google Ads client.</param>
        /// <param name="customerId">The Google Ads customer ID.</param>
        /// <param name="budgetResourceName">The resource name of the budget to use with the new
        ///     campaign.</param>
        /// <returns>The resource name of the newly created campaign.</returns>
        private string CreateCampaign(GoogleAdsClient client, long customerId,
            string budgetResourceName)
        {
            // Get the CampaignService client.
            CampaignServiceClient campaignServiceClient =
                client.GetService(Services.V8.CampaignService);

            // Create a campaign object.
            Campaign campaign = new Campaign
            {
                Name = $"Interplanetary Cruise Local #{ExampleUtilities.GetRandomString()}",
                CampaignBudget = budgetResourceName,
                // Recommendation: Set the campaign to PAUSED when creating it to prevent the ads
                // from immediately serving. Set to ENABLED once you've added targeting and the ads
                // are ready to serve.
                Status = CampaignStatus.Paused,
                // All Local campaigns have an advertisingChannelType of LOCAL and
                // advertisingChannelSubtype of LOCAL_CAMPAIGN.
                AdvertisingChannelType = AdvertisingChannelType.Local,
                AdvertisingChannelSubType = AdvertisingChannelSubType.LocalCampaign,
                // Bidding strategy must be set directly on the campaign.Setting a portfolio bidding
                // strategy by resource name is not supported. Maximize conversion value is the only
                // strategy supported for Local campaigns. An optional ROAS (Return on Advertising
                // Spend) can be set for MaximizeConversionValue. The ROAS value must be specified
                // as a ratio in the API. It is calculated by dividing "total value" by
                // "total spend". For more information on maximize conversion value, see the support
                // article: http://support.google.com/google-ads/answer/7684216.
                MaximizeConversionValue = new MaximizeConversionValue
                {
                    TargetRoas = 3.5
                },
                // Configure the Local campaign setting.
                LocalCampaignSetting = new Campaign.Types.LocalCampaignSetting
                {
                    LocationSourceType = LocationSourceType.GoogleMyBusiness
                },
                // Optimization goal setting is mandatory for Local campaigns. This example selects
                // driving directions and call clicks as goals.
                OptimizationGoalSetting = new Campaign.Types.OptimizationGoalSetting
                {
                    OptimizationGoalTypes =
                    {
                        OptimizationGoalType.CallClicks, OptimizationGoalType.DrivingDirections
                    }
                }
            };

            // Create a campaign operation.
            CampaignOperation campaignOperation = new CampaignOperation
            {
                Create = campaign
            };

            // Issue a mutate request to add the campaign, then print and return the resulting
            // campaign's resource name.
            MutateCampaignsResponse campaignResponse =
                campaignServiceClient.MutateCampaigns(customerId.ToString(),
                    new[] { campaignOperation });

            string campaignResourceName = campaignResponse.Results.First().ResourceName;
            Console.WriteLine("Created Local campaign with resource name " +
                $"'{campaignResourceName}'.");

            return campaignResourceName;
        }

        /// <summary>
        /// Creates an ad group for the given campaign.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="campaignResourceName">The campaign resource name to which to attach the ad
        ///     group.</param>
        /// <returns>The string resource name for the newly created ad group.</returns>
        private string CreateAdGroup(GoogleAdsClient client, long customerId,
            string campaignResourceName)
        {
            // Create the ad group service client.
            AdGroupServiceClient adGroupServiceClient =
                client.GetService(Services.V8.AdGroupService);

            // Create the ad group.
            // Note that the ad group type must not be set.
            // Since the advertisingChannelSubType is LOCAL_CAMPAIGN:
            //   1. you cannot override bid settings at the ad group level.
            //   2. you cannot add ad group criteria.
            AdGroup adGroup = new AdGroup()
            {
                Name = $"Earth to Mars Cruises #{ExampleUtilities.GetRandomString()}",
                Campaign = campaignResourceName,
                Status = AdGroupStatus.Enabled
            };

            // Create the ad group operation.
            AdGroupOperation adGroupOperation = new AdGroupOperation()
            {
                Create = adGroup
            };

            // Issue a mutate request to add the ad group, then print and return the resulting ad
            // group's resource name.
            MutateAdGroupsResponse adGroupResponse = adGroupServiceClient.MutateAdGroups(
                customerId.ToString(), new[] { adGroupOperation });

            string adGroupResourceName = adGroupResponse.Results.First().ResourceName;
            Console.WriteLine($"Created ad group with resource name '{adGroupResourceName}'.");
            return adGroupResourceName;
        }

        /// <summary>
        /// Creates a Local ad for the given ad group.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="adGroupResourceName">The ad group resource name to which the ad will
        ///     belong.</param>
        private void CreateLocalAd(GoogleAdsClient client, in long customerId,
            string adGroupResourceName)
        {
            // Create the ad group service client.
            AdGroupAdServiceClient adGroupAdServiceClient =
                client.GetService(Services.V8.AdGroupAdService);

            // Create an ad group ad.
            AdGroupAd adGroupAd = new AdGroupAd
            {
                AdGroup = adGroupResourceName,
                Status = AdGroupAdStatus.Enabled,
                Ad = new Ad
                {
                    FinalUrls = { "https://www.example.com" },
                    LocalAd = new LocalAdInfo
                    {
                        Headlines =
                        {
                            CreateAdTextAsset("Best Space Cruise Line"),
                            CreateAdTextAsset("Experience the Stars")
                        },
                        Descriptions =
                        {
                            CreateAdTextAsset("Buy your tickets now"),
                            CreateAdTextAsset("Visit the Red Planet")
                        },
                        CallToActions = { CreateAdTextAsset("Shop Now") },
                        // Set the marketing image and logo image assets.
                        MarketingImages =
                        {
                            new AdImageAsset
                            {
                                Asset = CreateImageAsset(client, customerId, MARKETING_IMAGE_URL,
                                    "Marketing Image")
                            }
                        },
                        LogoImages =
                        {
                            new AdImageAsset
                            {
                                Asset = CreateImageAsset(client, customerId, LOGO_IMAGE_URL,
                                    "Square Marketing Image")
                            }
                        },
                        // Set the video assets.
                        Videos =
                        {
                            new AdVideoAsset
                            {
                                Asset = CreateYoutubeVideoAsset(client, customerId,
                                    YOUTUBE_VIDEO_ID, "Local Campaigns")
                            }
                        }
                    }
                }
            };

            // Create an ad group ad operation.
            AdGroupAdOperation adGroupAdOperation = new AdGroupAdOperation
            {
                Create = adGroupAd
            };

            // Issue a mutate request to add the ad group ad and print the resulting ad group ad's
            // resource name.
            MutateAdGroupAdsResponse adGroupAdResponse =
                adGroupAdServiceClient.MutateAdGroupAds(customerId.ToString(),
                    new[] { adGroupAdOperation });

            Console.WriteLine("Created ad group ad with resource name " +
                $"'{adGroupAdResponse.Results.First().ResourceName}'.");
        }

        /// <summary>
        /// Creates an ad text asset with the given text.
        /// </summary>
        /// <param name="text">The text to include in the asset.</param>
        /// <returns>A new ad text asset with the given text.</returns>
        private AdTextAsset CreateAdTextAsset(string text)
        {
            return new AdTextAsset
            {
                Text = text
            };
        }

        /// <summary>
        /// Creates an image asset.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="imageUrl">The URL of the image source.</param>
        /// <param name="imageName">The name to associate with the image asset.</param>
        /// <returns>A new ad text asset with the given text.</returns>
        private string CreateImageAsset(GoogleAdsClient client, long customerId, string imageUrl,
            string imageName)
        {
            // Get the AssetService client.
            AssetServiceClient assetService = client.GetService(Services.V8.AssetService);

            // Creates an image asset.
            byte[] imageContent = MediaUtilities.GetAssetDataFromUrl(imageUrl, client.Config);
            Asset asset = new Asset
            {
                Name = imageName,
                Type = AssetType.Image,
                ImageAsset = new ImageAsset
                {
                    Data = ByteString.CopyFrom(imageContent),
                }
            };

            // Create an asset operation.
            AssetOperation assetOperation = new AssetOperation
            {
                Create = asset
            };

            // Issue a mutate request to add the asset, then print and return the resulting asset's
            // resource name.
            MutateAssetsResponse assetResponse =
                assetService.MutateAssets(customerId.ToString(), new[] { assetOperation });

            string assetResourceName = assetResponse.Results.First().ResourceName;
            Console.WriteLine("A new image asset has been added with resource name: " +
                $"'{assetResourceName}'.");

            return assetResourceName;
        }

        /// <summary>
        /// Creates a YouTube video asset.
        /// </summary>
        /// <param name="client">The Google Ads API client.</param>
        /// <param name="customerId">The client customer ID.</param>
        /// <param name="youtubeVideoId">The YouTube video ID to be attached to the asset.</param>
        /// <param name="youtubeVideoName">The name to associate with the video.</param>
        /// <returns></returns>
        private string CreateYoutubeVideoAsset(GoogleAdsClient client, in long customerId,
            string youtubeVideoId, string youtubeVideoName)
        {
            // Get the AssetService client.
            AssetServiceClient assetServiceClient = client.GetService(Services.V8.AssetService);

            // Create an asset.
            Asset asset = new Asset
            {
                Name = youtubeVideoName,
                Type = AssetType.YoutubeVideo,
                YoutubeVideoAsset = new YoutubeVideoAsset
                {
                    YoutubeVideoId = youtubeVideoId
                }
            };

            // Create an asset operation.
            AssetOperation assetOperation = new AssetOperation
            {
                Create = asset
            };

            // Issue a mutate request to add the asset, then print and return the resulting asset's
            // resource name.
            MutateAssetsResponse assetResponse =
                assetServiceClient.MutateAssets(customerId.ToString(), new[] { assetOperation });

            string assetResourceName = assetResponse.Results.First().ResourceName;
            Console.WriteLine("A new YouTube video asset has been added with resource name: " +
                $"'{assetResourceName}'.");

            return assetResourceName;
        }
    }
}

      

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\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\V8\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V8\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V8\GoogleAdsException;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\V8\Common\AdImageAsset;
use Google\Ads\GoogleAds\V8\Common\AdTextAsset;
use Google\Ads\GoogleAds\V8\Common\AdVideoAsset;
use Google\Ads\GoogleAds\V8\Common\ImageAsset;
use Google\Ads\GoogleAds\V8\Common\LocalAdInfo;
use Google\Ads\GoogleAds\V8\Common\MaximizeConversionValue;
use Google\Ads\GoogleAds\V8\Common\YoutubeVideoAsset;
use Google\Ads\GoogleAds\V8\Enums\AdGroupAdStatusEnum\AdGroupAdStatus;
use Google\Ads\GoogleAds\V8\Enums\AdGroupStatusEnum\AdGroupStatus;
use Google\Ads\GoogleAds\V8\Enums\AdvertisingChannelSubTypeEnum\AdvertisingChannelSubType;
use Google\Ads\GoogleAds\V8\Enums\AdvertisingChannelTypeEnum\AdvertisingChannelType;
use Google\Ads\GoogleAds\V8\Enums\AssetTypeEnum\AssetType;
use Google\Ads\GoogleAds\V8\Enums\BudgetDeliveryMethodEnum\BudgetDeliveryMethod;
use Google\Ads\GoogleAds\V8\Enums\CampaignStatusEnum\CampaignStatus;
use Google\Ads\GoogleAds\V8\Enums\LocationSourceTypeEnum\LocationSourceType;
use Google\Ads\GoogleAds\V8\Enums\OptimizationGoalTypeEnum\OptimizationGoalType;
use Google\Ads\GoogleAds\V8\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V8\Resources\Ad;
use Google\Ads\GoogleAds\V8\Resources\AdGroup;
use Google\Ads\GoogleAds\V8\Resources\AdGroupAd;
use Google\Ads\GoogleAds\V8\Resources\Asset;
use Google\Ads\GoogleAds\V8\Resources\Campaign;
use Google\Ads\GoogleAds\V8\Resources\Campaign\LocalCampaignSetting;
use Google\Ads\GoogleAds\V8\Resources\Campaign\OptimizationGoalSetting;
use Google\Ads\GoogleAds\V8\Resources\CampaignBudget;
use Google\Ads\GoogleAds\V8\Services\AdGroupOperation;
use Google\Ads\GoogleAds\V8\Services\AdGroupAdOperation;
use Google\Ads\GoogleAds\V8\Services\AssetOperation;
use Google\Ads\GoogleAds\V8\Services\CampaignBudgetOperation;
use Google\Ads\GoogleAds\V8\Services\CampaignOperation;
use Google\Ads\GoogleAds\V8\Services\MutateAdGroupAdsResponse;
use Google\Ads\GoogleAds\V8\Services\MutateAdGroupsResponse;
use Google\Ads\GoogleAds\V8\Services\MutateCampaignBudgetsResponse;
use Google\Ads\GoogleAds\V8\Services\MutateCampaignsResponse;
use Google\ApiCore\ApiException;

/**
 * This example adds a Local campaign.
 *
 * Prerequisite: To create a Local campaign, you need to define the store locations you want to
 * promote by linking your Google My Business account or selecting affiliate locations. More
 * information about Local campaigns can be found at:
 * https://support.google.com/google-ads/answer/9118422.
 */
class AddLocalCampaign
{
    private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE';

    private const MARKETING_IMAGE_URL = 'https://gaagl.page.link/Eit5';
    private const LOGO_IMAGE_URL = 'https://gaagl.page.link/bjYi';
    private const YOUTUBE_VIDEO_ID = 'ECpDzH9gXh8';

    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
    ) {
        $budgetResourceName = self::createCampaignBudget($googleAdsClient, $customerId);
        $campaignResourceName = self::createCampaign(
            $googleAdsClient,
            $customerId,
            $budgetResourceName
        );
        $adGroupResourceName = self::createAdGroup(
            $googleAdsClient,
            $customerId,
            $campaignResourceName
        );
        self::createLocalAd($googleAdsClient, $customerId, $adGroupResourceName);
    }

    /**
     * Creates a campaign budget.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @return string the campaign budget resource name
     */
    private static function createCampaignBudget(
        GoogleAdsClient $googleAdsClient,
        int $customerId
    ) {
        $campaignBudget = new CampaignBudget([
            'name' => 'Interplanetary Cruise Budget #' . Helper::getPrintableDatetime(),
            'delivery_method' => BudgetDeliveryMethod::STANDARD,
            'amount_micros' => 50000000,
            // A Local campaign cannot use a shared campaign budget.
            'explicitly_shared' => false
        ]);

        // Creates a campaign budget operation.
        $campaignBudgetOperation = new CampaignBudgetOperation();
        $campaignBudgetOperation->setCreate($campaignBudget);

        // Issues a mutate request to add campaign budget.
        $campaignBudgetServiceClient = $googleAdsClient->getCampaignBudgetServiceClient();
        /** @var MutateCampaignBudgetsResponse $campaignBudgetResponse */
        $campaignBudgetResponse = $campaignBudgetServiceClient->mutateCampaignBudgets(
            $customerId,
            [$campaignBudgetOperation]
        );

        $campaignBudgetResourceName = $campaignBudgetResponse->getResults()[0]->getResourceName();
        printf(
            "Created campaign budget with resource name: '%s'.%s",
            $campaignBudgetResourceName,
            PHP_EOL
        );

        return $campaignBudgetResourceName;
    }

    /**
     * Creates a Local campaign.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $campaignBudgetResourceName the resource name of the campaign budget
     * @return string the resource name of the newly created campaign
     */
    private static function createCampaign(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $campaignBudgetResourceName
    ) {
        $campaign = new Campaign([
            'name' => 'Interplanetary Cruise Local #' . Helper::getPrintableDatetime(),
            'campaign_budget' => $campaignBudgetResourceName,
            // Recommendation: Set the campaign to PAUSED when creating it to prevent the ads
            // from immediately serving. Set to ENABLED once you've added targeting and the ads
            // are ready to serve.
            'status' => CampaignStatus::PAUSED,
            // All Local campaigns have an advertisingChannelType of LOCAL and
            // advertisingChannelSubType of LOCAL_CAMPAIGN.
            'advertising_channel_type' => AdvertisingChannelType::LOCAL,
            'advertising_channel_sub_type' => AdvertisingChannelSubType::LOCAL_CAMPAIGN,
            // Bidding strategy must be set directly on the campaign.
            // Setting a portfolio bidding strategy by resource name is not supported.
            // Maximize conversion value is the only strategy supported for Local campaigns. An
            // optional ROAS (Return on Advertising Spend) can be set for
            // MaximizeConversionValue. The ROAS value must be specified as a ratio in the API. It
            // is calculated by dividing "total value" by "total spend".
            // For more information on maximize conversion value, see the support article:
            // http://support.google.com/google-ads/answer/7684216.
            'maximize_conversion_value' => new MaximizeConversionValue(['target_roas' => 3.5]),
            // Configures the Local campaign setting.
            'local_campaign_setting' => new LocalCampaignSetting([
                // Use the locations associated with the customer's linked Google My Business
                // account.
                'location_source_type' => LocationSourceType::GOOGLE_MY_BUSINESS
            ]),
            // Optimization goal setting is mandatory for Local campaigns. This example selects
            // driving directions and call clicks as goals.
            'optimization_goal_setting' => new OptimizationGoalSetting([
                'optimization_goal_types' => [
                    OptimizationGoalType::CALL_CLICKS,
                    OptimizationGoalType::DRIVING_DIRECTIONS
                ]
            ])
        ]);

        // Creates a campaign operation.
        $campaignOperation = new CampaignOperation();
        $campaignOperation->setCreate($campaign);

        // Issues a mutate request to add campaign.
        $campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
        /** @var MutateCampaignsResponse $campaignResponse */
        $campaignResponse = $campaignServiceClient->mutateCampaigns(
            $customerId,
            [$campaignOperation]
        );

        $campaignResourceName = $campaignResponse->getResults()[0]->getResourceName();
        printf(
            "Created Local campaign with resource name: '%s'.%s",
            $campaignResourceName,
            PHP_EOL
        );

        return $campaignResourceName;
    }

    /**
     * Creates an ad group.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $campaignResourceName the resource name of the campaign
     * @return string the resource name of the newly created ad group
     */
    private static function createAdGroup(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $campaignResourceName
    ) {
        // Creates an ad group.
        // Note that the ad group type must not be set.
        // Since the advertisingChannelSubType is LOCAL_CAMPAIGN:
        //   1. you cannot override bid settings at the ad group level.
        //   2. you cannot add ad group criteria.
        $adGroup = new AdGroup([
            'name' => 'Earth to Mars Cruises #' . Helper::getPrintableDatetime(),
            'campaign' => $campaignResourceName,
            'status' => AdGroupStatus::ENABLED
        ]);

        // Creates an ad group operation.
        $adGroupOperation = new AdGroupOperation();
        $adGroupOperation->setCreate($adGroup);

        // Issues a mutate request to add the ad group.
        $adGroupServiceClient = $googleAdsClient->getAdGroupServiceClient();
        /** @var MutateAdGroupsResponse $adGroupResponse */
        $adGroupResponse = $adGroupServiceClient->mutateAdGroups($customerId, [$adGroupOperation]);

        $adGroupResourceName = $adGroupResponse->getResults()[0]->getResourceName();
        printf("Created ad group with resource name: '%s'.%s", $adGroupResourceName, PHP_EOL);

        return $adGroupResourceName;
    }

    /**
     * Creates a Local ad.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $adGroupResourceName the ad group resource name
     */
    private static function createLocalAd(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $adGroupResourceName
    ) {
        $adGroupAd = new AdGroupAd([
            'ad_group' => $adGroupResourceName,
            'status' => AdGroupAdStatus::ENABLED,
            'ad' => new Ad([
                'final_urls' => ['https://www.example.com'],
                'local_ad' => new LocalAdInfo([
                    'headlines' => [
                        new AdTextAsset(['text' => 'Best Space Cruise Line']),
                        new AdTextAsset(['text' => 'Experience the Stars'])
                    ],
                    'descriptions' => [
                        new AdTextAsset(['text' => 'Buy your tickets now']),
                        new AdTextAsset(['text' => 'Visit the Red Planet'])
                    ],
                    'call_to_actions' => [new AdTextAsset(['text' => 'Shop Now'])],
                    // Sets the marketing image and logo image assets.
                    'marketing_images' => [new AdImageAsset(['asset' => self::createImageAsset(
                        $googleAdsClient,
                        $customerId,
                        self::MARKETING_IMAGE_URL,
                        'Marketing Image'
                    )])],
                    'logo_images' => [new AdImageAsset(['asset' => self::createImageAsset(
                        $googleAdsClient,
                        $customerId,
                        self::LOGO_IMAGE_URL,
                        'Square Marketing Image'
                    )])],
                    // Sets the video assets.
                    'videos' => [new AdVideoAsset(['asset' => self::createYoutubeVideoAsset(
                        $googleAdsClient,
                        $customerId,
                        self::YOUTUBE_VIDEO_ID,
                        'Local Campaigns'
                    )])]
                ])
            ])
        ]);

        // Creates an ad group ad operation.
        $adGroupAdOperation = new AdGroupAdOperation();
        $adGroupAdOperation->setCreate($adGroupAd);

        // Issues a mutate request to add the ad group ad.
        $adGroupAdServiceClient = $googleAdsClient->getAdGroupAdServiceClient();
        /** @var MutateAdGroupAdsResponse $adGroupAdResponse */
        $adGroupAdResponse = $adGroupAdServiceClient->mutateAdGroupAds(
            $customerId,
            [$adGroupAdOperation]
        );

        printf(
            "Created ad group ad with resource name: '%s'.%s",
            $adGroupAdResponse->getResults()[0]->getResourceName(),
            PHP_EOL
        );
    }

    /**
     * Creates an image asset.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $imageUrl the image URL
     * @param string $imageName the image name
     * @return string the created image asset's resource name
     */
    private static function createImageAsset(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $imageUrl,
        string $imageName
    ) {
        // Creates an asset.
        $asset = new Asset([
            'name' => $imageName,
            'type' => AssetType::IMAGE,
            'image_asset' => new ImageAsset(['data' => file_get_contents($imageUrl)])
        ]);

        // Creates an asset operation.
        $assetOperation = new AssetOperation();
        $assetOperation->setCreate($asset);

        // Issues a mutate request to add the asset.
        $assetServiceClient = $googleAdsClient->getAssetServiceClient();
        $response = $assetServiceClient->mutateAssets($customerId, [$assetOperation]);

        // Prints out information about the newly added asset.
        $assetResourceName = $response->getResults()[0]->getResourceName();
        printf(
            "A new image asset has been added with resource name: '%s'.%s",
            $assetResourceName,
            PHP_EOL
        );

        return $assetResourceName;
    }

    /**
     * Creates a YouTube video asset.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $youtubeVideoId the Youtube video ID
     * @param string $youtubeVideoName the Youtube video name
     * @return string the created video asset's resource name
     */
    private static function createYoutubeVideoAsset(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $youtubeVideoId,
        string $youtubeVideoName
    ) {
        // Creates an asset.
        $asset = new Asset([
            'name' => $youtubeVideoName,
            'type' => AssetType::YOUTUBE_VIDEO,
            'youtube_video_asset' => new YoutubeVideoAsset(['youtube_video_id' => $youtubeVideoId])
        ]);

        // Creates an asset operation.
        $assetOperation = new AssetOperation();
        $assetOperation->setCreate($asset);

        // Issues a mutate request to add the asset.
        $assetServiceClient = $googleAdsClient->getAssetServiceClient();
        $response = $assetServiceClient->mutateAssets($customerId, [$assetOperation]);

        // Prints out information about the newly added asset.
        $assetResourceName = $response->getResults()[0]->getResourceName();
        printf(
            "A new YouTube video asset has been added with resource name: '%s'.%s",
            $assetResourceName,
            PHP_EOL
        );

        return $assetResourceName;
    }
}

AddLocalCampaign::main();

      

Python

#!/usr/bin/env python
# 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 adds a Local campaign.

Prerequisite: To create a Local campaign, you need to define the store locations
you want to promote by linking your Google My Business account or selecting
affiliate locations. More information about Local campaigns can be found at:
https://support.google.com/google-ads/answer/9118422.
"""


import argparse
import requests
import sys
from uuid import uuid4


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


_MARKETING_IMAGE_URL = "https://gaagl.page.link/Eit5"
_LOGO_IMAGE_URL = "https://gaagl.page.link/bjYi"
_YOUTUBE_VIDEO_ID = "ECpDzH9gXh8"


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 str.
    """
    budget_resource_name = _create_campaign_budget(client, customer_id)
    campaign_resource_name = _create_campaign(
        client, customer_id, budget_resource_name
    )
    ad_group_resource_name = _create_ad_group(
        client, customer_id, campaign_resource_name
    )
    create_local_ad = _create_local_ad(
        client, customer_id, ad_group_resource_name
    )


def _create_campaign_budget(client, customer_id):
    """Adds a campaign budget to the given client account.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID str.

    Returns:
        A str of the resource name for the newly created campaign budget.
    """
    # Create a CampaignBudgetOperation.
    campaign_budget_operation = client.get_type("CampaignBudgetOperation")
    campaign_budget = campaign_budget_operation.create
    campaign_budget.name = f"Interplanetary Cruise Budget #{uuid4()}"
    campaign_budget.amount_micros = 50000000
    campaign_budget.delivery_method = (
        client.enums.BudgetDeliveryMethodEnum.STANDARD
    )
    # A Local campaign cannot use a shared campaign budget.
    campaign_budget.explicitly_shared = False

    # Issue a mutate request to add the campaign budget.
    campaign_budget_service = client.get_service("CampaignBudgetService")
    response = campaign_budget_service.mutate_campaign_budgets(
        customer_id=customer_id, operations=[campaign_budget_operation]
    )
    resource_name = response.results[0].resource_name
    print(f"Created campaign budget with resource name: '{resource_name}'")
    return resource_name


def _create_campaign(client, customer_id, budget_resource_name):
    """Adds a Local campaign to the given client account using the given budget.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID str.
        budget_resource_name: the resource name str for a campaign budget.

    Returns:
        A str of the resource name for the newly created campaign.
    """
    # Create a CampaignOperation.
    campaign_operation = client.get_type("CampaignOperation")
    # Create a Campaign.
    campaign = campaign_operation.create
    campaign.name = f"Interplanetary Cruise Local #{uuid4()}"
    campaign.campaign_budget = budget_resource_name
    # Recommendation: Set the campaign to PAUSED when creating it to prevent
    # the ads from immediately serving. Set to ENABLED once you've added
    # targeting and the ads are ready to serve.
    campaign.status = client.enums.CampaignStatusEnum.PAUSED
    # All Local campaigns have an advertising_channel_type of LOCAL and
    # advertising_channel_sub_type of LOCAL_CAMPAIGN.
    campaign.advertising_channel_type = (
        client.enums.AdvertisingChannelTypeEnum.LOCAL
    )
    campaign.advertising_channel_sub_type = (
        client.enums.AdvertisingChannelSubTypeEnum.LOCAL_CAMPAIGN
    )
    # Bidding strategy must be set directly on the campaign.
    # Setting a portfolio bidding strategy by resource name is not supported.
    # Maximize conversion value is the only strategy supported for Local
    # campaigns. An optional ROAS (Return on Advertising Spend) can be set for
    # maximize_conversion_value. The ROAS value must be specified as a ratio in
    # the API. It is calculated by dividing "total value" by "total spend".
    # For more information on maximize conversion value, see the support
    # article: http://support.google.com/google-ads/answer/7684216.
    # A target_roas of 3.5 corresponds to a 350% return on ad spend.
    campaign.maximize_conversion_value.target_roas = 3.5
    # Configure the Local campaign setting. Use the locations associated with
    # the customer's linked Google My Business account.
    campaign.local_campaign_setting.location_source_type = (
        client.enums.LocationSourceTypeEnum.GOOGLE_MY_BUSINESS
    )
    # Optimization goal setting is mandatory for Local campaigns. This example
    # selects driving directions and call clicks as goals.
    optimization_goal_type_enum = client.enums.OptimizationGoalTypeEnum
    campaign.optimization_goal_setting.optimization_goal_types.extend(
        [
            optimization_goal_type_enum.CALL_CLICKS,
            optimization_goal_type_enum.DRIVING_DIRECTIONS,
        ]
    )

    campaign_service = client.get_service("CampaignService")
    response = campaign_service.mutate_campaigns(
        customer_id=customer_id, operations=[campaign_operation]
    )
    resource_name = response.results[0].resource_name
    print(f"Created Local Campaign with resource name: '{resource_name}'")
    return resource_name


def _create_ad_group(client, customer_id, campaign_resource_name):
    """Adds an ad group to the given client account under the given campaign.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID str.
        campaign_resource_name: the resource name str for a campaign.

    Returns:
        A str of the resource name for the newly created ad group.
    """
    ad_group_operation = client.get_type("AdGroupOperation")
    ad_group = ad_group_operation.create
    # Note that the ad group type must not be set.
    # Since the advertising_channel_subType is LOCAL_CAMPAIGN:
    #   1. you cannot override bid settings at the ad group level.
    #   2. you cannot add ad group criteria.
    ad_group.name = f"Earth to Mars Cruises #{uuid4()}"
    ad_group.status = client.enums.AdGroupStatusEnum.ENABLED
    ad_group.campaign = campaign_resource_name

    ad_group_service = client.get_service("AdGroupService")
    response = ad_group_service.mutate_ad_groups(
        customer_id=customer_id, operations=[ad_group_operation]
    )
    resource_name = response.results[0].resource_name
    print(f"Created AdGroup with resource name: '{resource_name}'")
    return resource_name


def _create_local_ad(client, customer_id, ad_group_resource_name):
    """Adds a local ad to the given client account under the given ad group.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID str.
        ad_group_resource_name: the resource name str for a ad group.
    """
    ad_group_ad_operation = client.get_type("AdGroupAdOperation")
    ad_group_ad = ad_group_ad_operation.create
    ad_group_ad.ad_group = ad_group_resource_name
    ad_group_ad.status = client.enums.AdGroupAdStatusEnum.ENABLED
    ad_group_ad.ad.final_urls.append("https://www.example.com")
    ad_group_ad.ad.local_ad.headlines.extend(
        [
            _create_ad_text_asset(client, "Best Space Cruise Line"),
            _create_ad_text_asset(client, "Experience the Stars"),
        ]
    )
    ad_group_ad.ad.local_ad.descriptions.extend(
        [
            _create_ad_text_asset(client, "Buy your tickets now"),
            _create_ad_text_asset(client, "Visit the Red Planet"),
        ]
    )
    ad_group_ad.ad.local_ad.call_to_actions.append(
        _create_ad_text_asset(client, "Shop Now")
    )
    marketing_image = client.get_type("AdImageAsset")
    marketing_image.asset = _create_image_asset(
        client, customer_id, _MARKETING_IMAGE_URL, "Marketing Image"
    )
    ad_group_ad.ad.local_ad.marketing_images.append(marketing_image)

    logo_image = client.get_type("AdImageAsset")
    logo_image.asset = _create_image_asset(
        client, customer_id, _LOGO_IMAGE_URL, "Square Marketing Image"
    )
    ad_group_ad.ad.local_ad.logo_images.append(logo_image)

    video = client.get_type("AdVideoAsset")
    video.asset = _create_youtube_video_asset(
        client, customer_id, _YOUTUBE_VIDEO_ID, "Local Campaigns"
    )
    ad_group_ad.ad.local_ad.videos.append(video)

    ad_group_ad_service = client.get_service("AdGroupAdService")
    response = ad_group_ad_service.mutate_ad_group_ads(
        customer_id=customer_id, operations=[ad_group_ad_operation]
    )
    resource_name = response.results[0].resource_name
    print(f"Created ad group ad with resource name: '{resource_name}'")


def _create_ad_text_asset(client, text):
    """Creates an ad text asset with the given text value.

    Args:
        client: an initialized GoogleAdsClient instance.
        text: a str for the text value of the ad text asset.

    Returns:
        an ad text asset.
    """
    ad_text_asset = client.get_type("AdTextAsset")
    ad_text_asset.text = text
    return ad_text_asset


def _create_image_asset(client, customer_id, image_url, image_name):
    """Creates an asset with the given image URL and name.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID str.
        image_url: a str URL to download an image.
        image_name: a str to use to name the image.

    Returns:
        an asset.
    """
    asset_operation = client.get_type("AssetOperation")
    asset = asset_operation.create
    asset.name = image_name
    asset.type_ = client.enums.AssetTypeEnum.IMAGE
    asset.image_asset.data = _get_image_bytes(image_url)
    asset_service = client.get_service("AssetService")
    response = asset_service.mutate_assets(
        customer_id=customer_id, operations=[asset_operation]
    )
    resource_name = response.results[0].resource_name
    print(
        "A new image asset has been added with resource name: "
        f"'{resource_name}'"
    )
    return resource_name


def _get_image_bytes(url):
    """Loads image data from a URL.

    Args:
        url: a URL str.

    Returns:
        Images bytes loaded from the given URL.
    """
    response = requests.get(url)
    return response.content


def _create_youtube_video_asset(
    client, customer_id, youtube_video_id, youtube_video_name
):
    """Creates a asset with the given YouTube video ID and name.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID str.
        youtube_video_id: a str of a YouTube video ID.
        youtube_video_name: a str to use for the name of the video asset.

    Returns:
        an Asset.
    """
    asset_operation = client.get_type("AssetOperation")
    asset = asset_operation.create
    asset.name = youtube_video_name
    asset.type_ = client.enums.AssetTypeEnum.YOUTUBE_VIDEO
    asset.youtube_video_asset.youtube_video_id = youtube_video_id

    asset_service = client.get_service("AssetService")
    response = asset_service.mutate_assets(
        customer_id=customer_id, operations=[asset_operation]
    )
    resource_name = response.results[0].resource_name
    print(
        "A new YouTube video asset has been added with resource name: "
        f"'{resource_name}'"
    )
    return 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="v8")

    parser = argparse.ArgumentParser(
        description="Adds a Local Campaign to the given account."
    )
    # 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()
    try:
        main(googleads_client, args.customer_id)
    except GoogleAdsException as ex:
        print(
            f'Request with ID "{ex.request_id}" failed with status '
            f'"{ex.error.code().name}" and includes the following errors:'
        )
        for error in ex.failure.errors:
            print(f'\tError with message "{error.message}".')
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print(f"\t\tOn field: {field_path_element.field_name}")
        sys.exit(1)

      

Ruby

#!/usr/bin/env ruby
# Encoding: utf-8
#
# Copyright 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 adds a Local campaign.
#
# Prerequisite: To create a Local campaign, you need to define the store
# locations you want to promote by linking your Google My Business account or
# selecting affiliate locations. More information about Local campaigns can be
# found at: https://support.google.com/google-ads/answer/9118422.

require 'optparse'
require 'date'
require 'open-uri'
require 'google/ads/google_ads'

def add_local_campaign(customer_id)
  client = Google::Ads::GoogleAds::GoogleAdsClient.new

  budget_resource_name = create_campaign_budget(client, customer_id)

  campaign_resource_name = create_campaign(
    client,
    customer_id,
    budget_resource_name,
  )

  ad_group_resource_name = create_ad_group(
    client,
    customer_id,
    campaign_resource_name,
  )

  create_local_ad(client, customer_id, ad_group_resource_name)
end

def create_campaign_budget(client, customer_id)
  # Creates a campaign budget operation.
  operation = client.operation.create_resource.campaign_budget do |cb|
    cb.name = "Interplanetary Cruise Budget ##{(Time.new.to_f * 1000).to_i}"
    cb.delivery_method = :STANDARD
    cb.amount_micros = 50_000_000
    # A Local campaign cannot use a shared campaign budget.
    cb.explicitly_shared = false
  end

  # Issues a mutate request to add campaign budget.
  response = client.service.campaign_budget.mutate_campaign_budgets(
    customer_id: customer_id,
    operations: [operation],
  )

  budget_resource_name = response.results.first.resource_name
  puts "Created campaign budget with resource name: '#{budget_resource_name}'."

  budget_resource_name
end

def create_campaign(client, customer_id, budget_resource_name)
  # Creates a campaign operation.
  operation = client.operation.create_resource.campaign do |c|
    c.name = "Interplanetary Cruise Local ##{(Time.new.to_f * 1000).to_i}"
    c.campaign_budget = budget_resource_name
    # Recommendation: Set the campaign to PAUSED when creating it to prevent
    # the ads from immediately serving. Set to ENABLED once you've added
    # targeting and the ads are ready to serve.
    c.status = :PAUSED
    # All Local campaigns have an advertisingChannelType of LOCAL and
    # advertisingChannelSubType of LOCAL_CAMPAIGN.
    c.advertising_channel_type = :LOCAL
    c.advertising_channel_sub_type = :LOCAL_CAMPAIGN
    # Bidding strategy must be set directly on the campaign.
    # Setting a portfolio bidding strategy by resource name is not supported.
    # Maximize conversion value is the only strategy supported for Local
    # campaigns. An optional ROAS (Return on Advertising Spend) can be set for
    # maximize_conversion_value. The ROAS value must be specified as a ratio in
    # the API. It is calculated by dividing "total value" by "total spend".
    # For more information on maximize conversion value, see the support article:
    # http://support.google.com/google-ads/answer/7684216.
    c.maximize_conversion_value = Google::Ads::GoogleAds::V8::Common::MaximizeConversionValue.new
    c.maximize_conversion_value.target_roas = 3.5
    # Configures the Local campaign setting.
    c.local_campaign_setting = client.resource.local_campaign_setting do |lcs|
      # Use the locations associated with the customer's linked
      # Google My Business account.
      lcs.location_source_type = :GOOGLE_MY_BUSINESS
    end
    # Optimization goal setting is mandatory for Local campaigns. This example
    # selects driving directions and call clicks as goals.
    c.optimization_goal_setting = client.resource.optimization_goal_setting do |ogs|
      ogs.optimization_goal_types += [:CALL_CLICKS, :DRIVING_DIRECTIONS]
    end
  end

  # Issues a mutate request to add campaign.
  response = client.service.campaign.mutate_campaigns(
    customer_id: customer_id,
    operations: [operation],
  )

  campaign_resource_name = response.results.first.resource_name
  puts "Created Local campaign with resource name: '#{campaign_resource_name}'."

  campaign_resource_name
end

def create_ad_group(client, customer_id, campaign_resource_name)
  # Creates an ad group operation.
  # Note that the ad group type must not be set.
  # Since the advertising_channel_sub_type is LOCAL_CAMPAIGN:
  #   1. you cannot override bid settings at the ad group level.
  #   2. you cannot add ad group criteria.
  operation = client.operation.create_resource.ad_group do |ag|
    ag.name = "Earth to Mars Cruises ##{(Time.new.to_f * 1000).to_i}"
    ag.campaign = campaign_resource_name
    ag.status = :ENABLED
  end

  # Issues a mutate request to add the ad group.
  response = client.service.ad_group.mutate_ad_groups(
    customer_id: customer_id,
    operations: [operation],
  )

  ad_group_resource_name = response.results.first.resource_name
  puts "Created ad group with resource name: '#{ad_group_resource_name}'."

  ad_group_resource_name
end

def create_local_ad(client, customer_id, ad_group_resource_name)
  # Creates an ad group ad operation.
  operation = client.operation.create_resource.ad_group_ad do |aga|
    aga.ad_group = ad_group_resource_name
    aga.status = :ENABLED
    aga.ad = client.resource.ad do |ad|
      ad.final_urls << "https://www.example.com"
      ad.local_ad = client.resource.local_ad_info do |lai|
        lai.headlines << client.resource.ad_text_asset do |ata|
          ata.text = "Best Space Cruise Line"
        end
        lai.headlines << client.resource.ad_text_asset do |ata|
          ata.text = "Experience the Stars"
        end
        lai.descriptions << client.resource.ad_text_asset do |ata|
          ata.text = "Buy your tickets now"
        end
        lai.descriptions << client.resource.ad_text_asset do |ata|
          ata.text = "Visit the Red Planet"
        end
        lai.call_to_actions << client.resource.ad_text_asset do |ata|
          ata.text = "Shop Now"
        end
        # Sets the marketing image and logo image assets.
        lai.marketing_images << client.resource.ad_image_asset do |aia|
          aia.asset = create_image_asset(
            client, customer_id, MARKETING_IMAGE_URL, "Marketing Image")
        end
        lai.logo_images << client.resource.ad_image_asset do |aia|
          aia.asset = create_image_asset(
            client, customer_id, LOGO_IMAGE_URL, "Square Marketing Image")
        end
        # Sets the video assets.
        lai.videos << client.resource.ad_video_asset do |aia|
          aia.asset = create_youtube_video_asset(
            client, customer_id, YOUTUBE_VIDEO_ID, "Local Campaigns")
        end
      end
    end
  end

  # Issues a mutate request to add the ad group ad.
  response = client.service.ad_group_ad.mutate_ad_group_ads(
    customer_id: customer_id,
    operations: [operation],
  )

  puts "Created ad group ad with resource name: " \
    "'#{response.results.first.resource_name}'."
end

def create_image_asset(client, customer_id, image_url, image_name)
  # Creates an asset operation.
  operation = client.operation.create_resource.asset do |a|
    a.name = image_name
    a.type = :IMAGE
    a.image_asset = client.resource.image_asset do |ia|
      ia.data = open(image_url) { |f| f.read }
    end
  end

  # Issues a mutate request to add the asset.
  response = client.service.asset.mutate_assets(
    customer_id: customer_id,
    operations: [operation],
  )

  # Prints out information about the newly added asset.
  asset_resource_name = response.results.first.resource_name
  puts "A new image asset has been added with resource name: " \
    "'#{asset_resource_name}'."

  asset_resource_name
end

def create_youtube_video_asset(
  client,
  customer_id,
  youtube_video_id,
  youtube_video_name
)
  # Creates an asset operation.
  operation = client.operation.create_resource.asset do |a|
    a.name = youtube_video_name
    a.type = :YOUTUBE_VIDEO
    a.youtube_video_asset = client.resource.youtube_video_asset do |yva|
      yva.youtube_video_id = youtube_video_id
    end
  end

  # Issues a mutate request to add the asset.
  response = client.service.asset.mutate_assets(
    customer_id: customer_id,
    operations: [operation],
  )

  # Prints out information about the newly added asset.
  asset_resource_name = response.results.first.resource_name
  puts "A new YouTube video asset has been added with resource name: " \
    "'#{asset_resource_name}'."

  asset_resource_name
end

if __FILE__ == $0
  MARKETING_IMAGE_URL = 'https://gaagl.page.link/Eit5'.freeze
  LOGO_IMAGE_URL = 'https://gaagl.page.link/bjYi'.freeze
  YOUTUBE_VIDEO_ID = 'ECpDzH9gXh8'.freeze

  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
    add_local_campaign(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 2020, Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This example adds an Local campaign.
#
# Prerequisite: To create a Local campaign, you need to define the store locations
# you want to promote by linking your Google My Business account or selecting
# affiliate locations. More information about Local campaigns can be found at:
# https://support.google.com/google-ads/answer/9118422.

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::MediaUtils;
use Google::Ads::GoogleAds::V8::Resources::CampaignBudget;
use Google::Ads::GoogleAds::V8::Resources::Campaign;
use Google::Ads::GoogleAds::V8::Resources::LocalCampaignSetting;
use Google::Ads::GoogleAds::V8::Resources::OptimizationGoalSetting;
use Google::Ads::GoogleAds::V8::Resources::AdGroup;
use Google::Ads::GoogleAds::V8::Resources::AdGroupAd;
use Google::Ads::GoogleAds::V8::Resources::Ad;
use Google::Ads::GoogleAds::V8::Resources::Asset;
use Google::Ads::GoogleAds::V8::Common::MaximizeConversionValue;
use Google::Ads::GoogleAds::V8::Common::LocalAdInfo;
use Google::Ads::GoogleAds::V8::Common::AdTextAsset;
use Google::Ads::GoogleAds::V8::Common::AdImageAsset;
use Google::Ads::GoogleAds::V8::Common::AdVideoAsset;
use Google::Ads::GoogleAds::V8::Common::ImageAsset;
use Google::Ads::GoogleAds::V8::Common::YoutubeVideoAsset;
use Google::Ads::GoogleAds::V8::Enums::BudgetDeliveryMethodEnum qw(STANDARD);
use Google::Ads::GoogleAds::V8::Enums::CampaignStatusEnum qw(PAUSED);
use Google::Ads::GoogleAds::V8::Enums::AdvertisingChannelTypeEnum qw(LOCAL);
use Google::Ads::GoogleAds::V8::Enums::AdvertisingChannelSubTypeEnum
  qw(LOCAL_CAMPAIGN);
use Google::Ads::GoogleAds::V8::Enums::LocationSourceTypeEnum
  qw(GOOGLE_MY_BUSINESS);
use Google::Ads::GoogleAds::V8::Enums::OptimizationGoalTypeEnum
  qw(CALL_CLICKS DRIVING_DIRECTIONS);
use Google::Ads::GoogleAds::V8::Enums::AdGroupStatusEnum;
use Google::Ads::GoogleAds::V8::Enums::AdGroupAdStatusEnum;
use Google::Ads::GoogleAds::V8::Enums::AssetTypeEnum qw(IMAGE YOUTUBE_VIDEO);
use
  Google::Ads::GoogleAds::V8::Services::CampaignBudgetService::CampaignBudgetOperation;
use Google::Ads::GoogleAds::V8::Services::CampaignService::CampaignOperation;
use Google::Ads::GoogleAds::V8::Services::AdGroupService::AdGroupOperation;
use Google::Ads::GoogleAds::V8::Services::AdGroupAdService::AdGroupAdOperation;
use Google::Ads::GoogleAds::V8::Services::AssetService::AssetOperation;
use Google::Ads::GoogleAds::V8::Utils::ResourceNames;

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

use constant MARKETING_IMAGE_URL => "https://gaagl.page.link/Eit5";
use constant LOGO_IMAGE_URL      => "https://gaagl.page.link/bjYi";
use constant YOUTUBE_VIDEO_ID    => "ECpDzH9gXh8";

# 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 add_local_campaign {
  my ($api_client, $customer_id) = @_;

  # Create a budget for the campaign.
  my $budget_resource_name = create_campaign_budget($api_client, $customer_id);

  # Create a campaign.
  my $campaign_resource_name =
    create_campaign($api_client, $customer_id, $budget_resource_name);

  # Create an ad group.
  my $ad_group_resource_name =
    create_ad_group($api_client, $customer_id, $campaign_resource_name);

  # Create a Local ad.
  create_local_ad($api_client, $customer_id, $ad_group_resource_name);

  return 1;
}

# Creates a campaign budget.
sub create_campaign_budget {
  my ($api_client, $customer_id) = @_;

  # Create a campaign budget.
  my $campaign_budget =
    Google::Ads::GoogleAds::V8::Resources::CampaignBudget->new({
      name           => "Interplanetary Cruise Budget #" . uniqid(),
      amountMicros   => 50000000,
      deliveryMethod => STANDARD,
      # A Local campaign cannot use a shared campaign budget.
      explicitlyShared => "false"
    });

  # Create a campaign budget operation.
  my $campaign_budget_operation =
    Google::Ads::GoogleAds::V8::Services::CampaignBudgetService::CampaignBudgetOperation
    ->new({
      create => $campaign_budget
    });

  # Issue a mutate request to add the campaign budget.
  my $campaign_budgets_response = $api_client->CampaignBudgetService()->mutate({
      customerId => $customer_id,
      operations => [$campaign_budget_operation]});

  my $campaign_budget_resource_name =
    $campaign_budgets_response->{results}[0]{resourceName};
  printf "Created campaign budget with resource name: '%s'.\n",
    $campaign_budget_resource_name;

  return $campaign_budget_resource_name;
}

# Creates a Local campaign.
sub create_campaign {
  my ($api_client, $customer_id, $budget_resource_name) = @_;

  # Create a campaign.
  my $campaign = Google::Ads::GoogleAds::V8::Resources::Campaign->new({
      name           => "Interplanetary Cruise Local #" . uniqid(),
      campaignBudget => $budget_resource_name,
      # Recommendation: Set the campaign to PAUSED when creating it to prevent
      # the ads from immediately serving. Set to ENABLED once you've added
      # targeting and the ads are ready to serve.
      status => PAUSED,
      # All Local campaigns have an advertisingChannelType of LOCAL and
      # advertisingChannelSubType of LOCAL_CAMPAIGN.
      advertisingChannelType    => LOCAL,
      advertisingChannelSubType => LOCAL_CAMPAIGN,
      # Bidding strategy must be set directly on the campaign.
      # Setting a portfolio bidding strategy by resource name is not supported.
      # Maximize conversion value is the only strategy supported for Local
      # campaigns. An optional ROAS (Return on Advertising Spend) can be set for
      # MaximizeConversionValue. The ROAS value must be specified as a ratio in the
      # API. It is calculated by dividing "total value" by "total spend".
      # For more information on maximize conversion value, see the support article:
      # http://support.google.com/google-ads/answer/7684216.
      maximizeConversionValue =>
        Google::Ads::GoogleAds::V8::Common::MaximizeConversionValue->new(
        {targetRoas => 3.5}
        ),
      # Configure the Local campaign setting.
      localCampaignSetting =>
        Google::Ads::GoogleAds::V8::Resources::LocalCampaignSetting->new({
          # Use the locations associated with the customer's linked Google
          # My Business account.
          locationSourceType => GOOGLE_MY_BUSINESS
        }
        ),
      # Optimization goal setting is mandatory for Local campaigns. This example
      # selects driving directions and call clicks as goals.
      optimizationGoalSetting =>
        Google::Ads::GoogleAds::V8::Resources::OptimizationGoalSetting->new({
          optimizationGoalTypes => [CALL_CLICKS, DRIVING_DIRECTIONS]})});

  # Create a campaign operation.
  my $campaign_operation =
    Google::Ads::GoogleAds::V8::Services::CampaignService::CampaignOperation->
    new({
      create => $campaign
    });

  # Issue a mutate request to add the campaign.
  my $campaigns_response = $api_client->CampaignService()->mutate({
      customerId => $customer_id,
      operations => [$campaign_operation]});

  my $campaign_resource_name =
    $campaigns_response->{results}[0]{resourceName};
  printf "Created Local campaign with resource name: '%s'.\n",
    $campaign_resource_name;

  return $campaign_resource_name;
}

# Creates an ad group for a given campaign.
sub create_ad_group {
  my ($api_client, $customer_id, $campaign_resource_name) = @_;

  # Create an ad group.
  # Note that the ad group type must not be set.
  # Since the advertisingChannelSubType is LOCAL_CAMPAIGN:
  #   1. you cannot override bid settings at the ad group level.
  #   2. you cannot add ad group criteria.
  my $ad_group = Google::Ads::GoogleAds::V8::Resources::AdGroup->new({
    name     => "Earth to Mars Cruises #" . uniqid(),
    status   => Google::Ads::GoogleAds::V8::Enums::AdGroupStatusEnum::ENABLED,
    campaign => $campaign_resource_name
  });

  # Create an ad group operation.
  my $ad_group_operation =
    Google::Ads::GoogleAds::V8::Services::AdGroupService::AdGroupOperation->
    new({create => $ad_group});

  # Issue a mutate request to add the ad group.
  my $ad_groups_response = $api_client->AdGroupService()->mutate({
      customerId => $customer_id,
      operations => [$ad_group_operation]});

  my $ad_group_resource_name =
    $ad_groups_response->{results}[0]{resourceName};
  printf "Created ad group with resource name: '%s'.\n",
    $ad_group_resource_name;

  return $ad_group_resource_name;
}

# Creates an Local ad for a given ad group.
sub create_local_ad {
  my ($api_client, $customer_id, $ad_group_resource_name) = @_;

  # Create an ad group ad.
  my $ad_group_ad = Google::Ads::GoogleAds::V8::Resources::AdGroupAd->new({
      adGroup => $ad_group_resource_name,
      status => Google::Ads::GoogleAds::V8::Enums::AdGroupAdStatusEnum::ENABLED,
      ad     => Google::Ads::GoogleAds::V8::Resources::Ad->new({
          finalUrls => ["https://www.example.com"],
          localAd   => Google::Ads::GoogleAds::V8::Common::LocalAdInfo->new({
              headlines => [
                create_ad_text_asset("Best Space Cruise Line"),
                create_ad_text_asset("Experience the Stars")
              ],
              descriptions => [
                create_ad_text_asset("Buy your tickets now"),
                create_ad_text_asset("Visit the Red Planet")
              ],
              callToActions => [create_ad_text_asset("Shop Now")],
              # Set the marketing image and logo image assets.
              marketingImages => [
                Google::Ads::GoogleAds::V8::Common::AdImageAsset->new({
                    asset => create_image_asset(
                      $api_client,         $customer_id,
                      MARKETING_IMAGE_URL, "Marketing Image"
                    )})
              ],
              logoImages => [
                Google::Ads::GoogleAds::V8::Common::AdImageAsset->new({
                    asset => create_image_asset(
                      $api_client,    $customer_id,
                      LOGO_IMAGE_URL, "Square Marketing Image"
                    )})
              ],
              # Set the video assets.
              videos => [
                Google::Ads::GoogleAds::V8::Common::AdVideoAsset->new({
                    asset => create_youtube_video_asset(
                      $api_client,      $customer_id,
                      YOUTUBE_VIDEO_ID, "Local Campaigns"
                    )})]})})}

  );

  # Create an ad group ad operation.
  my $ad_group_ad_operation =
    Google::Ads::GoogleAds::V8::Services::AdGroupAdService::AdGroupAdOperation
    ->new({create => $ad_group_ad});

  # Issue a mutate request to add the ad group ad.
  my $ad_group_ads_response = $api_client->AdGroupAdService()->mutate({
      customerId => $customer_id,
      operations => [$ad_group_ad_operation]});

  printf "Created ad group ad with resource name: '%s'.\n",
    $ad_group_ads_response->{results}[0]{resourceName};
}

# Creates an ad text asset.
sub create_ad_text_asset {
  my ($text) = @_;

  return Google::Ads::GoogleAds::V8::Common::AdTextAsset->new({
    text => $text
  });
}

# Creates an image asset.
sub create_image_asset {
  my ($api_client, $customer_id, $image_url, $image_name) = @_;

  # Create an asset.
  my $asset = Google::Ads::GoogleAds::V8::Resources::Asset->new({
      name       => $image_name,
      type       => IMAGE,
      imageAsset => Google::Ads::GoogleAds::V8::Common::ImageAsset->new({
          data => get_base64_data_from_url($image_url)})});

  # Create an asset operation.
  my $asset_operation =
    Google::Ads::GoogleAds::V8::Services::AssetService::AssetOperation->new({
      create => $asset
    });

  # Issue a mutate request to add the asset.
  my $assets_response = $api_client->AssetService()->mutate({
      customerId => $customer_id,
      operations => [$asset_operation]});

  # Print out information about the newly added asset.
  my $asset_resource_name = $assets_response->{results}[0]{resourceName};
  printf "A new image asset has been added with resource name: '%s'.\n",
    $asset_resource_name;

  return $asset_resource_name;
}

# Creates a YouTube video asset.
sub create_youtube_video_asset {
  my ($api_client, $customer_id, $youtube_video_id, $youtube_video_name) = @_;

  # Create an asset.
  my $asset = Google::Ads::GoogleAds::V8::Resources::Asset->new({
      name              => $youtube_video_name,
      type              => YOUTUBE_VIDEO,
      youtubeVideoAsset =>
        Google::Ads::GoogleAds::V8::Common::YoutubeVideoAsset->new({
          youtubeVideoId => $youtube_video_id
        })});

  # Create an asset operation.
  my $asset_operation =
    Google::Ads::GoogleAds::V8::Services::AssetService::AssetOperation->new({
      create => $asset
    });

  # Issue a mutate request to add the asset.
  my $assets_response = $api_client->AssetService()->mutate({
      customerId => $customer_id,
      operations => [$asset_operation]});

  # Print out information about the newly added asset.
  my $asset_resource_name = $assets_response->{results}[0]{resourceName};
  printf "A new YouTube video asset has been added with resource name: '%s'.\n",
    $asset_resource_name;

  return $asset_resource_name;
}

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

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

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

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

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

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

=pod

=head1 NAME

add_local_campaign

=head1 DESCRIPTION

This example adds an Local campaign.

Prerequisite: To create a Local campaign, you need to define the store locations
you want to promote by linking your Google My Business account or selecting
affiliate locations. More information about Local campaigns can be found at:
https://support.google.com/google-ads/answer/9118422.

=head1 SYNOPSIS

add_local_campaign.pl [options]

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

=cut