Showing posts with label discover_v2009. Show all posts
Showing posts with label discover_v2009. Show all posts

Discover v2009: Working with AuthTokens

Thursday, July 01, 2010


Authorization tokens were introduced with v2009 as part of the authorization mechanism adopted for the new version, ClientLogin. This new approach allows us to separate authorization from API requests, making it a two step process: first retrieve a token, and then include it with your requests.


How ClientLogin works


ClientLogin was designed as a standalone authentication and authorization procedure that returns a token, if successful. This token is then supplied together with the requests as a form of proof that the user is who they claim to be, and that they are allowed access to the API. Since both the authorization and the requests happen over SSL connections, there is no risk of anyone retrieving the token and impersonating the user.

Explaining how to implement a full ClientLogin handler is outside the scope of this blog post, but for the full details on the protocol please consult the documentation. Here is a small example of how to log in using the AuthToken module included with the Ruby client library (which can be used outside of it, since its only dependency is the httpclient gem):

require 'authtoken'

auth_token = AdWords::AuthToken.get_token(email, password,

'www.google.com', 443, true)


Other client library projects include NoClientLib pages in their wikis detailing how to perform the ClientLogin step (as well as all other steps in a successful request) without the client library.

If you’re using the client libraries, the ClientLogin step is usually handled for you, although you’ll still need to keep an eye out for any errors. The Readme file included with your client library has more details.

Remember to reuse the authorization tokens


This is a point of some confusion among developers, and illustrates one of the key differences in authorization between v13 and v2009: In v13, you authenticated and authorized every request by sending your account credentials as part of the header; in v2009, you authenticate with ClientLogin beforehand and then authorize your request to the AdWords API by supplying the token generated by ClientLogin.

A naive migration from v13 to v2009 would generate a new token for every request and insert it into the header. This is a bad idea. Such an implementation will very likely cause your software to run into CAPTCHAs and block your accounts until the CAPTCHAs are resolved.

A correct implementation would generate the token, cache it, and reuse it for all subsequent requests with that email address, even against the sandbox.

Handling expiration and errors


Tokens don’t last forever; as a security mechanism, they only last up to two weeks. Do bear in mind, though, that this doesn’t mean they’ll last a full two weeks: Authorization tokens can at any time be revoked for any number of reasons (usually for security). If a token has been revoked, you’ll get back an AuthenticationError with the reason GOOGLE_ACCOUNT_COOKIE_INVALID.

Most of these errors can be handled simply by requesting a new authorization token, but if you get back a CaptchaRequired error when performing the ClientLogin interactions, you’ll need the user to resolve the CAPTCHA before you’re allowed generation of new tokens (or wait approximately 5 minutes, after which it will work again). The error message will include a URL to the image and a CAPTCHA token, so you can embed this directly into your application, without having to redirect the user to a web page. Check the ClientLogin documentation for details.

What to keep in mind when implementing your application


When implementing your application, keep these best practices in mind:
  • Generate a new token before the first request your application makes. You’ll need a token for every different email header that you use, so:
    • if you log in by setting the email header to your MCC (My Client Center) account and then change the clientEmail header to the different accounts you’re accessing, you’ll only need a single token;
    • if you log in by setting the email and password headers directly to those of the different accounts you’re accessing, you’ll need a new token for each.
  • Reuse this token in subsequent requests.
  • If you receive an AuthenticationError back, take a look at the reason:
    • if it indicates an expired token, try generating a new one and proceeding;
    • if it indicates an unrecoverable error, present the information to the user, and let them decide how to proceed.


Finally, if you’re using one of our client libraries, then we have good news for you: the first two steps are already taken care of! Just set your credentials according to the instructions for your specific client library, and it will manage both v13 and v2009 authorization for you.

Keep in mind that if you have any further questions or run into any other authorization issues, the documentation and the forum are the right place to go!


--Sérgio Gomes, AdWords API Team



Discover v2009: Do more with mutate

Thursday, March 25, 2010


In previous versions of the API, services had separate methods for adding, updating, and removing items in an AdWords account. The v2009 version changed this paradigm and combined the functionality into a single method called mutate. The mutate method works on operations, where each operation defines the action to perform (operator) and the item to perform it against (operand).

While it may not be immediately obvious, the mutate method is designed to process many operations in one call. For example, the following method uses the PHP client library to add multiple keywords in one request.

function addKeywords($keywords, $adGroupId, $adGroupCriterionService) {
$operations = array();

foreach ($keywords as $keyword) {
// Create biddable ad group criterion.
$adGroupCriterion = new BiddableAdGroupCriterion();
$adGroupCriterion->adGroupId = $adGroupId;
$adGroupCriterion->criterion = $keyword;

// Create operation.
$operation = new AdGroupCriterionOperation();
$operation->operand = $adGroupCriterion;
$operation->operator = 'ADD';

// Add operation to array.
$operations[] = $operation;
}

// Make mutate request.
$results = $adGroupCriterionService->mutate($operations);

return $results;
}

It’s important to note that performing multiple operations in one request can be substantially faster then performing them one at a time. Making any request to the AdWords API comes with a certain amount of overhead, so performing more work per request can dramatically improve the performance of your application. For example, in a simple test I ran adding 500 keywords in a single request was over 100x faster than performing 500 separate requests.

Also of note is that the operations in a mutate request can contain any mixture of operators and span any number of campaigns, ad groups, etc. That means you can add a keyword to one ad group and update a keyword in a different ad group in the same request.

More information on the mutate method of a service and the operations it supports can be found in the developer documentation, and any questions you have can be posted to the forum.

- Eric Koleda, AdWords API Team

Discover v2009: Location Extensions

Wednesday, December 23, 2009


Location, location, location: so goes the mantra of the real estate business. Although, in this constantly connected world where people are carrying Internet-enabled mobile devices more and more, location is important to every retail business. Often, users are looking for the closest provider of a service or a product, rather than your specific business.

So how can you get your business on the map? In the past, we had an entirely separate ad type: the Local Business Ad (LBA). But with the new AdWords interface and AdWords API v2009, we have a much simpler solution available: Location Extensions. These allow you to easily add location information to any text ad in your campaigns.

Let's look at an example. Say your business has a few branches open throughout the city, and you want to add location information to your existing ads. The first step is to retrieve the location of each branch, based on its address. That means making a call to the new GeoLocationService, which uses a process known as "geocoding."

// Create address object.
Address address = new Address();
address.setStreetAddress("123 Easy Street");
address.setCityName("Mountain View");
address.setProvinceCode("US-CA");
address.setPostalCode("94043");
address.setCountryCode("US");
// Get location information from the service.
GeoLocationSelector selector = new GeoLocationSelector();
selector.setAddresses(new Address[] {address});
GeoLocation[] locations = geoLocationService.get(selector);
location = locations[0];

The next step is to use the CampaignAdExtensionService to add a location extension to your campaign using the information returned by the GeoLocationService:

// Create LocationExtension.
LocationExtension locationExtension = new LocationExtension();
locationExtension.setAddress(location.getAddress());
locationExtension.setGeoPoint(location.getGeoPoint());
locationExtension.setEncodedLocation(location.getEncodedLocation());
locationExtension.setCompanyName("Foo");
locationExtension.setPhoneNumber("650-555-5555");
locationExtension.setSource(LocationExtensionSource.ADWORDS_FRONTEND);
// Create CampaignAdExtension.
CampaignAdExtension campaignAdExtension = new CampaignAdExtension();
campaignAdExtension.setCampaignId(campaignId);
campaignAdExtension.setAdExtension(locationExtension);
// Add location extension to the campaign.
CampaignAdExtensionOperation operation = new CampaignAdExtensionOperation();
operation.setOperand(campaignAdExtension);
operation.setOperator(Operator.ADD);
CampaignAdExtensionOperation[] operations =
new CampaignAdExtensionOperation[] {operation};
CampaignAdExtensionReturnValue result =
campaignAdExtensionService.mutate(operations);

Multiple location extensions can be added to the same campaign, and by default each ad in the campaign will be associated with every location. When serving your ad the AdWords system will choose the most relevant location to display to the user. Do keep in mind that there is a limit of 9 manually created location extensions per campaign. Alternatively you can have AdWords pull addresses directly from your Local Business Center (LBC) account, which isn't subject to the same restriction. For now, LBC synchronization is only supported via the AdWords interface, but the next API version will include support for it as well.

Of course, not all ads are created equal, and you may want some ads to target only a single store. In that case, the solution is to create an Ad Extension Override for the one location extension that you do want to associate with that ad:

// Create ad extension override for the specified ad Id.
AdExtensionOverride adExtensionOverride = new AdExtensionOverride();
adExtensionOverride.setAdId(adId);
// Create ad extension object using specified campaign ad extension Id.
// This will be the only extension used for the specified ad.
AdExtension adExtension = new AdExtension();
adExtension.setId(campaignAdExtensionId);
adExtensionOverride.setAdExtension(adExtension);
// Add the override.
AdExtensionOverrideOperation operation = new AdExtensionOverrideOperation();
operation.setOperand(adExtensionOverride);
operation.setOperator(Operator.ADD);
AdExtensionOverrideOperation[] operations =
new AdExtensionOverrideOperation[] {operation};
AdExtensionOverrideReturnValue result =
adExtensionOverrideService.mutate(operations);

If you're looking for more detailed examples, be sure to check the 'examples' directory for the client library of your choice.

Extending your ads with location information will enable them to be shown on Google.com and other properties (such as Google Maps), bringing you closer to your customers' local searches. That way they'll not only find out about your offers, they'll actually be able to find you.

-- Sérgio Gomes, AdWords API Team

Discover v2009: New Examples in Client Libraries

Friday, December 11, 2009


Our Discover v2009 series has focused on introducing you to the new services and objects that come with the update to the API. And while we hope these posts have been informative we know there is nothing like running a code example yourself to bring the concepts to life. That's why we've spent the last few weeks completely re-hauling the examples in our client libraries to provide a more complete set of sample code to try out. The following client libraries now have over 30 examples for the v200909 version of the API:

If you haven't tried out the v2009 API there is no better time to get started. With our client libraries you can go from download to making requests in under five minutes, and the built-in logging and utility classes make learning v2009 a breeze. Many client libraries (Java, .NET, Python, and Ruby) even come bundled with v13 support, allowing you to take advantage of new v2009 features without having to update your entire application at once.

As always, we are here to answer your questions, collect feedback, and assist with migration to the v2009 API.

- Eric Koleda, AdWords API Team

Discover v2009: validateOnly header

Wednesday, December 09, 2009


While making AdWords API calls, a common task that you have to perform as a developer is to ensure that the SOAP requests you make to the server are valid. This includes validation in terms of parameters required for an API call, as well as ensuring that your ads and criteria are in accordance with Adwords policies. AdWords API v200909 introduces a new RequestHeader field named
validateOnly to help you validate your API calls.

While making an API call in AdWords API v200909, if you include the validateOnly header in an API call, the servers will perform validation on the API parameters, but will not perform the requested operation like creating campaigns, ads, etc. For instance, the relevant parts of a SOAP request and response xml to validate a call to CampaignService::mutate() are given below.

SOAP Request

<soap:Header>
..<RequestHeader xmlns="https://adwords.google.com/api/adwords/cm/v200909">
....<!-- other headers here -->
....<validateOnly>true</validateOnly>
--</RequestHeader>
</soap:Header>

SOAP Response (Success)

<soap:Body>
..<mutateResponse xmlns="https://adwords.google.com/api/adwords/cm/v200909"/>
</soap:Body>

SOAP Response (Failure)

<soap:Body>
..<soap:Fault>
....<faultcode>...</faultcode>
....<faultstring>...</faultstring>
....<detail>
......<ApiExceptionFault
..........x
mlns="https://adwords.google.com/api/adwords/cm/v200909">
........<message>...</message>
........<ApplicationException.Type>ApiException</ApplicationException.Type>
........<errors.xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
...........xsi:type="BudgetError">
..........<fieldPath>operations[1].operand.budget</fieldPath>
..........<trigger/>
..........<ApiError.Type>BudgetError</ApiError.Type>
..........<reason>NON_MULTIPLE_OF_MINIMUM_CURRENCY_UNIT</reason>
........</errors>
........<!-- More errors here. -->
......</ApiExceptionFault>
....</detail>
..</soap:Fault>
</soap:Body>

As you can see, if the request were successful, then you would get an empty mutateResponse, which shows that the request was validated successfully, but no campaign was created. If the request had errors, then you would get back an APIException, and the errors field will contain a collection of ApiError objects, one for each error encountered on validation. The fieldPath contains the OGNL field path to identify cause of error, whereas other fields like reason and trigger gives you more information why the error occurred. For instance, the failed response xml shown above had an error in the second operation. It triggered a BudgetError since its budget was not a multiple of the minimum currency unit.

You can also use validateOnly headers to check if a batch of ads or criteria has any policy errors. AdWords API v13 exposed two methods, checkAds and checkCriteria to check a batch of ads or criteria for policy errors. The following java code snippet shows how you can use validateOnly headers to perform policy checks on ads, similar to checkAds.

AdGroupAdServiceInterface adGroupAdService = (AdGroupAdServiceInterface) ....user.getValidationService(AdWordsService.V200909.ADGROUP_AD_SERVICE);

TextAd textAd = new TextAd();
textAd.setHeadline(
"Luxury Cruise to MARS");
textAd.setDescription1(
"Visit the Red Planet in style.");
textAd.setDescription2(
"Low-gravity fun for everyone!!!"); // Force a policy violation.
textAd.setDisplayUrl("www.example.com");
textAd.setUrl(
"http://www.example.com");

AdGroupAd
adGroupAd = new AdGroupAd();
adGroupAd.setAd(textAd);
adGroupAd.setAdGroupId(Long.parseLong(
"INSERT_ADGROUP_ID_HERE"));
adGroupAd.setStatus(
AdGroupAdStatus.ENABLED);

AdGroupAdOperation
operation = new AdGroupAdOperation();
operation.setOperator(
Operator.ADD);
operation.setOperand(adGroupAd);

try
{
..AdGroupAdReturnValue result =
......adGroupAdService.mutate(new AdGroupAdOperation[] {operation});

..// No policy violations found. Add the ads using the non-validating service.
..adGroupAdService = (AdGroupAdServiceInterface)
......user.getService(AdWordsService.V200909.ADGROUP_AD_SERVICE);
..result = adGroupAdService.mutate(new AdGroupAdOperation[] {operation});
}
catch (ApiException e) {
..for (ApiError error: e.getErrors()) {
....if (error instanceof PolicyViolationError) {
......PolicyViolationError policyError = (PolicyViolationError) error;
......// Handle your policy violations here.
....}
..}
}


Finally, the use of validateOnly header will cost you only 0.05 units per validated item. All costs are rounded to the next greater or equal integer (i.e., both .05 and .95 are rounded to 1). This way, you can validate your calls and fix the errors without wasting a lot of API units on a failed API call. We've included support for validateOnly in all of our client libraries to help get you started, so please try it out and let us know of any feedback you may have on our forum.

-- Anash P. Oommen, AdWords API Team

Discover v2009: Setting ad parameters with the AdParamService

Wednesday, November 25, 2009


In a blog post yesterday we introduced ad parameters, a new AdWords feature that allows for dynamic insertion of numeric and currency values into ads while retaining ad history. To manage ad parameters, a new service was added to the v200909 API: the AdParamService.

In the example introduced earlier, you own a business selling antique cups that wants to add price and inventory information to your ads. To leverage ad parameters you create a text ad like:


and you configure the following ad parameters on your keywords:

keyword
param1
param2
antique cups
$80
18

A user searching for "antique cups" would will see the following ad text:


Text ads, even those with ad parameter placeholders, can be created using the normal methods of the AdGroupAdService. The AdParamService is only used for setting ad parameter values on keywords. This service allows for the getting and setting of AdParam objects, which contain the ad group ID and criterion ID for the target keyword, the insertion text, and the parameter index.

For example, to set the ad parameters for "antique cups" we would use the following PHP code (using the AdWords API PHP Client Library):
$adParam1 = new AdParam($adGroupId, $criterionId, '$80', 1);
$adParam2 = new AdParam($adGroupId, $criterionId, '18', 2);

$operation1 = new AdParamOperation($adParam1, 'SET');
$operation2 = new AdParamOperation($adParam2, 'SET');

$adParams = $adParamService->mutate(array($operation1, $operation2));
Existing ad params can be selected by ad group ID or by ad group ID and criterion ID. To get the ad parameters set above we would run the following:
$selector = new AdParamSelector(array($adGroupId), array($criterionId));
$adParamPage = AdParamServiceTest::$service->get($selector);
Some key points to remember about the ad parameters and the AdParamService are:
  • Ad parameters are set on keywords, not ads.
  • Ad parameters can only accept numerical and currency values, but the default text of the placeholder in the ad can be any string.
  • The length of the default text in the placeholder contributes to the total length of the line in the ad, but the curly braces, parameters name, and colon do not.
  • Ad parameters are 1-based indexed, meaning the two parameters are "1" and "2".
  • The AdParamOperation should always use the "SET" operator, even when you are setting the parameters for the first time.
To help you get started, we've included support for this service in our client libraries. As always, we are here to answer your questions, collect feedback, and assist with migration to v2009 of the AdWords API.