Add Sitelinks

  • The code examples demonstrate how to add sitelinks to a campaign using assets in various programming languages.

  • Sitelink assets are created first, defining the text, descriptions, and URLs (including mobile-specific URLs).

  • These sitelink assets are then linked to a specific campaign using CampaignAsset operations.

  • The process involves using the AssetService and CampaignAssetService to mutate assets and campaign assets, respectively.

Java

// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.ads.googleads.examples.assets; 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.v22.common.SitelinkAsset; import com.google.ads.googleads.v22.enums.AssetFieldTypeEnum.AssetFieldType; import com.google.ads.googleads.v22.errors.GoogleAdsError; import com.google.ads.googleads.v22.errors.GoogleAdsException; import com.google.ads.googleads.v22.resources.Asset; import com.google.ads.googleads.v22.resources.CampaignAsset; import com.google.ads.googleads.v22.services.AssetOperation; import com.google.ads.googleads.v22.services.AssetServiceClient; import com.google.ads.googleads.v22.services.CampaignAssetOperation; import com.google.ads.googleads.v22.services.CampaignAssetServiceClient; import com.google.ads.googleads.v22.services.MutateAssetResult; import com.google.ads.googleads.v22.services.MutateAssetsResponse; import com.google.ads.googleads.v22.services.MutateCampaignAssetResult; import com.google.ads.googleads.v22.services.MutateCampaignAssetsResponse; import com.google.ads.googleads.v22.utils.ResourceNames; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; /** Adds sitelinks to a campaign using Assets. To create a campaign, run AddCampaigns.java. */ public class AddSitelinks {  private static class AddSitelinksParams extends CodeSampleParams {  @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true)  private Long customerId;  @Parameter(names = ArgumentNames.CAMPAIGN_ID, required = true)  private Long campaignId;  }  public static void main(String[] args) {  AddSitelinksParams params = new AddSitelinksParams();  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");  params.campaignId = Long.parseLong("INSERT_CAMPAIGN_ID_HERE");  }  GoogleAdsClient googleAdsClient = null;  try {  googleAdsClient = GoogleAdsClient.newBuilder().fromPropertiesFile().build();  } catch (FileNotFoundException fnfe) {  System.err.printf(  "Failed to load GoogleAdsClient configuration from file. Exception: %s%n", fnfe);  System.exit(1);  } catch (IOException ioe) {  System.err.printf("Failed to create GoogleAdsClient. Exception: %s%n", ioe);  System.exit(1);  }  try {  new AddSitelinks().runExample(googleAdsClient, params.customerId, params.campaignId);  } catch (GoogleAdsException gae) {  // GoogleAdsException is the base class for most exceptions thrown by an API request.  // Instances of this exception have a message and a GoogleAdsFailure that contains a  // collection of GoogleAdsErrors that indicate the underlying causes of the  // GoogleAdsException.  System.err.printf(  "Request ID %s failed due to GoogleAdsException. Underlying errors:%n",  gae.getRequestId());  int i = 0;  for (GoogleAdsError googleAdsError : gae.getGoogleAdsFailure().getErrorsList()) {  System.err.printf(" Error %d: %s%n", i++, googleAdsError);  }  System.exit(1);  }  }  /**  * Runs the example.  *  * @param googleAdsClient the Google Ads API client.  * @param customerId the client customer ID.  * @param campaignId the campaign ID on which to add the sitelinks.  * @throws GoogleAdsException if an API request failed with one or more service errors.  */  private void runExample(GoogleAdsClient googleAdsClient, long customerId, long campaignId) {  // Creates a sitelink asset.  List<String> resourceNames = createSitelinkAssets(googleAdsClient, customerId);  // Associates the sitelinks at the campaign level.  linkSitelinksToCampaign(googleAdsClient, resourceNames, customerId, campaignId);  }  /** Creates a {@link SitelinkAsset} which can then be added to campaigns. */  private List<String> createSitelinkAssets(GoogleAdsClient googleAdsClient, long customerId) {  // Creates some sitelink assets.  SitelinkAsset storeLocatorSitelinkAsset =  SitelinkAsset.newBuilder()  .setDescription1("Get in touch")  .setDescription2("Find your local store")  .setLinkText("Store locator")  .build();  SitelinkAsset storeSitelinkAsset =  SitelinkAsset.newBuilder()  .setDescription1("Buy some stuff")  .setDescription2("It's really good")  .setLinkText("Store")  .build();  SitelinkAsset storeAdditionalSitelinkAsset =  SitelinkAsset.newBuilder()  .setDescription1("Even more stuff")  .setDescription2("There's never enough")  .setLinkText("Store for more")  .build();  // Wraps the sitelinks in an Asset and sets the URLs.  List<Asset> assets = new ArrayList();  assets.add(  Asset.newBuilder()  .setSitelinkAsset(storeLocatorSitelinkAsset)  .addFinalUrls("http://example.com/contact/store-finder")  // Optionally sets a different URL for mobile.  .addFinalMobileUrls("http://example.com/mobile/contact/store-finder")  .build());  assets.add(  Asset.newBuilder()  .setSitelinkAsset(storeSitelinkAsset)  .addFinalUrls("http://example.com/store")  // Optionally sets a different URL for mobile.  .addFinalMobileUrls("http://example.com/mobile/store")  .build());  assets.add(  Asset.newBuilder()  .setSitelinkAsset(storeAdditionalSitelinkAsset)  .addFinalUrls("http://example.com/store/more")  // Optionally sets a different URL for mobile.  .addFinalMobileUrls("http://example.com/mobile/store/more")  .build());  // Creates an operation to add each asset.  List<AssetOperation> operations =  assets.stream()  .map(a -> AssetOperation.newBuilder().setCreate(a).build())  .collect(Collectors.toList());  // Creates the service client.  try (AssetServiceClient client =  googleAdsClient.getLatestVersion().createAssetServiceClient()) {  // Sends the mutate request.  MutateAssetsResponse response = client.mutateAssets(String.valueOf(customerId), operations);  // Prints some information about the result.  List<String> resourceNames =  response.getResultsList().stream()  .map(MutateAssetResult::getResourceName)  .collect(Collectors.toList());  for (String resName : resourceNames) {  System.out.printf("Created sitelink asset with resource name '%s'.%n", resName);  }  return resourceNames;  }  }  /** Links the assets to a campaign. */  private void linkSitelinksToCampaign(  GoogleAdsClient googleAdsClient,  List<String> sitelinkAssetResourceName,  long customerId,  long campaignId) {  // Creates CampaignAssets representing the association between sitelinks and campaign.  List<CampaignAssetOperation> campaignAssetOperations =  sitelinkAssetResourceName.stream()  // Creates the CampaignAsset link.  .map(  resName ->  CampaignAsset.newBuilder()  .setAsset(resName)  .setCampaign(ResourceNames.campaign(customerId, campaignId))  .setFieldType(AssetFieldType.SITELINK)  .build())  // Creates a CampaignAssetOperation to create the CampaignAsset.  .map(a -> CampaignAssetOperation.newBuilder().setCreate(a).build())  .collect(Collectors.toList());  // Creates the service client.  try (CampaignAssetServiceClient client =  googleAdsClient.getLatestVersion().createCampaignAssetServiceClient()) {  // Sends the mutate request.  MutateCampaignAssetsResponse response =  client.mutateCampaignAssets(String.valueOf(customerId), campaignAssetOperations);  // Prints some information about the result.  for (MutateCampaignAssetResult result : response.getResultsList()) {  System.out.printf(  "Linked sitelink to campaign with resource name '%s'.%n", result.getResourceName());  }  }  } }   

C#

// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using CommandLine; using Google.Ads.Gax.Examples; using Google.Ads.GoogleAds.Lib; using Google.Ads.GoogleAds.V22.Common; using Google.Ads.GoogleAds.V22.Errors; using Google.Ads.GoogleAds.V22.Resources; using Google.Ads.GoogleAds.V22.Services; using System; using System.Collections.Generic; using System.Linq; using static Google.Ads.GoogleAds.V22.Enums.AssetFieldTypeEnum.Types; namespace Google.Ads.GoogleAds.Examples.V22 {  /// <summary>  /// This code example adds sitelinks to a campaign using assets. Run AddCampaigns.cs to  /// create a campaign.  /// </summary>  public class AddSitelinks : ExampleBase  {  /// <summary>  /// Command line options for running the <see cref="AddSitelinks"/> example.  /// </summary>  public class Options : OptionsBase  {  /// <summary>  /// The customer ID for which the call is made.  /// </summary>  [Option("customerId", Required = true, HelpText =  "The customer ID for which the call is made.")]  public long CustomerId { get; set; }  /// <summary>  /// ID of the campaign to which sitelinks are added.  /// </summary>  [Option("campaignId", Required = true, HelpText =  "ID of the campaign to which sitelinks are added.")]  public long CampaignId { get; set; }  }  /// <summary>  /// Main method, to run this code example as a standalone application.  /// </summary>  /// <param name="args">The command line arguments.</param>  public static void Main(string[] args)  {  Options options = ExampleUtilities.ParseCommandLine<Options>(args);  AddSitelinks codeExample = new AddSitelinks();  Console.WriteLine(codeExample.Description);  codeExample.Run(new GoogleAdsClient(), options.CustomerId, options.CampaignId);  }  /// <summary>  /// Returns a description about the code example.  /// </summary>  public override string Description =>  "This code example adds sitelinks to a campaign using assets. Run AddCampaigns.cs " +  "to create a campaign.";  /// <summary>  /// Runs the code example.  /// </summary>  /// <param name="client">The Google Ads client.</param>  /// <param name="customerId">The customer ID for which the call is made.</param>  /// <param name="campaignId">ID of the campaign to which sitelinks are added.</param>  public void Run(GoogleAdsClient client, long customerId, long campaignId)  {  try  {  // Creates a sitelink asset.  List<string> siteLinkResourceNames = CreateSitelinkAssets(client, customerId);  // Associates the sitelinks at the campaign level.  LinkSitelinksToCampaign(client, customerId, campaignId, siteLinkResourceNames);  }  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 list of <see cref="SitelinkAsset"/> objects which can then be added  /// to campaigns.  /// </summary>  /// <param name="client">The Google Ads client.</param>  /// <param name="customerId">The customer ID for which the call is made.</param>  /// <returns>The list of sitelink resource names.</returns>  private List<string> CreateSitelinkAssets(GoogleAdsClient client, long customerId)  {  AssetServiceClient assetService = client.GetService(Services.V22.AssetService);  // Creates some sitelink assets.  SitelinkAsset storeLocatorAsset = new SitelinkAsset()  {  Description1 = "Get in touch",  Description2 = "Find your local store",  LinkText = "Store locator"  };  SitelinkAsset storeAsset = new SitelinkAsset()  {  Description1 = "Buy some stuff",  Description2 = "It's really good",  LinkText = "Store"  };  SitelinkAsset storeAdditionalAsset = new SitelinkAsset()  {  Description1 = "Even more stuff",  Description2 = "There's never enough",  LinkText = "Store for more"  };  // Wraps the sitelinks in an Asset and sets the URLs.  List<Asset> assets = new List<Asset>()  {  new Asset()  {  SitelinkAsset = storeLocatorAsset,  FinalUrls = { "http://example.com/contact/store-finder" },  // Optionally sets a different URL for mobile.  FinalMobileUrls = { "http://example.com/mobile/contact/store-finder" }  },  new Asset()  {  SitelinkAsset = storeAsset,  FinalUrls = { "http://example.com/store" },  // Optionally sets a different URL for mobile.  FinalMobileUrls = {"http://example.com/mobile/store" }  },  new Asset()  {  SitelinkAsset = storeAdditionalAsset,  FinalUrls = { "http://example.com/store/more" },  // Optionally sets a different URL for mobile.  FinalMobileUrls = { "http://example.com/mobile/store/more" }  }  };  // Creates an operation to add each asset.  List<AssetOperation> operations = assets.Select(  asset => new AssetOperation()  {  Create = asset,  }).ToList();  // Sends the mutate request.  MutateAssetsResponse response = assetService.MutateAssets(  customerId.ToString(), operations);  // Prints some information about the result.  List<string> resourceNames = response.Results.Select(  result => result.ResourceName).ToList();  foreach (string resourceName in resourceNames)  {  Console.WriteLine($"Created sitelink asset with resource name '{resourceNames}'.");  }  return resourceNames;  }  /** Links the assets to a campaign. */  /// <summary>  /// Links the sitelinks to campaign.  /// </summary>  /// <param name="client">The Google Ads client.</param>  /// <param name="customerId">The customer ID for which the call is made.</param>  /// <param name="campaignId">ID of the campaign to which sitelinks are added.  /// </param>  /// <param name="sitelinkAssetResourceNames">The sitelink asset resource names.</param>  private void LinkSitelinksToCampaign(GoogleAdsClient client, long customerId,  long campaignId, List<string> sitelinkAssetResourceNames)  {  CampaignAssetServiceClient campaignAssetService = client.GetService(  Services.V22.CampaignAssetService);  string campaignResourceName = ResourceNames.Campaign(customerId, campaignId);  // Creates operations.  List<CampaignAssetOperation> campaignAssetOperations =  sitelinkAssetResourceNames.Select(resourceName =>  new CampaignAssetOperation()  {  // Creates CampaignAsset representing the association between sitelinks  // and campaign.  Create = new CampaignAsset()  {  Asset = resourceName,  Campaign = campaignResourceName,  FieldType = AssetFieldType.Sitelink  }  }).ToList();  // Sends the mutate request.  MutateCampaignAssetsResponse response = campaignAssetService.MutateCampaignAssets(  customerId.ToString(), campaignAssetOperations);  // Prints some information about the result.  foreach (MutateCampaignAssetResult result in response.Results)  {  Console.WriteLine($"Linked sitelink to campaign with resource " +  $"name '{result.ResourceName}'.");  }  }  } }  

PHP

This example is not yet available in PHP; you can take a look at the other languages. 

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. """Adds sitelinks to a campaign using Assets. Run basic_operations/add_campaigns.py to create a campaign. """ import argparse from typing import List import sys from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException from google.ads.googleads.v22.services.types.asset_service import AssetOperation from google.ads.googleads.v22.resources.types.asset import Asset from google.ads.googleads.v22.services.types.campaign_asset_service import ( CampaignAssetOperation, ) from google.ads.googleads.v22.resources.types.campaign_asset import ( CampaignAsset, ) def main(client: GoogleAdsClient, customer_id: str, campaign_id: str) -> None:  """Adds sitelinks to a campaign using assets.  Args:  client: The Google Ads client.  customer_id: The customer ID for which to add the keyword.  campaign_id: The campaign to which sitelinks will be added.  """ # Creates sitelink assets. resource_names: List[str] = create_sitelink_assets(client, customer_id) # Associates the sitelinks at the campaign level. link_sitelinks_to_campaign(client, customer_id, campaign_id, resource_names) def create_sitelink_assets( client: GoogleAdsClient, customer_id: str ) -> List[str]:  """Creates sitelink assets, which can be added to campaigns.  Args:  client: The Google Ads client.  customer_id: The customer ID for which to add the keyword.  Returns:  a list of sitelink asset resource names.  """ store_locator_operation: AssetOperation = client.get_type("AssetOperation") store_locator_asset: Asset = store_locator_operation.create store_locator_asset.final_urls.append( "http://example.com/contact/store-finder" ) store_locator_asset.final_mobile_urls.append( "http://example.com/mobile/contact/store-finder" ) store_locator_asset.sitelink_asset.description1 = "Get in touch" store_locator_asset.sitelink_asset.description2 = "Find your local store" store_locator_asset.sitelink_asset.link_text = "Store locator" store_asset_operation: AssetOperation = client.get_type("AssetOperation") store_asset: Asset = store_asset_operation.create store_asset.final_urls.append("http://example.com/store") store_asset.final_mobile_urls.append("http://example.com/mobile/store") store_asset.sitelink_asset.description1 = "Buy some stuff" store_asset.sitelink_asset.description2 = "It's really good" store_asset.sitelink_asset.link_text = "Store" store_addnl_asset_operation: AssetOperation = client.get_type( "AssetOperation" ) store_addnl_asset: Asset = store_addnl_asset_operation.create store_addnl_asset.final_urls.append("http://example.com/store/more") store_addnl_asset.final_mobile_urls.append( "http://example.com/mobile/store/more" ) store_addnl_asset.sitelink_asset.description1 = "Buy some stuff" store_addnl_asset.sitelink_asset.description2 = "It's really good" store_addnl_asset.sitelink_asset.link_text = "Store" asset_service = client.get_service("AssetService") response = asset_service.mutate_assets( customer_id=customer_id, operations=[ store_locator_operation, store_asset_operation, store_addnl_asset_operation, ], ) resource_names: List[str] = [ result.resource_name for result in response.results ] for resource_name in resource_names: print(f"Created sitelink asset with resource name '{resource_name}'.") return resource_names def link_sitelinks_to_campaign( client: GoogleAdsClient, customer_id: str, campaign_id: str, resource_names: List[str], ) -> None:  """Creates sitelink assets, which can be added to campaigns.  Args:  client: The Google Ads client.  customer_id: The customer ID for which to add the keyword.  campaign_id: The campaign to which sitelinks will be added.  resource_names: a list of sitelink asset resource names.  """ campaign_service = client.get_service("CampaignService") operations: List[CampaignAssetOperation] = [] for resource_name in resource_names: operation: CampaignAssetOperation = client.get_type( "CampaignAssetOperation" ) campaign_asset: CampaignAsset = operation.create campaign_asset.asset = resource_name campaign_asset.campaign = campaign_service.campaign_path( customer_id, campaign_id ) campaign_asset.field_type = client.enums.AssetFieldTypeEnum.SITELINK operations.append(operation) campaign_asset_service = client.get_service("CampaignAssetService") response = campaign_asset_service.mutate_campaign_assets( customer_id=customer_id, operations=operations ) for result in response.results: print( "Linked sitelink to campaign with resource name '{result.resource_name}'." ) if __name__ == "__main__": parser: argparse.ArgumentParser = argparse.ArgumentParser( description="Adds sitelinks to a campaign using feed services." ) # The following argument(s) should be provided to run the example. parser.add_argument( "-c", "--customer_id", type=str, required=True, help="The Google Ads customer ID.", ) parser.add_argument( "-i", "--campaign_id", type=str, required=True, default=None, help="ID of the campaign to which sitelinks will be added.", ) args: argparse.Namespace = parser.parse_args() # GoogleAdsClient will read the google-ads.yaml configuration file in the # home directory if none is specified. googleads_client: GoogleAdsClient = GoogleAdsClient.load_from_storage( version="v22" ) try: main(googleads_client, args.customer_id, args.campaign_id) except GoogleAdsException as ex: print( f"Request with ID '{ex.request_id}' failed with status " f"'{ex.error.code().name}' and includes the following errors:" ) for error in ex.failure.errors: print(f"\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. # # Adds sitelinks to a campaign. To create a campaign, run add_campaigns.rb. require 'optparse' require 'google/ads/google_ads' require 'date' def add_sitelinks(customer_id, campaign_id)  # GoogleAdsClient will read a config file from  # ENV['HOME']/google_ads_config.rb when called without parameters  client = Google::Ads::GoogleAds::GoogleAdsClient.new  resource_names = create_sitelink_assets(client, customer_id)  link_sitelinks_to_campaign(client, resource_names, customer_id, campaign_id) end def create_sitelink_assets(client, customer_id)  assets = [  client.resource.asset do |asset|  asset.sitelink_asset = client.resource.sitelink_asset do |sitelink|  sitelink.description1 = "Get in touch"  sitelink.description2 = "Find your local store"  sitelink.link_text = "Store locator"  end  asset.final_urls << "http://example.com/contact/store-finder"  asset.final_mobile_urls << "http://example.com/mobile/contact/store-finder"  end,  client.resource.asset do |asset|  asset.sitelink_asset = client.resource.sitelink_asset do |sitelink|  sitelink.description1 = "But some stuff"  sitelink.description2 = "It's really good"  sitelink.link_text = "Store"  end  asset.final_urls << "http://example.com/store"  asset.final_mobile_urls << "http://example.com/mobile/store"  end,  client.resource.asset do |asset|  asset.sitelink_asset = client.resource.sitelink_asset do |sitelink|  sitelink.description1 = "Even more stuff"  sitelink.description2 = "There's never enough"  sitelink.link_text = "Store for more"  end  asset.final_urls << "http://example.com/store/more"  asset.final_mobile_urls << "http://example.com/mobile/store/more"  end,  ]  operations = assets.map do |asset|  client.operation.create_resource.asset(asset)  end  response = client.service.asset.mutate_assets(  customer_id: customer_id,  operations: operations,  )  response.results.map do |result|  puts "Created sitelink asset with resource name #{result.resource_name}"  result.resource_name  end end def link_sitelinks_to_campaign(client, resource_names, customer_id, campaign_id)  operations = resource_names.map do |resource_name|  client.operation.create_resource.campaign_asset do |ca|  ca.asset = resource_name  ca.campaign = client.path.campaign(customer_id, campaign_id)  ca.field_type = :SITELINK  end  end  response = client.service.campaign_asset.mutate_campaign_assets(  customer_id: customer_id,  operations: operations,  )  response.results.each do |result|  puts "Created campaign asset with resource name #{result.resource_name}."  end end if __FILE__ == $0  options = {}  # The following parameter(s) should be provided to run the example. You can  # either specify these by changing the INSERT_XXX_ID_HERE values below, or on  # the command line.  #  # Parameters passed on the command line will override any parameters set in  # code.  #  # Running the example with -h will print the command line usage.  options[:customer_id] = 'INSERT_CUSTOMER_ID_HERE'  options[:campaign_id] = 'INSERT_CAMPAIGN_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.on('-c', '--campaign-id CAMPAIGN-ID', String, 'Campaign ID') do |v|  options[:campaign_id] = v  end  opts.separator ''  opts.separator 'Help:'  opts.on_tail('-h', '--help', 'Show this message') do  puts opts  exit  end  end.parse!  begin  add_sitelinks(options.fetch(:customer_id).tr("-", ""), options.fetch(:campaign_id))  rescue Google::Ads::GoogleAds::Errors::GoogleAdsError => e  e.failure.errors.each do |error|  STDERR.printf("Error with message: %s\n", error.message)  if error.location  error.location.field_path_elements.each do |field_path_element|  STDERR.printf("\tOn field: %s\n", field_path_element.field_name)  end  end  error.error_code.to_h.each do |k, v|  next if v == :UNSPECIFIED  STDERR.printf("\tType: %s\n\tCode: %s\n", k, v)  end  end  raise  end end   

Perl

#!/usr/bin/perl -w # # Copyright 2021, Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Adds sitelinks to a campaign using Assets. To create a campaign, run add_campaigns.pl. 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::V22::Resources::Asset; use Google::Ads::GoogleAds::V22::Resources::CampaignAsset; use Google::Ads::GoogleAds::V22::Common::SitelinkAsset; use Google::Ads::GoogleAds::V22::Enums::AssetFieldTypeEnum qw(SITELINK); use Google::Ads::GoogleAds::V22::Services::AssetService::AssetOperation; use  Google::Ads::GoogleAds::V22::Services::CampaignAssetService::CampaignAssetOperation; use Google::Ads::GoogleAds::V22::Utils::ResourceNames; use Getopt::Long qw(:config auto_help); use Pod::Usage; use Cwd qw(abs_path); # The following parameter(s) should be provided to run the example. You can # either specify these by changing the INSERT_XXX_ID_HERE values below, or on # the command line. # # Parameters passed on the command line will override any parameters set in # code. # # Running the example with -h will print the command line usage. my $customer_id = "INSERT_CUSTOMER_ID_HERE"; my $campaign_id = "INSERT_CAMPAIGN_ID_HERE"; sub add_sitelinks_using_assets {  my ($api_client, $customer_id, $campaign_id) = @_;  # Create sitelink assets.  my $sitelink_asset_resource_names =  create_sitelink_assets($api_client, $customer_id);  # Associate the sitelinks at the campaign level.  link_sitelinks_to_campaign($api_client, $sitelink_asset_resource_names,  $customer_id, $campaign_id);  return 1; } # Creates sitelink assets which can then be added to campaigns. sub create_sitelink_assets {  my ($api_client, $customer_id) = @_;  # Create some sitelink assets.  my $store_locator_asset =  Google::Ads::GoogleAds::V22::Common::SitelinkAsset->new({  description1 => "Get in touch",  description2 => "Find your local store",  linkText => "Store locator"  });  my $store_asset = Google::Ads::GoogleAds::V22::Common::SitelinkAsset->new({  description1 => "Buy some stuff",  description2 => "It's really good",  linkText => "Store"  });  my $store_additional_asset =  Google::Ads::GoogleAds::V22::Common::SitelinkAsset->new({  description1 => "Even more stuff",  description2 => "There's never enough",  linkText => "Store for more"  });  # Wrap the sitelinks in an Asset and set the URLs.  my $assets = [];  push @$assets, Google::Ads::GoogleAds::V22::Resources::Asset->new({  sitelinkAsset => $store_locator_asset,  finalUrls => ["http://example.com/contact/store-finder"],  # Optionally set a different URL for mobile.  finalMobileUrls => ["http://example.com/mobile/contact/store-finder"]});  push @$assets, Google::Ads::GoogleAds::V22::Resources::Asset->new({  sitelinkAsset => $store_asset,  finalUrls => ["http://example.com/store"],  # Optionally set a different URL for mobile.  finalMobileUrls => ["http://example.com/mobile/store"]});  push @$assets, Google::Ads::GoogleAds::V22::Resources::Asset->new({  sitelinkAsset => $store_additional_asset,  finalUrls => ["http://example.com/store/more"],  # Optionally set a different URL for mobile.  finalMobileUrls => ["http://example.com/mobile/store/more"]});  # Create the operations to add each asset.  my $operations = [];  foreach my $asset (@$assets) {  push @$operations,  Google::Ads::GoogleAds::V22::Services::AssetService::AssetOperation->new((  {  create => $asset  }));  }  # Send the mutate request.  my $response = $api_client->AssetService()->mutate({  customerId => $customer_id,  operations => $operations  });  # Print some information about the result.  my $resource_names = [];  foreach my $result (@{$response->{results}}) {  push @$resource_names, $result->{resourceName};  printf "Created sitelink asset with resource name '%s'.\n",  $result->{resourceName};  }  return $resource_names; } # Links the assets to a campaign. sub link_sitelinks_to_campaign {  my ($api_client, $sitelink_asset_resource_names, $customer_id, $campaign_id)  = @_;  # Create CampaignAssets representing the association between sitelinks and campaign.  my $operations = [];  foreach my $sitelink_asset_resource_name (@$sitelink_asset_resource_names) {  push @$operations,  # Create a CampaignAssetOperation to create the CampaignAsset.  Google::Ads::GoogleAds::V22::Services::CampaignAssetService::CampaignAssetOperation  ->new({  # Create the CampaignAsset link.  create => Google::Ads::GoogleAds::V22::Resources::CampaignAsset->new({  asset => $sitelink_asset_resource_name,  campaign =>  Google::Ads::GoogleAds::V22::Utils::ResourceNames::campaign(  $customer_id, $campaign_id  ),  fieldType => SITELINK  })});  }  # Send the mutate request.  my $response = $api_client->CampaignAssetService()->mutate({  customerId => $customer_id,  operations => $operations  });  # Print some information about the result.  foreach my $result (@{$response->{results}}) {  printf "Linked sitelink to campaign with resource name '%s'.\n",  $result->{resourceName};  } } # Don't run the example if the file is being included. if (abs_path($0) ne abs_path(__FILE__)) {  return 1; } # Get Google Ads Client, credentials will be read from ~/googleads.properties. my $api_client = Google::Ads::GoogleAds::Client->new(); # By default examples are set to die on any server returned fault. $api_client->set_die_on_faults(1); # Parameters passed on the command line will override any parameters set in code. GetOptions("customer_id=s" => \$customer_id, "campaign_id=i" => \$campaign_id); # Print the help message if the parameters are not initialized in the code nor # in the command line. pod2usage(2) if not check_params($customer_id, $campaign_id); # Call the example. add_sitelinks_using_assets($api_client, $customer_id =~ s/-//gr, $campaign_id); =pod =head1 NAME add_sitelinks_using_assets.pl =head1 DESCRIPTION Adds sitelinks to a campaign using Assets. To create a campaign, run add_campaigns.pl. =head1 SYNOPSIS add_sitelinks.pl [options]  -help Show the help message.  -customer_id The Google Ads customer ID.  -campaign_id The campaign ID. =cut