জাভা
// Copyright 2021 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.ads.googleads.examples.advancedoperations; import static com.google.ads.googleads.examples.utils.CodeSampleHelper.getPrintableDateTime; import static com.google.ads.googleads.v22.enums.EuPoliticalAdvertisingStatusEnum.EuPoliticalAdvertisingStatus.DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING; 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.AudienceInfo; import com.google.ads.googleads.v22.common.ImageAsset; import com.google.ads.googleads.v22.common.LanguageInfo; import com.google.ads.googleads.v22.common.LocationInfo; import com.google.ads.googleads.v22.common.MaximizeConversionValue; import com.google.ads.googleads.v22.common.SearchThemeInfo; import com.google.ads.googleads.v22.common.TextAsset; import com.google.ads.googleads.v22.enums.AdvertisingChannelTypeEnum.AdvertisingChannelType; import com.google.ads.googleads.v22.enums.AssetAutomationStatusEnum.AssetAutomationStatus; import com.google.ads.googleads.v22.enums.AssetAutomationTypeEnum.AssetAutomationType; import com.google.ads.googleads.v22.enums.AssetFieldTypeEnum.AssetFieldType; import com.google.ads.googleads.v22.enums.AssetGroupStatusEnum.AssetGroupStatus; import com.google.ads.googleads.v22.enums.BudgetDeliveryMethodEnum.BudgetDeliveryMethod; import com.google.ads.googleads.v22.enums.CampaignStatusEnum.CampaignStatus; 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.AssetGroup; import com.google.ads.googleads.v22.resources.AssetGroupAsset; import com.google.ads.googleads.v22.resources.AssetGroupSignal; import com.google.ads.googleads.v22.resources.Campaign; import com.google.ads.googleads.v22.resources.Campaign.AssetAutomationSetting; import com.google.ads.googleads.v22.resources.Campaign.AssetAutomationSettingOrBuilder; import com.google.ads.googleads.v22.resources.CampaignAsset; import com.google.ads.googleads.v22.resources.CampaignBudget; import com.google.ads.googleads.v22.resources.CampaignCriterion; import com.google.ads.googleads.v22.services.AssetGroupAssetOperation; import com.google.ads.googleads.v22.services.AssetGroupOperation; import com.google.ads.googleads.v22.services.AssetGroupSignalOperation; import com.google.ads.googleads.v22.services.AssetOperation; import com.google.ads.googleads.v22.services.CampaignAssetOperation; import com.google.ads.googleads.v22.services.CampaignBudgetOperation; import com.google.ads.googleads.v22.services.CampaignCriterionOperation; import com.google.ads.googleads.v22.services.CampaignOperation; import com.google.ads.googleads.v22.services.GoogleAdsServiceClient; import com.google.ads.googleads.v22.services.MutateGoogleAdsResponse; import com.google.ads.googleads.v22.services.MutateOperation; import com.google.ads.googleads.v22.services.MutateOperationResponse; import com.google.ads.googleads.v22.utils.ResourceNames; import com.google.common.collect.ImmutableList; import com.google.common.io.ByteStreams; import com.google.protobuf.ByteString; import com.google.protobuf.Descriptors.FieldDescriptor; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; import java.util.stream.Collectors; import org.joda.time.DateTime; /** * This example shows how to create a Performance <M>ax campaign. * * pFor more information about Performance Max campaigns, see * https://developers.google.com/google-ads/api/docs/performance<->max/overview * * pPrerequisites: - You must have at least one conversion action in the account. For more about * conversion actions, see * https://developers.google.com/google-ads/api/docs/conversions/overview#conve<r>sion_actions * * pThis example uses the default customer conversion goals. For an example of setting * campaign-specific conversion goals, see {@link * com.google.ads.googleads.examples.shoppingads.AddPerformanceMaxRetailCampaign}. */ public class AddPerformanceMaxCampaign { // We specify temporary IDs that are specific to a single mutate request. Temporary IDs are always // negative and unique within one mutate< >request. // // pSee https://developers.google.com/google-ads/api/docs/mutating/best-practices for further //< >details. // // pThese temporary IDs are fixed because they are used in multiple places. private static final int BUDGET_TEMPORARY_ID = -1; private static final int PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID = -2; private static final int ASSET_GROUP_TEMPORARY_ID = -3; // There are also entities that will be created in the same request but do not // need to be fixed temporary IDs because they are referenced only once. private static long temporaryId = ASSET_GROUP_TEMPORARY_ID - 1; private static class AddPerformanceMaxCampaignParams extends CodeSampleParams { @Parameter(names = ArgumentNames.CUSTOMER_ID, required = true) private Long customerId; @Parameter( names = ArgumentNames.AUDIENCE_ID, description = "An audience ID to use to improve the targeting of the Performance Max campaign") private Long audienceId; @Parameter( names = ArgumentNames.BRAND_GUIDELINES_ENABLED, arity = 1, description = "A boolean value indicating if the created campaign is enabled for brand guidelines") private boolean brandGuidelinesEnabled = true; } public static void main(String[] args) throws IOException { AddPerformanceMaxCampaignParams params = new AddPerformanceMaxCampaignParams(); 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"); // Optional: Specify an audience ID. // params.audienceId = Long.parseLong("INSERT_AUDIENCE_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 AddPerformanceMaxCampaign() .runExample( googleAdsClient, params.customerId, params.audienceId, params.brandGuidelinesEnabled); } 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 audienceId the optional audience ID. * @param brandGuidelinesEnabled indicates if the campaign is enabled for brand guidelines. */ private void runExample( GoogleAdsClient googleAdsClient, long customerId, Long audienceId, boolean brandGuidelinesEnabled) throws IOException { // Performance Max campaigns require that repeated assets such as headlines // and descriptions be created before the campaign. // For the list of required assets for a Performance Max campaign, see // https://developers<.googl>e.com/google-ads/api/docs/performance-max/assets // // Creates the headlin<es. > ListString headlines = ImmutableList.of("Travel", "Travel Reviews", "Book travel"); ListString headlineAssetR<esourc>eNames = createMultipleTextAssets(googleAdsClient, customerId, headlines)<; >// Creates the descriptions. ListString descriptions = ImmutableList.of("Take to the air!", "Fly to the sky!"); ListString descriptionAssetResourceNames = createMultipleTextAssets(googleAdsClient, customerId, descriptions); // The below methods create and return MutateOperations that we later // provide to the GoogleAdsService.Mutate method in order to create the // entities in a single request. Since the entities for a Performance Max // campaign are closely tied to one-another, it's considered a best practice // to create them in a single Mutate request, so they all complete < // successful>ly or fail entirely, leaving no o<>rphaned entities. See: // https://developers.google.com/google-ads/api/docs/mutating/overview ListMutateOperation mutateOperations = new ArrayList(); mutateOperations.add(createCampaignBudgetOperation(customerId)); mutateOperations.add(createPerformanceMaxCampaignOperation(customerId, brandGuidelinesEnabled)); mutateOperations.addAll(createCampaignCriterionOperations(customerId)); String assetGroupResourceName = ResourceNames.assetGroup(customerId, ASSET_GROUP_TEMPORARY_ID); mutateOperations.addAll( createAssetGroupOperations( customerId, assetGroupResourceName, headlineAssetResourceNames, descriptionAssetResourceNames, brandGuidelinesEnabled)); mutateOperations.addAll( createAssetGroupSignalOperations(customerId, assetGroupResourceName, audienceId)); try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { MutateGoogleAdsResponse response = googleAdsServiceClient.mutate(Long.toString(customerId), mutateOperations); printResponseDetails(response); } } /** Creates a MutateOperation that creates a new CampaignBudget. */ private MutateOperation createCampaignBudgetOperation(long customerId) { CampaignBudget campaignBudget = CampaignBudget.newBuilder() .setName("Performance Max campaign budget #" + getPrintableDateTime()) // The budget period already defaults to DAILY. .setAmountMicros(50_000_000) .setDeliveryMethod(BudgetDeliveryMethod.STANDARD) // A Performance Max campaign cannot use a shared campaign budget. .setExplicitlyShared(false) // Set a temporary ID in the budget's resource name, so it can be referenced // by the campaign in later steps. .setResourceName(ResourceNames.campaignBudget(customerId, BUDGET_TEMPORARY_ID)) .build(); return MutateOperation.newBuilder() .setCampaignBudgetOperation( CampaignBudgetOperation.newBuilder().setCreate(campaignBudget).build()) .build(); } /** Creates a MutateOperation that creates a new Performance Max campaign. */ private MutateOperation createPerformanceMaxCampaignOperation( long customerId, boolean brandGuidelinesEnabled) { Campaign performanceMaxCampaign = Campaign.newBuilder() .setName("Performance Max campaign #" + getPrintableDateTime()) // Sets the campaign status as PAUSED. The campaign is the only entity in // the mutate request that should have its status set. .setStatus(CampaignStatus.PAUSED) // All Performance Max campaigns have an advertising_channel_type of // PERFORMANCE_MAX. The advertising_channel_sub_type should not be set. .setAdvertisingChannelType(AdvertisingChannelType.PERFORMANCE_MAX) // Bidding strategy must be set directly on the campaign. // Setting a portfolio bidding strategy by resource name is not supported. // Max Conversion and Maximize Conversion Value are the only strategies // supported for Performance Max 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 targetRoas of 3.5 corresponds to a 350% return on ad spend. .setMaximizeConversionValue( MaximizeConversionValue.newBuilder().setTargetRoas(3.5).build()) // Sets if the campaign is enabled for brand guidelines. For more information on brand // guidelines, see https://support.google.com/google-ads/answer/14934472. .setBrandGuidelinesEnabled(brandGuidelinesEnabled) // Assigns the resource name with a temporary ID. .setResourceName( ResourceNames.campaign(customerId, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID)) // Sets the budget using the given budget resource name. .setCampaignBudget(ResourceNames.campaignBudget(customerId, BUDGET_TEMPORARY_ID)) // Declares whether this campaign serves political ads targeting the EU. .setContainsEuPoliticalAdvertising(DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING) // Optional fields. .setStartDate(new DateTime().plusDays(1).toString("yyyyMMdd")) .setEndDate(new DateTime().plusDays(365).toString("yyyyMMdd")) // Configures the optional opt-in/out status for asset automation settings. .addAllAssetAutomationSettings(ImmutableList.of( AssetAutomationSetting.newBuilder() .setAssetAutomationType(AssetAutomationType.GENERATE_IMAGE_EXTRACTION) .setAssetAutomationStatus(AssetAutomationStatus.OPTED_IN).build(), AssetAutomationSetting.newBuilder() .setAssetAutomationType( AssetAutomationType.FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION) .setAssetAutomationStatus(AssetAutomationStatus.OPTED_IN).build(), AssetAutomationSetting.newBuilder() .setAssetAutomationType(AssetAutomationType.TEXT_ASSET_AUTOMATION) .setAssetAutomationStatus(AssetAutomationStatus.OPTED_IN).build(), AssetAutomationSetting.newBuilder() .setAssetAutomationType(AssetAutomationType.GENERATE_ENHANCED_YOUTUBE_VIDEOS) .setAssetAutomationStatus(AssetAutomationStatus.OPTED_IN).build(), AssetAutomationSetting.newBuilder() .setAssetAutomationType(AssetAutomationType.GENERATE_IMAGE_ENHANCEMENT) .setAssetAutomationStatus(AssetAutomationStatus.OPTED_IN).build())) .build(); return MutateOperation.newBuilder() .setCamp<aignOperation( > CampaignOperation.newBuilder().setCreate(performanceMaxCampaign).build()) .build(); } /** Creates a list of MutateOperations that create new campaign cri<teria. */ priva>te ListMutateOperation createCamp<>aignCriterionOperations(long customerId) { String campaignResourceName = ResourceNames.campaign(customerId, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID); ListCampaignCriterion campaignCriteria = new ArrayList(); // Sets the LOCATION campaign criteria. // Targets all of New York City except Brooklyn. // Location IDs are listed here: // https://developers.google.com/google-ads/api/reference/data/geotargets // and they can also be retrieved using the GeoTargetConstantService as shown // here: https://developers.google.com/google-ads/api/docs/targeting/location-targeting // // We will add one positive location target for New York City (ID=1023191) // and one negative location target for Brooklyn (ID=1022762). // First, adds the positive (negative = False) for New York City. campaignCriteria.add( CampaignCriterion.newBuilder() .setCampaign(campaignResourceName) .setLocation( LocationInfo.newBuilder() .setGeoTargetConstant(ResourceNames.geoTargetConstant(1023191)) .build()) .setNegative(false) .build()); // Next adds the negative target for Brooklyn. campaignCriteria.add( CampaignCriterion.newBuilder() .setCampaign(campaignResourceName) .setLocation( LocationInfo.newBuilder() .setGeoTargetConstant(ResourceNames.geoTargetConstant(1022762)) .build()) .setNegative(true) .build()); // Sets the LANGUAGE campaign criterion. campaignCriteria.add( CampaignCriterion.newBuilder() .setCampaign(campaignResourceName) // Sets the language. // For a list of all language codes, see: // https://developers.google.com/google-ads/api/reference/data/codes-formats#expandable-7 .setLanguage( LanguageInfo.newBuilder() .setLanguageConstant(ResourceNames.languageConstant(1000>)) // English .build()) .build()); // Returns a list of mutate operations with one operation per criterion. return campaignCriteria.stream() .map( criterion - MutateOperation.newBuilder() .setCampaignCriterionOperation( CampaignCriterionOp<eratio>n.newBuilder().setCreate(criterion).build()) .build()) .col<lect(C>ollectors.toList()<); } /** >Creates multiple text assets and <>returns the list of resource names. */ private ListString createMultipleTextAssets( GoogleAdsClient googleAdsClient, long customerId, ListString texts) { ListMutateOperation mutateOperations = new ArrayList(); for (String text : texts) { Asset asset = Asset.newBuilder().setTextAsset(TextAsset.newBuilder().setText(text)<).buil>d(); AssetOperation assetOper<>ation = AssetOperation.newBuilder().setCreate(asset).build(); mutateOperations.add(MutateOperation.newBuilder().setAssetOperation(assetOperation).build()); } ListString assetResourceNames = new ArrayList(); // Creates the service client. try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { // Sends the operations in a single Mutate request. MutateGoogleAdsResponse response = googleAdsServiceClient.mutate(Long.toString(customerId), mutateOperations); for (MutateOperationResponse result : response.getMutateOperationResponsesList()) { if (result.hasAssetResult()) { assetResourceNames.add(result.getAss<etResult().getR>esourceName()); } } printResponseDetails(response); } return assetResou<rceNam>es; } /** Creates a list of Mutat<eOpera>tions that create a new AssetGroup. */ private ListMutateOperation createAssetGroupOperations( lo<ng customerId, > String assetGroupResourceNa<>me, ListString headlineAssetResourceNames, ListString descriptionAssetResourceNames, boolean brandGuidelinesEnabled) throws IOException { ListMutateOperation mutateOperations = new ArrayList(); String campaignResourceName = ResourceNames.campaign(customerId, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID); // Creates the AssetGroup. AssetGroup assetGroup = AssetGroup.newBuilder() .setName("Performance Max asset group #" + getPrintableDateTime()) .setCampaign(campaignResourceName) .addFinalUrls("http://www.example.com") .addFinalMobileUrls("http://www.example.com") .setStatus(AssetGroupStatus.PAUSED) .setResourceName(assetGroupResourceName) .build(); AssetGroupOperation assetGroupOperation = AssetGroupOperation.newBuilder().setCreate(assetGroup).build(); mutateOperations.add( MutateOperation.newBuilder().setAssetGroupOperation(assetGroupOperation).build()); // For the list of required assets for a Performance Max campaign, see // https://developers.google.com/google-ads/api/docs/performance-max/assets // An AssetGroup is linked to an Asset by creating a new AssetGroupAsset // and providing: // the resource name of the AssetGroup // the resource name of the Asset // the field_type of the Asset in this AssetGroup. // To learn more about AssetGroups, see // https://developers.google.com/google-ads/api/docs/performance-max/asset-groups // Links the previously created multiple text assets. // Links the headline assets. for (String resourceName : headlineAssetResourceNames) { mutateOperations.add( createAssetGroupAssetMutateOperation( AssetFieldType.HEADLINE, resourceName, assetGroupResourceName)); } // Links the description assets. for (String resourceName : descriptionAs<setResourceName>s) { mutateOperations.add( createAssetGroupAssetMutateOperation( AssetFieldType.DESCRIPTION, resourceName, assetGroupResourceName)); } // Creates and links the long headline text asset. ListMutateOperation createAndLink<TextAssetOperat>ions = createAndLinkTextAsset(customerId, "Travel the World", AssetFieldType.LONG_HEADLINE); mutateOperations.addAll(createAndLinkTextAssetOperations); // Creates and links the business name and logo assets. ListMutateOperation createAndLinkBrandAssets = createAndLinkBrandAssets( customerId, brandGuidelinesEnabled, "Interplanetary Cruises", "https://gaagl.page.link/bjYi", "Marketing Logo"); mutateOperations.addAll(createAndLinkBrandAssets); // Creates and links the image assets. // Creates and links the Marketing Image Asset. createAndLinkTextAssetOperations = createAndLinkImageAsset( customerId, "https://gaagl.page.link/Eit5", AssetFieldType.MARKETING_IMAGE, "Marketing Image"); mutateOperations.addAll(createAndLinkTextAssetOperations); // Creates and links the Square Marketing Image Asset. createAndLinkTextAssetOperations = createAndLinkImageAsset( customerId, <"https://g>aagl.page.link/bjYi", AssetFieldType.SQUARE_MARKETING_IMAGE, "Square< Marketing Imag>e"); mutateOperations.ad<>dAll(createAndLinkTextAssetOperations); return mutateOperations; } /** Creates a list of MutateOperations that create a new linked text asset. */ ListMutateOperation createAndLinkTextAsset( long customerId, String text, AssetFieldType assetFieldType) { ListMutateOperation mutateOperations = new ArrayList(); String assetResourceName = ResourceNames.asset(customerId, getNextTemporaryId()); // Creates the Text Asset. Asset asset = Asset.newBuilder() .setResourceName(assetResourceName) .setTextAsset(TextAsset.newBuilder().setText(text).build()) .build(); AssetOperation assetOperation = AssetOperation.newBuilder().setCreate(asset).build(); mutateOperations.add(MutateOperation.newBuilder().setAssetOperation(assetOperation).build()); // Creates an AssetGroupAsset to link the Asset to the AssetGroup. m<utateOperations>.add( createAssetGroupAssetMutateOperation( assetFieldType, assetResourceName, ResourceNames.assetGro<up(customerId, >ASSET_GROUP_TEMPORARY_ID))); <> return mutateOperations; } /** Creates a list of MutateOperations that create a new linked image asset. */ ListMutateOperation createAndLinkImageAsset( long customerId, String url, AssetFieldType assetFieldType, String assetName) throws IOException { ListMutateOperation mutateOperations = new ArrayList(); String assetResourceName = ResourceNames.asset(customerId, getNextTemporaryId()); // Creates a media file. byte[] assetBytes = ByteStreams.toByteArray(new URL(url).openStream()); // Creates the Image Asset. Asset asset = Asset.newBuilder() .setResourceName(assetResourceName) .setImageAsset(ImageAsset.newBuilder().setData(ByteString.copyFrom(assetBytes)).build()) // Provides a unique friendly name to identify your asset. When there is an existing // image asset with the same content but a different name, the new name will be dropped // silently. .setName(assetName) .build(); AssetOperation assetOperation = AssetOperation.newBuilder().setCreate(asset).build(); mutateOperations.add(MutateOperation.newBuilder().setAssetOperation(assetOperation).build()); // Creates an AssetGroupAsset to link the Asset to the AssetGroup.< mutateOper>ations.add( createAssetGroupAssetMutateOperation( assetFieldType, assetResourceName, ResourceNames.assetGroup(customerId, ASSET_GROUP_TEMPORARY_ID))); < return mut>ateOperations; } /** Creates<> a list of MutateOperations that create linked brand assets. */ ListMutateOperation createAndLinkBrandAssets( long customerId, boolean brandGuidelinesEnabled, String businessName, String logoUrl, String logoName) throws IOException { ListMutateOperation mutateOperations = new ArrayList(); // Creates the brand name text asset. String businessNameAssetResourceName = ResourceNames.asset(customerId, getNextTemporaryId()); Asset businessNameAsset = Asset.newBuilder() .setResourceName(businessNameAssetResourceName) .setTextAsset(TextAsset.newBuilder().setText(businessName).build()) .build(); AssetOperation businessNameAssetOperation = AssetOperation.newBuilder().setCreate(businessNameAsset).build(); mutateOperations.add( MutateOperation.newBuilder().setAssetOperation(businessNameAssetOperation).build()); // Creates the logo image asset. String logoAssetResourceName = ResourceNames.asset(customerId, getNextTemporaryId()); // Creates a media file. byte[] logoBytes = ByteStreams.toByteArray(new URL(logoUrl).openStream()); Asset logoAsset = Asset.newBuilder() .setResourceName(logoAssetResourceName) .setImageAsset(ImageAsset.newBuilder().setData(ByteString.copyFrom(logoBytes)).build()) // Provides a unique friendly name to identify your asset. When there is an existing // image asset with the same content but a different name, the new name will be dropped // silently. .setName(logoName) .build(); AssetOperation logoImageAssetOperation = AssetOperation.newBuilder().setCreate(logoAsset).build(); mutateOperations.add( MutateOperation.newBuilder().setAssetOperation(logoImageAssetOperation).build()); if (brandGuidelinesEnabled) { // Creates CampaignAsset resources to link the Asset resources to the Campaign. mutateOperations.add( createCampaignAssetMutateOperation( customerId, AssetFieldType.BUSINESS_NAME, businessNameAssetResourceName)); mutateOperations.add( createCampaignAssetMutateOperation( customerId, AssetFieldType.LOGO, logoAssetResourceName)); } else { // Creates an AssetGroupAsset to link the Asset to the AssetGroup. mutateOperations.add( createAssetGroupAssetMutateOperation( AssetFieldType.BUSINESS_NAME, businessNameAssetResourceName, ResourceNames.assetGroup(customerId, ASSET_GROUP_TEMPORARY_ID))); mutateOperations.add( createAssetGroupAssetMutateOperation( AssetFieldType.LOGO, logoAssetResourceName, ResourceNames.assetGroup(customerId, ASSET_GROUP_TEMPORARY_ID))); } return mutateOperations; } /** Creates a MutateOperation to add an AssetGroupAsset. */ MutateOperation createAssetGroupAssetMutateOperation( AssetFieldType fieldType, String assetResourceName, String assetGroupResourceName) { AssetGroupAsset assetGroupAsset = AssetGroupAsset.newBuilder() .setFieldType(fieldType) .setAssetGroup(assetGroupResourceName) .setAsset(assetResourceName) .build(); AssetGroupAssetOperation assetGroupAssetOperation = AssetGroupAssetOperation.newBuilder().setCreate(assetGroupAsset).build(); return MutateOperation.newBuilder() .setAssetGroupAssetOperation(assetGroupAssetOperation) .build(); } /** Creates a MutateOperation to add a CampaignAsset. */ MutateOperation createCampaignAssetMutateOperation( long customerId, AssetFieldType fieldType, String assetResourceName) { CampaignAsset campaignAsset = CampaignAsset.newBuilder() .setFieldType(fieldType) .setCampaign(ResourceNames.campaign(customerId, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID)) .setAsset(assetResourceName) .build(); CampaignAssetOperation campaignAssetOperation = Cam<paignAssetOpera>tion.newBuilder().setCreate(campaignAsset).build(); return MutateOperation.newBuilder().setCampaignAssetOperatio<n(campaignAsset>Operation).build(); } /** <> * Creates a list of MutateOperations that create {@link * com.google.ads.googleads.v22.resources.AssetGroupSignal} objects. */ private ListMutateOperation createAssetGroupSignalOperations( long customerId, String assetGroupResourceName, Long audienceId) { ListMutateOperation mutateOperations = new ArrayList(); if (audienceId != null) { // Creates an audience asset group signal. // To learn more about Audience Signals, see: // https://developers.google.com/google-ads/api/performance-max/asset-group-signals#audiences AssetGroupSignal audienceSignal = AssetGroupSignal.newBuilder() .setAssetGroup(assetGroupResourceName) .setAudience( AudienceInfo.newBuilder() .setAudience(ResourceNames.audience(customerId, audienceId))) .build(); mutateOperations.add( MutateOperation.newBuilder() .setAssetGroupSignalOperation( AssetGroupSignalOperation.newBuilder().setCreate(audienceSignal)) .build()); } // Creates a search theme asset group signal. // To learn more about Search Themes Signals, see: // https://developers.google.com/google-ads/api/performance-max/asset-group-signals#search_themes AssetGroupSignal searchThemeSignal = AssetGroupSignal.newBuilder() .setAssetGroup(assetGroupResourceName) .setSearchTheme(SearchThemeInfo.newBuilder().setText("travel").build()) < > .build(); mutateOperations.add( MutateOperation.newBuilder() .setAssetGroupSignalOperation( AssetGroupSignalOperation.newBuilder().setCreate(searchThemeSignal)) .build()); return mutateOperations; } /** * Prints the details of a MutateGoogleAdsResponse. * * pParses the "response" oneof field name and uses it to extract the new entity's n<ame and * resource n>ame. */ private void printResponseDetails(MutateGoogleAdsResponse response) { // Parses the Mutate response to print details about the entities that were created by the // request. String suffix = "_result"; for (MutateOperationResponse result : response.getMutateOperationResponsesList()) { for (EntryFieldDescriptor, Object responseFields : result.getAllFields().entrySet()) { String fieldName = responseFields.getKey().getName(); String value = responseFields.getValue().toString().trim(); uffix)) { fieldName = fieldName.substring(0, fieldName.length() - suffix.length()); } System.out.printf("Created a(n) %s with %s.%n", fieldName, value); } } } /** Returns the next temporary ID and decreases it by one. */ private long getNextTemporaryId() { return temporaryId--; } } AddPerformanceMaxCampaign.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 // // 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.Gax.Util; using Google.Ads.GoogleAds.Config; 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 Google.Protobuf; using System; using System.Collections.Generic; using System.Threading; using static Google.Ads.GoogleAds.V22.Enums.AdvertisingChannelTypeEnum.Types; using static Google.Ads.GoogleAds.V22.Enums.AssetAutomationStatusEnum.Types; using static Google.Ads.GoogleAds.V22.Enums.AssetAutomationTypeEnum.Types; using static Google.Ads.GoogleAds.V22.Enums.AssetFieldTypeEnum.Types; using static Google.Ads.GoogleAds.V22.Enums.AssetGroupStatusEnum.Types; using static Google.Ads.GoogleAds.V22.Enums.CampaignStatusEnum.Types; using static Google.Ads.GoogleAds.V22.Enums.EuPoliticalAdvertisingStatusEnum.Types; namespace Google.Ads.GoogleAds.Exa<mples.V>22 { /// summary /// This example shows how to create a Performance Max campaign. /// /// For more information about Performance Max campaigns, see /// https://developers.google.com/google-ads/api/docs/performance-max/overview /// /// Prerequisites: /// - You must have at least one conversion action in the account. For /// more about conversion actions, see /// https://developers.google.com/google-ads/api/docs/conversions/overview#conversion_actions /// /// This example uses the default customer conversion goals. For an example /// of setting campaign-specific conversion goals, see /// ShoppingAds/AddPerformanceMaxRetail<Campaign>.cs /// /summary public class AddPerformanceMaxCampaign : ExampleBas<e {> /// summary /// Command line opti<ons for running the see cref="Ad>dPerformanceMaxCampaig<n"/> example. /// /summary public class Options : OptionsB<ase > { /// summary /// The Google Ads< custome>r ID. /// /summary [Option("customerId", Required = true, HelpText = "The Google Ads customer ID.")] publ<ic long> CustomerId { get; set; } /// summary /// Optional: An audience ID to use to improve the targeting of the Performa<nce Max<>/span> /// campaign. /// /summary [Option("audienceId", Required = false, HelpText = "The ID of an audience."<)] > public long? AudienceId { get; set; } /// summary /// Optional: A boolean value indicating if the camp<aign is >enabled for brand /// guidelines. /// /summary [Option("brandGuidelinesEnabled", Required = false, HelpText = "A boolean value indicating if the campaign is enabled for brand guidelines.&qu<ot;)] > public bool BrandGuidelinesEnabled { get; set; } } /// summary < />// Main metho<d, to run this co>de example as a standalone <applic>ation. /// /summary /// param name="args"The command line arguments./param public stati<c void >Main(string[] args) { Options options = ExampleUtilities.ParseCommandLineOptions(args); AddPerformanceMaxCampaign codeExample = new AddPerformanceMaxCampaign(); Console.WriteLine(codeExample.Description); codeExample.Run( new GoogleAdsClient(), options.CustomerId, options.AudienceId, options.BrandGuidelinesEnabled ); } // We specify temporary IDs that are specific to a single mutate request. Temporary IDs are // always negative and unique within one mutate request. // // See https://developers.google.com/google-ads/api/docs/mutating/best-practices for further // details. // // These temporary IDs are fixed because they are used in multiple places. private const int TEMPORARY_ID_BUDGET = -1; private const int TEMPORARY_ID_CAMPAIGN = -2; private const int TEMPORARY_ID_ASSET_GROUP = -3; // There are also entities that will be created in the same request but do not need to be // fixed temporary IDs because they are referenced only once. private class AssetTemporaryResourceNameGenerator { private long customerId; private long next; public AssetTemporaryResourceNameGenerator(long customerId, long assetGroupId) { this.customerId = customerId; this.next = assetGroupId - 1; } public string Next() { long i = next; Interlocked.Decrement(ref nex<t); > return ResourceNames.Asset(customerId, i); } < }> /// summary /// Returns a d>escription about the code example. /// /summary public override string Des<criptio>n = "This example shows how to <create a> Performance <Max campaign.">; /// summary< > /// Runs t<he code example. > /// /summary /// <param >name="cl<ient"The Google Ad>s client./param /<// par>am name="<;customerId"The Google Ads cus>tomer ID./param /// param name=&qu<ot;aud>ienceId"The optional audience ID./param /// param name="brandGuidelinesEnabled"Whether or not to enable brand guidelines./param public void Run(GoogleAdsClient client, long customerId, long? audienceId, bool brandGuidelinesEnabled) { try { GoogleAdsServiceClient googleAdsServiceClient = client.GetService(Services.V22.GoogleAdsService); // Performance Max campaigns require that repeated assets such as headlines and // descriptions be created before the campaign. // // For the list of required assets for a Performance Max campaign, see // htt<ps://d>evelopers.google.com/google-ads/api/docs/performance-max/assets // // Create the headlines. Liststring headlineAssetResourceNames = CreateMultipleTextAssets( client, customerId, new[] { "Travel", < &quo>t;Travel Reviews", "Book travel" } ); // Create the descriptions. Liststring descriptionAssetResourceNames = CreateMultipleTextAssets( client, customerId, new[] { "Take to the air!", "Fly to the sky!" } ); string tempResourceNameCampaignBudget = ResourceNames.CampaignBudget( customerId, TEMPORARY_ID_BUDGET ); // The below methods create and return MutateOperations that we later provide to // the GoogleAdsService.Mutate method in order to create the entities in a single // request. Since the entities for a Performance Max campaign are closely tied to // one-another, it is considered a best practice to create them in a single Mutate // request so they all complete successfully or fail entirely, leaving no // orphaned entities. // // See: https://developers.google.com/google-ads/api/docs/mutating/overview MutateOperation campaignBudgetOperation = CreateCampaignBudgetOperation( tempResourceNameCampaignBudget ); string tempResourceNameCampaign = ResourceNames.Campaign( customerId, TEMPORARY_ID_CAMPAIGN ); MutateOperation performanceMaxCampaignOperation = CreatePerformanceMaxCampaignOperatio<n( > tempResourceNameCampaign, tempResourceNameCampaignBudget, brandGuidelines<Enabled > ); ListMutateOperation campaignCriterionOperations = CreateCampaignCriterionOperations(tempResourceNameCampaign); ListMutateOperation assetGroupOperations = CreateAssetGroupOperations( tempResourceNameCampaign, ResourceNames.AssetGroup(customerId, TEMPORARY_ID_ASSET_GROUP), headlineAssetResourceNames, descriptionAssetResourceNames, new AssetTemporaryResourceNameGenerator( customerId, < > TEMPORARY_ID_ASSET_GROUP ), client.Config, brandGuidelinesEnabled ); ListMutateOperation assetGroupSignalOperations = CreateAssetGroupSignalOperations( customerId, ResourceNames.AssetGroup(customerId, TEMPORARY_ID_ASSET_GROUP), audienceId ); MutateGoogleAdsRequest request = new MutateGoogleAdsRequest { CustomerId = customerId.ToString() }; // It's important to create these entities in this order because they depend on // each other. // // Additionally, we take several lists of operations and flatten them into one // large list. request.MutateOperations.Add(campaignBudgetOperation); request.MutateOperations.Add(performanceMaxCampaignOperation); request.MutateOperations.AddRange(campaignCriterionOperations); request.MutateOperations.AddRange(assetGroupOperations); request.MutateOperations.AddRange(assetGroupSignalOperations); MutateGoogleAdsResponse response = googleAdsServiceClient.Mutate(request); PrintResponseDetails(response); } catch (GoogleAdsException e) { Console.WriteLine("Failure:"); Console.WriteLi<ne($&qu>ot;Message: {e.Message}"); Console.WriteLine($"Failure: {e.Failure}"); Console.WriteLine($"Request ID: {e.RequestId}"); throw; } } /// summary /// Creates a< MutateO>peration that< creates a new CampaignBudget.<>/span> /// /// A temporary ID will be assigned to this <campai>gn budget so <that it> can be /// referenced by other objects <being cr>eated in the same Mutate request. /// /summary /// param name="budgetResourceName"The temporary resource name of the budget to /// create./param /// returnsA MutateOperation that creates a CampaignBudget./returns private MutateOperation CreateCampaignBudgetOperation(string budgetResourceName) { MutateOperation operation = new MutateOperation { CampaignBudgetOperation = new CampaignBudgetOperation { Create = new CampaignBudget { Name = "Performance Max campaign budget #" + ExampleUtilities.GetRandomString(), // The budget period already defaults to DAILY. AmountMicros = 50000000, // A Performance Max campaign cannot use a shared campaign budget. ExplicitlyShared = false, // Set a temporary ID in the budget's resource name so it can be referenced // by the campaign< in later steps. > ResourceName = budg<etReso>urceName < } } > }; return op<eratio>n; } < /// Creates a MutateOpera>tion that creates a new Performance Max ca<mpaign>. ///< param >name="campaignResourceName"The campaign reso<urce nam>e./param /// param name="campaignBudgetResourceName"The campaign budget resource name./param /// param name="brandGuidelinesEnabled"Whether or not to enable brand guidelines./param /// returnsA MutateOperations that will create this new campaign./returns private MutateOperation CreatePerformanceMaxCampaignOperation( string campaignResourceName, string campaignBudgetResourceName, bool brandGuidelinesEnabled) { Campaign campaign = new Campaign() { Name = "Performance Max campaign #" + ExampleUtilities.GetRandomString(), // Set the campaign status as PAUSED. The campaign is the only entity in // the mutate request that should have its status set. Status = CampaignStatus.Paused, // All Performance Max campaigns have an AdvertisingChannelType of // PerformanceMax. The AdvertisingChannelSubType should not be set. AdvertisingChannelType = AdvertisingChannelType.PerformanceMax, // Bidding strategy must be set directly on the campaign. Setting a // portfolio bidding strategy by resource name is not supported. Max // Conversion and Maximize Conversion Value are the only strategies // supported for Performance Max campaigns. BiddingStrategyType is // read-only and cannot be set by the API. An optional ROAS (Return on // Advertising Spend) can be set to enable the MaximizeConversionValue // bidding strategy. 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. MaximizeConversionValue = new MaximizeConversionValue() { TargetRoas = 3.5 }, // Use the temporary resource name created earlier ResourceName = campaignResourceName, // Set the budget using the given budget resource name. CampaignBudget = campaignBudgetResourceName, // Set if the campaign is enabled for brand guidelines. For more information // on brand guidelines, see https://support.google.com/google-ads/answer/14934472. BrandGuidelinesEnabled = brandGuidelinesEnabled, // Declare whether or not this campaign contains political ads targeting the EU. ContainsEuPoliticalAdvertising = EuPoliticalAdvertisingStatus.DoesNotContainEuPoliticalAdvertising, // Optional fields StartDate = DateTime.Now.AddDays(1).ToString("yyyyMMdd"), EndDate = DateTime.Now.AddDays(365).ToString("yyyyMMdd") }; campaign.AssetAutomationSettings.AddRange(new[]{ new Campaign.Types.AssetAutomationSetting { AssetAutomationType = AssetAutomationType.GenerateImageExtraction, AssetAutomationStatus = AssetAutomationStatus.OptedIn }, new Campaign.Types.AssetAutomationSetting { AssetAutomationType = AssetAutomationType.FinalUrlExpansionTextAssetAutomation, AssetAutomationStatus = AssetAutomationStatus.OptedIn }, new Campaign.Types.AssetAutomationSetting { AssetAutomationType = AssetAutomationType.TextAssetAutomation, AssetAutomationStatus = AssetAutomationStatus.OptedIn }, new Campaign.Types.AssetAutomationSetting { AssetAutomationType = AssetAutomationType.GenerateEnhancedYoutubeVideos, AssetAutomationStatus = AssetAutomationStatus.OptedIn }, new Campaign.Types.AssetAutomationSetting { AssetAutomationType = AssetAutomationType.GenerateImageEnhancement, AssetAutomationStatus <= Asset>AutomationStatus.OptedIn }, }); MutateOperation operat<ion = ne>w MutateOpera<tion() { > CampaignOperation = new< Campa>ignOperation(<) > { Create = campaign < } > }; < return o>peration; } /// summary /// Creates a list of MutateOperations that create ne<w campaign crit>eria. /// /sum<mary //>/ param name="campaignResourceName"The campaign resource name./param /// returnsA list of MutateOperations that create new campaign criteria./returns private ListMutateOperation CreateCampaignCriterionOperations( string campaignResourceName) { ListMutateOperation operations = new ListMutateOperation(); // Set the LOCATION campaign criteria. // Target all of New York City except Brooklyn. // Location IDs are listed here: // https://developers.google.com/google-ads/api/reference/data/geotargets // and they can also be retrieved using the GeoTargetConstantService as shown // here: https://developers.google.com/google-ads/api/docs/targeting/location-targeting // // We will add one positive location target for New York City (ID=1023191) // and one negative location target for Brooklyn (ID=1022762). // First, add the positive (negative = False) for New York City. MutateOperation operation1 = new MutateOperation() { CampaignCriterionOperation = new CampaignCriterionOperation() { Create = new CampaignCriterion() { Campaign = campaignResourceName, Location = new LocationInfo() { GeoTargetConstant = ResourceNames.GeoTargetConstant(1023191) }, Negative = false } } }; operations.Add(operation1); // Next add the negative target for Brooklyn. MutateOperation operation2 = new MutateOperation() { CampaignCriterionOperation = new CampaignCriterionOperation() { Create = new CampaignCriterion() { Campaign = campaignResourceName, Location = new LocationInfo() { GeoTargetConstant = ResourceNames.GeoTargetConstant(1022762) }, Negative = true } } }; operations.Add(operation2); // Set the LANGUAGE campaign criterion. MutateOperation operation3 = new MutateOperation() { CampaignCriterionOperation = new CampaignCriterionOperation() { Create = new CampaignCriterion() { Campaign = campaignResourceName, // Set the language. // For a list of all language codes, see: // https://developers.google.com/google-ads/api/reference/data/codes-formats#expandabl<e-7 > Language = new LanguageInfo() { < > LanguageCo<nstant = ResourceNa>mes.LanguageConstant(1<000) />/ English < },> < } > < } };> ope<ration>s.Add(operati<on3); > return operations; < >} /// summa<ry > /// Creates multiple text assets and returns the list of resource names. /// /summary /// param name="client"The Google Ads Client./param /// param name="customerId"The customer's ID./param /// param name="texts"The texts to add./param /// returnsA list of asset resource names./returns private Liststring CreateMultipleTextAssets( GoogleAdsClient client, long customerId, string[] texts) { // Get the GoogleAdsService. GoogleAdsServiceClient googleAdsServiceClient = client.GetService(Services.V22.GoogleAdsService); MutateGoogleAdsRequest request = new MutateGoogleAdsRequest() { CustomerId = customerId.ToString() }; foreach (string text in texts) { request.MutateOperations.Add( new MutateOperation() { AssetOperation = new AssetOperation() { Create = new Asset() { TextAsset = new TextAsset() < > { < > Text = text } } } } ); } // Send the operations in a single Mutate request. MutateGoogleAdsResponse response = googleAdsServiceClient.Mutate(request); Liststring assetResourceNames = new Listst<ring();> foreach (MutateOperationResponse operationResponse in response.MutateOperatio<nRespons>es) < { MutateAssetR>esult assetResult = operati<onResp>onse.AssetRes<ult; assetResourceN>ames.Add(assetResult.ResourceN<ame); > }< PrintResponseDetails(resp>onse); return assetRe<source>Names; < } /// summary /// Crea>tes a list of MutateOperations that create a new <asset_>group. < /// /summary /// param n>ame="campaignResourceName"Th<e camp>aign resource< name./param > /// param name="<;asset>GroupResource<Name"The asset group resource >name./param /// param name="h<eadlin>eAssetResourc<eNames&>quot;The headline asset resource names./param /// p<aram nam>e="descriptionAs<setResourceName>s"The description asset resource /// names./param /// param name="resourceNameGenerator"A generato<r for >unique temporary ID's./param /// <param >name="config"The Google Ads config./param /// param name="brandGuidelinesEnabled"Whether or not to enable brand guidelines./param /// returnsA list of MutateOperations th<at create the n>ew asset group./return<s priva>te ListMutateOperation CreateAssetGroupOperations( string campaignResourceName, string assetGroupResourceName, Liststring headlineAssetResourceNames, Liststring descriptionAssetResourceNames, AssetTemporaryResourceNameGenerator resourceNameGenerator, GoogleAdsConfig config, bool brandGuidelinesEnabled) { ListMutateOperation operations = new ListMutateOperation(); // Create the AssetGroup operations.Add( new MutateOperation() { AssetGroupOperation = new AssetGroupOperation() { Create = new AssetGroup() { Name = "Performance Max asset group #" + ExampleUtilities.GetRandomString(), Campaign = campaignResourceName, FinalUrls = { "http://www.example.com" }, FinalMobileUrls = { "http://www.example.com" }, Status = AssetGroupStatus.Paused, ResourceName = assetGroupResourceName } } } ); // For the list of required assets for a Performance Max campaign, see // https://developers.google.com/google-ads/api/docs/performance-max/assets // An AssetGroup is linked to an Asset by creating a new AssetGroupAsset // and providing: // the resource name of the AssetGroup // the resource name of the Asset // the field_type of the Asset in this AssetGroup. // // To learn more about AssetGroups, see // https://developers.google.com/google-ads/api/docs/performance-max/asset-groups // Link the previously created multiple text assets. // Link the headline assets. foreach (string resourceName in headlineAssetResourceNames) { operations.Add( new MutateOperation() { AssetGroupAssetOperation = new AssetGroupAssetOperation() { Create = new AssetGroupAsset() { FieldType = AssetFieldType.Headline, AssetGroup = assetGroupResourceName, Asset = resourceName } } } ); } // Link the description assets. foreach (string resourceName in descriptionAssetResourceNames) { operations.Add( new MutateOperation() { AssetGroupAssetOperation = new AssetGroupAssetOperation() { Create = new AssetGroupAsset() { FieldType = AssetFieldType.Description, AssetGroup = assetGroupResourceName, Asset = resourceName } } } ); } // Create and link the brand assets. operations.AddRange( CreateAndLinkBrandAssets( assetGroupResourceName, campaignResourceName, resourceNameGenerator, "Interplanetary Cruises", "https://gaagl.page.link/bjYi", "Marketing Logo", config, brandGuidelinesEnabled ) ); // Create and link the long headline text asset. operations.AddRange( CreateAndLinkTextAsset( assetGroupResourceName, resourceNameGenerator.Next(), "Travel the World", AssetFieldType.LongHeadline ) ); // Create and link the image assets. // Create and link the Marketing Image Asset. operations.AddRange( CreateAndLinkImageAsset( assetGroupResourceName, resourceNameGenerator.Next(), "https://gaagl.page.link/Eit5", AssetFieldType.MarketingImage, "Marketing Image", < > config ) ); // Create and link the Square Marketing <Image As>set. < operations.AddRange( > CreateAndLinkImageAsset( assetGroupRe<source>Name, < resourceNameGener>ator.Next(), "https://gaagl.page.link</bjYi&>quot;, < Ass>etFieldType.SquareMarketingImage, < > &<quot;Square Marketing >Image", config < > ) < > ); return operations; } /// summ<ary > /// Creates a lis<t of MutateOper>ations that create a new linked text asset. /// /summary /// param name="assetGroupResourceName"The resource name of the asset group to be /// created./param < /// param >name="assetResour<ceName"The> resource name of the text asset to be /// created./param /// param name="text"The text of the asset to be created./param /// param name="fieldType"The field type of the asset to be created./param /// returnsA list of MutateOperations that create the new linked text asset./returns private ListMutateOperation CreateAndLinkTextAsset( string assetGroupResourceName, string assetResourceName, string text, AssetFieldType fieldType) { ListMutateOperation operations = new ListMutateOperation(); // Create the Text Asset. operations.Add( new MutateOperation() { AssetOperation = new AssetOperation() { Create = new Asset() { ResourceName = assetResourceName, TextAsset = new TextAsset() { Text = text } } } } ); // Create an AssetGrou<pAsset >to link the Asset to the AssetGroup. operations.Add( new MutateOperati<on() > <{ AssetGroupAss>etOperation = new AssetGroupAssetOperation() < { > < Create = new AssetGro>upAsset() { < Fiel>dType = field<Type, > AssetGroup = assetGroupResourceName, < > < Asset = assetReso>urceName } < > } < } > ); < r>eturn operati<ons; } > /// summary < //>/ Creates a l<ist of >MutateOperations that create a new linked image asset. /<// /summ>ary /// param< name="ass>etGroupResourceName"The resource name of the asset group to be /// created./param /// param name="assetResourceName"The resource name of the text asset to be /// created./param /// param name="url&<quot;The url of> the image to be retri<eved and put in>to an asset./param /// param name="fieldType"The field type of the asset to be created./param /// param name="assetName"The asset name./param /// param name="config"The Google Ads Config./param /// returnsA list of MutateOperations that create a new linked image asset./returns private ListMutateOperation CreateAndLinkImageAsset( string assetGroupResourceName, string assetResourceName, string url, AssetFieldType fieldType, string assetName, GoogleAdsConfig config) { ListMutateOperation operations = new ListMutateOperation(); // Create the Image Asset. operations.Add( new MutateOperation() { AssetOperation = new AssetOperation() { Create = new Asset() { ResourceName = assetResourceName, ImageAsset = new ImageAsset() { Data = ByteString.CopyFrom( MediaUtilities.GetAssetDataFromUrl(url, config) ) }, // Provide a unique friendly name to identify your asset. // When there is an existing image asset with the same content but a // different name, the new name will be dropped silently. Name = assetName } } < > } ); // Create an AssetGroupAsset to link the Asset to the AssetGroup. < > operations.<Add( new MutateOper>ation() { AssetGroupAssetOperat<ion = >new AssetGrou<pAssetOperation() > { Create = new AssetGroupAsset() < > < { FieldT>ype = fieldType, AssetGroup = assetGroup<Resour>ceName, < As>set = assetResourceName < } > < } > } ); return operations; < } > /// su<mmary /// Cre>ates a list of MutateOperat<ions t>hat create an<d link the brand as>sets. /// /sum<mary > /// pa<ram name="assetGroupResourceNa>me"The resource name of the asset gro<up to >link assets < >/// to./param /// param name="campaignResourceName&<quot;The> resource name of the< campaign to li>nk assets /// to./param /// param name="assetResourceNameGenerator"The resource name generator of the assets to be /// created./param /// param name="businessName"The business name text to be put into an asset./param /// param name="logoUrl"The url of the logo to be retrieved and put into an asset./param < /// param n>ame="logoName&quo<t;The asset nam>e of the logo./param /// param name="config"The Google Ads Config./param /// param name="brandGuidelinesEnabled"Whether or not to enable brand guidelines./param /// returnsA list of MutateOperations that create a new linked image asset./returns private ListMutateOperation CreateAndLinkBrandAssets( string assetGroupResourceName, string campaignResourceName, AssetTemporaryResourceNameGenerator assetResourceNameGenerator, string businessName, string logoUrl, string logoName, GoogleAdsConfig config, bool brandGuidelinesEnabled) { ListMutateOperation operations = new ListMutateOperation(); string logoAssetResourceName = assetResourceNameGenerator.Next(); string businessNameAssetResourceName = assetResourceNameGenerator.Next(); // Create the Image Asset. operations.Add( new MutateOperation() { AssetOperation = new AssetOperation() { Create = new Asset() { ResourceName = logoAssetResourceName, ImageAsset = new ImageAsset() { Data = ByteString.CopyFrom( MediaUtilities.GetAssetDataFromUrl(logoUrl, config) ) }, // Provide a unique friendly name to identify your asset. // When there is an existing image asset with the same content but a // different name, the new name will be dropped silently. Name = logoName } } } ); // Create the business name asset. operations.Add( new MutateOperation() { AssetOperation = new AssetOperation() { Create = new Asset() { ResourceName = businessNameAssetResourceName, TextAsset = new TextAsset() { Text = businessName, } } } } ); if (brandGuidelinesEnabled) { // Create CampaignAssets to link the Assets to the Campaign. operations.Add( new MutateOperation() { CampaignAssetOperation = new CampaignAssetOperation() { Create = new CampaignAsset() { FieldType = AssetFieldType.Logo, Campaign = campaignResourceName, Asset = logoAssetResourceName } } } ); operations.Add( new MutateOperation() { CampaignAssetOperation = new CampaignAssetOperation() { Create = new CampaignAsset() { FieldType = AssetFieldType.BusinessName, Campaign = campaignResourceName, Asset = businessNameAssetResourceName } } } ); } else { // Create AssetGroupAssets to link the Assets to the AssetGroup. operations.Add( new MutateOperation() { AssetGroupAssetOperation = new AssetGroupAssetOperation() { Create = new AssetGroupAsset() { FieldType = AssetFieldType.Logo, AssetGroup = assetGroupResourceName, Asset = logoAssetResourceName < > } } } ); op<erations>.Add( < new Mutate>Operation() < > { < AssetGroupAs>setOperation = new AssetGroupAssetOperation() < > { < Creat>e = new AssetGroupAsset()< > < > { FieldType = AssetFieldType.Busi<nessName>, < As>setGroup = assetGroupResourceName, Asset = businessNameAssetResourceName } } < > } )<; >} return operations; } /// summary /// Creates a list of MutateOperations that may create AssetGroupSignals /// /summary /// param name="customerId"The customer ID./param /// param name="assetGroupResourceName"The resource name of the asset group to be /// created./param /// param name="audienceId"The optional audience ID./param /// returnsA list of MutateOperations that create may create AssetGroupSignals./returns private ListMutateOperation CreateAssetGroupSignalOperations( long customerId, string assetGroupResourceName, long? audienceId) { ListMutateOperation operations = new ListMutateOperation(); if (audienceId.HasValue) { // Create an audience asset group signal. // To learn more about Audience Signals, see // https://developers.google.com/google-ads/api/docs/performance-max/asset-groups#audience_signals operations.Add( new MutateOperation() { AssetGroupSignalOperation = new AssetGroupSignalOperation() { Create = new AssetGroupSignal() { AssetGroup = assetGroupResourceName, Audience = new AudienceInfo() { Audience = ResourceNames.Audience(customerId, audienceId.Value) } } } } ); } // Create a search theme asset group signal. // To learn more< about >Search Themes Signals, see: // https://developers.google.com/google-ads/api/performance-max/asset-group-signals#search_themes operations.Add( new Mut<ateOpera>tion() < { > AssetGroupSignalOperatio<n = ne>w AssetGroupSignalOperation() { Create = new AssetGroupSignal() { AssetGroup = assetGroupResourceName, SearchTheme = new SearchThemeInfo() { Text = "travel" } } } } ); return operations; } /// summary /// Prints the details of a MutateGoogleAdsResponse. Parses the "response" oneof field name /// and uses it to extract the new entity's name and resource name. /// /summary /// param name="response"A MutateGoogleAdsResponse instance./param private void PrintResponseDetails(MutateGoogleAdsResponse response) { // Parse the Mutate response to print details about the entities that were created // in the request. foreach (MutateOperationResponse operationResponse in response.MutateOperationResponses) { string entityName = operationResponse.ResponseCase.ToString(); // Trim the substring "Result" from the end of the entity name. entityName = entityName.Remove(entityName.Length - 6); string resourceName; switch (operationResponse.ResponseCase) { case MutateOperationResponse.ResponseOneofCase.AdGroupResult: resourceName = operationResponse.AdGroupResult.ResourceName; break; case MutateOperationResponse.ResponseOneofCase.AdGroupAdResult: resourceName = operationResponse.AdGroupAdResult.ResourceName; break; case MutateOperationResponse.ResponseOneofCase.CampaignResult: resourceName = operationResponse.CampaignResult.ResourceName; break; case MutateOperationResponse.ResponseOneofCase.CampaignBudgetResult: resourceName = operationResponse.CampaignBudgetResult.ResourceName; break; case MutateOperationResponse.ResponseOneofCase.CampaignCriterionResult: resourceName = operationResponse.CampaignCriterionResult.ResourceName; break; case MutateOperationResponse.ResponseOneofCase.SmartCampaig<nSettingR>esult: resourceName = operationResponse.SmartCampaignSettingResult.ResourceName; break; case MutateOperationResponse.ResponseOneofCase.Asse resourceName = operationResponse.AssetResult.ResourceName; break; case MutateOperationResponse.ResponseOneofCase.AssetGroupResult: resourceName = operationResponse.AssetGroupResult.ResourceName; break; case MutateOperationResponse.ResponseOneofCase.AssetGroupAssetResult: resourceName = operationResponse.AssetGroupAssetResult.ResourceName; break; default: resourceName = "not found"; break; } Console.WriteLine( $"Created a(n) {entityName} with resource name: '{resourceName}'."); } } } }AddPerformanceMaxCampaign.cs
পিএইচপি
<?php /** * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace Google\Ads\GoogleAds\Examples\AdvancedOperations; require __DIR__ . '/../../vendor/autoload.php'; use GetOpt\GetOpt; use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames; use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser; use Google\Ads\GoogleAds\Examples\Utils\Helper; use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder; use Google\Ads\GoogleAds\Lib\V22\GoogleAdsClient; use Google\Ads\GoogleAds\Lib\V22\GoogleAdsClientBuilder; use Google\Ads\GoogleAds\Lib\V22\GoogleAdsException; use Google\Ads\GoogleAds\Util\V22\ResourceNames; use Google\Ads\GoogleAds\V22\Common\AudienceInfo; use Google\Ads\GoogleAds\V22\Common\ImageAsset; use Google\Ads\GoogleAds\V22\Common\LanguageInfo; use Google\Ads\GoogleAds\V22\Common\LocationInfo; use Google\Ads\GoogleAds\V22\Common\MaximizeConversionValue; use Google\Ads\GoogleAds\V22\Common\TextAsset; use Google\Ads\GoogleAds\V22\Enums\AssetAutomationTypeEnum\AssetAutomationType; use Google\Ads\GoogleAds\V22\Enums\AssetAutomationStatusEnum\AssetAutomationStatus; use Google\Ads\GoogleAds\V22\Enums\AdvertisingChannelTypeEnum\AdvertisingChannelType; use Google\Ads\GoogleAds\V22\Enums\AssetFieldTypeEnum\AssetFieldType; use Google\Ads\GoogleAds\V22\Enums\AssetGroupStatusEnum\AssetGroupStatus; use Google\Ads\GoogleAds\V22\Enums\BudgetDeliveryMethodEnum\BudgetDeliveryMethod; use Google\Ads\GoogleAds\V22\Enums\CampaignStatusEnum\CampaignStatus; use Google\Ads\GoogleAds\V22\Enums\EuPoliticalAdvertisingStatusEnum\EuPoliticalAdvertisingStatus; use Google\Ads\GoogleAds\V22\Errors\GoogleAdsError; use Google\Ads\GoogleAds\V22\Resources\Asset; use Google\Ads\GoogleAds\V22\Resources\AssetGroup; use Google\Ads\GoogleAds\V22\Resources\AssetGroupAsset; use Google\Ads\GoogleAds\V22\Resources\AssetGroupSignal; use Google\Ads\GoogleAds\V22\Resources\Campaign; use Google\Ads\GoogleAds\V22\Resources\Campaign\AssetAutomationSetting; use Google\Ads\GoogleAds\V22\Resources\CampaignAsset; use Google\Ads\GoogleAds\V22\Resources\CampaignBudget; use Google\Ads\GoogleAds\V22\Resources\CampaignCriterion; use Google\Ads\GoogleAds\V22\Services\AssetGroupAssetOperation; use Google\Ads\GoogleAds\V22\Services\AssetGroupOperation; use Google\Ads\GoogleAds\V22\Services\AssetGroupSignalOperation; use Google\Ads\GoogleAds\V22\Services\AssetOperation; use Google\Ads\GoogleAds\V22\Services\CampaignAssetOperation; use Google\Ads\GoogleAds\V22\Services\CampaignBudgetOperation; use Google\Ads\GoogleAds\V22\Services\CampaignCriterionOperation; use Google\Ads\GoogleAds\V22\Services\CampaignOperation; use Google\Ads\GoogleAds\V22\Services\MutateGoogleAdsRequest; use Google\Ads\GoogleAds\V22\Services\MutateGoogleAdsResponse; use Google\Ads\GoogleAds\V22\Services\MutateOperation; use Google\Ads\GoogleAds\V22\Services\MutateOperationResponse; use Google\ApiCore\ApiException; use Google\ApiCore\Serializer; /** * This example shows how to create a Performance Max campaign. * * For more information about Performance Max campaigns, see * https://developers.google.com/google-ads/api/docs/performance-max/overview. * * Prerequisites: * - You must have at least one conversion action in the account. For more about conversion actions, * see * https://developers.google.com/google-ads/api/docs/conversions/overview#conversion_actions. * * This example uses the default customer conversion goals. For an example of setting * campaign-specific conversion goals, see ShoppingAds/AddPerformanceMaxRetailCampaign.php. */ class AddPerformanceMaxCampaign { private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE'; // Optional: An audience ID to use to improve the targeting of the Performance Max campaign. private const AUDIENCE_ID = null; // Optional: Indicates whether the created campaign is enabled for brand guidelines. private const BRAND_GUIDELINES_ENABLED = false; // We specify temporary IDs that are specific to a single mutate request. // Temporary IDs are always negative and unique within one mutate request. // // See https://developers.google.com/google-ads/api/docs/mutating/best-practices // for further details. // // These temporary IDs are fixed because they are used in multiple places. private const BUDGET_TEMPORARY_ID = -1; private const PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID = -2; private const ASSET_GROUP_TEMPORARY_ID = -3; // There are also entities that will be created in the same request but do not need to be fixed // temporary IDs because they are referenced only once. /** @var int the negative temporary ID used in bulk mutates. */ private static $nextTempId = self::ASSET_GROUP_TEMPORARY_ID - 1; 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, > ArgumentNames::AUDIENCE_ID = GetOpt::OPTIONAL_ARGUMENT, Argum>entNames::BRAND_GUIDELINES_ENABLED = GetOpt::OPTIONAL_ARGUMENT ]); // Generate a refreshable OAuth2 credential for authentication. $oAuth2Cred>ential = (n>ew OAuth2TokenBuilder())-fromFile()-build(); // Construct a Google Ads client configured from a properties file and the // OAuth2 credentials above. $googleAdsClient = (new Goo>gleAdsClientBuilder()) > -fromFile() -withOAuth2Credent>ial($oAuth2Credential) -build(); try { self::runExample( $googleAdsClient, $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID, $options[ArgumentNames::AUDIENCE_ID] ?: self::AUDIENCE_ID, filter_var( $options[ArgumentNames::BRAND_GUIDELINES_ENABLED] ?: self::BRAND_GUIDELINES_ENABLED, FILTER_VALIDATE_BOOLEAN ) ); } 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( > &q>uot;\t%s: %s%s", $>error-getErrorCode()-getErrorCode(), $error-getMessage(), PHP_EOL ); } exit(1); } catch (ApiException $apiException) { printf( "ApiExcep>tion 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 * @param int|null $audienceId the audience ID * @param bool $brandGuidelinesEnabled whether the created campaign will be enabled for brand * guidelines */ public static function runExample( GoogleAdsClient $googleAdsClient, int $customerId, ?int $audienceId, bool $brandGuidelinesEnabled ) { // Performance Max campaigns require that repeated assets such as headlines // and descriptions be created before the campaign. // For the list of required assets for a Performance Max campaign, see // https://developers.google.com/google-ads/api/docs/performance-max/assets. // // Creates the headlines. $headlineAssetResourceNames = self::createMultipleTextAssets( $googleAdsClient, $customerId, ["Travel", "Travel Reviews", "Book travel"] ); // Creates the descriptions. $descriptionAssetResourceNames = self::createMultipleTextAssets( $googleAdsClient, $customerId, ["Take to the air!", "Fly to the sky!"] ); // It's important to create the below entities in this order because they depend on // each other. $operations = []; // The below methods create and return MutateOperations that we later // provide to the GoogleAdsService.Mutate method in order to create the // entities in a single request. Since the entities for a Performance Max // campaign are closely tied to one-another, it's considered a best practice // to create them in a single Mutate request so they all complete // successfully or fail entirely, leaving no orphaned entities. See: // https://developers.google.com/google-ads/api/docs/mutating/overview. $operations[] = self::createCampaignBudgetOperation($customerId); $operations[] = self::createPerformanceMaxCampaignOperation($customerId, $brandGuidelinesEnabled); $operations = array_merge($operations, self::createCampaignCriterionOperations($customerId)); $operations = array_merge($operations, self::createAssetGroupOperations( $customerId, $headlineAssetResourceNames, $descriptionAssetResourceNames, $brandGuidelinesEnabled )); $operations = array_merge($operations, self::createAssetGroupSignalOperations( $customerId, ResourceNames::forAssetGroup($customerId, self::ASSET_GROUP_TEMPORARY_ID), $audienceId >)); // Issues a mutate request to create everything and prints i>ts information. $googleAdsServiceClient = $googleAdsClient-getGoogleAdsServiceClient(); $response = $googleAdsServiceClient-mutate(MutateGoogleAdsRequest::build( $customerId, $operations )); self::printResponseDetails($response); } /** * Creates a MutateOperation that creates a new CampaignBudget. * * A temporary ID will be assigned to this campaign budget so that it can be * referenced by other objects being created in the same Mutate request. * * @param int $customerId the customer ID * @return MutateOperation the mutate operation that creates a campaign budget */ private static function createCampaignBudgetOperation(int $customerId): MutateOperation { // Creates> a mutate operation that creates a campaign budget operat>ion. return new MutateOperation([ 'campaign_budget_operation' = new CampaignBudgetOperation([ 'create' = new CampaignBudget([ // Sets a tem>porary ID in the budget's resource name so it can be referenced // by the campaign in later steps. 'resource_name' = Reso>urceNames::forCampaignBudget( $customerId, self::BUDGET_TEMPORARY_ID ), 'name' => 'Performance Max campaign budget #' . Hel>per::getPrintableDatetime(), // The budget period already defaults to DAILY. 'amount_micros' = 50000000, > 'delivery_method' = BudgetDeliveryMethod::STANDARD, // A Performance Max campaign cannot use a shared campaign budget. 'explicitly_shared' = false ]) ]) ]); } /** * Creates a MutateOperation that creates a new Performance Max campaign. * * A temporary ID will be assigned to this campaign so that it can * be referenced by other objects being created in the same Mutate request. * * @param int $customerId the customer ID * @param bool $brandGuidelinesEnabled whether the created campaign will be enabled for brand * guidelines * @return MutateOperation the mutate operation that creates the campaign */ private static function createPerformanceMaxCampaignOperation( int $customerId>, bool $brandGuidelinesEnabled ): Mutat>eOperation { // Creates a mutate ope>ration that creates a campaign operation. return new MutateOperation([ 'campaign_operation' = new CampaignOperation([ 'crea>te' = new Campaign([ 'name' = 'Performance Max campaign #' . Helper::getPrintableDatetime(), // Assigns the resource name with a temporary ID. 'resource_name' = ResourceNames::forCampai>gn( $customerId, self::PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ), // Sets the budget using the given budget resource name. 'campaign_budget' = ResourceNames::forCampaignBudget( $customerId, self::BUDGET_TEMPORARY_ID ), // The campaign is the only entity in >the mutate request that should have its // status set. // Recommendation: Set the campaign to PAUSED when creating it to prevent // the ads from immediately serving. 'sta>tus' = CampaignStatus::PAUSED, // All Performance Max campaigns have an advertising_channel_type of // PERFORMANCE_MAX. The advertising_channel_sub_type should not be set. 'advertising_channel_type' = AdvertisingChannelType::PERFORMANCE_MAX, // Bidding strategy must be set directly on the campaign. // Setting a portfolio bidding strategy by resource name is not supported. // Max Conversion and Maximize Conversion Value are the only strategies // supported for Performance Max 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 suppor>t // article: http://support.google.com/google-ads/answer/7>684216. // A target_roas of 3.5 corresponds to a 350% return on ad spend. > 'maximize_conversion_value' = new MaximizeConversionValue([ >9;target_roas' = 3.5 ]), 'asset_automation_settings' = [ new AssetAutomationSetting([ > 'asset_automation_type' = AssetAutomationType::TEXT_ASSET_AU>TOMATION, 'asset_automation_status' = AssetAutomationStatus::OPTED_IN ]), new AssetAutomationSetting([ 'asset_automation_type' = AssetAutomationType::URL_EXPANSION, 'asset_automation_status' = AssetAut>omationStatus::OPTED_IN ]) ], // Sets if the campaign is enabled for brand guidelines. For more information > // on brand guidelines, see // https://support.google.com/google-ads/answer/14934472. 'brand_guidelines_enabled' => $brandGuidelinesEnabled, // Declare whether o>r not this campaign serves political ads targeting the EU. 'contains_eu_political_advertising' = EuPoliticalAdvertisingStatus::DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING, // Optional fields. 'start_date' = date('Ymd', strtotime('+1 day')), 'end_date' = date('Ymd', strtotime('+365 days')) ]) ]) ]); } /** * Creates a list of MutateOperations that create new campaign criteria. * * @param int $customerId the customer ID * @return MutateOperation[] a list of MutateOperations that create the new campaign criteria */ private static function createCampaignCriterionOperations(int $customerId): array { $operations = []; // Set the LOCATION campaign criteria. // Target all of New York City except Brooklyn. // Location IDs are listed here: // https://developers.google.com/google-ads/api/reference/data/geotargets // and they can also be retrieved using the GeoTargetConstantService as shown // he>re: https://developers.google.com/google-ads/api/docs/target>ing/location-targeting // // We will add >one positive location target for New York City (ID=1023191) // and one negative location target for Brooklyn (ID=1022762). // First, adds the positive (negative = false) for> New York City. $operations[] = new MutateOperation([ > 'campaign_criterion_operation' = new CampaignCriterionOperation([ '>create' = new CampaignCriterion([ 'campaign' = ResourceNames::forCampaign( $customerId, self::PERFORMANCE_MAX_CAMPAIGN_>TEMPORARY_ID ), '>;location' = new LocationInfo([ > 'geo_target_constant' = ResourceNames::forGeoTargetConstant(1023191) ]), 'negative' = false ]) ]) > ]); // Next adds the negative target for Brooklyn. > $operations[] = new MutateOperation([ 'campaign_criterion_operation' = new Ca>mpaignCriterionOperation([ 'create' = new CampaignCriterion([ 'campaign' = ResourceNames::forCampaign( $customerId, > self::PERFORMANCE_MAX_CAMPAIGN_TEMPO>RARY_ID ), 'l>ocation' = new LocationInfo([ 'geo_target_constant' = ResourceNames::forGeoTargetConstant(1022762) ]), 'negative' = true ]) ]) ]); // Sets the LANGUAGE campaign criterion. $operations[] = new MutateOperation([ 'campaign_criterion_operation' = ne>w CampaignCriterionOperation([ 'create' => new CampaignCriterion([ 'campaign' = ResourceNames::forCampaign( $customerId, self::PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ), // Set the language. // For a list of all language codes, see: // https://developers.google.com/google-ads/api/reference/data/codes-formats#expandable-7 'language' = new LanguageInfo([ 'language_constant' = ResourceNames::forLanguageConstant(1000) // English ]) ]) ]) ]); return $operations; } /** * Creates multiple text assets and returns the list of resource names. * * @param GoogleAdsClient $googleAdsClient the Google Ads API client * @param int $customerId the customer ID * @param string[] $texts a list of strings, each of which will be used to create a tex>t asset * @return string[] a list of asset reso>urce names */ pri>vate static function cre>ateMultipleTextAssets( GoogleAdsClient $googleAdsClient, int $customerId, array $texts ): array { // Here again, we use >the GoogleAdService to create multiple text assets in a single // request. $operations = []; foreach ($texts as $text) { // Cre>ates a mutate operation for a text asset. $operations[] = new MutateOperation([ 'asset_operation' = new As>setOperation([ 'create' = new Asset(['text_asset' = new TextAsset(['text' = $text])]) ]) > ]); > } // Issues a mutate request to add all assets. $googleAdsService = $googleAdsClient-getGoogleAdsServiceClient(); /** @var MutateGoogleAdsResponse $mutateGoogleAdsResponse */ $mutateGoogleAdsResponse = $googleAdsService-mutate(MutateGoogleAdsRequest::build($customerId, $operations)); $assetResourceNames = []; foreach ($mutateGoogleAdsResponse-getMutateOperationResponses() as $response) { /** @var MutateOperationResponse $response */ $assetResourceNames[] = $response-getAssetResult()-getResourceName(); } self::printResponseDetails($mutateGoogleAdsResponse); return $assetResourceNames; } /** * Creates a list of MutateOperations that create a new asset group. * * A temporary ID will be assigned to this asset group so that it can * be referenced by other objects being created in the same Mutate request. * * @param int $customerId the customer ID * @param string[] $headlineAssetResourceNames a list of headline resource names * @param string[] $descriptionAssetResourceNames a list of description resource names * @param bool $brandGuidelinesEnabled wheth>er the created campaign will be enabled for brand > * guidelines * @return MutateOperation[] a l>ist of MutateOperations that create new asset group */ private static function createAssetGroupOperations( int $customerId, array $headlineAssetResou>rceNames, array $descriptionAssetResourceNames, bool $brandGuidelinesEnabled ):> array { $operations = []; // Creates a new mutate operation that creates an asset group operation. $operations[] = new MutateOperation([ 'asset_group_>operation' = new AssetGroupOperation([ 'create>' = new AssetGroup([ 'resource_>name' = ResourceNames::forAssetGroup( $customerId, self::ASSET_GROUP_TEMPORARY_ID ), 'name' = 'Performance Max asset group #' . Helper::getPrintableDatetime(), 'campaign' = ResourceNames::forCampaign( $customerId, self::PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ), 'final_urls' = ['http://www.example.com'], 'final_mobile_urls' = ['http://www.example.com'], 'status' = AssetGroupStatus::PAUSED ]) ]) ]); // For the list of required assets for a Performance Max campaign, see // https://developers.google.com/google-ads/api/docs/performance-max/assets />/ An AssetGroup is linked to an Asset by creating a new AssetG>roupAsset // and providing: // - the re>source name of the AssetGroup // - the resourc>e name of the Asset // - the field_type of the Asset in this AssetGroup // // To learn more about AssetGroups, see // https://developers.google.com/google-ads/api/>docs/performance-max/asset-groups. // Links the previously created multiple text assets. // Links the headline assets. foreach ($headlineAssetResourceNames as $resourceName) { $operations[] = new MutateOperation([ 'asset_group_asset_operation>' = new AssetGroupAssetOperation([ >9;create' = new AssetGroupAsset([ > 'asset' = $resourceName, > 'asset_group' = ResourceNames::forAssetGroup( $customerId, self::ASSET_GROUP_TEMPORARY_ID ), > 'field_type' = AssetFieldType::HEADLINE ]) ]) ]); } // Links the description assets. foreach ($descriptionAssetResourceNames as $resourceName) { $operations[] = new MutateOperation([ 'asset_group_asset_operation' = new AssetGroupAssetOperation([ 'create' = new AssetGroupAsset([ 'asset' = $resourceName, 'asset_group' = ResourceNames::forAssetGroup( $customerId, self::ASSET_GROUP_TEMPORARY_ID ), 'field_type' = AssetFieldType::DESCRIPTION ]) ]) ]); } // Creates and links the long headline text asset. $operations = array_merge($operations, self::createAndLinkTextAsset( $customerId, 'Travel the World', AssetFieldType::LONG_HEADLINE )); // Creates and links the business name text asset. $operations = array_merge($operations, self::createAndLinkBrandAssets( $customerId, $brandGuidelinesEnabled, 'Interplanetary Cruises', 'https://gaagl.page.link/bjYi', 'Marketing Logo' )); // Creates and links the image assets. // Creates and links the Marketing Image Asset. $operations = array_merge($operations, self::createAndLinkImageAsset( $customerId, 'https://gaagl.page.link/Eit5', AssetFieldType::MARKETING_IMAGE, 'Marketing Image' )); // Creates and links the Square Marketing Image Asset. $operations = array_merge($operations, self::createAndLinkImageAsset( $customerId, 'https://gaagl.page.link/bjYi', AssetFieldType::SQUAR>E_MARKETING_IMAGE, 'Square Marke>ting Image' )); return $opera>tions; } /** * Creates a list of MutateOperations that create a new linked tex>t asset. * * @>param int $customerId the customer ID * @param string $text the text of the asset to be created * @param int $fieldType the field type of the new asset in the AssetGroupAsset * @return MutateOperation[] a lis>t of MutateOperations that create a new linked text asset > */ private static function createAndLinkTex>tAsset( int $customerId, string $text, int $fieldType ): array { > $operations = []; // Creates a new mutate operation that creates a text asset. $operations[] = new MutateOperation([ 'asset_operation' => new AssetOperation([ 'create' = new Asset([ 'resource_name' = ResourceNames::forAsset($customerId, self::$nextTempId), 'text_asset' = new TextAsset(['text' = $text]) ]) ]) ]); // Creates an asset group asset to link the asset to the asset group. $operations[] = new MutateOperation([ 'asset_group_asset_operation' = new AssetGroupAssetOperation([ 'create' = new AssetGroupAsset([ 'asset' = ResourceNames::forAsset($customerId, self::$nextTempId), 'asset_group' = ResourceNames::forAssetGroup( $customerId, self::ASSET_GROUP_TEMPORARY_ID ), 'field_type' = $fieldType ]) > ]) ]); self::$nextTe>mpId--; return $operations; } /*>* * Creates a list of MutateOperations that create a new linked image asset. * * @param int $customerId the customer ID * @param string $url the URL of the image to be retrieved and put into an asset * @param int $fieldType the field type of the new asset in the AssetGroupAsset * @param string $asset>Name the asset name * @return MutateOperati>on[] a list of MutateOper>ations that create a new linked image asset */ private static function createAndLinkImageAsset( int $customerId, string $url, int $fieldType, string $assetName ): array { $operations = [];> // Creates a new mutate operation that creates an> image asset. $operations[] = new MutateOper>ation([ 'asset_operation' = new AssetOperation([ 'cre>ate' = new Asset([ 'resource_name' = ResourceNames::forAsset($customerId, self::$nextTempId), // Provide a unique friendly name >to identify your asset. // When there is an existing image asset with the same content but a different // name, the new name will be dropped silently. 'name' = $assetName, 'image_asset' = new ImageAsset(['data' = file_get_contents($url)]) ]) ]) ]); // Creates an asset group asset to link the asset to the asset group. $operations[] = new MutateOperation([ 'asset_group_asset_operation' = new AssetGroupAssetOperation([ 'create' = new AssetGroupAsset([ 'asset' = ResourceNames::forAsset($customerId, self::$nextTempId), 'asset_group' = ResourceNames::forAssetGroup( $customerId, self::ASSET_GROUP_TEMPORARY_ID ), 'field_type' = $fieldType ]) ]) ]); self::$nextTempId--; return $operations; } /** * Creates a list of MutateOper>ations that create linked brand assets. * > * @param int $customerId the customer ID >* @param bool $brandGuidelinesEnabled whether the created campaign will be enabled for brand > * guidelines > * @param string $businessName the business name text to be put into an asset * @param string $logoUrl the URL of the logo to be retrieved and put into an asset * @param string $logoName the asset name of the logo * @return MutateOperation>[] a list of MutateOperations that create a new >linked text asset */ private static funct>ion createAndLinkBrandAssets( int $customerId, bool $brandGuidelinesEnabled, string $businessName, string $logoUrl, string $logoName ): array { $operations = []; // Creates a new mutate operation that creates a text asset. $businessNameTempId = self::$nextT>empId--; $operations[] = new MutateOper>ation([ '>asset_operation' = new AssetOperation([ 'create' = new Asset([ 'resource_name' = ResourceNames::forAsset($customerId, $businessNameTempId), 'text_asset' = new TextAsset(['text' = $businessName]) ]) > ]) ]); $logoTempId = self::$nextTem>pId--; // Creates a new mutate operation that >creates an image asset. $operations[] = new MutateOperation([ 'asset_ope>ration' = new AssetOperation([ 'create' = new Asset([ 'resource_name' = ResourceNames::forAsset($customerId, $logoTempId), // Provi>de a unique friendly name to identify your asset. // When there is an existing image asset with the same content but a different // name, the n>ew name will be dropped silently. 'n>ame' = $logoName, 'image_a>sset' = new ImageAsset(['data' = file_get_contents($logoUrl)]) > ]) ]) ]); if ($brandGuidelinesEnabled) { // Creates a campaign asset to link the business name and logo assets to the campaign. $operations[] = new Mut>ateOperation([ 'campaign_asset_operation' = new CampaignAssetOperation([ 'create' = new CampaignAsset([ 'asset' = ResourceNames::forAsset($customerId, $businessNameTempId), 'campaign' = ResourceNames>::forCampaign( $customerId, > self::PERFORMANCE_MAX_CAMPAIGN_TEM>PORARY_ID ), 'field_type' = AssetFieldType:>:BUSINESS_NAME ]) ]) ]); $operations[] = new MutateOperation([ 'campaign_asset_operation' = new CampaignAssetOpe>ration([ 'create' = new CampaignAsset([ 'asset' = ResourceNames::forAsset($customerId, $logoTempId), &>#39;campaign' = ResourceNames::forCampaign( > $customerId, s>elf::PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ), > 'field_type' = AssetFieldType::LOGO ]) ]) ]); } else { // Creates an asset group asset to link the business name and >logo assets to the asset // group. $operations[] = new MutateOperation([ 'asset_group_asset_operation' = new AssetGroupAssetOperation([ 'create' = new AssetGroupAsset([ 'asset' = ResourceNames::forAsset($customerId, $businessNameTempId), 'asset_group' = ResourceNames::forAssetGroup( $customerId, self::ASSET_GROUP_TEMPORARY_ID ), 'field_type' = AssetFieldType::BUSINESS_NAME ]) ]) ]); $operations[] = new MutateOperation([ 'asset_group_asset_operation' = new AssetGroupAssetOperation([ 'create' = new >AssetGroupAsset([ 'asset' = ResourceNames::forAsset($customerId, $logoTempId), 'asset_group' = ResourceNames::forAssetGroup( $customerId, > self::ASSET_GROUP_TEMPORARY_ID > ), 'field_ty>pe' = AssetFieldType::LOGO ]) > ]) ]); } return $operations; } /** * Creates a list of MutateOperations that may create asset group signals. * * @param int $customerId the customer ID * @param string $assetGroupResourceName the resource name of the asset group * @param int|null $audienceId the audience ID * @return MutateOperation[] a list of MutateOperations that may create asset group signals */ private static function createAssetGroupSignalOperations( int $customerId, string $assetGroupResourceName, ?int $audienc>eId ): array { $operations = []; if (is_null($audienceId)) { return $operations; } $operations[] = new Mutate>Operation([ 'asset_group_signal_operation' = new AssetGroupSignalOperation([ // To learn more about Audience Signals, see // https://developers.google.com/google-ads/api/docs/perfor>mance-max/asset-groups#audience_signals. '>;create>9; = new AssetGroupSignal([ 'asset_group' = $assetGroupResourceName, AudienceInfo([ 'audience' = ResourceNames::forAudience($customerId, $audienceId) ]) ]) ]) ]); return $operations; } /** * Prints the details of a MutateGoogleAdsResponse. Parses the "response" oneof field name and * uses it to extract the new entity's name and resource name. * * @param MutateGoogleAdsResponse $mutateGoogleAdsResponse the mutate Google Ads response */ private static function printResponseDetails( MutateGoogleAdsResponse $mutateGoogleAdsResponse ): void { foreach ($mutateGoogleAdsResponse-getMutateOperationResponses() as $response) { /** @var MutateOperationResponse $response */ $getter = Serializer::getGetter($response-getResponse()); printf( "Created a(n) %s with '%s'.%s", preg_replace( '/Result$/', '', ucfirst(Serializer::toCamelCase($response-getResponse())) ), $response-$getter()-getResourceName(), PHP_EOL ); } } } AddPerformanceMaxCampaign::main(); AddPerformanceMaxCampaign.php
পাইথন
#!/usr/bin/env python # Copyright 2021 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """This example shows how to create a Performance Max campaign. For more information about Performance Max campaigns, see https://developers.google.com/google-ads/api/docs/performance-max/overview Prerequisites: - You must have at least one conversion action in the account. For more about conversion actions, see https://developers.google.com/google-ads/api/docs/conversions/overview#conversion_actions This example uses the default customer conversion goals. For an example of setting campaign-specific conversion goals, see shopping_ads/add_performance_max_retail_campaign.py """ import argparse from datetime import datetime, timedelta import sys from typing import List, Optional, Iterable from uuid import uuid4 from examples.utils.example_helpers import get_image_bytes_from_url from google.ads.googleads.client import GoogleAdsClient from google.ads.googleads.errors import GoogleAdsException from google.ads.googleads.util import convert_snake_case_to_upper_case from google.ads.googleads.v22.enums.types.asset_field_type import ( AssetFieldTypeEnum, ) from google.ads.googleads.v22.resources.types.asset import Asset from google.ads.googleads.v22.resources.types.asset_group import AssetGroup from google.ads.googleads.v22.resources.types.asset_group_asset import ( AssetGroupAsset, ) from google.ads.googleads.v22.resources.types.asset_group_signal import ( AssetGroupSignal, ) from google.ads.googleads.v22.resources.types.campaign import Campaign from google.ads.googleads.v22.resources.types.campaign_asset import ( CampaignAsset, ) from google.ads.googleads.v22.resources.types.campaign_budget import ( CampaignBudget, ) from google.ads.googleads.v22.resources.types.campaign_criterion import ( CampaignCriterion, ) from google.ads.googleads.v22.services.services.asset_group_service import ( AssetGroupServiceClient, ) from google.ads.googleads.v22.services.services.asset_service import ( AssetServiceClient, ) from google.ads.googleads.v22.services.services.campaign_service import ( CampaignServiceClient, ) from google.ads.googleads.v22.services.services.geo_target_constant_service import ( GeoTargetConstantServiceClient, ) from google.ads.googleads.v22.services.services.google_ads_service import ( GoogleAdsServiceClient, ) from google.ads.googleads.v22.services.types.campaign_budget_service import ( CampaignBudgetOperation, ) from google.ads.googleads.v22.services.types.google_ads_service import ( MutateGoogleAdsResponse, MutateOperation, MutateOperationResponse, ) # We specify temporary IDs that are specific to a single mutate request. # Temporary IDs are always negative and unique within one mutate request. # # See https://developers.google.com/google-ads/api/docs/mutating/best-practices # for further details. # # These temporary IDs are fixed because they are used in multiple places. _BUDGET_TEMPORARY_ID = "-1" _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID = "-2" _ASSET_GROUP_TEMPORARY_ID = "-3" # There are also entities that will be created in the same request but do not # need to be fixed temporary IDs because they are referenced only once. next_temp_id = int(_ASSET_GROUP_TEMPORARY_ID) - 1 def main( client: GoogleAdsClient, customer_>id: str, audience_id: Optional[str], brand_guidelines_enabled: bool, ) - None: """The main method that creates all necessary entities for the example. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. audience_id: an optional audience ID. brand_guidelines_enabled: a boolean value indicating if the campaign is enabled for brand guidelines. """ googleads_service: GoogleAdsServiceClient = client.get_service( "GoogleAdsService" ) # Performance Max campaigns require that repeated assets such as headlines # and descriptions be created before the campaign. # For the list of required assets for a Performance Max campaign, see # https://developers.google.com/google-ads/api/docs/performance-max/assets # # Create the headlines. headline_asset_resource_names: List[str] = create_multiple_text_assets( client, customer_id, [ "Travel", "Travel Reviews", "Book travel", ], ) # Create the descriptions. description_asset_resource_names: List[str] = create_multiple_text_assets( client, customer_id, [ "Take to the air!", "Fly to the sky!", ], ) # The below methods create and return MutateOperations that we later # provide to the GoogleAdsService.Mutate method in order to create the # entities in a single request. Since the entities for a Performance Max # campaign are closely tied to one-another, it's considered a best practice # to create them in a single Mutate request so they all complete # successfully or fail entirely, leaving no orphaned entities. See: # https://developers.google.com/google-ads/api/docs/mutating/overview campaign_budget_operation: MutateOperation = ( create_campaign_budget_operation( client, customer_id, ) ) performance_max_campaign_operation: MutateOperation = ( create_performance_max_campaign_operation( client, customer_id, brand_guidelines_enabled, ) ) campaign_criterion_operations: List[MutateOperation] = ( create_campaign_criterion_operations( client, customer_id, ) ) asset_group_operations: List[MutateOperation] = ( create_asset_group_operation( client, customer_id, headline_asset_resource_names, description_asset_resource_names, brand_guidelines_enabled, ) ) asset_group_signal_operations: List[MutateOperation] = ( create_asset_group_signal_operations(client, customer_id, audience_id) ) mutate_operations: List[MutateOperation] = [ # It's important to create these entities in this order because # they depend on each other. campaign_budget_operation, performance_max_campaign_operation, # Expand the list of multiple operations into the list of # other mutate operations *campaign_criterion_operations, *asset_group_operations, *asset_group_signal_operations, ] # Send the operations in a single Mutate request. response: MutateGoogleAdsResponse = googleads_service.mutate( customer_id=customer_>id, mutate_operations=mutate_operations ) print_response_details(response) def create_campaign_budget_operation( client: GoogleAdsClient, customer_id: str, ) - MutateOperation: """Creates a MutateOperation that creates a new CampaignBudget. A temporary ID will be assigned to this campaign budget so that it can be referenced by other objects being created in the same Mutate request. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. Returns: a MutateOperation that creates a CampaignBudget. """ mutate_operation: MutateOperation = client.get_type("MutateOperation") campaign_budget_operation: CampaignBudgetOperation = ( mutate_operation.campaign_budget_operation ) campaign_budget: CampaignBudget = campaign_budget_operation.create campaign_budget.name = f"Performance Max campaign budget #{uuid4()}" # The budget period already defaults to DAILY. campaign_budget.amount_micros = 50000000 campaign_budget.delivery_method = ( client.enums.BudgetDeliveryMethodEnum.STANDARD ) # A Performance Max campaign cannot use a shared campaign budget. campaign_budget.explicitly_shared = False # Set a temporary ID in the budget's resource name so it can be referenced # by the campaign in later steps. campaign_budget.resource_name = client.get_service( "CampaignBudgetSe>rvice" ).campaign_budget_path(customer_id, _BUDGET_TEMPORARY_ID) return mutate_operation def create_performance_max_campaign_operation( client: GoogleAdsClient, customer_id: str, brand_guidelines_enabled: bool, ) - MutateOperation: """Creates a MutateOperation that creates a new Performance Max campaign. A temporary ID will be assigned to this campaign so that it can be referenced by other objects being created in the same Mutate request. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. brand_guidelines_enabled: a boolean value indicating if the campaign is enabled for brand guidelines. Returns: a MutateOperation that creates a campaign. """ mutate_operation: MutateOperation = client.get_type("MutateOperation") campaign: Campaign = mutate_operation.campaign_operation.create campaign.name = f"Performance Max campaign #{uuid4()}" # Set the campaign status as PAUSED. The campaign is the only entity in # the mutate request that should have its status set. campaign.status = client.enums.CampaignStatusEnum.PAUSED # All Performance Max campaigns have an advertising_channel_type of # PERFORMANCE_MAX. The advertising_channel_sub_type should not be set. campaign.advertising_channel_type = ( client.enums.AdvertisingChannelTypeEnum.PERFORMANCE_MAX ) # Bidding strategy must be set directly on the campaign. # Setting a portfolio bidding strategy by resource name is not supported. # Max Conversion and Maximize Conversion Value are the only strategies # supported for Performance Max 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.bidding_strategy_type = ( client.enums.BiddingStrategyTypeEnum.MAXIMIZE_CONVERSION_VALUE ) campaign.maximize_conversion_value.target_roas = 3.5 # Set if the campaign is enabled for brand guidelines. For more information # on brand guidelines, see https://support.google.com/google-ads/answer/14934472. campaign.brand_guidelines_enabled = brand_guidelines_enabled # Assign the resource name with a temporary ID. campaign_service: CampaignServiceClient = client.get_service( "CampaignService" ) campaign.resource_name = campaign_service.campaign_path( customer_id, _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ) # Set the budget using the given budget resource name. campaign.campaign_budget = campaign_service.campaign_budget_path( customer_id, _BUDGET_TEMPORARY_ID ) # Declare whether or not this campaign serves political ads targeting the # EU. Valid values are: # CONTAINS_EU_POLITICAL_ADVERTISING # DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING campaign.contains_eu_political_advertising = ( client.enums.EuPoliticalAdvertisingStatusEnum.DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING ) # Optional fields campaign.start_date = (datetime.now() + timedelta(1)).strftime("%Y%m%d") campaign.end_date = (datetime.now() + timedelta(365)).strftime("%Y%m%d") # Configures the optional opt-in/out status for asset automation settings. for asset_automation_type_enum in [ client.enums.AssetAutomationTypeEnum.GENERATE_IMAGE_EXTRACTION, client.enums.AssetAutomationTypeEnum.FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION, client.enums.AssetAutomationTypeEnum.TEXT_ASSET_AUTOMATION, client.enums.AssetAutomationTypeEnum.GENERATE_ENHANCED_YOUTUBE_VIDEOS, client.enums.AssetAutomationTypeEnum.GENERATE_IMAGE_ENHANCEMENT ]: asset_automattion_setting: Campaign.AssetAutomationSetting = client.get_type("Campaign").AssetAutomationSetting() asset_automattion_setting.asset_autom>ation_type = asset_automation_type_enum asset_automattion_setting.asset_automation_status = client.enums.AssetAutomationStatusEnum.OPTED_IN campaign.asset_automation_settings.append(asset_automattion_setting) return mutate_operation def create_campaign_criterion_operations( client: GoogleAdsClient, customer_id: str, ) - List[MutateOperation]: """Creates a list of MutateOperations that create new campaign criteria. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. Returns: a list of MutateOperations that create new campaign criteria. """ campaign_service: CampaignServiceClient = client.get_service( "CampaignService" ) geo_target_constant_service: GeoTargetConstantServiceClient = ( client.get_service("GeoTargetConstantService") ) googleads_service: GoogleAdsServiceClient = client.get_service( "GoogleAdsService" ) operations: List[MutateOperation] = [] # Set the LOCATION campaign criteria. # Target all of New York City except Brooklyn. # Location IDs are listed here: # https://developers.google.com/google-ads/api/reference/data/geotargets # and they can also be retrieved using the GeoTargetConstantService as shown # here: https://developers.google.com/google-ads/api/docs/targeting/location-targeting # # We will add one positive location target for New York City (ID=1023191) # and one negative location target for Brooklyn (ID=1022762). # First, add the positive (negative = False) for New York City. mutate_operation: MutateOperation = client.get_type("MutateOperation") campaign_criterion: CampaignCriterion = ( mutate_operation.campaign_criterion_operation.create ) campaign_criterion.campaign = campaign_service.campaign_path( customer_id, _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ) campaign_criterion.location.geo_target_constant = ( geo_target_constant_service.geo_target_constant_path("1023191") ) campaign_criterion.negative = False operations.append(mutate_operation) # Next add the negative target for Brooklyn. mutate_operation: MutateOperation = client.get_type("MutateOperation") campaign_criterion: CampaignCriterion = ( mutate_operation.campaign_criterion_operation.create ) campaign_criterion.campaign = campaign_service.campaign_path( customer_id, _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ) campaign_criterion.location.geo_target_constant = ( geo_target_constant_service.geo_target_constant_path("1022762") ) campaign_criterion.negative = True operations.append(mutate_operation) # Set the LANGUAGE campaign criterion. mutate_operation: MutateOperation = client.get_type("MutateOperation") campaign_criterion: CampaignCriterion = ( mutate_operation.campaign_criterion_operation.create ) campaign_criterion.campaign = campaign_service.campaign_path( customer_id, _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID> ) # Set the language. # For a list of all language codes, see: # https://developers.google.com/google-ads/api/reference/data/codes-formats#expandable-7 campaign_criterion.language.language_constant = ( googleads_service.language_constant_path("1000") ) # English operations.append(mutate_operation) return operations def create_multiple_text_assets( client: GoogleAdsClient, customer_id: str, texts: List[str] ) - List[str]: """Creates multiple text assets and returns the list of resource names. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. texts: a list of strings, each of which will be used to create a text asset. Returns: asset_resource_names: a list of asset resource names. """ # Here again we use the GoogleAdService to create multiple text # assets in a single request. googleads_service: GoogleAdsServiceClient = client.get_service( "GoogleAdsService" ) operations: List[MutateOperation] = [] for text in texts: mutate_operation: MutateOperation = client.get_type("MutateOperation") asset: Asset = mutate_operation.asset_operation.create asset.text_asset.text = text operations.append(mutate_operation) # Send the operations in a single Mutate request. response: MutateGoogleAdsResponse = googleads_service.mutate( customer_id=customer_id, mutate_operations=opera>tions, ) asset_resource_names: List[str] = [] for result in response.mutate_operation_responses: if result._pb.HasField("asset_result"): asset_resource_names.append(result.asset_result.resource_name) print_response_details(response) return asset_resource_names def create_asset_group_operation( client: GoogleAdsClient, customer_id: str, headline_asset_resource_names: List[str], description_asset_resource_names: List[str], brand_guidelines_enabled: bool, ) - List[MutateOperation]: """Creates a list of MutateOperations that create a new asset_group. A temporary ID will be assigned to this asset group so that it can be referenced by other objects being created in the same Mutate request. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. headline_asset_resource_names: a list of headline resource names. description_asset_resource_names: a list of description resource names. brand_guidelines_enabled: a boolean value indicating if the campaign is enabled for brand guidelines. Returns: MutateOperations that create a new asset group and related assets. """ asset_group_service: AssetGroupServiceClient = client.get_service( "AssetGroupService" ) campaign_service: CampaignServiceClient = client.get_service( "CampaignService" ) operations: List[MutateOperation] = [] # Create the AssetGroup mutate_operation: MutateOperation = client.get_type("MutateOperation") asset_group: AssetGroup = mutate_operation.asset_group_operation.create asset_group.name = f"Performance Max asset group #{uuid4()}" asset_group.campaign = campaign_service.campaign_path( customer_id, _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ) asset_group.final_urls.append("http://www.example.com") asset_group.final_mobile_urls.append("http://www.example.com") asset_group.status = client.enums.AssetGroupStatusEnum.PAUSED asset_group.resource_name = asset_group_service.asset_group_path( customer_id, _ASSET_GROUP_TEMPORARY_ID, ) operations.append(mutate_operation) # For the list of required assets for a Performance Max campaign, see # https://developers.google.com/google-ads/api/docs/performance-max/assets # An AssetGroup is linked to an Asset by creating a new AssetGroupAsset # and providing: # the resource name of the AssetGroup # the resource name of the Asset # the field_type of the Asset in this AssetGroup. # # To learn more about AssetGroups, see # https://developers.google.com/google-ads/api/docs/performance-max/asset-groups # Link the previously created multiple text assets. # Link the headline assets. for resource_name in headline_asset_resource_names: mutate_operation: MutateOperation = client.get_type("MutateOperation") asset_group_asset: AssetGroupAsset = ( mutate_operation.asset_group_asset_operation.create ) asset_group_asset.field_type = client.enums.AssetFieldTypeEnum.HEADLINE asset_group_asset.asset_group = asset_group_service.asset_group_path( customer_id, _ASSET_GROUP_TEMPORARY_ID, ) asset_group_asset.asset = resource_name operations.append(mutate_operation) # Link the description assets. for resource_name in description_asset_resource_names: mutate_operation: MutateOperation = client.get_type("MutateOperation") asset_group_asset: AssetGroupAsset = ( mutate_operation.asset_group_asset_operation.create ) asset_group_asset.field_type = ( client.enums.AssetFieldTypeEnum.DESCRIPTION ) asset_group_asset.asset_group = asset_group_service.asset_group_path( customer_id, _ASSET_GROUP_TEMPORARY_ID, ) asset_group_asset.asset = resource_name operations.append(mutate_operation) # Create and link the long headline text asset. mutate_operations: List[MutateOperation] = create_and_link_text_asset( client, customer_id, "Travel the World", client.enums.AssetFieldTypeEnum.LONG_HEADLINE, ) operations.extend(mutate_operations) # Create and link the business name and logo asset. mutate_operations: List[MutateOperation] = create_and_link_brand_assets( client, customer_id, brand_guidelines_enabled, "Interplanetary Cruises", "https://gaagl.page.link/bjYi", "Marketing Logo", ) operations.extend(mutate_operations) # Create and link the image assets. # Create and link the Marketing Image Asset. mutate_operations: List[MutateOperation] = create_and_link_image_asset( client, customer_id, "https:>//gaagl.page.link/Eit5", client.enums.AssetFieldTypeEnum.MARKETING_IMAGE, "Marketing Image", ) operations.extend(mutate_operations) # Create and link the Square Marketing Image Asset. mutate_operations: List[MutateOperation] = create_and_link_image_asset( client, customer_id, "https://gaagl.page.link/bjYi", client.enums.AssetFieldTypeEnum.SQUARE_MARKETING_IMAGE, "Square Marketing Image", ) operations.extend(mutate_operations) return operations def create_and_link_text_asset( client: GoogleAdsClient, customer_id: str, text: str, field_type: AssetFieldTypeEnum.AssetFieldType, ) - List[MutateOperation]: """Creates a list of MutateOperations that create a new linked text asset. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. text: the text of the asset to be created. field_type: the field_type of the new asset in the AssetGroupAsset. Returns: MutateOperations that create a new linked text asset. """ global next_temp_id operations: List[MutateOperation] = [] asset_service: AssetServiceClient = client.get_service("AssetService") asset_group_service: AssetGroupServiceClient = client.get_service( "AssetGroupService" ) # Create the Text Asset. mutate_operation: MutateOperation = client.get_type("MutateOperation") asset: Asset = mutate_operation.asset_operation.create asset.resource_name = asset_service.asset_path(customer_id, next_temp_id) asset.text_asset.text = text operations.append(mutate_operation) # Cre>ate an AssetGroupAsset to link the Asset to the AssetGroup. mutate_operation: MutateOperation = client.get_type("MutateOperation") asset_group_asset: AssetGroupAsset = ( mutate_operation.asset_group_asset_operation.create ) asset_group_asset.field_type = field_type asset_group_asset.asset_group = asset_group_service.asset_group_path( customer_id, _ASSET_GROUP_TEMPORARY_ID, ) asset_group_asset.asset = asset_service.asset_path( customer_id, next_temp_id ) operations.append(mutate_operation) next_temp_id -= 1 return operations def create_and_link_image_asset( client: GoogleAdsClient, customer_id: str, url: str, field_type: AssetFieldTypeEnum.AssetFieldType, asset_name: str, ) - List[MutateOperation]: """Creates a list of MutateOperations that create a new linked image asset. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. url: the url of the image to be retrieved and put into an asset. field_type: the field_type of the new asset in the AssetGroupAsset. asset_name: the asset name. Returns: MutateOperations that create a new linked image asset. """ global next_temp_id operations: List[MutateOperation] = [] asset_service: AssetServiceClient = client.get_service("AssetService") asset_group_service: AssetGroupServiceClient = client.get_service( "AssetGroupService" ) # Create the Image Asset. mutate_operation: MutateOperation = client.get_type("MutateOperation") asset: Asset = mutate_operation.asset_operation.create asset.resource_name = asset_service.asset_path(customer_id, next_temp_id) # Provide a unique friendly name to identify your asset. # When there is an existing image asset with the same content but a different # name, the new name will be dropped silently. asset.name = asset_name asset.type_ = client.enums.AssetTypeEnum.IMAGE asset.image_asset.data = get_image_bytes_from_ur>l(url) operations.append(mutate_operation) # Create an AssetGroupAsset to link the Asset to the AssetGroup. mutate_operation: MutateOperation = client.get_type("MutateOperation") asset_group_asset: AssetGroupAsset = ( mutate_operation.asset_group_asset_operation.create ) asset_group_asset.field_type = field_type asset_group_asset.asset_group = asset_group_service.asset_group_path( customer_id, _ASSET_GROUP_TEMPORARY_ID, ) asset_group_asset.asset = asset_service.asset_path( customer_id, next_temp_id ) operations.append(mutate_operation) next_temp_id -= 1 return operations def create_and_link_brand_assets( client: GoogleAdsClient, customer_id: str, brand_guidelines_enabled: bool, business_name: str, logo_url: str, logo_name: str, ) - List[MutateOperation]: """Creates a list of MutateOperations that create linked brand assets. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. brand_guidelines_enabled: a boolean value indicating if the campaign is enabled for brand guidelines. business_name: the business name text to be put into an asset. logo_url: the url of the logo to be retrieved and put into an asset. logo_name: the asset name of the logo. Returns: MutateOperations that create linked brand assets. """ global next_temp_id operations: List[MutateOperation] = [] asset_service: AssetServiceClient = client.get_service("AssetService") # Create the Text Asset. text_asset_temp_id = next_temp_id next_temp_id -= 1 text_mutate_operation = client.get_type("MutateOperation") text_asset: Asset = text_mutate_operation.asset_operation.create text_asset.resource_name = asset_service.asset_path( customer_id, text_asset_temp_id ) text_asset.text_asset.text = business_name operations.append(text_mutate_operation) # Create the Image Asset. image_asset_temp_id = next_temp_id next_temp_id -= 1 image_mutate_operation = client.get_type("MutateOperation") image_asset: Asset = image_mutate_operation.asset_operation.create image_asset.resource_name = asset_service.asset_path( customer_id, image_asset_temp_id ) # Provide a unique friendly name to identify your asset. # When there is an existing image asset with the same content but a different # name, the new name will be dropped silently. image_asset.name = logo_name image_asset.type_ = client.enums.AssetTypeEnum.IMAGE image_asset.image_asset.data = get_image_bytes_from_url(logo_url) operations.append(image_mutate_operation) if brand_guidelines_enabled: # Create CampaignAsset resources to link the Asset resources to the Campaign. campaign_service: CampaignServiceClient = client.get_service( "CampaignService" ) business_name_mutate_operation: MutateOperation = client.get_type( "MutateOperation" ) business_name_campaign_asset: CampaignAsset = ( business_name_mutate_operation.campaign_asset_operation.create ) business_name_campaign_asset.field_type = ( client.enums.AssetFieldTypeEnum.BUSINESS_NAME ) business_name_campaign_asset.campaign = campaign_service.campaign_path( customer_id, _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ) business_name_campaign_asset.asset = asset_service.asset_path( customer_id, text_asset_temp_id ) operations.append(business_name_mutate_operation) logo_mutate_operation: MutateOperation = client.get_type( "MutateOperation" ) logo_campaign_asset: CampaignAsset = ( logo_mutate_operation.campaign_asset_operation.create ) logo_campaign_asset.field_type = client.enums.AssetFieldTypeEnum.LOGO logo_campaign_asset.campaign = campaign_service.campaign_path( customer_id, _PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ) logo_campaign_asset.asset = asset_service.asset_path( customer_id, image_asset_temp_id ) operations.append(logo_mutate_operation) else: # Create AssetGroupAsset resources to link the Asset resources to the AssetGroup. asset_group_service: AssetGroupServiceClient = client.get_service( "AssetGroupService" ) business_name_mutate_operation: MutateOperation = client.get_type( "MutateOperation" ) business_name_asset_group_asset: AssetGroupAsset = ( business_name_mutate_operation.asset_group_asset_operation.create ) business_name_asset_group_asset.field_type = ( client.enums.AssetFieldTypeEnum.BUSINESS_NAME ) business_name_asset_group_asset.asset_group = ( asset_group_service.asset_group_path( customer_id, _ASSET_GROUP_TEMPORARY_ID, > ) ) business_name_asset_group_asset.asset = asset_service.asset_path( customer_id, text_asset_temp_id ) operations.append(business_name_mutate_operation) logo_mutate_operation: MutateOperation = client.get_type( "MutateOperation" ) logo_asset_group_asset: AssetGroupAsset = ( logo_mutate_operation.asset_group_asset_operation.create ) logo_asset_group_asset.field_type = client.enums.AssetFieldTypeEnum.LOGO logo_asset_group_asset.asset_group = ( asset_group_service.asset_group_path( customer_id, _ASSET_GROUP_TEMPORARY_ID, ) ) logo_asset_group_asset.asset = asset_service.asset_path( customer_id, image_asset_temp_id ) operations.append(logo_mutate_operation) return operations def print_response_details(response: MutateGoogleAdsResponse) - None: ">;""Prints the details of a MutateGoogleAdsResponse. Parses the "response" oneof field name and uses it to extract the new entity's name and resource name. Args: response: a MutateGoogleAdsResponse object. """ # Parse the Mutate response to print details about the entities that # were created by the request. results: Iterable[MutateOperation] = response.mutate_operation_responses suffix = "_result" for result in results: for field_descriptor, value in result._pb.ListFields(): if field_descriptor.name.endswith(suffix): name = field_descriptor.name[: -len(suffix)] else: name = field_descriptor.name print( f"Created a(n) {convert_snake_case_to_upper_case(name)} with " f"{str(value).strip()}." ) def create_asset_group_signal_operations( client: GoogleAdsClient, customer_id: str, audience_id: Optional[str] ) - List[MutateOperation]: """Creates a list of MutateOperations that may create asset group signals. Args: client: an initialized GoogleAdsClient instance. customer_id: a client customer ID. audience_id: an optional audience ID. Returns: MutateOperations that create new asset group signals. """ googleads_service: GoogleAdsServiceClient = client.get_service( "GoogleAdsService" ) asset_group_resource_name: str = googleads_service.asset_group_path( customer_id, _ASSET_GROUP_TEMPORARY_ID ) operations: List[MutateOperation] = [] if audience_id: # Create an audience asset group signal. # To learn more about Audience Signals, see: # https://developers.google.com/google-ads/api/performance-max/asset-group-signals#audiences mutate_operation: MutateOperation = client.get_type("MutateOperation") operation: AssetGroupSignal = ( mutate_operation.asset_group_signal_operation.create ) operation.asset_group = asset_group_resource_name operation.audience.audience = googleads_service.audience_path( customer_id, audience_id ) operations.append(mutate_operation) # Create a search theme asset group signal. # To learn more about Search Themes Signals, see: # https://developers.google.com/google-ads/api/performance-max/asset-group-signals#search_themes mutate_operation: MutateOperation = client.get_type("MutateOperation") operation: AssetGroupSignal = ( mutate_operation.asset_group_signal_operation.create ) operation.asset_group = asset_group_resource_name operation.search_theme.text = "travel" operations.append(mutate_operation) return operations if __name__ == "__main__": parser: argparse.ArgumentParser = argparse.ArgumentParser( description=("Creates a Performance Max campaign.") ) # The following argument(s) should be provided to run the example. parser.add_argument( "-c", "--customer_id", type=str, required=True, help="The Google Ads customer ID.", ) parser.add_argument( "-a", "--audience_id", type=str, help="The ID of an audience.", ) parser.adot;, "--brand_guidelines_enabled", type=bool, default=False, help=( "A boolean value indicating if the created campaign is enabled " "for brand guidelines." ), ) 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.audience_id, args.brand_guidelines_enabled, ) except GoogleAdsException as ex: print( f'Request with ID "{ex.request_id}" failed with status ' f'"{ex.error.code().name}" and includes the following errors:' ) for error in ex.failure.errors: print(f'Error with message "{error.message}".') if error.location: for field_path_element in error.location.field_path_elements: print(f"\t\tOn field: {field_path_element.field_name}") sys.exit(1) add_performance_max_campaign.py
রুবি
#!/usr/bin/env ruby # Encoding: utf-8 # # Copyright 2021 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This example shows how to create a Performance Max campaign. # # For more information about Performance Max campaigns, see # https://developers.google.com/google-ads/api/docs/performance-max/overview # # Prerequisites: # - You must have at least one conversion action in the account. For # more about conversion actions, see # https://developers.google.com/google-ads/api/docs/conversions/overview#conversion_actions # # This example uses the default customer conversion goals. For an example # of setting campaign-specific conversion goals, see # shopping_ads/add_performance_max_retail_campaign.rb require 'optparse' require 'date' require 'open-uri' require 'google/ads/google_ads' # We specify temporary IDs that are specific to a single mutate request. # Temporary IDs are always negative and unique within one mutate request. # # See https://developers.google.com/google-ads/api/docs/mutating/best-practices # for further details. # # These temporary IDs are fixed because they are used in multiple places. BUDGET_TEMPORARY_ID = "-1" PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID = "-2" ASSET_GROUP_TEMPORARY_ID = "-3" # There are also entities that will be created in the same request but do not # need to be fixed temporary IDs because they are referenced only once. def next_temp_id @id ||= ASSET_GROUP_TEMPORARY_ID.to_i @id -= 1 end def add_performance_max_campaign( customer_id, audience_id, brand_guidelines_enabled) # GoogleAdsClient will read a config file from # ENV['HOME']/google_ads_config.rb when called without parameters client = Google::Ads::GoogleAds::GoogleAdsClient.new # Performance Max campaigns require that repeated assets such as headlines # and descriptions be created before the campaign. # For the list of required assets for a Performance Max campaign, see # https://developers.google.com/google-ads/api/docs/performance-max/assets # # Create the headlines. headline_asset_resource_names = create_multiple_text_assets( client, customer_id, [ "Travel", "Travel Reviews", "Book travel", ]) # Create the descriptions. description_asset_resource_names = create_multiple_text_assets( client, customer_id, [ "Take to the air!", "Fly to the sky!", ]) # The below methods create and return MutateOperations that we later # provide to the GoogleAdsService.Mutate method in order to create the # entities in a single request. Since the entities for a Performance Max # campaign are closely tied to one-another, it's considered a best practice # to create them in a single Mutate request so they all complete # successfully or fail entirely, leaving no orphaned entities. See: # https://developers.google.com/google-ads/api/docs/mutating/overview campaign_budget_operation = create_campaign_budget_operation( client, customer_id, ) performance_max_campaign_operation = create_performance_max_campaign_operation( client, customer_id, brand_guidelines_enabled, ) campaign_criterion_operations = create_campaign_criterion_operations( client, customer_id, ) asset_group_operations = create_asset_group_operation( client, customer_id, headline_asset_resource_names, description_asset_resource_names, brand_guidelines_enabled, ) asset_group_signal_operations = create_asset_group_signal_operations( client, customer_id, audience_id, ) # Send the operations in a single Mutate request. response = client.service.google_ads.mutate( customer_id: customer_id, mutate_operations: [ # It's important to create these entities in this order because # they depend on each other. campaign_budget_operation, performance_max_campaign_operation, # Expand the list of multiple operations into the list of # other mutate operations campaign_criterion_operations, asset_group_operations, asset_group_signal_operations, ].flatten) print_response_details(response) end # Creates a MutateOperation that creates a new CampaignBudget. # # A temporary ID will be assigned to this campaign budget so that it can be # referenced by other objects being created in the same Mutate request. def create_campaign_budget_operation(client, customer_id) client.operation.mutate do |m| m.campaign_budget_operation = client.operation.create_resource.campaign_budget do |cb| cb.name = "Performance Max campaign budget #{SecureRandom.uuid}" # The budget period already defaults to DAILY. cb.amount_micros = 50_000_000 cb.delivery_method = :STANDARD # A Performance Max campaign cannot use a shared campaign budget. cb.explicitly_shared = false # Set a temporary ID in the budget's resource name so it can be referenced # by the campaign in later steps. cb.resource_name = client.path.campaign_budget(customer_id, BUDGET_TEMPORARY_ID) end end end # Creates a MutateOperation that creates a new Performance Max campaign. # # A temporary ID will be assigned to this campaign so that it can # be referenced by other objects being created in the same Mutate request. def create_performance_max_campaign_operation( client, customer_id, brand_guidelines_enabled) client.operation.mutate do |m| m.campaign_operation = client.operation.create_resource.campaign do |c| c.name = "Performance Max campaign #{SecureRandom.uuid}" # Set the campaign status as PAUSED. The campaign is the only entity in # the mutate request that should have its status set. c.status = :PAUSED # All Performance Max campaigns have an advertising_channel_type of # PERFORMANCE_MAX. The advertising_channel_sub_type should not be set. c.advertising_channel_type = :PERFORMANCE_MAX # Bidding strategy must be set directly on the campaign. # Setting a portfolio bidding strategy by resource name is not supported. # Max Conversion and Maximize Conversion Value are the only strategies # supported for Performance Max 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. c.bidding_strategy_type = :MAXIMIZE_CONVERSION_VALUE c.maximize_conversion_value = client.resource<<.maximize_conversion_value do |mcv| mcv.target_roas = 3.5 end # Configures the optional opt-in/out status for asset automation settings. c.asset_automation_settings client.resour<<ce.asset_automation_setting do |aas| aas.asset_automation_type = :GENERATE_IMAGE_EXTRACTION aas.asset_automation_status = :OPTED_IN end c.asset_automation_settings client.resource.asset_automat<<ion_setting do |aas| aas.asset_automation_type = :FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION aas.asset_automation_status = :OPTED_IN end c.asset_automation_settings client.re<<source.asset_automation_setting do |aas| aas.asset_automation_type = :TEXT_ASSET_AUTOMATION aas.asset_automation_status = :OPTED_IN end c.asset_automation_settings client.resource.asse<<t_automation_setting do |aas| aas.asset_automation_type = :GENERATE_ENHANCED_YOUTUBE_VIDEOS aas.asset_automation_status = :OPTED_IN end c.asset_automation_settings client.resource.asset_automation_setting do |aas| aas.asset_automation_type = :GENERATE_IMAGE_ENHANCEMENT aas.asset_automation_status = :OPTED_IN end # Set if the campaign is enabled for brand guidelines. For more # information on brand guidelines, see # https://support.google.com/google-ads/answer/14934472. c.brand_guidelines_enabled = brand_guidelines_enabled # Assign the resource name with a temporary ID. c.resource_name = client.path.campaign(customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID) # Set the budget using the given budget resource name. c.campaign_budget = client.path.campaign_budget(customer_id, BUDGET_TEMPORARY_ID) # Declare whether or not this campaign serves political ads targeting the EU. # Valid values are CONTAINS_EU_POLITICAL_ADVERTISING and # DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING. c.contains_eu_political_advertising = :DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING # Optional fields c.start_date = DateTime.parse((Date.today + 1).to_s).strftime('%Y%m%d') c.end_date = DateTime.parse(Date.today.next_year.to_s).strftime('%Y%m%d') end end end # Creates a list of MutateOperations that create new campaign criteria. def create_campaign_criterion_operations(client, customer_id) operations = [] # Set the LOCATION campaign criteria. # Target all of New York City except Brooklyn. # Location IDs are listed here: # https://developers.google.com/google-ads/api/reference/data/geotargets # and they can also be retrieved using the GeoTargetConstantService as shown # here: https://developers.google.com/google-ads/api/docs/targeting/location-targeting # # We will<< add one positive location target for New York City (ID=1023191) # and one negative location target for Brooklyn (ID=1022762). # First, add the positive (negative = false) for New York City. operations client.operation.mutate do |m| m.campaign_criterion_operation = client.operation.create_resource.campaign_criterion do |cc| cc.campaign = client.path.campaign( customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID) cc.location = client.resource.lo<<cation_info do |li| li.geo_target_constant = client.path.geo_target_constant("1023191") end cc.negative = false end end # Next add the negative target for Brooklyn. operations client.operation.mutate do |m| m.campaign_criterion_operation = client.operation.create_resource.campaign_criterion do |cc| cc.campaign = client.path.campaign( customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID) cc.location = c<<lient.resource.location_info do |li| li.geo_target_constant = client.path.geo_target_constant("1022762") end cc.negative = true end end # Set the LANGUAGE campaign criterion. operations client.operation.mutate do |m| m.campaign_criterion_operation = client.operation.create_resource.campaign_criterion do |cc| cc.campaign = client.path.campaign( customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID) # Set the language. # For a list of all language codes, see: # https://developers.google.com/google-ads/api/reference/data/codes-formats#expandable-7 cc.language = client.resource.language_info do |li| li.language_constant = client.path.language_constant("1000") # English end end end operations end # Creates multiple text assets and returns the list of resource names. def create_multiple_text_assets(client, customer_id, texts) operations = texts.map do |text| client.operation.mutate do |m| m.asset_operation = client.operation.create_resource.asset do |asset| asset.text_asset = client.resource.text_asset do |text_asset| text_asset.text = text end end end end # Send the operations in a single Mutate request. response = client.service.google_ads.mutate( customer_id: customer_id, mutate_operations: operations, ) asset_resource_names = [] response.mutate_operation_responses.each do |result| if result.asset_result asset_resource_names.append(result.asset_result.resource_name) end end print_response_details(response) asset_resource_names end # Creates a list of MutateOperations that create a new asset_group. # # A temporary ID will be assigned to this asset group so that it can # be referenced by other objects being created in the same Mu<<tate request. def create_asset_group_operation( client, customer_id, headline_asset_resource_names, description_asset_resource_names, brand_guidelines_enabled) operations = [] # Create the AssetGroup operations client.operation.mutate do |m| m.asset_group_operation = client.opera<<tion.create_resource.asset_group do |ag| ag.nam<<e = "Performance Max asset group #{SecureRandom.uuid}" ag.campaign = client.path.campaign( customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID) ag.final_urls "http://www.example.com" ag.final_mobile_urls "http://www.example.com" ag.status = :PAUSED ag.resource_name = client.path.asset_group( customer_id, ASSET_GROUP_TEMPORARY_ID) end end # For the list of required assets for a Performance Max campaign, see # https://developers.google.com/google-ads/api/docs/performance-max/assets # # An AssetGroup is linked to an Asset by creating a new AssetGroupAsset # and providing: # the resource name of the AssetGroup # the resource name of the Asset # the field_type of the Asset in this AssetGroup. # # To learn <<more about AssetGroups, see # https://developers.google.com/google-ads/api/docs/performance-max/asset-groups # Link the previously created multiple text assets. # Link the headline assets. headline_asset_resource_names.each do |resource_name| operations client.operation.mutate do |m| m.asset_group_asset_operation = client.operation.create_resource .asset_group_asset do |aga| aga.field_type = :HEADLINE a<<ga.asset_group = client.path.asset_group( customer_id, ASSET_GROUP_TEMPORARY_ID) aga.asset = resource_name end end end # Link the description assets. description_asset_resource_names.each do |resource_name| operations client.operation.mutate do |m| m.asset_group_asset_operation = client.operation.create_resource .asset_group_asset do |aga| aga.field_type = :DESCRIPTION aga.asset_group = client.path.asset_group( customer_id, ASSET_GROUP_TEMPORARY_ID) aga.asset = resource_name end end end # Create and link the long headline text asset. operations += create_and_link_text_asset( client, customer_id, "Travel the World", :LONG_HEADLINE) # Create and link the business name and logo asset. operations += create_and_link_brand_assets( client, customer_id, brand_guidelines_enabled, "Interplanetary Cruises", "https://gaagl.page.link/bjYi", "Marketing Logo") # Create and link the image assets. # Create and link the Marketing Image Asset. operations += create_and_link_image_asset( client, customer_id, "https://gaagl.page.link/Eit5", :MARKETING_IMAGE, "Marketing Image") # Create and link the Square Marketing Image Asset. operations += create_and_link_image_asset( client, customer_id, "http<<s://gaagl.page.link/bjYi", :SQUARE_MARKETING_IMAGE, "Square Marketing Image") operations end # Creates a list of MutateOperations that create a new linked text asset. def create_and_link_text_asset(client, customer_id, text, field_type) operations = [] temp_id = next_temp_id # Create the Text Asset. operations client.operation.<<mutate do |m| m.asset_operation = client.operation.create_resource.asset do |a| a.resource_name = client.path.asset(customer_id, temp_id) a.text_asset = client.resource.text_asset do |text_asset| text_asset.text = text end end end # Create an AssetGroupAsset to link the Asset to the AssetGroup. operations client.operation.mutate do |m| m.asset_group_asset_operation = client.operation.create_resource .asset_group_asset do |aga| aga.field_type = field_type aga.asset_group = client.path.asset_group( customer_id, ASSET_GROUP<<_TEMPORARY_ID) aga.asset = client.path.asset(customer_id, temp_id) end end operations end # Creates a list of MutateOperations that create a new linked image asset. def create_and_link_image_asset(client, customer_id, url, field_type, asset_name) operations = [] temp_id = next_temp_id # Create the Image Asset. operations client.operation.mutate do |m| m.asset_operation = client.operation.create_resource.asset do |a| a.resource_name = client.path.asset(customer_id, temp_id) # Provide a unique friendly name to identify your asset. # When there is an existing image asset with the sa<<me content but a different # name, the new name will be dropped silently. a.name = asset_name a.type = :IMAGE a.image_asset = client.resource.image_asset do |image_asset| image_asset.data = get_image_bytes(url) end end end # Create an AssetGroupAsset to link the Asset to the AssetGroup. operations client.operation.mutate do |m| m.asset_group_asset_operation = client.operation.create_resource. asset_group_asset do |aga| aga.field_type = field_type aga.asset_group = client.path.asset_group( customer_id, ASSET_GROUP_TEMPORARY_ID, ) aga.asset = client.path.asset(customer_id, <<temp_id) end end operations end # Creates a list of MutateOperations that create linked brand assets. def create_and_link_brand_assets( client, customer_id, brand_guidelines_enabled, business_name, logo_url, logo_name) operations = [] # Create the Text Asset. text_asset_temp_id = next_temp_id operations client.operation.mutate do |m| <<m.asset_operation = client.operation.create_resource.asset do |a| a.resource_name = client.path.asset(customer_id, text_asset_temp_id) a.text_asset = client.resource.text_asset do |text_asset| text_asset.text = business_name end end end # Create the Image Asset. image_asset_temp_id = next_temp_id operations client.operation.mutate do |m| m.asset_operation = client.operation.create_resource.asset do |a| a.resource_name = client.path.asset(customer_id, image_asset_temp_id) # Provide a unique friendly name to identify your asset. # When there is an existing image asset with the same content but a different # name, the new na<<me will be dropped silently. a.name = logo_name a.type = :IMAGE a.image_asset = client.resource.image_asset do |image_asset| image_asset.data = get_image_bytes(logo_url) end end end if brand_guidelines_enabled # Create CampaignAsset resources to link the Asset resources to the Campaign. operations client.operation.mutate do |m| m.campaign_asset_<<operation = client.operation.create_resource. campaign_asset do |ca| ca.field_type = :BUSINESS_NAME ca.campaign = client.path.campaign( customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID, ) ca.asset = client.path.asset(customer_id, text_asset_temp_id) end end operations client.operation.mutate do |m| m.campaign_asset_operation = client.operation.create_resource. campaign_asset do |ca| << ca.field_type = :LOGO ca.campaign = client.path.campaign( customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID, ) ca.asset = client.path.asset(customer_id, image_asset_temp_id) end end else # Create AssetGroupAsset resources to link the Asset resources to the AssetGroup. operations client.operation.mutate do |m| m.asset_group_asset_<<operation = client.operation.create_resource. asset_group_asset do |aga| aga.field_type = :BUSINESS_NAME aga.asset_group = client.path.asset_group( customer_id, ASSET_GROUP_TEMPORARY_ID, ) aga.asset = client.path.asset(customer_id, text_asset_temp_id) end end operations client.operation.mutate do |m| m.asset_group_asset_operation = client.operation.create_resource. asset_group_asset do |aga| aga.field_type = :LOGO aga.asset_group = client.path.asset_group( customer_id, ASSET_GROUP_TEMPO<<RARY_ID, ) aga.asset = client.path.asset(customer_id, image_asset_temp_id) end end end operations end # Create a list of MutateOperations that create AssetGroupSignals. def create_asset_group_signal_operations(client, customer_id, audience_id) operations = [] return operations if audience_id.nil? operations client.operation.mutate do |m| m.asset_group_signal_operation = client.operation.create_resource. asset_group_signal do |ags| ags.asset_group = client.path.asset_group( customer_id, ASSET_GROUP_TEMPORARY_ID, ) ags.audience = client.resource.audience_info do |ai| ai.audience = client.path.audience(customer_id, audience_id) end end end operations end # Loads image data from a URL. def get_image_bytes(url) URI.open(url).read end # Prints the details of a MutateGoogleAdsResponse. def print_response_details(response) # Parse the mutate response to print details about the entities that # were created by the request. suffix = "_result" response.mutate_operation_responses.each do |result| result.to_h.select {|k, v| v }.each do |name, value| if name.to_s.end_with?(suffix) name = name.to_s.delete_suffix(suffix) end puts "Created a(n) #{::Google::Ads::GoogleAds::Utils.camelize(name)} " \ "with #{value.to_s.strip}." end 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[:audience_id] = nil options[:brand_guidelines_enabled] = false 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('-D', '--audience-id AUDIENCE-ID', String, 'Audience ID (optional)') do |v| options[:audience_id] = v end opts.on('-B', '--brand-guidelines-enabled', >39;Enable brand guidelines (optional)') do options[:brand_guidelines_enabled] = true end opts.separator '' opts.separator 'Help:' opts.on_tail('-h', '--help', 'Show this message') do puts opts exit end end.parse! begin add_performance_max_campaign( options.fetch(:customer_id).tr("-", ""), options[:audience_id], options[:brand_guidelinle::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 add_performance_max_campaign.rb
পার্ল
#!/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. # # This example shows how to create a Performance Max campaign. # # For more information about Performance Max campaigns, see # https://developers.google.com/google-ads/api/docs/performance-max/overview. # # Prerequisites: # - You must have at least one conversion action in the account. For # more about conversion actions, see # https://developers.google.com/google-ads/api/docs/conversions/overview#conversion_actions. # # This example uses the default customer conversion goals. For an example of # setting campaign-specific conversion goals, see # shopping_ads/add_performance_max_retail_campaign.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::Utils::MediaUtils; use Google::Ads::GoogleAds::V22::Resources::CampaignBudget; use Google::Ads::GoogleAds::V22::Resources::Campaign; use Google::Ads::GoogleAds::V22::Resources::CampaignCriterion; use Google::Ads::GoogleAds::V22::Resources::CampaignAsset; use Google::Ads::GoogleAds::V22::Resources::Asset; use Google::Ads::GoogleAds::V22::Resources::AssetAutomationSetting; use Google::Ads::GoogleAds::V22::Resources::AssetGroup; use Google::Ads::GoogleAds::V22::Resources::AssetGroupAsset; use Google::Ads::GoogleAds::V22::Resources::AssetGroupSignal; use Google::Ads::GoogleAds::V22::Common::MaximizeConversionValue; use Google::Ads::GoogleAds::V22::Common::LocationInfo; use Google::Ads::GoogleAds::V22::Common::LanguageInfo; use Google::Ads::GoogleAds::V22::Common::TextAsset; use Google::Ads::GoogleAds::V22::Common::ImageAsset; use Google::Ads::GoogleAds::V22::Common::AudienceInfo; use Google::Ads::GoogleAds::V22::Enums::BudgetDeliveryMethodEnum qw(STANDARD); use Google::Ads::GoogleAds::V22::Enums::CampaignStatusEnum; use Google::Ads::GoogleAds::V22::Enums::AdvertisingChannelTypeEnum qw(PERFORMANCE_MAX); use Google::Ads::GoogleAds::V22::Enums::AssetAutomationStatusEnum qw(OPTED_IN); use Google::Ads::GoogleAds::V22::Enums::AssetAutomationTypeEnum qw(GENERATE_IMAGE_EXTRACTION FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION TEXT_ASSET_AUTOMATION GENERATE_ENHANCED_YOUTUBE_VIDEOS GENERATE_IMAGE_ENHANCEMENT); use Google::Ads::GoogleAds::V22::Enums::AssetGroupStatusEnum; use Google::Ads::GoogleAds::V22::Enums::AssetFieldTypeEnum qw(HEADLINE DESCRIPTION LONG_HEADLINE BUSINESS_NAME LOGO MARKETING_IMAGE SQUARE_MARKETING_IMAGE); use Google::Ads::GoogleAds::V22::Enums::EuPoliticalAdvertisingStatusEnum qw(DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING); use Google::Ads::GoogleAds::V22::Services::GoogleAdsService::MutateOperation; use Google::Ads::GoogleAds::V22::Services::CampaignBudgetService::CampaignBudgetOperation; use Google::Ads::GoogleAds::V22::Services::CampaignService::CampaignOperation; use Google::Ads::GoogleAds::V22::Services::CampaignCriterionService::CampaignCriterionOperation; use Google::Ads::GoogleAds::V22::Services::AssetService::AssetOperation; use Google::Ads::GoogleAds::V22::Services::AssetGroupService::AssetGroupOperation; use Google::Ads::GoogleAds::V22::Services::AssetGroupAssetService::AssetGroupAssetOperation; use Google::Ads::GoogleAds::V22::Services::AssetGroupSignalService::AssetGroupSignalOperation; 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); use Data::Uniqid qw(uniqid); use POSIX qw(strftime); # We specify temporary IDs that are specific to a single mutate request. # Temporary IDs are always negative and unique within one mutate request. # # See https://developers.google.com/google-ads/api/docs/mutating/best-practices # for further details. # # These temporary IDs are fixed because they are used in multiple places. use constant BUDGET_TE>MPORARY_ID = -1; use constant PERFORMAN>CE_MAX_CAMPAIGN_TEMPORARY_ID = -2; use constant ASSET_GRO>UP_TEMPORARY_ID = -3; # There are also entities that will be created in the same request but do not # need to be fixed temporary IDs because they are referenced only once. our $next_temp_id = ASSET_GROUP_TEMPORARY_ID - 1; sub add_performance_max_campaign { my ($api_client, $customer_id, $audience_id, $brand_guidelines_enabled) = @_; # Performance Max campaigns require that repeated assets such as headlines # and descriptions be created before the campaign. # For the list of required assets for a Performance Max campaign, see # https://developers.google.com/google-ads/api/docs/performance-max/assets. # # Create the headlines. my $headline_asset_resource_names = create_multiple_text_assets($api_client, $customer_id, ["Travel", "Travel Reviews", "Book travel"]); # Create the descriptions. my $description_asset_resource_names = create_multiple_text_assets($api_client, $customer_id, ["Take to the air!", "Fly to the sky!"]); # It's important to create the below entities in this order because they depend # on each other. my $operations = []; # The below methods c>reate and return MutateOperations that we later provide to # the GoogleAdsService-mutate() method in order to create the entities in a # single request. Since the entities for a Performance Max campaign are closely # tied to one-another, it's considered a best practice to create them in a # single mutate request so they all complete successfully or fail entirely, # leaving no orphaned entities. See: # https://developers.google.com/google-ads/api/docs/mutating/overview. push @$operations, create_campaign_budget_operation($customer_id); push @$operations, create_performance_max_campaign_operation($customer_id, $brand_guidelines_enabled); push @$operations, @{create_campaign_criterion_operations($customer_id)}; push @$operations, @{ create_asset_group_operations( $customer_id, $headline_asset_resource_names, $description_asset_resource_names, $brand_guidelines_enabled )}; push @$operations, @{create_asset_group_signal_operations($customer_id, $audience_id)}; # Issue a mutate request to crea>te everything and p>rint its information. my $mut>ate_google_ads_response = $api_client>-GoogleAdsService()-mutate({ customerId = $customer_id, mutateOperations = $operations }); print_response_details($mutate_google_ads_response); return 1; } # Creates a MutateOperation that creates a new CampaignBudget. # # A temporary ID will be assigned to this campaign budget so that it can be # referenced by other objects being created in the same mutate request. sub create_campaign_budget_operation { my ($customer_id) = @_; # Create a mutate operation that creates a campaign budget operation>. return Google::Ads::GoogleAds::V22>::Services::GoogleAdsService::MutateOperation- new({ campaignBudgetOperation = Google:>:Ads::GoogleAds::V22::Se>rvices::CampaignBudgetService::CampaignBudgetOperation > -new({ create = Google::Ads::GoogleAds::V22::Resources::CampaignBudget-new( { # Set a temporary ID in the budget's resource name so it ca>n be # referenced by the campaign in later steps. resourceName = Google::Ads::GoogleAds::V22::Utils::ResourceNames::campaign_budge>t( $customer_id, BUDGET_TEMPORARY_ID ), name = "Performance Max campaign budget #" .> uniqid(), # The budget per>iod already defaults to DAILY. amountMicros = 50000000, deliveryMethod = STANDARD, > # A Performance Max campaign cannot use a shared campaign budget. explicitlyShared = "false", })})}); } # Creates a MutateOperation that creates a new Performance Max campaign. # # A temporary ID will be assigned to this campaign so that it can be referenced # by other objects being created in the same mutate request. sub create_performance_max_campaign_operation { my ($customer_id, $brand_guidelines_enabled) = @_; # Configures the op>tional opt-in/out status for asset automation settings. # When we create the campaign object, we set campaign-{assetAutomationSettings} # equal to $asset_automation_settings. my $asset_automation_settings = []; my $asset_automation_types = [ GENERATE_IMAGE_EXTRACTION, FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION, TEXT_ASSET_AUTOMATION, GENERATE_ENHANCED_YOUTUBE_VIDEOS, GENERATE_IMAGE_ENHANCEMENT ]; foreach my $asset_automation_type (@$asset_automation_type>s) { push @$asset_automation_sett>ings, Google::Ads::GoogleAds::V22::R>esources::AssetAutomationSetting-new({ assetAutomationStatus = OPTED_IN, assetAutomationType = $asset_automation_type }); } # Create a mutate operation that crea>tes a campaign operation. return > Google::Ads::GoogleAds::V22::Services::GoogleAdsService::MutateOperation- new({ > campaignOperation = > Google::Ads::GoogleAds::V22::Services::Campai>gnService::CampaignOperation -new({ create = Google::Ads::GoogleAds::V22::Reso>urces::Campaign-new({ # Assign the resource name with a temporary ID. resourceName = Google::Ads::GoogleAds::V22::Utils::ResourceNames::campa>ign( $customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ), name = "Performance Max campai>gn #" . uniqid(), # Set the budget using the given budget resource name. campaignBudget = Google::Ads::GoogleAds::V22::Utils::ResourceNames::campaign_budget( $customer_id, BUDGET_TEMPORARY_ID ), # Set the campaign status as PAUSED. The> campaign is the only entity in # the mutate request that should have its status set. status = Google::Ads::GoogleAds::V22::Enums::CampaignStatusEnum::PAUSED, # All Performance Max campaigns have an advertisingChannelType o>f # PERFORMANCE_MAX. The advertisingChannelSubType should not be set. advertisingChannelType = PERFORMANCE_MAX, # Bidding strategy must be set directly on the campaign. # Setting a portfolio bidding strategy by resource name is not supported. # Max Conversion and Maximize Conversion Value are the only strategies # supported for Performance Max 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/go>ogle-ads/answer/7684216. # A targetRoas of 3.5 corresponds to a >350% return on ad spend. maximizeConver>sionValue = Google::Ads::GoogleAds::V22::Common::MaximizeConversionValue- new({ targetRoas = 3.5 } ), # Set if the campaign is enabled for brand guidelines. For more info>rmation # on brand guidelines, see https://support.google.com/google-ads/answer/14934472. brandGuidelinesEnabled = $brand_guideli>nes_enabled, # Configures the optional opt-in/out status for asset automa>tion settings. assetAutomationSettings = $asset_automation_setti>ngs, # Optional fields. startDate = strftime("%Y%m%d", localtime(time + 60 * 60 * 24)), endDate = strftime("%Y%m%d", localtime(time + 60 * 60 * 24 * 365)), # Declare whether or not this campaign serves political ads targeting the EU. ># Valid values are CONTAINS_EU_POLITICAL_ADVERTISING and # DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING. containsEuPoliticalAdvertising = DOES_NOT_CONTAIN_EU_POLITICAL_ADVERTISING })})}); } # Creates a list of MutateOperations that create new campaign criteria. sub create_campaign_criterion_operations { my ($customer_id) = @_; my $operations = []; # Set the LOCATION campaign criteria. # Target all of New York City except Brooklyn. # Location IDs are listed here: # https://developers.google.com/google-ads/api/reference/data/geotargets # and they can also be retrieved using the GeoTargetConstantService as shown # here: https://developers.google.com/google-ads/api/docs/targeting/location-targeting. # # We will add one positive location target for New York City (ID=1023191) # and one negative location target for Brooklyn (ID=1022762). ># First, add the positive (negative = false) >for New York City. push @$operations, Google::Ads::GoogleAds::V22::Services::GoogleAdsService::MutateOpe>ration- new({ >campaignCriterionOperation = Google::Ads::GoogleAds::V22::Servi>ces::CampaignCriterionService:>:CampaignCriterionOperation -new({ create = Google::Ads::GoogleAds::V22::Resources::CampaignCriterion-new({ campaign = Google::Ad>s::GoogleAds::V22::Utils::ResourceNames::campaign( >$customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMP>ORARY_ID ), location = Google::Ads::GoogleAds::V22::Common::LocationInfo-new({ geoTargetConstant = > Google::Ads::GoogleAds::V22::Utils::ResourceNames::geo_target_constant( 1023191)} ), negative = "false&>quot; })})}); # Next add the n>egative target for Brooklyn. push @$operations, Google::Ads::GoogleAds::V22::Services::GoogleAdsService:>:MutateOperation- ne>w({ campaignCriterionOperation = Google::Ads::GoogleAds::>V22::Services::CampaignCriteri>onService::CampaignCriterionOperation -new({ create = Google::Ads::GoogleAds::V22::Resources::CampaignCriterion-new({ campaign = >Google::Ads::GoogleAds::V22::Utils::ResourceNames::campaign( > $customer_id, PERFORMANCE_MAX_CAM>PAIGN_TEMPORARY_ID ), location = Google::Ads::GoogleAds::V22::Common::LocationInfo-new({ geoTargetCons>tant = Google::Ads::GoogleAds::V22::Utils::ResourceNames::geo_target_constant( 1022762)} ), negati>ve = "true" })})}); ># Set the LANGUAGE campaign criterion. push @$operations, Google::Ads::GoogleAds::V22::Services::GoogleA>dsService::MutateOperati>on- new({ campaignCriterionOperation = Google::Ads::G>oogleAds::V22::Services::Campa>ignCriterionService::CampaignCriterionOperation -new({ create = Google::Ads::GoogleAds::V22::Resources::CampaignCriterion-new({ campaign = Google::Ads::GoogleAds::V22::Utils::ResourceNames::campaign( $customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ), # Set the language. > # For a list of all language codes, see: > # https://developers.google.com/google-ad>s/api/reference/data/codes-formats#expandable-7. language = Google::Ads::GoogleAds::V22::Common::LanguageInfo-new({ languageConstant = Google::Ads::GoogleAds::V22::Utils::ResourceNames::language_constant( 1000) # English })})})}); return $operations; } # Creates multiple text assets and returns the list of resource names. sub create_multiple_text_assets { my ($api_client, $customer_id, $texts) = @_; # Here again we use the GoogleAdService to create multiple text assets in a # single request. my $operations = []; foreac>h my $text (@$texts) { # C>reate a mutate operation for a text asset. push @$operations, Google:>:Ads::GoogleAds::V22::Services::Googl>eAdsService::MutateOperation -new({ > assetOperation = Goo>gle::Ads::GoogleAds::V22::Services::AssetService::AssetOperation- > new({ crea>te = Google::Ads::GoogleAds::V22::Resources::Asset-new({ textAsset = Google::Ads::GoogleAds::V22::C>ommon::TextAsset-ne>w({ text = >$text })})})}); }> # Issue a mutate request to add all assets. my $mutate_google_ads_response = $api_client-GoogleAdsService>()-mutate({ customerId = $customer_id, mutateOperations = $ope>rations }); my $asset_resource_names = []; foreach my $response (@{$mutate_google_ads_response-{mutateOperationResponses}}) { push @$asset_resource_names, $response-{assetResult}{resourceName}; } print_response_details($mutate_google_ads_response); return $asset_resource_names; } # Creates a list of MutateOperations that create a new asset group. # # A temporary ID will be assigned to this asset group so that it can be referenced # by other objects being created in the same mutate request. sub create_asset_group_operations { my ( $customer_id, $headline_asset_resource_names, $description_asset_resource_names, $brand_guidelines_enabled ) = @_; my $op>erations = []; # Create a mutate ope>ration that creates an asset group operation. push @$operations, Google::Ads::GoogleAds::V>22::Services::GoogleAdsS>ervice::MutateOperation- new({ assetGroupO>peration = Google::Ads::Go>ogleAds::V22::Services::AssetGroupService::AssetGroupOperation -new({ create = Google::Ads::GoogleAds::V22::Resources::AssetGroup-new({ resourceNam>e = Google::Ads::GoogleAds::V22::Utils::ResourceNames>::asset_group( $customer_id, ASSET_GROUP_TEMPORARY_ID ), name = "Performance Max asset group #" . uniqid(), campaign = > Google::Ads::GoogleAds::V22::Utils::ResourceNam>es::campaign( $customer_id, PERFORMANCE_MAX_>CAMPAIGN_TEMPORARY_ID ), finalUrls = ["http://www.example.com"], finalMobileUrls = ["http://www.example.com"], status = Google::Ads::GoogleAds::V22::Enums::AssetGroupStatusEnum::PAUSED })})}); # For the list of required assets for a Performance Max campaign, see # https://developers.google.com/google-ads/api/docs/performance-max/assets. # An AssetGroup is linked to an Asset by creating a new AssetGroupAsset # and providing: # - the resource name of the AssetGroup # - the resource name of the Asset # - the fieldType of the Asset in this AssetGroup # # To learn more about AssetGroups, see # https://developers.google.com/google-ads/api/docs/performance-max/asset-groups. # Link the previously created multiple text >assets. # Link the headline assets. > foreach my $resource_name (@$headline_asset_resource_names) { push @$operations, Google::Ads::Googl>eAds::V22::Services::Googl>eAdsService::MutateOperation -new({ assetGroupAssetOperat>ion = Google::Ads::Googl>eAds::V22::Services::AssetGroupAssetService::>AssetGroupAssetOperation -new({ create = Google::Ads::GoogleAds::V22::Resources::AssetGroupAsset-new({ asset = $resource_name, > assetGroup = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset_group( $customer_id, ASSET_GROUP_TEMPORARY_ID ), fieldType = HEADLINE })})}); >} # Link the description assets. fo>reach my $resource_name (@$description_asset_resource_names) { push @$operations, Google::Ads::Googl>eAds::V22::Services::Googl>eAdsService::MutateOperation -new({ assetGroupAssetOperat>ion = Google::Ads::Googl>eAds::V22::Services::AssetGroupAssetService::>AssetGroupAssetOperation -new({ create = Google::Ads::GoogleAds::V22::Resources::AssetGroupAsset-new({ asset = $resource_name, > assetGroup = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset_group( $customer_id, ASSET_GROUP_TEMPORARY_ID ), fieldType = DESCRIPTION })})}); } # Create and link the long headline text asset. push @$operations, @{create_and_link_text_asset($customer_id, "Travel the World", LONG_HEADLINE)}; # Create and link the business name and logo asset. push @$operations, @{ create_and_link_brand_assets( $customer_id, $brand_guidelines_enabled, "Interplanetary Cruises", "https://gaagl.page.link/bjYi", "Marketing Logo" )}; # Create and link the image assets. # Create and link the marketing image asset. push @$operations, @{ create_and_link_image_asset( $customer_id, "https://gaagl.page.link/Eit5", MARKETING_IMAGE, "Marketing Image" )}; # Create and link the square marketing image asset. push @$operations, @{ create_and_link_image_asset( $customer_id, "https://gaagl.page.link/bjYi", SQUARE_MARKETING_IMAGE, "Square Marketing Image" )}; return $operations; } # Creates a list of MutateOperation>s that create a new linked text a>sset. sub create_and_link_text_asset { my ($customer_id, $text, $field_type>) = @_; my $operations = []; > # Create a new mutate operation for a text ass>et. push @$operations, Googl>e::Ads::GoogleAds::V22::Services::GoogleAdsService::MutateOperation- new({ assetOperation = Google::Ads::GoogleAds::V22::Services::AssetService::>AssetOperation- new({ create => Google::Ads::GoogleAds::V22::>Resources::Asset-new({ resourceName = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset( $customer_id, $next_temp_id ), > textAsset = Google::Ads::GoogleAds::V22::C>ommon::TextAsset-new({ text = $text })})})}); # Create an asset group> asset to link the asset> to the asset group. push @$operations, Google::Ads::GoogleAds:>:V22::Services::GoogleAdsSe>rvice::MutateOperation- new({ assetGroupAssetOperation = Google::Ads::GoogleAds::V22::Services::AssetGroupAssetService::AssetGro>upAssetOperation -new({ create = Google::Ads::GoogleAds::V22::Resources::AssetGroupAsset-new({ asset = Google::Ads::GoogleAds::V22::Util>s::ResourceNames::asset( $customer_id, $next_temp_id ), assetGroup = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset_group( $customer_id, ASSET_GROUP_TEMPORARY_ID ), fieldType = $field_type })})}); $next_temp_id--; return $operations; } # Creates a list of MutateOperations that create a >new linked image asset. sub creat>e_and_link_image_asset { my ($customer_id, $url, $field_type, $asset_name) >= @_; my $operations = []; #> Create a new mutate operation for an image ass>et. push @$operations, Googl>e::Ads::GoogleAds::V22::Services::GoogleAdsService::MutateOperation- new({ assetOperation = Google::Ads::GoogleAds::V22::Services::AssetService::AssetOperation- new({ create = Google::Ads::GoogleAds::V22::Resources::Asset-new({ resourceName = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset( $cust>omer_id, $next_temp_id )>, # Provide a unique friendly name to identify your> asset. # When t>here is an existing image asset with the same content but a different # name, the new name will be dropped silently. name = $asset_name, imageAsset = > Google::Ads::GoogleAds::V22::Common::Im>ageAsset-new({ data = get_base64_data_from_url($url)})})})}); # Create an asset group> asset to link the asset> to the asset group. push @$operations, Google::Ads::GoogleAds:>:V22::Services::GoogleAdsSe>rvice::MutateOperation- new({ assetGroupAssetOperation = Google::Ads::GoogleAds::V22::Services::AssetGroupAssetService::AssetGro>upAssetOperation -new({ create = Google::Ads::GoogleAds::V22::Resources::AssetGroupAsset-new({ asset = Google::Ads::GoogleAds::V22::Util>s::ResourceNames::asset( $customer_id, $next_temp_id ), assetGroup = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset_group( $customer_id, ASSET_GROUP_TEMPORARY_ID ), fieldType = $field_type })})}); $next_temp_id--; return $operations; } # Creates a list of MutateOperations that create linked brand assets. sub create_and_link_brand_assets { >my ($customer_id, $brand_guidelin>es_enabled, $business_name, $logo_url, $logo_name) = @_; my $opera>tions = []; # Create the text >asset. my $text_asset_temp_id = $next_temp_id>--; push @$operations, Googl>e::Ads::GoogleAds::V22::Services::GoogleAdsService::MutateOperation- new({ assetOperation = Google::Ads::GoogleAds::V22::Services::AssetService::AssetO>peration- new({ create = Googl>e::Ads::GoogleAds::V22::Resour>ces::Asset-new({ resourceName = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset( $customer_id, $text_asset_temp_id ), textAsset => Google::Ads::GoogleAds::V22::Com>mon::TextAsset-new({ text = $business_name >})})})}); # Create the image a>sset. my $image_asset_temp_id = $next_temp_id>--; push @$operations, Googl>e::Ads::GoogleAds::V22::Services::GoogleAdsService::MutateOperation- new({ assetOperation = Google::Ads::GoogleAds::V22::Services::AssetService::AssetOperation- new({ create = Google::Ads::GoogleAds::V22::Resources::Asset-new({ resourceName = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset( $customer_id>, $image_asset_temp_id >), # Provide a unique friendly name to identify you>r asset. # When >there is an existing image asset with the same content but a different # name, the new name will be dropped silently. name = $logo_name, imageAsset = Google::Ads::GoogleAds::V22::Common::ImageAsset-new({ > data = get_base64_data_fr>om_url($logo_url)})})})}); if ($brand_guidelines_enabled) { # Create CampaignAsset resources to lin>k the Asset resources to t>he Campaign. push @$operations, Google::Ads::GoogleAds::V22>::Services::GoogleAdsService::Mut>ateOperation -new({ campaignA>ssetOperation = Google::Ads::GoogleAds::V22::Services::CampaignAssetService::CampaignAssetOperation -new({ create = Google::Ads::GoogleAds::V22::Res>ources::CampaignAsset-new({ fieldType = BUSINESS_NAME, campaign = Google::Ads::GoogleAds::V22::Utils::ResourceNames::campaign( $customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID >), asset = > Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset( $customer_id, $text_ass>et_temp_id > )})})}); push @$operations, Google::Ads::GoogleAds::V22>::Services::GoogleAdsService::Mut>ateOperation -new({ >campaignAssetOperation = Google::Ads::GoogleAds::V22::Services::CampaignAssetService::CampaignAssetOperation -new({ create = Google::Ads::GoogleAds:>:V22::Resources::CampaignAsset-new({ fieldType = LOGO, campaign = Google::Ads::GoogleAds::V22::Utils::ResourceNames::campaign( $customer_id, PERFORMANCE_MAX_CAMPAIGN_TEMPORARY_ID ), asset = Google::Ads::GoogleAds::V22::Utils::ResourceNames::a>sset( $customer_id, $i>mage_asset_temp_id )})})}); } else { # Create AssetGroupAsset resources to link the As>set resources to the Asset>Group. push @$operations, Google::Ads::GoogleAds::V22::Servic>es::GoogleAdsService::MutateO>peration -new({ assetGroupAssetOperation = Google::Ads::GoogleAds::V22::Services::AssetGroupAssetService::AssetGroupAssetOperation -new({ > create = Google::Ads::GoogleAds::V22::Resources::AssetGroupAsset-new({ asset = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asse>t( $customer_id, $text_asset_temp_id ), assetGroup = Google::Ads::GoogleAds::>V22::Utils::ResourceNames::asset_group( > $customer_id, ASSET_GROUP_TEMPORARY_ID ), fieldType = BUSI>NESS_NAME })>})}); push @$operations, Google::Ads::GoogleAds::V22::Servic>es::GoogleAdsService::MutateO>peration -new({ assetGroupAssetOperation = Google::Ads::GoogleAds::V22::Services::AssetGroupAssetService::AssetGroupAssetOperation -new({ > create = Google::Ads::GoogleAds::V22::Resources::AssetGroupAsset-new({ asset = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset>( $customer_id, $image_asset_temp_id ), assetGroup = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset_group( $customer_id, ASSET_GROUP_TEMPORARY_ID ), fieldType = LOGO })})}); } return $operations; } # Creates a list of MutateOperatio>ns that create asset group signals. sub crea>te_asset_group_signal_operations { my ($customer_id, $audience_id) = @_; my $operations = []; return >$operations if not defined $audience_id; push @$operations, Google::Ads::GoogleAds::V22::Services::GoogleAdsService::MutateOperation- new({ assetGroupSignalOperation = > Google::Ads::GoogleAds::V22::Services::AssetGroupSignalService::>AssetGroupSignalOperation > -new({ # To learn more about Audience Signals, see: # https://developers.google.com/google-ads/api/docs/performance-max/asset-groups#audience_signals > create = Google::Ads::GoogleAds::V22::Resources::Ass>etGroupSignal-new({ >assetGroup = Google::Ads::GoogleAds::V22::Utils::ResourceNames::asset_group( $customer_id, ASSET_GROUP_TEMPORARY_ID ), audience = Google::Ads::GoogleAds::V22::Common::AudienceInfo-new({ audience = Google::Ads::GoogleAds::V22::Utils::ResourceNames::audience( $customer_id, $audience_id )})})})}); return $operations>; } # Prints the details of a MutateGoogleAdsResponse. # Parses the &quo>t;response" oneof field name and uses it to extract the new entity's # name and resource name. sub p>rint_response_details { my ($mutate_google_ads_response) = @_; foreach my $response (@{$mutate_google_ads_response-{mutateOperationResponses}}) { my $result_type = [keys %$response]-[0]; printf "Created a(n) %s with '%s'.\n", ucfirs>t $result_type =~ s/Result$//r, $response-{$result_type}{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 exa>mples are set to die on any server returned faul>t. $api_client-set_die_on_faults(1); my $custom>er_id = undef; my $audience_id = undef; my $brand_guidelines_enabled = "true"; # Parameters passed on the command line will override any parameters set in code. GetOptions( "customer_id=s" = \$customer_id, "audience_id=i" = \$audience_id, "brand_guidelines_enabled=s" = \$brand_guidelines_enabled ); # 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_performance_max_campaign( $api_client, $customer_id =~ s/-//gr, $audience_id, $brand_guidelines_enabled ); =pod =head1 NAME add_performance_max_campaign =head1 DESCRIPTION This example shows how to create a Performance Max campaign. For more information about Performance Max campaigns, see https://developers.google.com/google-ads/api/docs/performance-max/overview. Prerequisites: - You must have at least one conversion action in the account. For more about conversion actions, see https://developers.google.com/google-ads/api/docs/conversions/overview#conversion_actions. This example uses the default customer conversion goals. For an example of setting campaign-specific conversion goals, see shopping_ads/add_performance_max_retail_campaign.pl. =head1 SYNOPSIS add_performance_max_campaign.pl [options] -help Show the hel The Google Ads customer ID. -audience_id [optional] An audience ID to use to improve the targeting of the Performance Max campaign. -brand_guidelines_enabled [optional] A boolean value indicating if the campaign is enabled for brand guidelines. Defaults to false. =cut add_performance_max_campaign.pl