Tag Archives: Developer

Migrating off the Login field in the AdWords API

On November 5, 2014, we'll be sunsetting the login field in the ManagedCustomer class. We understand this may impact your applications and are recommending the following options to account for this change:

Maintaining customer contacts

You should not use the login field to manage your clients' contacts and email addresses. You should always maintain your own client contacts. If your application currently relies on the login field, you can use ManagedCustomerService.get() to create a mapping between customer IDs and login emails before November 5, 2014.

Identifying client accounts

CustomerId should be used instead of the login field to uniquely identify an account. To provide a friendly name for an account, you can use the name field. You may set the name field when creating a new account using the ManagedCustomerServer.mutate() method.

AdWords allows users to invite multiple users to manage their applications as well as change their AdWords sign-in information. However, the login field is not updated to reflect changes in AdWords sign-in information. So relying on the login field makes your application error prone if a user changes their AdWords sign-in information.

Determining the access level of a user

Your application runs with the same access levels as the user whose OAuth2 access token you send in your API calls. To determine if a user is authorized to make a particular change, you can make API calls with the validateOnly header set to true. If the user isn’t authorized to make changes, the call will fail with an AuthorizationError.

Login field information doesn't convey the access level the user has within AdWords. If you rely on a user’s login email to determine their access level, your application may run into errors if the user’s account access levels change.

If you have questions or feedback about this change, or encounter a use case we’ve missed, let us know on our developer forum or Google+ page.

Support for VPAID 2 JavaScript creatives in the IMA HTML5 SDK

We're pleased to announce that the IMA HTML5 SDK now supports VPAID 2 JavaScript creatives. Enabling support is as easy as including the following line before initializing your AdDisplayContainer:

    google.ima.settings.setVpaidAllowed(true);
...
var adDisplayContainer = new google.ima.AdDisplayContainer(adContainerElement);
var adsLoader = new google.ima.AdsLoader(adDisplayContainer);

VPAID 2 Support caveats

There are two differences to be aware of between the VPAID 2 spec and the way the IMA SDK supports VPAID 2. These differences do not impact player or SDK implementation code, but they are important for VPAID 2 JavaScript creative authors, as creatives may throw errors or not work as expected when rendered by the IMA HTML5 SDK.

  • IFrame security: The IMA SDK uses a secure iframe instead of a friendly iframe (same domain) or an in-page script to render VPAID 2 JavaScript creatives. This means that if a creative expects to access the DOM of the parent page, it could potentially cause an error.

  • Video player proxy element: For security and proper mobile functionality, the IMA SDK doesn't provide the actual video element to the ad; instead, it provides a proxy element that mimics much of the functionality of the normal video element. For ad creatives that only access supported video APIs available on the proxy element, there should be no behavior changes in the rendering of the creatives. See our guide to VPAID 2 creatives for a list of supported APIs on the video proxy element.

Learn more

For more information, including a listing of what API methods are supported in the video player proxy element, check out our guide to VPAID 2 creatives.

As always, if you have any questions, feel free to contact us via the support forum.

Sunsetting Login email in AdWords Scripts

We recently announced that we will sunset the login email field in AdWords API. To keep our APIs consistent, we will also sunset the getLoginEmail() method in AdWords scripts on November 5, 2014. We have identified some of the common use cases for this field and have come up with some possible workarounds.

Identifying accounts

When retrieving client accounts, use their Customer IDs instead of login emails to identify the accounts. You can use the getCustomerId() method to retrieve an account’s Customer ID. When available, you may also use the getName() method to retrieve the account’s friendly name. To set an account’s name,
  • Login to your My Client Center account and navigate to My Client Center tab
  • Click on the pencil logo in the corresponding Account’s the Client column
  • Provide a new name, and click the Save button to update the account name
Maintaining customer contacts

You should maintain your customer contacts going forward. If you were relying on the login email field to manage your client contacts, then you can use the getCustomerId() and getLoginEmail() methods to create a mapping from your customer ids to their login emails before November 5, 2014.

Determining access levels of a user in an account

Scripts run with the same access levels as the user who authorized the script. You shouldn’t rely on a login email to figure out a script’s access levels--this is a bad programming practice that makes your script error prone if the user’s account access level changes. Instead, make sure that the script is authorized by a user who has enough access levels as required by the script.

If you have questions or feedback about this change, or a use case we missed, let us know on our developer forum or our Google+ page.

Launching v6.1 of the Google Mobile Ads SDK for Android

Greetings developers!

We're happy to launch a new version of our Google Mobile Ads SDK for Android. You should see Google Play Services 6.1 (rev 20) available for download in your SDK manager.

This version includes the following changes:

  • Added a getLocation method to com.google.android.gms.ads.MediationAdRequest.
  • Added a content description for the interstitial close button.
  • Removed logging of "Google Play resources not found" when the library project is linked correctly.
  • Added getMediationAdapterClassName to AdView for getting the class name of the ad network mediation adapter currently showing an ad.

You can read the Google Play Services Announcement on the Android Developers Blog for a summary of what’s new with this release. For a full list of SDK changes, check out our release notes. For technical questions, post them on our forum.

The IMA SDKs now support VAST 3

We're taking VAST 3 support out of beta and launching it as a supported feature of the IMA SDKs for Flash, HTML5, iOS, and Android. VAST 3 adds support for a host of new features, including:

  • Enhanced reporting metrics and error codes.
  • Customizable skip times.
  • Ad podding.
  • Enhanced support for adaptive bitrate creatives (e.g., HLS).
  • Alternative companion creatives in HTML5 and iOS.
  • Icons in HTML5.
  • Companion adSlotId attribute in HTML5.

There are still a few features of VAST 3 that we will continue to add over time. Those include:

  • Alternative companion creatives in Flash and Android.
  • Companion adSlotId attribute in Flash, iOS, and Android.
  • Standardized fallback with the fallbackOnNoAd attribute.

Your IMA SDK integration already supports VAST 3 without any code changes on your end, but you will need to adjust your serving settings. To start serving VAST 3 check out the DFP help center articles for Small Business or Premium, depending on your account type.

For more information on the features and benefits of VAST 3, check out the IAB documentation. As always, if you have any questions feel free to contact us via the support forum.

Using LINQ with the DFP API

By now you're probably familiar with using PQL in the DFP API. The SQL-like filtering provides an expressive way of working with DFP, but occasionally you'll want to filter on a field that isn't supported by PQL. Luckily, if you're using the .NET library, you can utilize LINQ to augment your filtering capabilities.

Filter on any field

Similar to PQL, LINQ provides a friendly syntax for filtering iterables. As you page through entities from DFP, you can leverage LINQ to add that extra filtering with just a few lines of code.

This example finds all ImageCreatives that are missing altText - a field specific to the subclass and not filterable with PQL.

    CreativePage page = new CreativePage();
var creativesMissingAltText = new List();

// Create statement to select image creatives.
StatementBuilder statementBuilder = new StatementBuilder()
.Where("creativeType = :creativeType")
.OrderBy("id ASC")
.Limit(StatementBuilder.SUGGESTED_PAGE_LIMIT)
.WithBindVartiableValue("creativeType", "ImageCreative");

// Page through all creatives and select those that are missing the
// altText property with LINQ.
do {
page =
creativeService.getCreativesByStatement(statementBuilder.ToStatement());

creativesMissingAltText.AddRange(
from ImageCreative creative in page.results
where creative.altText == ""
select creative);

statementBuilder.IncreaseOffsetBy(StatementBuilder.SUGGESTED_PAGE_LIMIT);
} while (statementBuilder.GetOffset() < page.totalResultSetSize);

Console.WriteLine("Found {0} ImageCreatives missing altText",
creativesMissingAltText.Count);

While LINQ offers a way to extend filtering, it's important not to ignore PQL. You'll notice this example used PQL to pre-filter on the creative type. Working with smaller result sets will save you network overhead and processing cycles.

Filtering with regular expressions

Now let's take a look at a more complex example. In this scenario, your application needs to validate the htmlSnippet of CustomCreatives. LINQ allows you to use regular expressions while filtering to extract the matches. Here we'll use a regular expression to make sure URLs in the htmlSnippet point to a certain subdomain.

    // Make sure any URLs to mydomain go through the CDN.
Regex subdomainRegex = new Regex(@"https?://(?!cdn\.).*?mydomain.com");
var errors =
from CustomCreative creative in creativesToValidate
let matches = subdomainRegex.Matches(creative.htmlSnippet)
where matches.Count > 0
select new {
creativeId = creative.id,
matchedUrls = from Match match in matches select match.Value
};

foreach (var error in errors) {
Console.WriteLine("Invalid urls found in creative {0}: {1}",
error.creativeId, error.matchedUrls.Join(","));
}
LINQ also supports common functions like Average and Max, making it easy to interact with DFP entities. For more LINQ examples, check out 101 LINQ Samples. You just might find the missing link you need for your DFP application.

Launching v6.12.0 of the iOS Mobile Ads SDK with iOS 8 Support

Today, we’re happy to announce the launch of Google Mobile Ads SDK v6.12.0 with support for iOS 8. Specifically, it includes the following iOS 8 updates:

  • Less time is spent on the main thread while loading ads
  • Smart Banner ads are displayed correctly in landscape

New Framework Dependencies

Version 6.12.0 also requires that your app link to two additional frameworks:

  • EventKit
  • EventKitUI

If you’re using CocoaPods, simply run pod update to grab the update, and these new frameworks will be automatically linked for you. If you’re not using Cocoapods, the getting started guide has the full list of required frameworks.

See the release notes for a full list of updates. You can grab the latest SDK from the downloads page. If you have any technical questions about the new release, post them on the developer forum. Also follow our Google+ page to keep abreast of the latest developments for the Mobile Ads SDK.

Change to the default conversion optimizer mode for new AdWords Accounts

As announced in February, flexible conversion counting in AdWords now lets you decide how you want to count conversions for each of your accounts. As a follow up to this new feature, when new AdWords accounts are created through the UI or the API after October 1st, 2014, the default conversionOptimizerMode will be MANY_PER_CLICK instead of ONE_PER_CLICK. In addition, we'll change the conversionOptimizerMode to MANY_PER_CLICK on any existing account that is not using bidding strategies impacted by conversions.

Action required
Since the new default of MANY_PER_CLICK lets your conversion-based bidding strategies take full advantage of flexible conversion counting, we recommend keeping the default setting on new accounts. However, if you still want to use ONE_PER_CLICK for new accounts created via ManagedCustomerService, then add a second step in your account creation process that issues a CustomerService.mutate call that sets the conversionOptimizerMode on the Customer.

In addition, if you decide to utilize one of the conversion-based bidding strategies, you'll want to make sure that the conversionOptimizerMode is set to the value you'd prefer. The conversion-based bidding strategies affected by conversionOptimizerMode are: Additional information
If you'd like to learn more about conversion tracking in AdWords, check out the Help Center article on counting conversions. In addition, the remarketing examples folder in each client library contains an AddConversionTracker example that shows how to create an AdWordsConversionTracker via the API.

Still have questions? Feel free to visit us on the AdWords API Forum or our Google+ page.

‘Decorating’ your Python DFP API applications

Python has tons of cool idioms and features that are often overlooked or underutilized. List comprehensions to cut back on the use of unnecessary loops, decorators to wrap functions with annotations, and generator functions are just some that can be applied to working with the DFP API.

In this post, we'll tackle one of our most asked questions using decorators: "Why am I running into CONCURRENT_MODIFICATION or QUOTA_EXCEEDED errors, and how do I avoid this?".

Addressing these errors using decorators

CONCURRENT_MODIFICATION and QUOTA_EXCEEDED errors are similar in nature - the requests you’re making are failing, but not necessarily because the data you’re sending over is bad. In the first case, one of the objects you’re trying to modify is being updated elsewhere, but you likely want to try again after pulling down the same set of objects. You could certainly write code that retries your operations in all of your services for each object, but it may get a bit hard to maintain (especially with duplicated code). A much cleaner implementation would be to use a decorator!

The Python wiki has an entry under the decorators section that shows how a generic decorator might work for retrying a call. With a few modifications, we can tailor this to capture the two types of errors that might arise:

  import time
from functools import wraps

RESPONSES_TO_RETRY = ['CONCURRENT_MODIFICATION', 'QUOTA_EXCEEDED']

def retry(tries=4, delay=3, backoff=2):
''' Decorator that implements an exponential backoff for retrying on errors.

Args:
tries: int number of times to execute the wrapped function before failing
delay: int time to delay in seconds before the FIRST retry
backoff: int multiplier to extend the initial delay by for each retry
'''
def decorated_function_with_retry(func):
@wraps(func)
def function_to_retry(*args, **kwargs):
local_tries, local_delay = tries, delay
while local_tries > 1:
try:
return func(*args, **kwargs)
except Exception, e:
if [response for response in RESPONSES_TO_RETRY
if response in e.fault['faultstring']]:
print '%s, Retrying in %d seconds...' % (str(e),
local_delay)
time.sleep(local_delay)
local_tries -= 1
local_delay *= backoff
return func(*args, **kwargs)
return function_to_retry
return decorated_function_with_retry

Say you were making a call to update line items - with large networks, it’s not unlikely that someone might be editing the line item at the same time. Since you’d want to pull down the most recent copy of the line item any time the update fails, you would want to abstract out the update method to include the getLineItemsByStatement call, e.g.,

  @retry()
def fetch_and_update_line_item(statement):
# call to get the line item in question
response = line_item_service.getLineItemsByStatement(
statement.ToStatement())

updated_line_items = []
if 'results' in response:
for line_item in response['results']:
# Do something with your line items here and add them to
# updated_line_items.

line_item_service.updateLineItems(updated_line_items)

This would effectively allow you to, in the event of the update failing due to concurrent modification, pull down and update a new copy of the line item. Using the default constructor will retry 4 times with 3, 6, and 12 second delays in between.

To wrap things up, decorators are incredibly useful constructs in Python and are useful for the DFP API for several reasons:

  • Your application will be less flaky and less affected by intermittent application issues.
  • You’re less likely to run into quota errors.
  • This would prevent overwriting other changes (in the case of retrying failed calls on concurrent modification errors).
  • You could also use something like this to log errors on your end, which could help reveal poor code health or inefficient processes.

Make use of decorators in your code, and you'll soon be sitting pretty.

DoubleClick Ad Exchange Seller REST API v2.0

Today we launch the v2.0 release of the DoubleClick Ad Exchange Seller REST API. This release adds support for associating a single user to more than one account.

If your user ID is associated with only one account, you can continue to use v1.1 of the API as you have previously, although we recommend you always use v2.0 of the API. If your user ID is associated with more than one account, you must use the v2.0 API and supply the accountId of the appropriate customer account with each request.

For example, resource requests in v1.1 like this:
https://www.googleapis.com/adexchangeseller/v1.1/{resourceType}/{resourceId}

Will become this in v2.0:
https://www.googleapis.com/adexchangeseller/v2.0/accounts/{accountId}/{resourceType}/{resourceId}

Follow our Google+ page for other announcements and updates.