The reporting services of the AdWords API are designed to allow you to download large amounts of data, but it can often be useful to filter out certain rows from the start to cut down on processing and transfer time. DefinedReportJobs created using the v13 ReportService supported a limited set of filtering options, primarily on IDs and statuses. Filtering on a more complex set of criteria would require post processing the report client-side. The ReportDefinitionService introduced in v201003 supports Predicates, a more flexible system of filters that can be used to create very targeted reports.
A predicate is composed of three parts: the field, the operator, and the values. Predicates can be created for almost every field available, indicated by canFilter set to "true" in the results returned from getReportFields().
<rval>
<fieldName>Clicks</fieldName>
<displayFieldName>Clicks</displayFieldName>
<xmlAttributeName>clicks</xmlAttributeName>
<fieldType>Long</fieldType>
<canSelect>true</canSelect>
<canFilter>true</canFilter>
</rval>
There are a fixed set of operators that can be used to compare the value of the field selected. EQUALS can be used to filter for an exact match, while IN can be used to match any of a set of values. GREATER_THAN and LESS_THAN are available for comparing numerical values, and CONTAINS is useful when working with strings. Only one operator can be used per predicate, but multiple predicates can be created for the same field to create more complex logic.
The values used in the predicate depend heavily on the field being operated on. Numerical values should be used for Long, Double, and Integer fields, and arbitrary strings can be used for String fields. The values for Money and Bid fields must always be specified in micros, even if the report is eventually downloaded with whole currency amounts. Although percentage fields like Ctr are returned as whole numbers, the values used in predicates should be the decimal equivalents. Predicates on Enum fields must only use the values of the enum, as outlined in the documentation and in the enumValues property returned by getReportFields().
<rval>
<fieldName>CampaignStatus</fieldName>
<displayFieldName>Campaign state</displayFieldName>
<xmlAttributeName>campaignState</xmlAttributeName>
<fieldType>CampaignStatus</fieldType>
<enumValues>ACTIVE</enumValues>
<enumValues>DELETED</enumValues>
<enumValues>PAUSED</enumValues>
<canSelect>true</canSelect>
<canFilter>true</canFilter>
</rval>
If multiple predicates are used within a Selector they will be combined using AND logic, so that the resulting report will only contain rows that satisfies all of the predicates. It’s not possible to combine predicates using OR logic at this time, but some common use cases can be handled using a single predicate and the IN operator. For example, to match keywords with either the PHRASE or EXACT match type you could use the following predicate:
<predicates>
<field>KeywordMatchType</field>
<operator>IN</operator>
<values>PHRASE</values>
<values>EXACT</values>
</predicates>
When combined together, predicates can be quite powerful. Consider the following example: I own an electronics shop that is starting to sell a wider array of tablet computers, and I want to drive more traffic to that section of my website. I’d like to start by finding all my current keywords that include the word "tablet" and have a high CTR, and then use them to generate new keyword ideas using the TargetingIdeaService. I’m only interested in keywords with greater than a 10% CTR, that have at least 100 impressions, and that are in enabled or paused ad groups.
Using predicates I can create a KEYWORDS_PERFORMANCE_REPORT that only returns me the exact data I am interested in:
<predicates>
<field>CampaignId</field>
<operator>EQUALS</operator>
<values>123456789</values>
</predicates>
<predicates>
<field>AdGroupStatus</field>
<operator>IN</operator>
<values>ENABLED</values>
<values>PAUSED</values>
</predicates>
<predicates>
<field>KeywordText</field>
<operator>CONTAINS</operator>
<values>tablet</values>
</predicates>
<predicates>
<field>Ctr</field>
<operator>GREATER_THAN</operator>
<values>0.10</values>
</predicates>
<predicates>
<field>Impressions</field>
<operator>GREATER_THAN_EQUALS</operator>
<values>100</values>
</predicates>
Predicates are one of many new improvements introduced in the ReportDefinitionService, and if you aren’t using the service yet, now is a great time to start looking into migrating. The service is fully supported in all our client libraries, and we’re available on the forum to answer any questions you may have.
- Eric Koleda, AdWords API Team
Harness the power of predicates in your reports
Friday, December 10, 2010
Discover v201008: Partial Failure for AdGroupCriterionService
Tuesday, December 07, 2010
To utilize the new feature you’ll need to set this extra SOAP header:
partialFailure = true
Here’s an example from the Java client library:
// usual initialization code
AdWordsUser user = new AdWordsUser();
// Enable partial failure
user.setUsePartialFailure(true);
// Get the AdGroupCriterionService
AdGroupCriterionServiceInterface adGroupCriterionService =
user.getService(AdWordsService.V201008.ADGROUP_CRITERION_SERVICE);
// Set up operations and operands here
List<AdGroupCriterionOperation> operations = new ArrayList<AdGroupCriterionOperation>();
// [...]
// Execute operations (add ad group criteria)
AdGroupCriterionReturnValue result =
adGroupCriterionService.mutate(operations.toArray(
new AdGroupCriterionOperation[] {}));
Now processing succeeded results:
// Display results
if ((result != null) && (result.getValue() != null)) {
// A result is returned for every operation requested
for (AdGroupCriterion adGroupCriterionResult : result.getValue()) {
// Successful operation result will contain a non-null Criterion
if (adGroupCriterionResult.getCriterion() != null) {
System.out.printf("Ad group criterion with ad group id '%d', and " +
"criterion id '%d', and keyword '%s' was added.\n",
adGroupCriterionResult.getAdGroupId(),
adGroupCriterionResult.getCriterion().getId(),
((Keyword) adGroupCriterionResult.getCriterion()).getText());
}
}
} else {
System.out.println("No ad group criteria were added.");
}
Here is how to handle the failed operations:
// Is there any Partial Failure errors in the results?
if ((result != null) && (result.getPartialFailureErrors() != null)) {
// Retrieving ApiError object for each of failures
for (ApiError apiError : result.getPartialFailureErrors()) {
// The order of the fields might be different to the order of operations in the
// request, so we are getting the corresponding operation index from the fieldPath.
Matcher matcher = operationIndexPattern.matcher(apiError.getFieldPath());
if (matcher.matches()) {
int operationIndex = Integer.parseInt(matcher.group(1));
AdGroupCriterion adGroupCriterion =
operations.get(operationIndex).getOperand();
System.out.printf("Ad group criterion with ad group id '%d' and " +
"keyword '%s' triggered a failure for the following reason: '%s'.\n",
adGroupCriterion.getAdGroupId(),
((Keyword) adGroupCriterion.getCriterion()).getText(),
apiError.getErrorString());
} else {
System.out.printf(
"A failure for the following reason: '%s' has occurred.\n",
apiError.getErrorString());
}
}
}
Partial Failure is fully supported in our client libraries. If you have any questions please post them on the AdWords API forum. This topic is also covered in a video presentation.
-- Danial Klimkin, AdWords API Team.
Discover v201008 - Track your account notifications with AlertService
Monday, November 22, 2010
When you’re managing a large number of accounts using the AdWords API you may want to retrieve account alerts. This was previously possible with AccountService in v13. The v201008 version introduces the AlertService, which brings similar functionality to the new AdWords API. This blog post discusses the differences between how alerts are retrieved using these two services.
Retrieving client account alerts
In v13, you could retrieve the alerts associated with list of client accounts linked to a My Client Center (MCC) using the getMccAlerts method of AccountService. In v201008, you can use the get method of AlertService to get the same results. The following code shows the service in action:
// Get the AlertService.
AlertService alertService = (AlertService) user.GetService(
AdWordsService.v201008.AlertService);
// Create the alert query.
AlertQuery query = new AlertQuery();
query.filterSpec = FilterSpec.ALL;
query.clientSpec = ClientSpec.ALL;
query.triggerTimeSpec = TriggerTimeSpec.ALL_TIME;
query.severities = new AlertSeverity[] {AlertSeverity.GREEN,
AlertSeverity.YELLOW, AlertSeverity.RED};
query.types = new AlertType[] {AlertType.CAMPAIGN_ENDING,
AlertType.CAMPAIGN_ENDED};
// Create the selector.
AlertSelector selector = new AlertSelector();
selector.query = query;
selector.paging = new Paging();
selector.paging.startIndex = 0;
selector.paging.numberResults = 10;
AlertPage page = alertService.get(selector);
Once you retrieve the alerts, you can display them by enumerating the page entries.
if (page != null && page.entries != null && page.entries.Length > 0) {
Console.WriteLine("Retrieved {0} alerts out of {1}.",
page.entries.Length, page.totalNumEntries);
for (int i = 0; i < page.entries.Length; i++) {
Alert alert = page.entries[i];
Console.WriteLine("{0}) Customer Id is {1:###-###-####}, " +
"Alert type is '{2}',Severity is {3}", i + 1,
alert.clientCustomerId, alert.alertType, alert.alertSeverity);
for (int j = 0; j < alert.details.Length; j++) {
Console.WriteLine(" - Triggered at {0}", alert.details[j].triggerTime);
}
}
} else {
Console.WriteLine("No alerts were found.");
}
Differences between AccountService.getAllMccAlerts and AlertService.get
The main differences between the v13 AccountService.getAllMccAlerts and v201008 AlertService.get are in the table below.
| AccountService.getAllMccAlerts | AlertService.get |
|---|---|
| Returns alerts for all the client accounts immediately under the MCC. | You can choose to retrieve alerts for all the child accounts, for immediate child accounts only, or for a specific list of customers by using the clientSpec and clientCustomerIds fields of AlertQuery. |
| Returns all available types of alerts for your client accounts. | Returns only the types of alerts you request in your AlertQuery. |
| MccAlert provides multiple fields like clientLogin, clientName and clientCustomerId to associate an alert with a customer. | Alert provides only clientCustomerId field to associate the alert with a customer. |
| Gives you one MccAlert object for each occurrence of the alert. | Groups alerts of the same type for a given customer as a single Alert object. You can access the alert details from the details field of the alert object. |
| Alert priority can be low or high. | Alert severity can be red, yellow or green. |
The v201008 version of AlertService.get allows you to retrieve alerts only by predefined trigger time ranges. We plan to include support for filtering by custom date ranges in a future version of the AdWords API.
We have added support for AlertService in all of our client libraries, so please take advantage of this service and share your feedback with us on the forum.
-- Anash P. Oommen, AdWords API Team
Labels: AdWords API Blog
Changes to managed placement bidding on the Display Network
Tuesday, November 16, 2010
Currently, ad groups using manual CPC bidding which contain managed placements are required to have a managed placements bid (siteMaxCpc). Today, we’re announcing that we’ll be sunsetting siteMaxCpc on March 15, 2011 to help simplify bid management on the Google Display Network (GDN).
We’re making this change in response to feedback that having multiple ad group bids for the GDN complicates bid management. Most of you using managed placements are already using placement-level bidding to control your costs on the GDN, and you’ll be able to continue to do this. In addition, the content bid (keywordContentMaxCpc) will continue to be available, offering control at the ad group level.
Here’s how this change will affect you: after March 15, we’ll stop accepting changes to ManualCpcAdGroupBids that modify siteMaxCpc to set it to anything other than 0. After that date, calls that attempt to set siteMaxCpc will return the error BiddingError.Reason.CANNOT_SET_SITE_MAX_CPC.
We’ll be announcing this change to all AdWords users early next year but wanted to let you know early so that you can prepare to modify your applications to stop accepting new siteMaxCpc bids. When we make the broader announcement, we’ll make it possible to “self-migrate” existing managed placements bids by setting them to zero and modifying their other bids as appropriate. In March, when we stop accepting changes to these bids entirely, we’ll migrate any remaining bids to the placement level, according to clear rules which we’ll share with you in a blog post in January.
If you have any questions about this change, we’ll be happy to answer them on our forum.
Posted by Prabhu Balasubramanian, Product Manager
Labels: AdWords API Blog
AdWords Downtime: November 13, 10am-2pm PST
Tuesday, November 09, 2010
Labels: AdWords API Blog, downtime
Discover v201008: Remove incomplete BulkMutateJobs
Monday, November 08, 2010
The v201008 release of the AdWords API added a new feature to the BulkMutateJobService: the ability to remove incomplete jobs. This allows you to clean out your job queue after an application crash or other failure. In this post we’ll demonstrate how to use the feature and discuss some of its limitations.
When a BulkMutateJob is created the field numRequestParts is set, which determines how many BulkMutateRequest objects will be added to the job. Once the final request part has been added, the job enters into the account’s job queue, and when it reaches the front of the queue it begins processing. If the application crashes while the parts are being uploaded, the job will never start and remain stranded in the account.
Jobs that are incomplete and those that are complete but waiting in the queue behind a processing job will both have a PENDING status. An account can only have 10 pending jobs at a time, so stranded jobs can begin to fill up the account, until eventually no new jobs can be added. Prior to v201008 the only way to remove stranded jobs was to add the missing request parts so that the job would start. If the job had been stranded for a while though, the operations that were previously uploaded may make undesired changes to the account.
In v201008 the REMOVE operator can be used to delete incomplete jobs. The following code does this using the PHP client library.
$bulkMutateJobId = (float) 'INSERT_BULK_MUTATE_JOB_ID_HERE';
// Create BulkMutateJob.
$bulkMutateJob = new BulkMutateJob();
$bulkMutateJob->id = $bulkMutateJobId;
// Create operation.
$operation = new JobOperation();
$operation->operand = $bulkMutateJob;
$operation->operator = 'REMOVE';
// Delete bulk mutate job.
$bulkMutateJob = $bulkMutateJobService->mutate($operation);
After being removed, the job will be in the FAILED state and the failureReason field will contain JobError.USER_CANCELED_JOB.
A limitation of the REMOVE operator is that it only works on jobs that are in the PENDING state and that are incomplete (numRequestParts > numRequestPartsReceived). Jobs that are complete and have already entered the job queue, whether they be in the PENDING or PROCESSING state, cannot be deleted.
Code examples that show how to delete jobs are included in all of the client libraries. If you have any questions about this functionality or the BulkMutateJobService, ask us on the forum.
- Eric Koleda, AdWords API Team
A change to currency formatting in report downloads
Tuesday, November 02, 2010
If you're using the new AdWords API ReportDefinitionService, you may have noticed that monetary values in reports are returned as conventional currency instead of micros. At the request of the developer community, we'll be changing the format to micros on February 1, 2011 to make reporting more consistent with other AdWords API services.
A micro value is equal to one million times the conventional currency value, and is a standard we use throughout the AdWords API (including v13 reports) to represent money. For example, values currently returned as "1.50" (which would represent $1.50 for a USD account) will be returned as 1500000.
To help you with this change, we've introduced a new HTTP header flag (available immediately) that allows you to explicitly request the micros format. If you've written code that expects conventional currency values in reports, it's important that you update your code to expect micros and set the HTTP header "returnMoneyInMicros: true" when requesting a report download. Additionally, if you're just beginning to migrate from v13 reports, you should set this header on all your download requests.
To learn more about the new way to run reports via the API, see our blog post from this summer. As always, please post questions to the AdWords API Forum.
- Eric Koleda, AdWords API Team
