Ejemplo de código de Anuncios de hotel
En este ejemplo se muestra cómo configurar Hotel Ads.
Sugerencia
Use el selector de lenguaje en el encabezado de documentación para elegir C#, Java, Php o Python.
Para obtener tokens de acceso y actualización para el usuario de Microsoft Advertising y realizar la primera llamada de servicio mediante la API de Bing Ads, consulte la Guía de inicio rápido . Querrá revisar la guía de introducción y los tutoriales de su lenguaje preferido, por ejemplo, C#, Java, Php y Python.
Los archivos auxiliares para ejemplos de C#, Java, Php y Python están disponibles en GitHub. Puede clonar cada repositorio o reasignar fragmentos de código según sea necesario.
Importante
Los ejemplos de código de Hotel Ads están disponibles actualmente en C# y Java.
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Threading.Tasks;
using Microsoft.BingAds.V13.CampaignManagement;
using Microsoft.BingAds;
using System.Reflection;
namespace BingAdsExamplesLibrary.V13
{
/// <summary>
/// How to apply hotel group for Microsoft Hotel Campaigns.
/// </summary>
public class HotelAds : ExampleBase
{
public override string Description
{
get { return "Microsoft Hotel Campaigns | Campaign Management V13"; }
}
public async override Task RunAsync(AuthorizationData authorizationData)
{
try
{
ApiEnvironment environment = ((OAuthDesktopMobileAuthCodeGrant)authorizationData.Authentication).Environment;
CampaignManagementExampleHelper CampaignManagementExampleHelper = new CampaignManagementExampleHelper(
OutputStatusMessageDefault: this.OutputStatusMessage);
CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
authorizationData: authorizationData,
environment: environment);
// Create a hotel campaign.
var campaigns = new[] {
new Campaign
{
CampaignType = CampaignType.Hotel, // set campaign type to Hotel
Languages = new string[] { "All" }, // for hotel campaign, language should be set to "All"
BiddingScheme = new CommissionBiddingScheme // hotel campaign supports commission, percent cpc and manual cpc bidding scheme
{
CommissionRate = 3.14,
},
Name = "Everyone's Hotel " + DateTime.UtcNow,
DailyBudget = 50,
BudgetType = BudgetLimitType.DailyBudgetStandard,
TimeZone = "PacificTimeUSCanadaTijuana",
}
};
OutputStatusMessage("-----\nAddCampaigns:");
AddCampaignsResponse addCampaignsResponse = await CampaignManagementExampleHelper.AddCampaignsAsync(
accountId: authorizationData.AccountId,
campaigns: campaigns);
long?[] campaignIds = addCampaignsResponse.CampaignIds.ToArray();
BatchError[] campaignErrors = addCampaignsResponse.PartialErrors.ToArray();
OutputStatusMessage("CampaignIds:");
CampaignManagementExampleHelper.OutputArrayOfLong(campaignIds);
OutputStatusMessage("PartialErrors:");
CampaignManagementExampleHelper.OutputArrayOfBatchError(campaignErrors);
long campaignId = (long)campaignIds[0];
// Create the hotel ad group that will have the hotel groups. This is needed.
var adGroups = new[] {
new AdGroup
{
Name = "Everyone's Hotel",
AdGroupType = "HotelAds",
Settings = new []
{
new HotelSetting
{
HotelAdGroupType = HotelAdGroupType.HotelAd, // set ad group type, should be HotelAd or PropertyAd or specify both
}
},
StartDate = null,
EndDate = new Date {
Month = 12,
Day = 31,
Year = DateTime.UtcNow.Year + 1
},
// set ad group level bid value
// Here the campaign we created is using Commission bidding scheme, so we set CommissionRate
// if the campaign bidding scheme is PercentCpc, please set PercentCpcBid
// if the campaign bidding scheme is ManualCpc, please set CpcBid
CommissionRate = new RateBid
{
RateAmount = new RateAmount { Amount = 5.6 },
}
}
};
OutputStatusMessage("-----\nAddAdGroups:");
AddAdGroupsResponse addAdGroupsResponse = await CampaignManagementExampleHelper.AddAdGroupsAsync(
campaignId: (long)campaignIds[0],
adGroups: adGroups,
returnInheritedBidStrategyTypes: false);
long?[] adGroupIds = addAdGroupsResponse.AdGroupIds.ToArray();
BatchError[] adGroupErrors = addAdGroupsResponse.PartialErrors.ToArray();
OutputStatusMessage("AdGroupIds:");
CampaignManagementExampleHelper.OutputArrayOfLong(adGroupIds);
OutputStatusMessage("PartialErrors:");
CampaignManagementExampleHelper.OutputArrayOfBatchError(adGroupErrors);
long adGroupId = (long)adGroupIds[0];
// What about hotel ad entity?
// When we call addAdGroups method, an ad will be automatically created for hotel ad group
// So it's not needed to add an ad for hotel ad group manually
// Bid all hotels
// Create a hotel group tree with one single node (root node), then update bid of the node
var hotelGrouphelper = new HotelGroupActionHelper(adGroupId);
var root = hotelGrouphelper.AddUnit(
parent: null,
listing: new HotelListing { Operand = "All", Attribute = null },
bidAmount: 0.35,
isNegative: false);
OutputStatusMessage("-----\nApplyHotelGroupActions:");
OutputStatusMessage("Applying only the root as a Unit with a bid...");
var applytHotelGroupActionsResponse = await CampaignManagementExampleHelper.ApplyHotelGroupActionsAsync(
criterionActions: hotelGrouphelper.HotelGroupActions);
// HotelGroup is a kind of AdGroupCriterion, so we can use GetAdGroupCriterionsByIds to get HotelGroup.
// Also in this example code, "AdGroupCriterion", "HotelGroup" or "HotelGroupCriterion" are equivalent.
OutputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
var hotelGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
adGroupCriterionIds: null,
adGroupId: adGroupId,
criterionType: AdGroupCriterionType.HotelGroup,
null);
OutputStatusMessage("The ad group's hotel group tree only has a root node: \n");
OutputHotelGroupCriterions(hotelGroupCriterions?.AdGroupCriterions);
// Let's update the bid of the root unit we just added.
BiddableAdGroupCriterion updatedRoot = new BiddableAdGroupCriterion
{
Id = applytHotelGroupActionsResponse.AdGroupCriterionIds[0],
CriterionBid = new RateBid
{
RateAmount = new RateAmount { Amount = 0.45 }
}
};
hotelGrouphelper = new HotelGroupActionHelper(adGroupId);
hotelGrouphelper.UpdateHotelGroup(updatedRoot);
OutputStatusMessage("-----\nApplyHotelGroupActions:");
OutputStatusMessage("Updating the bid for the tree root node...");
await CampaignManagementExampleHelper.ApplyHotelGroupActionsAsync(
criterionActions: hotelGrouphelper.HotelGroupActions);
OutputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
hotelGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
adGroupCriterionIds: null,
adGroupId: adGroupId,
criterionType: AdGroupCriterionType.HotelGroup,
null);
OutputStatusMessage("Updated the bid for the tree root node: \n");
OutputHotelGroupCriterions(hotelGroupCriterions?.AdGroupCriterions);
// Initialize and overwrite existing tree root, and build a hotel group tree structure.
// we will build it in steps to demonstrate how to use the results from ApplyHotelGroupActions to update the tree.
hotelGrouphelper = new HotelGroupActionHelper(adGroupId);
// Get existing hotel groups and find the root node.
OutputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
hotelGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
adGroupCriterionIds: null,
adGroupId: adGroupId,
criterionType: AdGroupCriterionType.HotelGroup,
null);
var existingRoot = GetRootNode(hotelGroupCriterions?.AdGroupCriterions);
if (existingRoot != null)
{
hotelGrouphelper.DeleteHotelGroup(existingRoot);
}
var newRoot = hotelGrouphelper.AddSubdivision(
null,
new HotelListing { Operand = "All", Attribute = null }
);
// The direct children of any node must have the same Operand.
// For this example we will use StarRating nodes as children of the root.
var starRating5SubDivision = hotelGrouphelper.AddSubdivision(
parent: newRoot,
listing: new HotelListing { Operand = "StarRating", Attribute = "5" });
var starRating4Unit = hotelGrouphelper.AddUnit(
parent: newRoot,
listing: new HotelListing { Operand = "StarRating", Attribute = "4" },
bidAmount: 0.35,
isNegative: false);
// "Everything Else" node for StarRating condition. We should define everything else node for each condition/operand
// For StarRating, besides 5 stars and 4 stars, all the other hotels below 4 stars are belong to the node below
var otherStarRatingsUnit = hotelGrouphelper.AddUnit(
parent: newRoot,
listing: new HotelListing { Operand = "StarRating", Attribute = null },
bidAmount: 0.35,
isNegative: false);
var brandAUnit = hotelGrouphelper.AddUnit(
parent: starRating5SubDivision,
listing: new HotelListing { Operand = "Brand", Attribute = "Brand A" },
bidAmount: 0.35,
isNegative: false);
// If you won't bid on Brand B, set the helper method's bidAmount to '0' and isNegative to true.
// The helper method will create a NegativeAdGroupCriterion and apply the condition.
var brandBUnit = hotelGrouphelper.AddUnit(
parent: starRating5SubDivision,
listing: new HotelListing { Operand = "Brand", Attribute = "Brand B" },
bidAmount: 0,
isNegative: true);
var otherBrandsUnit = hotelGrouphelper.AddUnit(
parent: starRating5SubDivision,
listing: new HotelListing { Operand = "Brand", Attribute = null },
bidAmount: 0.35,
isNegative: false);
OutputStatusMessage("-----\nApplyHotelGroupActions:");
OutputStatusMessage("Applying hotel groups to the ad group...");
applytHotelGroupActionsResponse = await CampaignManagementExampleHelper.ApplyHotelGroupActionsAsync(
criterionActions: hotelGrouphelper.HotelGroupActions);
// To retrieve hotel groups after they have been applied, call GetAdGroupCriterionsByIds.
// The hotel group with ParentCriterionId set to null is the root node.
OutputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
hotelGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
adGroupCriterionIds: null,
adGroupId: adGroupId,
criterionType: AdGroupCriterionType.HotelGroup,
null);
// The hotel group tree now has 7 nodes.
//All hotels (Root Node)
// |
// +-- Star Rating 5 (StarRating)
// | |
// | +-- Brand A (Brand)
// | |
// | +-- Brand B (Brand)
// | |
// | +-- All other (Brand)
// |
// +-- Star Rating 4 (StarRating)
// |
// +-- All other (StarRating)
OutputStatusMessage("The hotel group tree now has 7 nodes: \n");
OutputHotelGroupCriterions(hotelGroupCriterions?.AdGroupCriterions);
// Let's replace the Star Rating 4 (StarRating) node created above with an Star Rating 4 (StarRating) node that
// has children i.e. Brand C (Brand), Brand D (Brand) and All other (Brand) as follows:
//Star Rating 4 (StarRating)
//|
//+-- Brand C (Brand)
//|
//+-- Brand D (Brand)
//|
//+-- All other (Brand)
hotelGrouphelper = new HotelGroupActionHelper(adGroupId);
// To replace a node we must know its Id and its ParentCriterionId. In this case the parent of the node
// we are replacing is All hotels (Root Node), and was created at Index 1 of the previous ApplyHotelGroupActions call.
// The node that we are replacing is Star Rating 4 (StarRating), and was created at Index 3.
var rootId = applytHotelGroupActionsResponse.AdGroupCriterionIds[1];
starRating4Unit.Id = applytHotelGroupActionsResponse.AdGroupCriterionIds[3];
hotelGrouphelper.DeleteHotelGroup(starRating4Unit);
var parent = new BiddableAdGroupCriterion() { Id = rootId };
var newStarRating4Subdivision = hotelGrouphelper.AddSubdivision(
parent: parent,
listing: new HotelListing { Operand = "StarRating", Attribute = "4" }
);
var brandCUnit = hotelGrouphelper.AddUnit(
parent: newStarRating4Subdivision,
listing: new HotelListing { Operand = "Brand", Attribute = "Brand C" },
bidAmount: 0.35,
isNegative: false);
var brandDUnit = hotelGrouphelper.AddUnit(
parent: newStarRating4Subdivision,
listing: new HotelListing { Operand = "Brand", Attribute = "Brand D" },
bidAmount: 0.35,
isNegative: false);
var otherBrands = hotelGrouphelper.AddUnit(
parent: newStarRating4Subdivision,
listing: new HotelListing { Operand = "Brand", Attribute = null },
bidAmount: 0.35,
isNegative: false);
OutputStatusMessage("-----\nApplyHotelGroupActions:");
OutputStatusMessage(
"Updating the hotel group to refine Star Rating 4 (StarRating) with 3 child nodes..."
);
applytHotelGroupActionsResponse = await CampaignManagementExampleHelper.ApplyHotelGroupActionsAsync(
criterionActions: hotelGrouphelper.HotelGroupActions);
OutputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
hotelGroupCriterions = await CampaignManagementExampleHelper.GetAdGroupCriterionsByIdsAsync(
adGroupCriterionIds: null,
adGroupId: adGroupId,
criterionType: AdGroupCriterionType.HotelGroup,
null);
// The hotel group tree now has 10 nodes, including the children of Star Rating 4 (StarRating):
//All hotels (Root Node)
// |
// +-- Star Rating 5 (StarRating)
// | |
// | +-- Brand A (Brand)
// | |
// | +-- Brand B (Brand)
// | |
// | +-- All other (Brand)
// |
// +-- Star Rating 4 (StarRating)
// | |
// | +-- Brand C (Brand)
// | |
// | +-- Brand D (Brand)
// | |
// | +-- All other (Brand)
// |
// +-- All other (StarRating)
OutputStatusMessage(
"The hotel group tree now has 10 nodes, including the children of Star Rating 4 (StarRating): \n"
);
OutputHotelGroupCriterions(hotelGroupCriterions?.AdGroupCriterions);
// Delete the campaign and everything it contains e.g., ad groups and ads.
OutputStatusMessage("-----\nDeleteCampaigns:");
await CampaignManagementExampleHelper.DeleteCampaignsAsync(
accountId: authorizationData.AccountId,
campaignIds: new[] { (long)campaignIds[0] });
OutputStatusMessage(string.Format("Deleted Campaign Id {0}", campaignIds[0]));
}
// Catch authentication exceptions
catch (OAuthTokenRequestException ex)
{
OutputStatusMessage(string.Format("Couldn't get OAuth tokens. Error: {0}. Description: {1}", ex.Details.Error, ex.Details.Description));
}
// Catch Campaign Management service exceptions
catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.AdApiFaultDetail> ex)
{
OutputStatusMessage(string.Join("; ", ex.Detail.Errors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
}
catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.ApiFaultDetail> ex)
{
OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
}
catch (FaultException<Microsoft.BingAds.V13.CampaignManagement.EditorialApiFaultDetail> ex)
{
OutputStatusMessage(string.Join("; ", ex.Detail.OperationErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
OutputStatusMessage(string.Join("; ", ex.Detail.BatchErrors.Select(error => string.Format("{0}: {1}", error.Code, error.Message))));
}
catch (Exception ex)
{
OutputStatusMessage(ex.Message);
}
}
/// <summary>
/// Returns the root node of a tree. This operation assumes that a complete
/// hotel group tree is provided for one ad group. The node that has
/// null ParentCriterionId is the root node.
/// </summary>
/// <param name="adGroupCriterions">The ad group criterions that contain
/// the hotel group tree.</param>
/// <returns>The ad group criterion that represents the tree root node.</returns>
private AdGroupCriterion GetRootNode(IList<AdGroupCriterion> adGroupCriterions)
{
AdGroupCriterion rootNode = null;
foreach (AdGroupCriterion adGroupCriterion in adGroupCriterions)
{
if (((HotelGroup)(adGroupCriterion.Criterion)).ParentCriterionId == null)
{
rootNode = adGroupCriterion;
break;
}
}
return rootNode;
}
/// <summary>
/// Helper class used to maintain a list of hotel group actions for an ad group.
/// The list of hotel group actions can be passed to the ApplyHotelGroupActions service operation.
/// </summary>
private class HotelGroupActionHelper
{
/// <summary>
/// Each criterion is associated with the same ad group.
/// </summary>
private long adGroupId;
/// <summary>
/// Each new hotel gorup will be assigned a temporary negative identifier, since it does not exist
/// and does not yet have a Microsoft Advertising system identifier. This identifier will be used as the ParentCriterionId
/// for any child node of the subdivision.
/// </summary>
private long referenceId = -1;
/// <summary>
/// The list of hotel group actions that can be passed to the ApplyHotelGroupActions service operation.
/// </summary>
private List<AdGroupCriterionAction> hotelGroupActions = new List<AdGroupCriterionAction>();
/// <summary>
/// Initializes an instance of the HotelGroupActionHelper class.
/// </summary>
/// <param name="adGroupId">The ad group identifier associated with each criterion.</param>
public HotelGroupActionHelper(long adGroupId)
{
this.adGroupId = adGroupId;
}
/// <summary>
/// Returns the list of hotel group actions that can be passed to the ApplyHotelGroupActions service operation.
/// </summary>
public IList<AdGroupCriterionAction> HotelGroupActions
{
get
{
return hotelGroupActions;
}
}
/// <summary>
/// Sets the Add action for a new BiddableAdGroupCriterion corresponding to the specified HotelGroup,
/// and adds it to the helper's list of HotelGroupActions.
/// </summary>
/// <param name="parent">The parent of the hotel group subdivision that you want to add.</param>
/// <param name="listing">The hotel listing for the new hotel group.</param>
/// <returns>The ad group criterion that was added to the list of HotelGroupActions.</returns>
public AdGroupCriterion AddSubdivision(
AdGroupCriterion parent,
HotelListing listing
)
{
var biddableAdGroupCriterion = new BiddableAdGroupCriterion()
{
Id = this.referenceId--,
Criterion = new HotelGroup()
{
ParentCriterionId = parent?.Id,
Listing = listing,
ListingType = HotelListingType.Subdivision
},
CriterionBid = null,
AdGroupId = this.adGroupId
};
var hotelGroupCriterionAction = new AdGroupCriterionAction()
{
Action = ItemAction.Add,
AdGroupCriterion = biddableAdGroupCriterion
};
this.hotelGroupActions.Add(hotelGroupCriterionAction);
return biddableAdGroupCriterion;
}
/// <summary>
/// Sets the Add action for a new AdGroupCriterion corresponding to the specified HotelListing,
/// and adds it to the helper's list of HotelGroupAction.
/// </summary>
/// <param name="parent">The parent of the hotel group unit that you want to add.</param>
/// <param name="listing">The hotel listing filter for the new hotel group.</param>
/// <param name="bidAmount">The bid amount for the new hotel group.</param>
/// <param name="isNegative">Indicates whether or not to add a NegativeAdGroupCriterion.
/// The default value is false, in which case a BiddableAdGroupCriterion will be added.</param>
/// <returns>The ad group criterion that was added to the list of HotelGroupActions.</returns>
public AdGroupCriterion AddUnit(
AdGroupCriterion parent,
HotelListing listing,
double bidAmount,
bool isNegative
)
{
AdGroupCriterion hotelGroupCriterion;
if (isNegative)
{
hotelGroupCriterion = new NegativeAdGroupCriterion();
}
else
{
hotelGroupCriterion = new BiddableAdGroupCriterion()
{
CriterionBid = new RateBid()
{
RateAmount = new RateAmount { Amount = bidAmount }
}
};
}
hotelGroupCriterion.AdGroupId = this.adGroupId;
hotelGroupCriterion.Criterion = new HotelGroup
{
Listing = listing,
ParentCriterionId = parent != null ? parent.Id : null,
ListingType = HotelListingType.Unit
};
var hotelGroupCriterionAction = new AdGroupCriterionAction()
{
Action = ItemAction.Add,
AdGroupCriterion = hotelGroupCriterion
};
this.hotelGroupActions.Add(hotelGroupCriterionAction);
return hotelGroupCriterion;
}
/// <summary>
/// Sets the Delete action for the specified AdGroupCriterion,
/// and adds it to the helper's list of HotelGroupAction.
/// </summary>
/// <param name="adGroupCriterion">The ad group criterion whose hotel group you want to delete.</param>
public void DeleteHotelGroup(AdGroupCriterion adGroupCriterion)
{
adGroupCriterion.AdGroupId = this.adGroupId;
var hotelGroupCriterionAction = new AdGroupCriterionAction()
{
Action = ItemAction.Delete,
AdGroupCriterion = adGroupCriterion
};
this.hotelGroupActions.Add(hotelGroupCriterionAction);
return;
}
/// <summary>
/// Sets the Update action for the specified BiddableAdGroupCriterion,
/// and adds it to the helper's list of HotelGroupAction.
/// When working with hotel groups, you cannot update the Criterion (HotelListing).
/// To update a HotelListing, you must delete the existing node (DeleteHotelGroup) and
/// add a new one (AddUnit or AddSubdivision) during the same call to ApplyHotelGroupActions.
/// </summary>
/// <param name="biddableAdGroupCriterion">The biddable ad group criterion (hotel group criterion) to update.</param>
public void UpdateHotelGroup(BiddableAdGroupCriterion biddableAdGroupCriterion)
{
biddableAdGroupCriterion.AdGroupId = this.adGroupId;
var hotelGroupCriterionAction = new AdGroupCriterionAction()
{
Action = ItemAction.Update,
AdGroupCriterion = biddableAdGroupCriterion
};
this.hotelGroupActions.Add(hotelGroupCriterionAction);
return;
}
}
/// <summary>
/// Outputs the list of hotel groups, formatted as a tree.
/// To ensure the complete tree is represented, you should first call GetAdGroupCriterionsByIds
/// where CriterionTypeFilter is HotelGroup, and pass the returned list of AdGroupCriterion to this method.
/// </summary>
/// <param name="hotelGroupCriterions">The list of hotel group criterions (of type AdGroupCriterion) to output formatted as a tree.</param>
private void OutputHotelGroupCriterions(IList<AdGroupCriterion> hotelGroupCriterions)
{
// Set up the tree for output
Dictionary<long, List<AdGroupCriterion>> childBranches = new Dictionary<long, List<AdGroupCriterion>>();
AdGroupCriterion treeRoot = null;
foreach (var hotelGroupCriterion in hotelGroupCriterions)
{
HotelGroup hotelGroup = (HotelGroup)hotelGroupCriterion.Criterion;
long? parentHotelGroupId = hotelGroup.ParentCriterionId;
if (parentHotelGroupId != null)
{
if (!childBranches.ContainsKey(parentHotelGroupId.Value))
{
childBranches[parentHotelGroupId.Value] = new List<AdGroupCriterion>();
}
childBranches[parentHotelGroupId.Value].Add(hotelGroupCriterion);
}
else
{
treeRoot = hotelGroupCriterion;
}
}
// Outputs the tree root node and any children recursively
OutputHotelGroupTree(treeRoot, childBranches, 0);
}
/// <summary>
/// Outputs the details of the specified hotel group node,
/// and passes any children to itself recursively.
/// </summary>
/// <param name="node">The node to output, whether a Subdivision or Unit.</param>
/// <param name="childBranches">The child branches or nodes if any exist.</param>
/// <param name="treeLevel">
/// The number of descendents from the tree root node.
/// Used by this operation to format the tree structure output.
/// </param>
private void OutputHotelGroupTree(
AdGroupCriterion node,
Dictionary<long, List<AdGroupCriterion>> childBranches,
int treeLevel)
{
OutputStatusMessage(string.Format("{0}{1}",
"".PadLeft(treeLevel, '\t'),
((HotelGroup)(node.Criterion)).ListingType)
);
OutputStatusMessage(string.Format("{0}ParentCriterionId: {1}",
"".PadLeft(treeLevel, '\t'),
((HotelGroup)(node.Criterion)).ParentCriterionId)
);
OutputStatusMessage(string.Format("{0}Id: {1}",
"".PadLeft(treeLevel, '\t'),
node.Id)
);
if (((HotelGroup)(node.Criterion)).ListingType == HotelListingType.Unit)
{
var biddableAdGroupCriterion = node as BiddableAdGroupCriterion;
if (biddableAdGroupCriterion != null)
{
OutputStatusMessage(string.Format("{0}Bid Amount: {1}",
"".PadLeft(treeLevel, '\t'),
((RateBid)(biddableAdGroupCriterion.CriterionBid)).RateAmount.Amount)
);
}
else
{
var negativeAdGroupCriterion = node as NegativeAdGroupCriterion;
if (negativeAdGroupCriterion != null)
{
OutputStatusMessage(string.Format("{0}Not Bidding on this Listing",
"".PadLeft(treeLevel, '\t'))
);
}
}
}
string nullAttribute = ((HotelGroup)(node.Criterion)).ParentCriterionId != null ? "(All other)" : "(Tree Root)";
OutputStatusMessage(string.Format("{0}Attribute: {1}",
"".PadLeft(treeLevel, '\t'),
((HotelGroup)(node.Criterion)).Listing.Attribute ?? nullAttribute)
);
OutputStatusMessage(string.Format("{0}Operand: {1}\n",
"".PadLeft(treeLevel, '\t'),
((HotelGroup)(node.Criterion)).Listing.Operand)
);
if (childBranches.ContainsKey((long)(node.Id)))
{
foreach (AdGroupCriterion childNode in childBranches[(long)(node.Id)])
{
OutputHotelGroupTree(childNode, childBranches, treeLevel + 1);
}
}
}
}
}
package com.microsoft.bingads.examples.v13;
import com.microsoft.bingads.ServiceClient;
import com.microsoft.bingads.v13.campaignmanagement.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
// How to apply hotel group for Microsoft Hotel Campaigns.
public class HotelAds extends ExampleBase {
private static ArrayOfAdGroupCriterionAction _hotelGroupActions = new ArrayOfAdGroupCriterionAction();
private static long _referenceId = -1;
public static void main(java.lang.String[] args) {
// To set up hotel ads, we need to create at least a Campaign, an AdGroup under this campaign, and some Hotel Groups
try
{
authorizationData = getAuthorizationData();
CampaignManagementExampleHelper.CampaignManagementService = new ServiceClient<ICampaignManagementService>(
authorizationData,
API_ENVIRONMENT,
ICampaignManagementService.class);
// Create the hotel campaign. This is needed.
ArrayOfNullableOflong campaignIds = createHotelCampaign();
// Create the hotel ad group that will have the hotel groups. This is needed.
ArrayOfNullableOflong adGroupIds = createHotelAdGroup(campaignIds);
// Hotel groups are also needed.
// Create and update the hotel groups.
addAndUpdateSingleHotelCriterion(adGroupIds.getLongs().get(0));
ApplyHotelGroupActionsResponse applyHotelGroupActionsResponse = addBranchAndLeafHotelCriterionsToRoot(adGroupIds.getLongs().get(0));
long rootId = applyHotelGroupActionsResponse.getAdGroupCriterionIds().getLongs().get(1);
long starRating4HotelGroupId = applyHotelGroupActionsResponse.getAdGroupCriterionIds().getLongs().get(3);
updateBranchAndLeafHotelCriterionsForStarRating4(adGroupIds.getLongs().get(0), rootId, starRating4HotelGroupId);
// Delete the campaign and everything it contains e.g., ad groups and ads.
outputStatusMessage("-----\nDeleteCampaigns:");
ArrayOflong deleteCampaignIds = new ArrayOflong();
deleteCampaignIds.getLongs().add(campaignIds.getLongs().get(0));
CampaignManagementExampleHelper.deleteCampaigns(
authorizationData.getAccountId(),
deleteCampaignIds);
outputStatusMessage(String.format("Deleted CampaignId %d", deleteCampaignIds.getLongs().get(0)));
}
catch (Exception ex) {
String faultXml = ExampleExceptionHelper.getBingAdsExceptionFaultXml(ex, System.out);
outputStatusMessage(faultXml);
String message = ExampleExceptionHelper.handleBingAdsSDKException(ex, System.out);
outputStatusMessage(message);
}
}
// create hotel campaign
static ArrayOfNullableOflong createHotelCampaign() throws Exception {
Campaign campaign = new Campaign();
// set campaign type to Hotel
ArrayList<CampaignType> campaignTypes = new ArrayList<CampaignType>();
campaignTypes.add(CampaignType.HOTEL);
campaign.setCampaignType(campaignTypes);
// Hotel campaign supports commission, percent cpc and manual cpc bidding scheme
CommissionBiddingScheme biddingScheme = new CommissionBiddingScheme();
biddingScheme.setCommissionRate(3.14);
campaign.setBiddingScheme(biddingScheme);
// for hotel campaign, language should be set to "All"
ArrayOfstring languages = new ArrayOfstring();
languages.getStrings().add("All");
campaign.setLanguages(languages);
// set other fields
campaign.setBudgetType(BudgetLimitType.DAILY_BUDGET_STANDARD);
campaign.setDailyBudget(50.00);
campaign.setName("Everyone's Hotel " + System.currentTimeMillis());
campaign.setTimeZone("PacificTimeUSCanadaTijuana");
ArrayOfCampaign campaigns = new ArrayOfCampaign();
campaigns.getCampaigns().add(campaign);
outputStatusMessage("-----\nAddCampaigns:");
AddCampaignsResponse addCampaignsResponse = CampaignManagementExampleHelper.addCampaigns(
authorizationData.getAccountId(),
campaigns);
ArrayOfNullableOflong campaignIds = addCampaignsResponse.getCampaignIds();
ArrayOfBatchError campaignErrors = addCampaignsResponse.getPartialErrors();
outputStatusMessage("CampaignIds:");
CampaignManagementExampleHelper.outputArrayOfNullableOflong(campaignIds);
outputStatusMessage("PartialErrors:");
CampaignManagementExampleHelper.outputArrayOfBatchError(campaignErrors);
return campaignIds;
}
// create hotel ad group
static ArrayOfNullableOflong createHotelAdGroup(ArrayOfNullableOflong campaignIds) throws Exception {
AdGroup adGroup = new AdGroup();
// ad group type should be set to "HotelAds"
adGroup.setAdGroupType("HotelAds");
// set ad group type, should be HotelAd or PropertyAd or specify both
ArrayList<HotelAdGroupType> hotelAdGroupTypes = new ArrayList<HotelAdGroupType>();
hotelAdGroupTypes.add(HotelAdGroupType.HOTEL_AD);
HotelSetting hotelSetting = new HotelSetting();
hotelSetting.setHotelAdGroupType(hotelAdGroupTypes);
ArrayOfSetting adGroupSettings = new ArrayOfSetting();
adGroupSettings.getSettings().add(hotelSetting);
adGroup.setSettings(adGroupSettings);
// set ad group level bid value
// Here the campaign we created is using Commission bidding scheme, so we set CommissionRate
// if the campaign bidding scheme is PercentCpc, please set PercentCpcBid
// if the campaign bidding scheme is ManualCpc, please set CpcBid
RateBid rateBid = getRateBid(5.6);
adGroup.setCommissionRate(rateBid);
// Hotel AdGroups will inherit Hotel Campaign setting, which enforces the “All” language.
adGroup.setLanguage(null);
adGroup.setName("Everyone's Hotel");
adGroup.setStartDate(null);
Calendar calendar = Calendar.getInstance();
adGroup.setEndDate(new com.microsoft.bingads.v13.campaignmanagement.Date());
adGroup.getEndDate().setDay(31);
adGroup.getEndDate().setMonth(12);
adGroup.getEndDate().setYear(calendar.get(Calendar.YEAR));
ArrayOfAdGroup adGroups = new ArrayOfAdGroup();
adGroups.getAdGroups().add(adGroup);
outputStatusMessage("-----\nAddAdGroups:");
// when we call addAdGroups method, an ad will be automatically created for hotel ad group
AddAdGroupsResponse addAdGroupsResponse = CampaignManagementExampleHelper.addAdGroups(
campaignIds.getLongs().get(0),
adGroups,
false);
ArrayOfNullableOflong adGroupIds = addAdGroupsResponse.getAdGroupIds();
ArrayOfBatchError adGroupErrors = addAdGroupsResponse.getPartialErrors();
outputStatusMessage("AdGroupIds:");
CampaignManagementExampleHelper.outputArrayOfNullableOflong(adGroupIds);
outputStatusMessage("PartialErrors:");
CampaignManagementExampleHelper.outputArrayOfBatchError(adGroupErrors);
return adGroupIds;
}
// Create a hotel group tree with one single node (root node), then update bid of the node.
static void addAndUpdateSingleHotelCriterion(long adGroupId) throws Exception
{
// Add a biddable criterion as the root.
HotelListing rootHotelListing = new HotelListing();
rootHotelListing.setAttribute(null);
rootHotelListing.setOperand("All");
AdGroupCriterion root = addHotelCriterion(
adGroupId,
null,
rootHotelListing,
HotelListingType.UNIT,
getRateBid(0.35),
false);
outputStatusMessage("-----\nApplyHotelGroupActions:");
outputStatusMessage("Applying a biddable criterion as the root...");
ApplyHotelGroupActionsResponse applyHotelGroupActionsResponse = CampaignManagementExampleHelper.applyHotelGroupActions(
_hotelGroupActions);
CampaignManagementExampleHelper.outputArrayOfNullableOflong(applyHotelGroupActionsResponse.getAdGroupCriterionIds());
CampaignManagementExampleHelper.outputArrayOfBatchError(applyHotelGroupActionsResponse.getPartialErrors());
ArrayList<AdGroupCriterionType> criterionType = new ArrayList<AdGroupCriterionType>();
criterionType.add(AdGroupCriterionType.HOTEL_GROUP);
outputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
ArrayOfAdGroupCriterion adGroupCriterions = CampaignManagementExampleHelper.getAdGroupCriterionsByIds(
null,
adGroupId,
criterionType,
null).getAdGroupCriterions();
outputStatusMessage("Printing the ad group's hotel group; contains only the tree root node");
printHotelGroups(adGroupCriterions);
// Update the bid from 0.35 to 0.40, of the root node that we just added.
BiddableAdGroupCriterion updatedRoot = new BiddableAdGroupCriterion();
updatedRoot.setId(applyHotelGroupActionsResponse.getAdGroupCriterionIds().getLongs().get(0));
updatedRoot.setAdGroupId(adGroupId);
updatedRoot.setCriterionBid(getRateBid(0.40));
_hotelGroupActions.getAdGroupCriterionActions().clear();
addAdGroupCriterionAction(updatedRoot, ItemAction.UPDATE);
outputStatusMessage("-----\nApplyHotelGroupActions:");
outputStatusMessage("Updating the bid for the tree root node...");
applyHotelGroupActionsResponse = CampaignManagementExampleHelper.applyHotelGroupActions(
_hotelGroupActions);
outputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
adGroupCriterions = CampaignManagementExampleHelper.getAdGroupCriterionsByIds(
null,
adGroupId,
criterionType,
null).getAdGroupCriterions();
outputStatusMessage("Updated the bid for the tree root node");
printHotelGroups(adGroupCriterions);
}
// Add branch and leaf nodes to the hotel group tree and then update it.
static ApplyHotelGroupActionsResponse addBranchAndLeafHotelCriterionsToRoot(long adGroupId) throws Exception
{
_hotelGroupActions.getAdGroupCriterionActions().clear();
ArrayList<AdGroupCriterionType> criterionType = new ArrayList<AdGroupCriterionType>();
criterionType.add(AdGroupCriterionType.HOTEL_GROUP);
outputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
ArrayOfAdGroupCriterion adGroupCriterions = CampaignManagementExampleHelper.getAdGroupCriterionsByIds(
null,
adGroupId,
criterionType,
null).getAdGroupCriterions();
// If we want to update the tree structure at a node, we must delete existing node and then add a new equivalent node,
// Here we modify the root node and add some new branches and leafs, so we delete it first.
AdGroupCriterion existingRoot = getRootHotelCriterion(adGroupCriterions);
if (existingRoot != null)
{
addAdGroupCriterionAction(existingRoot, ItemAction.DELETE);
}
// Add the equivalent new root node
HotelListing newRootHotelListing = new HotelListing();
newRootHotelListing.setAttribute(null);
newRootHotelListing.setOperand("All");
AdGroupCriterion newRoot = addHotelCriterion(
adGroupId,
null,
newRootHotelListing,
HotelListingType.SUBDIVISION,
null,
false);
HotelListing starRating5HotelListing = new HotelListing();
starRating5HotelListing.setAttribute("5");
starRating5HotelListing.setOperand("StarRating");
AdGroupCriterion starRating5SubDivision = addHotelCriterion(
adGroupId,
newRoot,
starRating5HotelListing,
HotelListingType.SUBDIVISION,
null,
false);
HotelListing starRating4HotelListing = new HotelListing();
starRating4HotelListing.setAttribute("4");
starRating4HotelListing.setOperand("StarRating");
AdGroupCriterion starRating4Unit = addHotelCriterion(
adGroupId,
newRoot,
starRating4HotelListing,
HotelListingType.UNIT,
getRateBid(0.35),
false);
// "Everything Else" node for StarRating condition. We should define everything else node for each condition/operand
// For StarRating, besides 5 stars and 4 stars, all the other hotels below 4 stars are belong to the node below
HotelListing otherStarRatingsHotelListing = new HotelListing();
otherStarRatingsHotelListing.setAttribute(null);
otherStarRatingsHotelListing.setOperand("StarRating");
AdGroupCriterion otherStarRatingsUnit = addHotelCriterion(
adGroupId,
newRoot,
otherStarRatingsHotelListing,
HotelListingType.UNIT,
getRateBid(0.35),
false);
HotelListing brandAHotelListing = new HotelListing();
brandAHotelListing.setAttribute("Brand A");
brandAHotelListing.setOperand("Brand");
AdGroupCriterion brandAUnit = addHotelCriterion(
adGroupId,
starRating5SubDivision,
brandAHotelListing,
HotelListingType.UNIT,
getRateBid(0.35),
false);
HotelListing brandBHotelListing = new HotelListing();
brandBHotelListing.setAttribute("Brand B");
brandBHotelListing.setOperand("Brand");
AdGroupCriterion brandBUnit = addHotelCriterion(
adGroupId,
starRating5SubDivision,
brandBHotelListing,
HotelListingType.UNIT,
null,
true);
// everything else node for Brand condition
HotelListing otherBrandsHotelListing = new HotelListing();
otherBrandsHotelListing.setAttribute(null);
otherBrandsHotelListing.setOperand("Brand");
AdGroupCriterion otherBrandsUnit = addHotelCriterion(
adGroupId,
starRating5SubDivision,
otherBrandsHotelListing,
HotelListingType.UNIT,
getRateBid(0.35),
false);
outputStatusMessage("-----\nApplyHotelGroupActions:");
outputStatusMessage("Applying hotel groups to the ad group...");
ApplyHotelGroupActionsResponse applyHotelGroupActionsResponse = CampaignManagementExampleHelper.applyHotelGroupActions(
_hotelGroupActions);
outputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
adGroupCriterions = CampaignManagementExampleHelper.getAdGroupCriterionsByIds(
null,
adGroupId,
criterionType,
null).getAdGroupCriterions();
outputStatusMessage("The hotel group tree now has 7 nodes");
printHotelGroups(adGroupCriterions);
return applyHotelGroupActionsResponse;
}
// update starRating 4 node to have more leaf hotel groups
static void updateBranchAndLeafHotelCriterionsForStarRating4(long adGroupId, long rootId, long existingStarRating4CriterionId) throws Exception
{
_hotelGroupActions.getAdGroupCriterionActions().clear();
AdGroupCriterion starRating4Criterion = new BiddableAdGroupCriterion();
starRating4Criterion.setId(existingStarRating4CriterionId);
starRating4Criterion.setAdGroupId(adGroupId);
addAdGroupCriterionAction(starRating4Criterion, ItemAction.DELETE);
BiddableAdGroupCriterion parent = new BiddableAdGroupCriterion();
parent.setId(rootId);
HotelListing newStarRating4HotelListing = new HotelListing();
newStarRating4HotelListing.setAttribute("4");
newStarRating4HotelListing.setOperand("StarRating");
AdGroupCriterion newStarRating4Subdivision = addHotelCriterion(
adGroupId,
parent,
newStarRating4HotelListing,
HotelListingType.SUBDIVISION, // it's not leave node anymore, the type should set to SUBDIVISION
null,
false);
// Add leafs of "Brand C", "Brand D" and other brands, to the star rating 4 branch.
HotelListing brandCHotelListing = new HotelListing();
brandCHotelListing.setAttribute("Brand C");
brandCHotelListing.setOperand("Brand");
AdGroupCriterion brandCUnit = addHotelCriterion(
adGroupId,
newStarRating4Subdivision,
brandCHotelListing,
HotelListingType.UNIT,
getRateBid(0.35),
false);
HotelListing brandDHotelListing = new HotelListing();
brandDHotelListing.setAttribute("Brand D");
brandDHotelListing.setOperand("Brand");
AdGroupCriterion brandDUnit = addHotelCriterion(
adGroupId,
newStarRating4Subdivision,
brandDHotelListing,
HotelListingType.UNIT,
getRateBid(0.35),
false);
HotelListing otherBrandsHotelListing = new HotelListing();
otherBrandsHotelListing.setAttribute(null);
otherBrandsHotelListing.setOperand("Brand");
AdGroupCriterion otherBrandsUnit = addHotelCriterion(
adGroupId,
newStarRating4Subdivision,
otherBrandsHotelListing,
HotelListingType.UNIT,
getRateBid(0.35),
false);
outputStatusMessage("-----\nApplyHotelGroupActions:");
outputStatusMessage("Updating the star rating 4 hotel group...");
ApplyHotelGroupActionsResponse applyHotelGroupActionsResponse = CampaignManagementExampleHelper.applyHotelGroupActions(
_hotelGroupActions);
ArrayList<AdGroupCriterionType> criterionType = new ArrayList<AdGroupCriterionType>();
criterionType.add(AdGroupCriterionType.HOTEL_GROUP);
outputStatusMessage("-----\nGetAdGroupCriterionsByIds:");
ArrayOfAdGroupCriterion adGroupCriterions = CampaignManagementExampleHelper.getAdGroupCriterionsByIds(
null,
adGroupId,
criterionType,
null).getAdGroupCriterions();
outputStatusMessage("The hotel group tree now has 10 nodes");
printHotelGroups(adGroupCriterions);
}
// Get the root hotel group node.
static AdGroupCriterion getRootHotelCriterion(ArrayOfAdGroupCriterion adGroupCriterions)
{
AdGroupCriterion rootNode = null;
for (AdGroupCriterion adGroupCriterion : adGroupCriterions.getAdGroupCriterions())
{
if (((HotelGroup)adGroupCriterion.getCriterion()).getParentCriterionId() == null)
{
rootNode = adGroupCriterion;
break;
}
}
return rootNode;
}
// Get a Rate bid object with the specified bid amount.
static RateBid getRateBid(final double bidAmount)
{
RateAmount rateAmount = new RateAmount();
rateAmount.setAmount(bidAmount);
RateBid rateBid = new RateBid();
rateBid.setRateAmount(rateAmount);
return rateBid;
}
// Add a criterion action to the list of actions.
static void addAdGroupCriterionAction(final AdGroupCriterion CRITERION, final ItemAction ITEM_ACTION)
{
AdGroupCriterionAction hotelGroupAction = new AdGroupCriterionAction();
hotelGroupAction.setAction(ITEM_ACTION);
hotelGroupAction.setAdGroupCriterion(CRITERION);
_hotelGroupActions.getAdGroupCriterionActions().add(hotelGroupAction);
}
// Add either a negative or biddable hotel group criterion.
// To call Microsoft Ads API, we need to wrap hotel group to AdGroupCriterion
static AdGroupCriterion addHotelCriterion(
long adGroupId,
AdGroupCriterion parent,
HotelListing hotelListing,
HotelListingType hotelListingType,
RateBid bid,
Boolean isNegative)
{
AdGroupCriterion adGroupCriterion = null;
if (isNegative)
{
adGroupCriterion = new NegativeAdGroupCriterion();
}
else
{
adGroupCriterion = new BiddableAdGroupCriterion();
((BiddableAdGroupCriterion)adGroupCriterion).setCriterionBid(bid);
}
adGroupCriterion.setAdGroupId(adGroupId);
HotelGroup hotelGroup = new HotelGroup();
hotelGroup.setListing(hotelListing);
hotelGroup.setParentCriterionId((parent != null) ? parent.getId() : null);
if (hotelListingType == HotelListingType.SUBDIVISION)
{
hotelGroup.setListingType(HotelListingType.SUBDIVISION); // Branch
adGroupCriterion.setId(_referenceId--);
}
else
{
hotelGroup.setListingType(HotelListingType.UNIT);; // Leaf
}
adGroupCriterion.setCriterion(hotelGroup);
addAdGroupCriterionAction(adGroupCriterion, ItemAction.ADD);
return adGroupCriterion;
}
// Print the hotel group
static void printHotelGroups(ArrayOfAdGroupCriterion adGroupCriterions)
{
Map<Long, ArrayList<AdGroupCriterion>> childBranches = new HashMap<Long, ArrayList<AdGroupCriterion>>();
AdGroupCriterion treeRoot = null;
for (AdGroupCriterion adGroupCriterion : adGroupCriterions.getAdGroupCriterions())
{
HotelGroup hotelGroup = (HotelGroup)adGroupCriterion.getCriterion();
childBranches.put(adGroupCriterion.getId(), new ArrayList<AdGroupCriterion>());
if (hotelGroup.getParentCriterionId() != null)
{
childBranches.get(hotelGroup.getParentCriterionId()).add(adGroupCriterion);
}
else
{
treeRoot = adGroupCriterion;
}
}
printHotelGroupTree(treeRoot, childBranches, 0);
}
// Print the hotel group tree.
static void printHotelGroupTree(
AdGroupCriterion node,
Map<Long, ArrayList<AdGroupCriterion>> childBranches,
int treeLevel)
{
HotelGroup criterion = (HotelGroup) node.getCriterion();
outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s\n",
"",
criterion.getListingType()));
outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s%d\n",
"",
"ParentCriterionId: ",
criterion.getParentCriterionId()));
outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s%d\n",
"",
"Id: ",
node.getId()));
if (criterion.getListingType() == HotelListingType.UNIT)
{
if (node instanceof BiddableAdGroupCriterion)
{
outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s%.2f\n",
"",
"Bid amount: ",
((RateBid)((BiddableAdGroupCriterion)node).getCriterionBid()).getRateAmount().getAmount()));
}
else
{
if (node instanceof NegativeAdGroupCriterion)
{
outputStatusMessage(String.format("%" + treeLevel * 4 + "s%s\n",
"",
"Not bidding on this listing"));
}
}
}
String nullAttribute = (criterion.getParentCriterionId() != null) ? "(All Others)" : "(Tree Root)";
outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s%s\n",
"",
"Attribute: ",
(criterion.getListing().getAttribute() == null) ? nullAttribute : criterion.getListing().getAttribute()));
outputStatusMessage(String.format("%" + ((treeLevel > 0) ? treeLevel * 4 : "") + "s%s%s\n",
"",
"Listing: ",
criterion.getListing().getOperand()));
for (AdGroupCriterion childNode : childBranches.get(node.getId()))
{
printHotelGroupTree(childNode, childBranches, treeLevel + 1);
}
}
}