Как выгрузить сырые данные из Google Ads в Google BigQuery

98
2977
Материалы для скачивания
978.32 Kb

Анализируя эффективность рекламных кампаний Google Ads в Google Analytics, вы можете столкнуться с семплированием, агрегированием данных и другими ограничениями, обусловленными интерфейсом систем. К счастью, эта проблема легко решается выгрузкой сырых данных из рекламного сервиса в Google BigQuery.

В этой статье вы узнаете, как выгрузить сырые данные из вашего аккаунта Google Ads в BigQuery и определить при этом все UTM-метки кампаний с авторазметкой.

Чтобы связать информацию о рекламных кампаниях с действиями пользователей на сайте, вам понадобится OWOX BI. Запишитесь на демо, и мы подробно расскажем о всех задачах, которые вы можете решить с OWOX BI.

Содержание

Зачем нужны сырые данные из Google Ads

Сырые данные из Google Ads позволят вам анализировать рекламные кампании с точностью до ключевого слова. Выгрузив их в BigQuery, вы сможете:

  • Строить отчеты нужной вам глубины в разрезе любых параметров и не зависеть от ограничений GA.
  • Определять эффективность рекламных кампаний на уровне сессии и пользователей.
  • Рассчитывать ROI, ROAS, ДРР в разрезе региона, типа пользователя (новый или вернувшийся), устройства и любых других параметров.
  • Эффективно управлять рекламными ставками и создавать списки ремаркетинга.
  • Объединить данные из Google Ads, Google Analytics и CRM, чтобы оценить эффективность кампаний с учетом маржинальности и выкупаемости ваших товаров.
  • Обучать свою ML-модель для более точного планирования.

Чтобы понять, какие кампании, объявления и ключевые слова приводят пользователей на ваш сайт, нужно объединить данные из Google Ads и Analytics в BigQuery. Сделать это можно с помощью потока OWOX BI.

Этот поток передает в GBQ несемплированные данные о поведении пользователей на вашем сайте. Хиты передаются в режиме реального времени, затем на основе этих хитов формируются сессии.

БЕСПЛАТНО ПОПРОБОВАТЬ OWOX BI

Информацию об источнике трафика OWOX BI берет из UTM-разметки объявлений. Разметка бывает ручной и автоматической.

Допустим, вы разметили объявление вручную и у вас получился такой URL:

www://example. com/? utm_source=facebook&utm_medium=cpc&utm_campaign=utm_metki

В таком случае после подключения OWOX BI у вас в таблице GBQ будут доступны данные об источнике, канале и кампании:

  • trafficSource.source — google
  • trafficSource.medium — cpc
  • trafficSource.campaign — utm_metki
Читайте подробнее о том, как правильно создавать UTM-метки.

Если же вы включили в рекламном сервисе функцию автоматической разметки, то каждому вашему объявлению присваивается специальный параметр gclid. Он добавляется в URL целевой страницы, когда пользователь нажимает на объявление. Пример такой ссылки:

http://www. example. com/? gclid=TeSter-123

Если вы используете авторазметку, то получить значение source, medium и campaign из gclid без сырых данных не получится — в таблицах BigQuery, которые собирает OWOX BI, эти поля будут пустыми.

Что же делать в таком случае и как получить название кампаний и других параметров, имея только gclid? Настроить автоматическую выгрузку из Google Ads в GBQ.

Примечание: если объявление не размечено вообще, OWOX BI определит переход по ссылке:

  • Для не-Google источников как реферальный трафик (например, facebook/referral).
  • Для Google источника как прямой трафик (direct/none).

Если в ваших отчетах очень много direct/none трафика, возможно, у вас не включена фильтрация ботов или большое количество неразмеченных объявлений.

Два способа выгрузки сырых данных из Google Ads в BigQuery

Для выгрузки сырых данных из Google Ads мы используем сами и рекомендуем клиентам два метода: коннектор Data Transfer и Ads Script.

Какой способ выбрать, зависит от ваших целей и бюджета. Чтобы вам было легче сделать выбор, мы по подготовили сравнительную таблицу:

ПреимуществаНедостатки
Data Transfer1. Нативная интеграция с GBQ.

2. Выгрузка исторических данных за любой период без ограничений.
Стоимость: 2,5 $ в месяц за выгрузку из каждого аккаунта Google Ads. Независимо от того, как часто вы выгружаете данные.
Google Ads ScriptБесплатно.1. Нельзя выгрузить исторические данные. Загружается информация только за предыдущий день.

2. Требует больше усилий, если нужно настроить выгрузку из большого количества аккаунтов. Необходимо будет вручную вносить изменения в скрипты по каждому аккаунту. При этом высокий риск совершить ошибку.

Что понадобится для настроек

Активные проекты и аккаунты в:

  • Google Cloud Platform (GCP)
  • Google BigQuery (GBQ)
  • OWOX BI
  • Google Ads

Доступы уровня:

  • Владелец в GCP
  • Администратор в GBQ
  • Редактирование в OWOX BI. Важно: только тот пользователь, который создавал поток Google Analytics → Google BigQuery, может подключать выгрузку из Google Ads.
  • Чтение в Google Ads

Как предоставить права доступа в GBQ

Откройте консоль GCP и в боковом меню выберите «IAM и администрирование» — «Управление ресурсами». Затем выберите проект и нажмите «Добавить участника». Введите email пользователя, выберите роль «Администратор BigQuery» и сохраните изменения.
Доступы в BigQuery

Как настроить выгрузку с помощью Data Transfer

Шаг 1. Создайте проект в Google Cloud Platform

Если у вас уже есть проект в GCP, пропустите этот шаг. Если нет, откройте консоль GCP и в боковом меню выберите «IAM и администрирование» — «Управление ресурсами». Нажмите на кнопку «Создать проект». Затем введите название проекта, укажите организацию и нажмите «Создать»:
Создать проект в Google Cloud Platform
Обязательно включите биллинг. Для этого откройте в боковом меню откройте вкладку «Оплата» — «Управление аккаунтом», выберите проект и нажмите «Привязать платежный аккаунт»:
Биллинг в Google Cloud Platform
Далее заполните все поля: укажите ваши контакты и данные платежной карты. Если это ваш первый проект в GCP, вы получите 300 $, которые сможете использовать в течение 12 месяцев. Проектам, у которых 1-2 аккаунта в Google Ads и до 100 тыс. уникальных пользователей в месяц, этой суммы вполне хватит на год. Когда вы исчерпаете этот лимит, деньги возвращать не нужно — для дальнейшего использования достаточно пополнить карту, которую вы подвязали к проекту.

Шаг 2. Включите API BigQuery

После создания проекта нужно активировать API BigQuery. Для этого из бокового меню GCP перейдите в раздел «API и сервисы» — «Панель управления», выберите проект и нажмите кнопку «Включить API и сервисы»:
Активировать API BigQuery
В библиотеке API с помощью строки поиска найдите «BigQuery API» и нажмите «Включить»:
Чтобы использовать API, нажмите на кнопку «Создать учетные данные»:
Создать учетные данные
В выпадающем списке найдите BigQuery API и нажмите кнопку «Выбрать тип учетных данных»:
Придумайте название сервисного аккаунта и укажите уровень доступа «Администратор BigQuery». Выберите тип ключа JSON и нажмите «Продолжить»:

Шаг 3. Активируйте Data Transfer API

Далее вам необходимо активировать службу передачи данных в BigQuery. Для этого откройте GBQ и в боковом меню слева выберите «Переносы». Затем включите BigQuery Data Transfer API:
Активировать службу передачи данных в BigQuery

Шаг 4. Подготовьте набор данных в GBQ

В BigQuery выберите проект и нажмите кнопку справа «Создать набор данных». Заполните все необходимые поля для нового набора данных (название, локацию, срок хранения данных):
Создать набор данных в BigQuery

Шаг 5. Настройте передачу данных из Google Ads

Откройте вкладку «Переносы» в боковом меню и нажмите кнопку «Создать перенос». Затем выберите источник Google Ads (formerly AdWords), введите название выгрузки, например, Data Transfer.

В разделе «Настройки расписания» вы можете оставить значение по умолчанию «Начать» (то есть сейчас) или установить нужные вам дату и время для начала выгрузки. В поле «Повтор» выберите, как часто выполнять выгрузку: ежедневно, еженедельно, ежемесячно по требованию и т. д.
Настройка Data Transfer
Затем укажите набор данных GBQ, в который будут загружаться отчеты из Google Ads. Введите Customer ID — это идентификатор вашего аккаунта Google Ads или ID MCC и нажмите «Добавить». Посмотреть Customer ID вы можете в своем аккаунте Google Ads в правом верхнем углу, рядом с вашим email.
Затем необходимо пройти авторизацию, используя свой gmail аккаунт. На следующий день информация появится в том наборе данных, который вы указали при настройке трансфера.

В результате вы получите в GBQ большое количество сырых данных, с которыми сможете работать: таблицы по кампаниям, аудиториям, общие (кастомные) таблицы, по ключевым словам, по конверсиям. Например, если вы захотите построить какой-нибудь кастомный дашборд, то сможете вытянуть неагрегированные данные из этих таблиц.

Как настроить выгрузку с помощью Ads Script

Откройте ваш аккаунт Google Ads, кликните на «Инструменты и настройки» в правом верхнем углу, выберите «Массовые действия» — «Скрипты» и нажмите на плюс:
Скрипт в Google Ads
Затем в верхнем правом углу нажмите кнопку «Расширенные API», выберите BigQuery и сохраните изменения:
Обязательно авторизуйтесь под почтой того аккаунта, с помощью которого вошли в Google Ads:
Авторизация в Google Ads

Скопируйте скрипт, приведенный ниже. В строках BIGQUERY_PROJECT_ID, BIGQUERY_DATASET_ID и Your email замените имеющиеся значения на свои: название проекта, набора данных в GBQ и email. Вставьте текст скрипта в текстовый редактор.

    
/**
 * @name Export Data to BigQuery
 *
 * @overview The Export Data to BigQuery script sets up a BigQuery
 * dataset and tables, downloads a report from AdWords and then
 * loads the report to BigQuery.
 *
 * @author AdWords Scripts Team [adwords-scripts@googlegroups.com]
 *
 * @version 1.3
 */
 
var CONFIG = {
 BIGQUERY_PROJECT_ID: 'BQ project name',
 BIGQUERY_DATASET_ID: AdWordsApp.currentAccount().getCustomerId().replace(/-/g, '_'),
 
 // Truncate existing data, otherwise will append.
 TRUNCATE_EXISTING_DATASET: false,
 TRUNCATE_EXISTING_TABLES: true,
 
 // Lists of reports and fields to retrieve from AdWords.
 REPORTS: [],
 
 RECIPIENT_EMAILS: [
 'Your email'
 ]
};
 
var report = {
 NAME: 'CLICK_PERFORMANCE_REPORT', //https://developers.google.com/adwords/api/docs/appendix/reports/click-performance-report
 CONDITIONS: '',
 FIELDS: {'AccountDescriptiveName': 'STRING',
 'AdFormat': 'STRING',
 'AdGroupId': 'STRING',
 'AdGroupName': 'STRING', 
 'AoiCountryCriteriaId': 'STRING',
 'CampaignId': 'STRING',
 'CampaignLocationTargetId': 'STRING',
 'CampaignName': 'STRING',
 'CampaignStatus': 'STRING',
 'Clicks': 'INTEGER',
 'ClickType': 'STRING', 
 'CreativeId': 'STRING', 
 'CriteriaId': 'STRING', 
 'CriteriaParameters': 'STRING', 
 'Date': 'DATE',
 'Device': 'STRING', 
 'ExternalCustomerId': 'STRING', 
 'GclId': 'STRING',
 'KeywordMatchType': 'STRING', 
 'LopCountryCriteriaId': 'STRING', 
 'Page': 'INTEGER'
 },
 DATE_RANGE: new Date(new Date().setDate(new Date().getDate()-1)).toISOString().slice(0, 10).replace(/-/g, "")+','+new Date(new Date().setDate(new Date().getDate()-1)).toISOString().slice(0, 10).replace(/-/g, ""),
 DATE: new Date(new Date().setDate(new Date().getDate()-1)).toISOString().slice(0, 10).replace(/-/g, "")
};
 
//Regular export
CONFIG.REPORTS.push(JSON.parse(JSON.stringify(report)));
 
//One-time historical export
//for(var i=2;i<91;i++){
// report.DATE_RANGE = new Date(new Date().setDate(new Date().getDate()-i)).toISOString().slice(0, 10).replace(/-/g, "")+','+new Date(new Date().setDate(new Date().getDate()-i)).toISOString().slice(0, 10).replace(/-/g, "");
// report.DATE = new Date(new Date().setDate(new Date().getDate()-i)).toISOString().slice(0, 10).replace(/-/g, "");
// CONFIG.REPORTS.push(JSON.parse(JSON.stringify(report)));
//}
 
/**
 * Main method
 */
function main() {
 createDataset();
 for (var i = 0; i < CONFIG.REPORTS.length; i++) {
 var reportConfig = CONFIG.REPORTS[i];
 createTable(reportConfig);
 }
 
 var jobIds = processReports();
 waitTillJobsComplete(jobIds);
 sendEmail(jobIds);
}
 
 
/**
 * Creates a new dataset.
 *
 * If a dataset with the same id already exists and the truncate flag
 * is set, will truncate the old dataset. If the truncate flag is not
 * set, then will not create a new dataset.
 */
function createDataset() {
 if (datasetExists()) {
 if (CONFIG.TRUNCATE_EXISTING_DATASET) {
 BigQuery.Datasets.remove(CONFIG.BIGQUERY_PROJECT_ID,
 CONFIG.BIGQUERY_DATASET_ID, {'deleteContents' : true});
 Logger.log('Truncated dataset.');
 } else {
 Logger.log('Dataset %s already exists. Will not recreate.',
 CONFIG.BIGQUERY_DATASET_ID);
 return;
 }
 }
 
 // Create new dataset.
 var dataSet = BigQuery.newDataset();
 dataSet.friendlyName = CONFIG.BIGQUERY_DATASET_ID;
 dataSet.datasetReference = BigQuery.newDatasetReference();
 dataSet.datasetReference.projectId = CONFIG.BIGQUERY_PROJECT_ID;
 dataSet.datasetReference.datasetId = CONFIG.BIGQUERY_DATASET_ID;
 
 dataSet = BigQuery.Datasets.insert(dataSet, CONFIG.BIGQUERY_PROJECT_ID);
 Logger.log('Created dataset with id %s.', dataSet.id);
}
 
/**
 * Checks if dataset already exists in project.
 *
 * @return {boolean} Returns true if dataset already exists.
 */
function datasetExists() {
 // Get a list of all datasets in project.
 var datasets = BigQuery.Datasets.list(CONFIG.BIGQUERY_PROJECT_ID);
 var datasetExists = false;
 // Iterate through each dataset and check for an id match.
 if (datasets.datasets != null) {
 for (var i = 0; i < datasets.datasets.length; i++) {
 var dataset = datasets.datasets[i];
 if (dataset.datasetReference.datasetId == CONFIG.BIGQUERY_DATASET_ID) {
 datasetExists = true;
 break;
 }
 }
 }
 return datasetExists;
}
 
/**
 * Creates a new table.
 *
 * If a table with the same id already exists and the truncate flag
 * is set, will truncate the old table. If the truncate flag is not
 * set, then will not create a new table.
 *
 * @param {Object} reportConfig Report configuration including report name,
 * conditions, and fields.
 */
function createTable(reportConfig) {
 var tableName = reportConfig.NAME+reportConfig.DATE;
 if (tableExists(tableName)) {
 if (CONFIG.TRUNCATE_EXISTING_TABLES) {
 BigQuery.Tables.remove(CONFIG.BIGQUERY_PROJECT_ID,
 CONFIG.BIGQUERY_DATASET_ID, tableName);
 Logger.log('Truncated table %s.', tableName);
 } else {
 Logger.log('Table %s already exists. Will not recreate.',
 tableName);
 return;
 }
 }
 
 // Create new table.
 var table = BigQuery.newTable();
 var schema = BigQuery.newTableSchema();
 var bigQueryFields = [];
 
 // Add each field to table schema.
 var fieldNames = Object.keys(reportConfig.FIELDS);
 for (var i = 0; i < fieldNames.length; i++) {
 var fieldName = fieldNames[i];
 var bigQueryFieldSchema = BigQuery.newTableFieldSchema();
 bigQueryFieldSchema.description = fieldName;
 bigQueryFieldSchema.name = fieldName;
 bigQueryFieldSchema.type = reportConfig.FIELDS[fieldName];
 
 bigQueryFields.push(bigQueryFieldSchema);
 }
 
 schema.fields = bigQueryFields;
 table.schema = schema;
 table.friendlyName = tableName;
 
 table.tableReference = BigQuery.newTableReference();
 table.tableReference.datasetId = CONFIG.BIGQUERY_DATASET_ID;
 table.tableReference.projectId = CONFIG.BIGQUERY_PROJECT_ID;
 table.tableReference.tableId = tableName;
 
 table = BigQuery.Tables.insert(table, CONFIG.BIGQUERY_PROJECT_ID,
 CONFIG.BIGQUERY_DATASET_ID);
 
 Logger.log('Created table with id %s.', table.id);
}
 
/**
 * Checks if table already exists in dataset.
 *
 * @param {string} tableId The table id to check existence.
 *
 * @return {boolean} Returns true if table already exists.
 */
function tableExists(tableId) {
 // Get a list of all tables in the dataset.
 var tables = BigQuery.Tables.list(CONFIG.BIGQUERY_PROJECT_ID,
 CONFIG.BIGQUERY_DATASET_ID);
 var tableExists = false;
 // Iterate through each table and check for an id match.
 if (tables.tables != null) {
 for (var i = 0; i < tables.tables.length; i++) {
 var table = tables.tables[i];
 if (table.tableReference.tableId == tableId) {
 tableExists = true;
 break;
 }
 }
 }
 return tableExists;
}
 
/**
 * Process all configured reports
 *
 * Iterates through each report to: retrieve AdWords data,
 * backup data to Drive (if configured), load data to BigQuery.
 *
 * @return {Array.<string>} jobIds The list of all job ids.
 */
function processReports() {
 var jobIds = [];
 
 // Iterate over each report type.
 for (var i = 0; i < CONFIG.REPORTS.length; i++) {
 var reportConfig = CONFIG.REPORTS[i];
 Logger.log('Running report %s', reportConfig.NAME);
 // Get data as csv
 var csvData = retrieveAdwordsReport(reportConfig);
 //Logger.log(csvData);
 // Convert to Blob format.
 var blobData = Utilities.newBlob(csvData, 'application/octet-stream');
 // Load data
 var jobId = loadDataToBigquery(reportConfig, blobData);
 jobIds.push(jobId);
 }
 return jobIds;
}
 
/**
 * Retrieves AdWords data as csv and formats any fields
 * to BigQuery expected format.
 *
 * @param {Object} reportConfig Report configuration including report name,
 * conditions, and fields.
 *
 * @return {string} csvData Report in csv format.
 */
function retrieveAdwordsReport(reportConfig) {
 var fieldNames = Object.keys(reportConfig.FIELDS);
 var query = 'SELECT ' + fieldNames.join(', ') +
 ' FROM ' + reportConfig.NAME + '' + reportConfig.CONDITIONS +
 ' DURING ' + reportConfig.DATE_RANGE;
 Logger.log(query);
 var report = AdWordsApp.report(query);
 var rows = report.rows();
 var csvRows = [];
 // Header row
 csvRows.push(fieldNames.join(','));
 
 // Iterate over each row.
 while (rows.hasNext()) {
 var row = rows.next();
 var csvRow = [];
 for (var i = 0; i < fieldNames.length; i++) {
 var fieldName = fieldNames[i];
 var fieldValue = row[fieldName].toString();
 var fieldType = reportConfig.FIELDS[fieldName];
 // Strip off % and perform any other formatting here.
 if (fieldType == 'FLOAT' || fieldType == 'INTEGER') {
 if (fieldValue.charAt(fieldValue.length - 1) == '%') {
 fieldValue = fieldValue.substring(0, fieldValue.length - 1);
 }
 fieldValue = fieldValue.replace(/,/g,'');
 
 if (fieldValue == '--' || fieldValue == 'Unspecified') {
 fieldValue = ''
 }
 }
 // Add double quotes to any string values.
 if (fieldType == 'STRING') {
 if (fieldValue == '--') {
 fieldValue = ''
 }
 fieldValue = fieldValue.replace(/"/g, '""');
 fieldValue = '"' + fieldValue + '"'
 } 
 csvRow.push(fieldValue);
 }
 csvRows.push(csvRow.join(','));
 }
 Logger.log('Downloaded ' + reportConfig.NAME + ' with ' + csvRows.length +
 ' rows.');
 return csvRows.join('\n');
}
 
/**
 * Creates a BigQuery insertJob to load csv data.
 *
 * @param {Object} reportConfig Report configuration including report name,
 * conditions, and fields.
 * @param {Blob} data Csv report data as an 'application/octet-stream' blob.
 *
 * @return {string} jobId The job id for upload.
 */
function loadDataToBigquery(reportConfig, data) {
 // Create the data upload job.
 var job = {
 configuration: {
 load: {
 destinationTable: {
 projectId: CONFIG.BIGQUERY_PROJECT_ID,
 datasetId: CONFIG.BIGQUERY_DATASET_ID,
 tableId: reportConfig.NAME + reportConfig.DATE
 },
 skipLeadingRows: 1
 }
 }
 };
 
 var insertJob = BigQuery.Jobs.insert(job, CONFIG.BIGQUERY_PROJECT_ID, data);
 Logger.log('Load job started for %s. Check on the status of it here: ' +
 'https://bigquery.cloud.google.com/jobs/%s', reportConfig.NAME,
 CONFIG.BIGQUERY_PROJECT_ID);
 return insertJob.jobReference.jobId;
}
 
/**
 * Polls until all jobs are 'DONE'.
 *
 * @param {Array.<string>} jobIds The list of all job ids.
 */
function waitTillJobsComplete(jobIds) {
 var complete = false;
 var remainingJobs = jobIds;
 while (!complete) {
 if (AdWordsApp.getExecutionInfo().getRemainingTime() < 5){
 Logger.log('Script is about to timeout, jobs ' + remainingJobs.join(',') +
 ' are still incomplete.');
 }
 remainingJobs = getIncompleteJobs(remainingJobs);
 if (remainingJobs.length == 0) {
 complete = true;
 }
 if (!complete) {
 Logger.log(remainingJobs.length + ' jobs still being processed.');
 // Wait 5 seconds before checking status again.
 Utilities.sleep(5000);
 }
 }
 Logger.log('All jobs processed.');
}
 
/**
 * Iterates through jobs and returns the ids for those jobs
 * that are not 'DONE'.
 *
 * @param {Array.<string>} jobIds The list of job ids.
 *
 * @return {Array.<string>} remainingJobIds The list of remaining job ids.
 */
function getIncompleteJobs(jobIds) {
 var remainingJobIds = [];
 for (var i = 0; i < jobIds.length; i++) {
 var jobId = jobIds[i];
 var getJob = BigQuery.Jobs.get(CONFIG.BIGQUERY_PROJECT_ID, jobId);
 if (getJob.status.state != 'DONE') {
 remainingJobIds.push(jobId);
 }
 }
 return remainingJobIds;
}
 
 
/**
 * Sends a notification email that jobs have completed loading.
 *
 * @param {Array.<string>} jobIds The list of all job ids.
 */
function sendEmail(jobIds) {
 var html = [];
 html.push(
 '<html>',
 '<body>',
 '<table width=800 cellpadding=0 border=0 cellspacing=0>',
 '<tr>',
 '<td colspan=2 align=right>',
 "<div style='font: italic normal 10pt Times New Roman, serif; " +
 "margin: 0; color: #666; padding-right: 5px;'>" +
 'Powered by AdWords Scripts</div>',
 '</td>',
 '</tr>',
 "<tr bgcolor='#3c78d8'>",
 '<td width=500>',
 "<div style='font: normal 18pt verdana, sans-serif; " +
 "padding: 3px 10px; color: white'>Adwords data load to " +
 "Bigquery report</div>",
 '</td>',
 '<td align=right>',
 "<div style='font: normal 18pt verdana, sans-serif; " +
 "padding: 3px 10px; color: white'>",
 AdWordsApp.currentAccount().getCustomerId(),
 '</tr>',
 '</table>',
 '<table width=800 cellpadding=0 border=1 cellspacing=0>',
 "<tr bgcolor='#ddd'>",
 "<td style='font: 12pt verdana, sans-serif; " +
 'padding: 5px 0px 5px 5px; background-color: #ddd; ' +
 "text-align: left'>Report</td>",
 "<td style='font: 12pt verdana, sans-serif; " +
 'padding: 5px 0px 5px 5px; background-color: #ddd; ' +
 "text-align: left'>JobId</td>",
 "<td style='font: 12pt verdana, sans-serif; " +
 'padding: 5px 0px 5x 5px; background-color: #ddd; ' +
 "text-align: left'>Rows</td>",
 "<td style='font: 12pt verdana, sans-serif; " +
 'padding: 5px 0px 5x 5px; background-color: #ddd; ' +
 "text-align: left'>State</td>", 
 "<td style='font: 12pt verdana, sans-serif; " +
 'padding: 5px 0px 5x 5px; background-color: #ddd; ' +
 "text-align: left'>ErrorResult</td>",
 '</tr>',
 createTableRows(jobIds),
 '</table>',
 '</body>',
 '</html>');
 
 MailApp.sendEmail(CONFIG.RECIPIENT_EMAILS.join(','),
 'Adwords data load to Bigquery Complete', '',
 {htmlBody: html.join('\n')});
}
 
/**
 * Creates table rows for email report.
 *
 * @param {Array.<string>} jobIds The list of all job ids.
 */
function createTableRows(jobIds) {
 var html = [];
 for (var i = 0; i < jobIds.length; i++) {
 var jobId = jobIds[i];
 var job = BigQuery.Jobs.get(CONFIG.BIGQUERY_PROJECT_ID, jobId);
 var errorResult = ''
 if (job.status.errorResult) {
 errorResult = job.status.errorResult;
 }
 
 html.push('<tr>',
 "<td style='padding: 0px 10px'>" +
 job.configuration.load.destinationTable.tableId + '</td>',
 "<td style='padding: 0px 10px'>" + jobId + '</td>',
 "<td style='padding: 0px 10px'>" + job.statistics.load?job.statistics.load.outputRows:0 + '</td>',
 "<td style='padding: 0px 10px'>" + job.status.state + '</td>',
 "<td style='padding: 0px 10px'>" + errorResult + '</td>',
 '</tr>');
 }
 return html.join('\n');
}
    

Перед тем, как запустить скрипт, обязательно нажмите на кнопку «Просмотр» в правом нижнем углу, чтобы проверить. Если в нем есть ошибки, система напишет об этом и укажет, в какой именно строке, как на скриншоте:

Запустить скрипт
Если ошибок нет, нажмите на кнопку «Выполнить»:
Настроить выгрузку с помощью Ads Script
В результате вы получите новый отчет CLICK_PERFORMANCE_REPORT в вашем GBQ, данные в котором будут доступны уже на следующий день:

Напомним, что при использовании Data Transfer вы получаете большое количество сырых неагрегированных данных. С Ads Script же вы будете иметь информацию только об определенных полях.

В таблицы OWOX BI с данными о сессиях попадают следующие поля из этой выгрузки:

  • GclId
  • CampaignId
  • CampaignName
  • AdGroupId
  • AdGroupName
  • CriteriaId
  • CriteriaParameters
  • KeywordMatchType

Как подключить выгрузку из Google Ads к OWOX BI

Теперь нужно объединить информацию из Google Ads с данными сайта, чтобы понять, по каким кампаниям пользователи попали на ваш сайт. В таблицах, которые вы получите в BigQuery, например, при помощи Data Transfer, нет параметра Client ID. Определить, какой клиент кликнул по рекламе, вы можете только связав данные по gclid с данными потока OWOX BI.

Если у вас еще нет потока Google Analytics → Google BigQuery в OWOX BI, ознакомьтесь с инструкцией как его создать.

Затем зайдите в свой проект OWOX BI, откройте этот поток. Перейдите на вкладку «Настройка» и в разделе «Сбор данных о сессиях» нажмите «Изменить настройки»:
Настройка стриминга OWOX BI
С помощью ползунка включите сбор данных кампаний Google Ads с авторазметкой и нажмите «Изменить настройки»:
Включить сбор данных кампаний Google Ads с авторазметкой
Выберите тип разметки «Авторазметка», определите метод загрузки BigQuery Data Transfer или Ads scripts. Укажите проект и набор данных, откуда будут загружаться данные Google Ads, и сохраните настройки:

Полезные советы

Совет 1. С помощью Data Transfer вы можете загружать исторические данные из Google Ads в GBQ. При этом нет ограничений на общий период загрузки (хоть за год, хоть за три), но данные нужно загружать порционно за каждые 180 дней.

Активировать загрузку и указать период вы можете с помощью кнопки «Schedule Backfill» во вкладке «Переносы», выбрав нужный вам трансфер:
Загрузка исторических данных

Совет 2. Если вы хотите проверить количество аккаунтов Google Ads, за которые GCP будет брать оплату, вам необходимо определить количество ExternalCustomerID в таблице «Customer» с помощью запроса:

    
SELECT 
ExternalCustomerId
FROM `project_name.dataset_name.Customer_*`
WHERE _PARTITIONTIME >= "2019-01-01 00:00:00" AND _PARTITIONTIME < "2019-07-10 00:00:00"
group by 1
    

Даты в запросе можно редактировать.

Совет 3. Вы можете самостоятельно обращаться к загруженным данным с помощью SQL-запросов. Вот, например, запрос для определения эффективности кампаний из таблиц «Campaign» и «CampaignBasicStats», полученных методом Data Transfer:

    
SELECT
{source language="sql"}
  c.ExternalCustomerId,
  c.CampaignName,
  c.CampaignStatus,
  SUM(cs.Impressions) AS Impressions,
  SUM(cs.Interactions) AS Interactions,
{/source}
  (SUM(cs.Cost) / 1000000) AS Cost
FROM
  `[DATASET].Campaign_[CUSTOMER_ID]` c
LEFT JOIN
{source language="sql"}
{source language="sql"}
  `[DATASET].CampaignBasicStats_[CUSTOMER_ID]` cs
ON
  (c.CampaignId = cs.CampaignId
   AND cs._DATA_DATE BETWEEN
   DATE_ADD(CURRENT_DATE(), INTERVAL -31 DAY) AND DATE_ADD(CURRENT_DATE(), INTERVAL -1 DAY))
WHERE
  c._DATA_DATE = c._LATEST_DATE
GROUP BY
  1, 2, 3
ORDER BY
  Impressions DESC
    

P. S. Если вам нужна помощь с выгрузкой и объединением данных в Google BigQuery, мы готовы помочь. Запишитесь на демо — обсудим детали.

ПОЛУЧИТЬ ДЕМО

Использованные инструменты

Вас также могут заинтересовать