Posted:
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.

Posted:

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.

Posted:

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.

Posted:

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.

Posted:

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.

Posted:
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.

Posted:

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.