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

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

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

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

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

Содержание

Наши клиенты
растут на 22% быстрее

Растите быстрее, анализируя, что лучше сработает в вашем маркетинге

Измеряйте KPI, находите зоны роста и увеличивайте свой ROI

Записаться на демо

Зачем нужны сырые данные из 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 Transfer:

  • Нативная интеграция с GBQ.
  • Выгрузка исторических данных за любой период без ограничений.
  • С 01.01.2020 Data Transfer для Google Ads стал бесплатным. До этого взималась плата 2,5 $ в месяц за выгрузку из каждого аккаунта Google Ads.

Особенности Google Ads Script:

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

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

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

  • 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, мы готовы помочь. Запишитесь на демо — обсудим детали.

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

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

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