Tag Archives: reports

The Query Builder Blog Series: Part 2 – Designing a Resource Schema

This blog series follows the journey of building the recently released Interactive Google Ads Query Builder tool. Part 1 of this series outlined what we’ll be covering in the series as well as the rationale behind publishing this content. Part 2 will focus on designing a detailed JSON resource schema that will serve as the canonical data set for the Interactive Query Builder Angular application.

Background

As mentioned in Part 1, one of the major benefits of the new Interactive Query Builder is that it provides real-time feedback detailing why fields may or may not be selectable in a given clause of a Google Ads Query Language (GAQL) query.

For example, let’s say you are constructing a GAQL query with ad_group as the main resource in the FROM clause. Both segments.conversion_action and metrics.absolute_top_impression_percentage are selectable on the ad_group resource. However, taking a look at the detailed reference documentation for segments.conversion_action, we can see that there is a list of “Selectable With” fields, and that list does not include metrics.absolute_top_impression_percentage. Therefore, those two fields are incompatible. Regardless of what resource is in the FROM clause, if one of those two fields is present in the query, we know that the other cannot be. That is why metrics.absolute_top_impression_percentage is no longer selectable in the Interactive Query Builder once segments.conversion_action is selected.

Rather than trying to piece together all of this logic at runtime with various back-and-forth server calls, we thought it would be beneficial to feed that data into the application with static JSON files containing the resource schema. What might that optimal schema look like?

Schema Design (definition at the end of the blog post)

A GAQL string requires a single resource in the FROM clause. Given that constraint, the top level JSON schema will be a map from resources to detailed schemas for each resource. For example, the ad_group entry in our schema will look like this:



{

"ad_group": {

"name": "ad_group",
"display_name": "Ad Group",
"description": "An ad group.",
// Array of all attribute and attributed resource fields.
"attributes": [
"ad_group.ad_rotation_mode",
"ad_group.base_ad_group",
"ad_group.campaign",
...
"campaign.ad_serving_optimization_status",
"campaign.advertising_channel_sub_type",
"campaign.advertising_channel_type",
...
"customer.auto_tagging_enabled",
"customer.call_reporting_setting.call_conversion_action",
"customer.call_reporting_setting.call_conversion_reporting_enabled",
...
],
// Array of all metrics selectable with ad_group.
"metrics": [...],
// Array of all segments selectable with ad_group.
"segments": [...],
// Expanded info for all items listed in attributes, metrics, and segments arrays.
"fields": {...}

}




The crux of this enhanced schema is the fields entry. The keys of this object will be all of the attributes, metrics, and segments of the top level resource (e.g. ad_group). The value of each item in this object will be objects containing detailed information about that given field, as well as an additional field called incompatible_fields, an array of the fields that are incompatible with the given field. For example, the metrics.phone_impressions entry of the fields object would look like this:





"metrics.phone_impressions": {
"field_details": {
"name": "metrics.phone_impressions",
"category": "METRIC",
"selectable": true,
"filterable": true,
"sortable": true,
"data_type": "INT64",
"is_repeated": false,
"type_url": "",
"description": "Number of offline phone impressions.",
"enum_values": [],
"selectable_with": [
"ad_group",
"ad_group_ad",
"campaign",
"customer",
"extension_feed_item",
"segments.ad_network_type",
"segments.click_type",
"segments.date",
"segments.day_of_week",
"segments.interaction_on_this_extension",
"segments.keyword.ad_group_criterion",
"segments.keyword.info.match_type",
"segments.keyword.info.text",
"segments.month",
"segments.month_of_year",
"segments.quarter",
"segments.week",
"segments.year"
]
},
"incompatible_fields": [
"segments.slot",
"segments.device",
"segments.external_conversion_source",
"segments.conversion_action_category",
"segments.conversion_lag_bucket",
"segments.hour",
"segments.conversion_action_name",
"segments.conversion_action",
"segments.conversion_adjustment",
"segments.conversion_or_adjustment_lag_bucket"
]
},




The recursive nature of the schema may seem somewhat redundant, as some fields will appear in multiple resources. However, we will ultimately divide this main schema into individual JSON files for each resource to decrease load times, and we will only retrieve a single resource-specific schema depending on the resource in the FROM clause.


Schema Definition

For reference, the full schema definition is below:



interface ResourceSchema {
name: string; // the name of the resource
display_name: string; // the display name of the resource
description: string; // the description of the resource
attributes: string[]; // the resource's fields (including attributed resource fields)
metrics: string[]; // available metrics when the resource is in the FROM clause
segments: string[]; // available segments when the resource is in the FROM clause
fields: { // detailed info about all fields, metrics, and segments
[key: string]: {
field_details: FieldDetails; // details about the field (defined below)
incompatible_fields: string[]; // fields that are incompatible with the current field
}
};
}

interface FieldDetails {
name: string; // the name of the field
category: string; // the field's category (e.g. ATTRIBUTE, METRIC, SEGMENT)
selectable: boolean; // whether or not the field is allowed to be placed in the SELECT clause
filterable: boolean; // whether or not the field is allowed to be placed in the WHERE clause
sortable: boolean; // whether or not the field is allowed to be placed in the ORDER BY clause
data_type: string; // the field's data type
is_repeated: boolean; // whether or not the field is a repeated field
type_url: string; // the field's type_url
description: string; // the field's description
enum_values: string[]; // possible enum values if the field is of type ENUM
selectable_with: string[]; // the list of field the current field is selectable with
}


Conclusion

With that, we now have designed an expanded resource schema containing detailed field information and a list of incompatible fields for each field, which we can use in our Angular application. In part 3, we’ll discuss how to create this schema using the GoogleAdsFieldService.
Hopefully this has deepened your understanding of and shown you what is possible with the Google Ads API. If you have any questions or need additional help, contact us via the forum or at [email protected].

The Query Builder Blog Series: Part 1 – Setting the Stage

An important part of our role in Developer Relations is gathering your feedback, as developers using our APIs, so that we can improve products and create tools that will make for a better developer experience. This is particularly important now because the Google Ads API is now out of Beta. We have received several important pieces of feedback as it relates to the Google Ads Query Language (GAQL) and constructing GAQL queries. Specifically, we’ve learned that

  • GAQL is a powerful and flexible mechanism for retrieving data from the Google Ads API. In order to get the most out of it and construct queries efficiently, it is important to understand the details and nuances of this query language.
  • The previous version of the Interactive Google Ads Query Builder tool was useful for constructing GAQL query strings. However, there were opportunities to make the query building process faster while exposing some of the logic behind the tool to better understand how GAQL query string validation works.
As a result, we have released a new version of the Interactive Google Ads Query Builder tool that has several benefits, which you can view in the release blog post.

In developing this new tool, we approached the Google Ads API from a user's perspective to better understand developer use cases. Throughout the process, we documented our experience to share how we approach using the Google Ads API. This is the first in a series of blog posts following that journey. The Query Builder Blog Series will include the following topics.

  • Designing a resource schema: designing a detailed JSON resource schema that will serve as the canonical data set for the Interactive Query Builder Angular application.
  • Creating a resource schema: how we can use the GoogleAdsFieldService to create an enhanced resource schema that includes incompatible fields to make building this application easier.
  • Creating a resource service: how to create a resource service that determines which fields are displayed to users in various parts of the application.
  • Determining Field Selectability: how to create a selection service that determines whether a field is selectable or not in a given clause of a Google Ads Query Language (GAQL) query string.
  • Field Selection & Query Validation: how to update the selection service to select fields and validate the GAQL string.
  • Summary: a summary of key lessons learned from this process.

We hope you enjoy and learn from this blog series. Stay tuned for more interesting content.

If you have any questions or need additional help, contact us via the forum or at [email protected].

Announcing the New and Improved Interactive Query Builder

Today, we are releasing a new and improved version of the Google Ads Query Language (GAQL) interactive query builder. The new version is resource-centric and helps you build a GAQL query based on the resource in the FROM clause. There are two ways to to access the query builder:


Navigate to the developer documentation Reports tab. Expand the Query Builder on the left side of the page. Choose your resource.

Click the Help me build a query button for any resource in the reporting reference documentation.







Highlights

As users type, the new search bar filters fields dynamically.





We also designed this tool with a goal of educating developers about the Google Ads Query Language as they use it. The query builder dynamically surfaces hints (such as field compatibility)





and prompts (for example, to notify users of requirements to add fields to multiple clauses of a query).





The new query builder features “pretty print” mode to display queries in an easy to read format, as well as “interactive” mode, which provides the ability to remove and reorder fields directly within the query box.





As you get started with the new query builder, please feel free to share feedback by clicking the Send feedback button on the top right of any page.




If you have any questions or need additional help, contact us via the forum or at [email protected].

AdFormat in Search Query Performance Report will start returning UNKNOWN starting 2021-05-12

On 2021-05-12 we will deprecate the  AdFormat column in the Search Query Performance Report for AdWords API and Google Ads scripts. From then onwards, the report will return UNKNOWN for this field. This does not affect the Google Ads API.

The AdFormat column provides the type of creative that was triggered such as text, image, or video. If you still require this information, you can instead select AdGroupId and CreativeId from the same report, then call AdGroupAdService.get() to retrieve the Ad.type field.

This completes the migration that was started in January 2020 to remove AdFormat from all reports.

If you have any questions about this or anything else related to the AdWords API, please reach out to our support team on the forum.

Nick Birnie, Google Ads API Team

Changes to campaign_bid_modifier reporting in the Google Ads API

Starting on September 1, 2020, we will be making a change to how the Google Ads API reports campaign-level bid modifiers to make the API’s results more consistent with the Google Ads UI.

Currently, Google Ads Query Language queries for campaign_bid_modifier resources only return rows if either of the following conditions are met:
  1. A non-zero bid modifier is set, or
  2. The row’s associated criterion_id has accrued metrics for the CALLS interaction type.
After this change goes into effect, queries for campaign_bid_modifier resources will return rows for all campaigns, more closely matching what a user sees in the Google Ads UI’s Advanced bid adj. > Interactions screen.

Users who wish to keep using a restricted view of their campaign_bid_modifier reports can add a predicate such as “WHERE campaign_bid_modifier.bid_modifier != 1.0" (where a 1.0 value is equivalent to a bid adjustment of ±0%) to their queries to limit reporting to non-zero bid modifier rows.

This change will not affect the behavior of the AdWords API.

If you have any questions about this change, please reach out to us on the forum.

Reporting issues April 30 and May 1, 2019

On May 1, at approximately 5pm PST, a bug caused Google Ads reporting for April 30 and May 1 (Pacific Time) to be incorrect. This bug impacts reports in all Google Ads interfaces, including any report data downloaded via the AdWords API, Google Ads API and Google Ads Scripts.

We are actively working on fixing the bug and correcting the data. Metrics reported for May 2nd will also be delayed until later that morning PST.

We appreciate your patience as we work to resolve this issue as quickly as possible.

If you have any questions or need help, please contact us via the forum.

Support for v201809 reports in Google Ads Scripts

We have added support for AdWords API v201809 reports in Google Ads Scripts. The key changes in this release include:
  • The DESTINATION_URL_REPORT has been removed. Use the FINAL_URL_REPORT instead.
  • New conversion fields have been added to multiple reports:
    • ConversionAttributionEventType (CAMPAIGN_PERFORMANCE_REPORT only)
    • ConversionAdjustment
    • ConversionAdjustmentLagBucket
Read the AdWords API release notes for complete details, including additional features not listed here.

If you use API versioning in your reports, you need to modify your code to use v201809:

var report = AdsApp.report(query, {
apiVersion: 'v201809'
});
If you don't use API versioning, no code changes are required. We are updating the default reporting version to v201806 along with this change, and your reports will upgrade automatically.

If you have any questions about these changes or Google Ads scripts in general, you can post them on our developer forum.

New features in AdWords scripts

Today we're announcing the launch of a few new features in AdWords scripts:
  • Support for reporting version v201806
  • Multi-file script support
  • Support for final URL suffix for parallel tracking
Reporting
Support for v201806 of reports has been added. The main features in this reporting version are:
  • New fields for Responsive Search Ads and Multi-Asset Responsive Display Ads.
  • The ClickType and CampaignSubType columns will return new values to reflect changes in product names. The underlying data is unaffected; the rendered value is the only change. For example, the CampaignSubType of "Product Listing Ads" will now be "Shopping ads", and there are similar changes for ClickType.
Read the AdWords API release notes for complete details, including additional features not listed here.

If you use API versioning in your reports, you need to modify your code to use v201806:

var report = AdWordsApp.report(query, {
apiVersion: 'v201806'
});
We will also be updating the default reporting version from v201710 to v201802 on July 23, 2018. This will affect you if you do not use API versioning as outlined above.

Multi-File Support
Over the next few weeks, we will be rolling out support for scripts with multiple files. This lets you separate your utility logic from your business logic, organize your code however you see fit, and generally produce more maintainable scripts. Please try it out and let us know what you think on the forum!

Parallel Tracking Support
We have added methods to support the final URL suffix for parallel tracking. You can use the new getFinalUrlSuffix, setFinalUrlSuffix, and clearFinalUrlSuffix methods on objects that have final URLs.

As announced earlier this year, starting October 30, 2018, parallel tracking will be required for all AdWords accounts. You can consult the AdWords API documentation on click tracking for more details on how to migrate, as the same concepts apply to scripts. Please make sure to update your scripts before the deadline.

If you have any questions about these changes or AdWords scripts in general, you can post them on our developer forum.

Click measurement changes in AdWords

AdWords now allows you to enable parallel tracking for all advertisers from frontend and API. People who click your ads will go directly to your landing page while their browser handles click measurement requests in the background. This helps reduce lost visits which can happen if a customer clicks on your ad but never sees your landing page because they navigate away before the redirect from your tracking URL completes.

All ads using third-party click measurement will begin using parallel tracking at a later date. However, you should start developing for compatibility as soon as possible to give yourself enough time for the migration. If you implement your own click measurement server or provide this service to your customers, refer to our newly published guide for help with implementation. If you are an advertiser who uses a third-party measurement solution, reach out to your service provider to prepare for the switch.

If you need additional support, please email us at [email protected].

Support for v201802 reports in AdWords scripts

We have added support for AdWords API v201802 reports in AdWords scripts. The key changes in this release include:
  • A new report type, LANDING_PAGE_REPORT, to provide performance stats for the pages that receive traffic from your ads.
  • ConversionLagBucket field added to various reports to help you determine how long it takes customers to convert.
  • New fields added to support Gmail ads.
Read the AdWords API release notes for complete details, including additional features not listed here.

If you use API versioning in your reports, you need to modify your code to use v201802:

var report = AdWordsApp.report(query, {
apiVersion: 'v201802'
});
If you don't use API versioning, no code changes are required. We are updating the default reporting version to v201710 along with this change, and your reports will upgrade automatically.

If you have any questions about these changes or AdWords scripts in general, you can post them on our developer forum.