программирование для селлеров - OZON API

Как выгрузить данные из OZON API о рекламных кампаниях и оптимизировать рекламу

Как устроен процесс получения данных по рекламным кампаниям через OZON API

Чтобы получить отчет по рекламным кампаниям на OZON, нам необходимо выполнить несколько шагов.
  • 1

    Получение API ключей

    Для начала нам нужно получить credentials (API ключи) для доступа к OZON Performance API. Вам понадобятся client_id и client_secret. Эти данные можно найти в вашем кабинете на OZON.
  • 2

    Получение списка рекламных кампаний

    Для оптимизации процесса можно выгружать только активные кампании и кампании по которым были траты за указанный период, потому что весь список рекламных кампаний может грузиться очень долго
  • 3

    Получение динамического токена для доступа к API

    Для доступа к API нам нужно получить токен. Он выдается на ограниченное время и необходим для аутентификации.
  • 4

    Получение UUID отчёта и скачивание его с помощью download_report

    Для каждой активной кампании мы отправляем запрос на получение данных. Ответ приходит в виде UUID — уникального идентификатора задачи.
  • 5

    Основная функция и сохранение данных в Google Sheets

    После получения UUID мы запрашиваем готовый отчет и выгружаем данные в Google Sheets для дальнейшего анализа.

Получение API-ключей

Итак получаем список активных кампаний из OZON:

2. Получение списка кампаний

Итак получаем список активных кампаний из OZON:
Список возможных рекламных кампаний
function fetchCampaigns() {
  var apiToken = getApiToken(); // Получаем API токен
  var advObjectType = 'SKU'; // Тип кампаний, например, трафареты
  var desiredStates = 'CAMPAIGN_STATE_RUNNING'; // Берем только активные кампании

  var url = 'https://performance.ozon.ru/api/client/campaign?' +
    'advObjectType=' + encodeURIComponent(advObjectType);

  var options = {
    'method': 'get',
    'headers': {
      'Authorization': 'Bearer ' + apiToken,
      'Accept': 'application/json'
    }
  };

  try {
    var response = UrlFetchApp.fetch(url, options);
    if (response.getResponseCode() === 200) {
      var data = JSON.parse(response.getContentText());
      var campaignIds = data.list.map(campaign => campaign.id);
      Logger.log('Получено ' + campaignIds.length + ' активных кампаний');
      return campaignIds;
    } else {
      Logger.log('Ошибка получения кампаний: ' + response.getResponseCode());
      return [];
    }
  } catch (e) {
    Logger.log('Ошибка: ' + e.toString());
    return [];
  }
}

3. Получение Токена API

Итак у нас есть список кампаний, теперь по ним мы хотим получить отчёты, но не так всё просто. Для того чтобы получить отчёт мы должны отправить запрос для генерации отчёта по рекламе, в качестве ответа мы получим UUID, по которому в дальнейшем мы получим свои данные.
function getApiToken() {
  var clientId = 'ВАШ_CLIENT_ID';
  var clientSecret = 'ВАШ_CLIENT_SECRET';
  var url = 'https://performance.ozon.ru/api/client/token';
  
  var payload = {
    'client_id': clientId,
    'client_secret': clientSecret,
    'grant_type': 'client_credentials'
  };

  var options = {
    'method': 'post',
    'contentType': 'application/json',
    'payload': JSON.stringify(payload)
  };

  try {
    var response = UrlFetchApp.fetch(url, options);
    if (response.getResponseCode() === 200) {
      var responseData = JSON.parse(response.getContentText());
      var accessToken = responseData['access_token'];
      Logger.log('Получен новый API токен: ' + accessToken);
      return accessToken;
    } else {
      Logger.log('Ошибка получения API токена: ' + response.getResponseCode());
      return null;
    }
  } catch (e) {
    Logger.log('Ошибка: ' + e.toString());
    return null;
  }
}

4. Получение отчета по UUID кампаний

Итак у нас есть список кампаний, теперь по ним мы хотим получить отчёты, но не так всё просто. Для того чтобы получить отчёт мы должны отправить запрос для генерации отчёта по рекламе, в качестве ответа мы получим UUID, по которому в дальнейшем мы получим свои данные.
Данный запрос не является оптимальным и приводится для объяснения принципа работы
function fetchCampaignUUID(campaignId, apiToken) {
  var url = 'https://performance.ozon.ru/api/client/statistics/json'; // URL для запроса статистики по рекламной кампании
  var payload = JSON.stringify({
    "campaigns": [campaignId], // можно передать список до 10 кампаний
    "dateFrom": '2024-01-01', // дата начала сбора статистики в формате ГГГГ-ММ-ДД
    "dateTo": '2024-01-31', // дата конца сбора статистики в том же формате
    "groupBy": "DATE"  // группировка данных в отчете по дате  
  });

  var options = {
    'method': 'post',
    'headers': {
      'Authorization': 'Bearer ' + apiToken, // Токен аутентификации
      'Content-Type': 'application/json'
    },
    'payload': payload
  };

  try {
    var response = UrlFetchApp.fetch(url, options);
    if (response.getResponseCode() === 200) {
      var data = JSON.parse(response.getContentText());
      return data['UUID']; // Возвращаем UUID отчета
    } else if (response.getResponseCode() === 429) { // Обработка ошибки превышения лимита запросов
      Logger.log('Превышен лимит запросов. Максимум 1 запрос. Сервер OZON задумался (HTTP 429).');
      return null; // Вернем null, чтобы попробовать снова
    } else {
      Logger.log('Ошибка получения UUID : ' + campaignId + ' . Код ответа: ' + response.getResponseCode());
      return null;
    }
  } catch (e) {
    Logger.log('Ошибка: ' + e.toString());
    return null;
  }
}

5. Функция download_report

Функция для скачивания данных отчёта по кампании
function downloadReport(UUID, apiToken) {
  var url = 'https://performance.ozon.ru/api/client/statistics/report?UUID=' + UUID; 
  // URL для получения отчета по UUID
  var headers = {
    'Authorization': 'Bearer ' + apiToken, // Токен аутентификации
    'Content-Type': 'application/json'
  };

  var options = {
    'method': 'get',
    'headers': headers
  };

  try {
    var response = UrlFetchApp.fetch(url, options);
    if (response.getResponseCode() === 200) {
      Logger.log('Отчет успешно загружен для UUID: ' + UUID);
      return response.getContentText(); // Возвращаем данные отчета
    } else {
      Logger.log('Ошибка загрузки отчета для UUID: ' + UUID);
      return null;
    }
  } catch (e) {
    Logger.log('Ошибка: ' + e.toString());
    return null;
  }
}

5. Общая функция

Как всё работает.
  1. Вы запускаете в интерфейсе Google App Script Функцию main().
  2. Она запускает процесс получения API токен.
  3. Затем происходит запрос списка активных кампаний через fetchCampaigns().
  4. Для каждой кампании запрашивается UUID отчета через fetchCampaignReportUUID(). Процесс может занимать длительное время.
  5. Если получены UUID, происходит запрос отчета, и он обрабатывается функцией processReport, которая добавляет данные в Google Sheets.
Лимиты OZON Performance API. запрещают отправлять параллельно несколько запросов. Кроме этого прогцесс может занимать длительное время и поэтому предпочительнее использовать серверный код для загрузки данных по данному отчёту. За настройкой решения вы можете обратить ко мне в Telegram t.me/mislawsky
function main() {
  var apiToken = getApiToken(); // Получаем токен доступа от OZON performance API
  if (!apiToken) {
    Logger.log('Ошибка: токен не был получен.');
    return;
  }

  var campaignIds = fetchCampaigns(apiToken); // Получаем список активных кампаний из первого пункта
  if (campaignIds.length === 0) {
    Logger.log('Нет активных кампаний для обработки.');
    return;
  }

  Logger.log('Получено кампаний: ' + campaignIds.length);
  
  // Получение отчетов по каждому campaign_id
  var maxRetries = 5; // Максимальное число попыток при ошибке 429
  var sleepTime = 1000; // Начальное время ожидания в случае ошибки 429
  
  // Цикл по обходу списка campaign_ids
  for (var i = 0; i < campaignIds.length; i++) {
    var campaignId = campaignIds[i];
    Logger.log('Запрашиваем отчет для кампании ID: ' + campaignId);

    for (var retry = 0; retry < maxRetries; retry++) {
      var reportUUID = fetchCampaignReportUUID(campaignId, apiToken); // Получаем UUID отчета для текущей кампании
      
      if (reportUUID) {
        Logger.log('Получен UUID отчета для кампании: ' + campaignId + ' UUID: ' + reportUUID);
        // Скачиваем и обрабатываем отчет по полученному UUID
        var reportData = downloadReport(reportUUID, apiToken);
        if (reportData) {
          processReport(reportData); // Обрабатываем отчет и добавляем данные в Google Sheets
        }
        break; // Выходим из цикла попыток, так как отчет был успешно получен
      } else {
        Logger.log('Получена ошибка или пустой UUID, пробуем снова через ' + sleepTime + ' мс.');
        Utilities.sleep(sleepTime); // Ждем перед повторной попыткой
        sleepTime *= 2; // Увеличиваем время ожидания в два раза для экспоненциального backoff
      }

      if (retry === maxRetries - 1) {
        Logger.log('Достигнуто максимальное количество попыток для кампании: ' + campaignId);
      }
    }
  }
}

function processReport(reportData) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('raw data');
  if (!sheet) {
    sheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet('raw data'); // Создаем лист, если его нет
    sheet.appendRow(['Дата', 'Клики', 'Показы', 'CTR', 'Расход']); // Заголовки столбцов
  }

  var jsonData = JSON.parse(reportData); // Преобразуем данные отчета в JSON
  var reportRows = jsonData.report.rows;

  // Проходим по строкам отчета и добавляем данные в Google Sheets
  reportRows.forEach(function(row) {
    sheet.appendRow([
      row.date, // Дата
      row.clicks, // Количество кликов
      row.views, // Количество показов
      row.ctr.replace(',', '.'), // CTR с заменой запятой на точку
      row.moneySpent.replace(',', '.') // Расход с заменой запятой на точку
    ]);
  });

  Logger.log('Отчет успешно обработан и добавлен в Google Sheets.');
}

Обработка 429 ошибки

Если сервер возвращает ошибку 429 (превышен лимит запросов), процесс ожидает и повторяет запрос, увеличивая время ожидания для каждой следующей попытки. Это важно, чтобы избежать блокировок со стороны API и корректно получать данные.

Заключение и предложение сотрудничества

Этот подход помогает вам получать данные по рекламным кампаниям OZON, добавлять их на отдельную вкладку Google Sheets и строить по ним дашборды и отчёты для анализа бизнеса. Для небольших магазинов это решение может быть удобным поскольку не требует оплаты абонентской платы за сервисы аналитики таких как Маяк, SellMonitor, MPSTAT, однако, если у вас крупный магазин, то вы просто можете не поместиться в лимиты Google Sheets и тут требуют заказывать отдельное решение по загрузке данных с помощью вашего хостинга.

Мы предлагаем подобное решение, которое позволит хранить ваши данные в удобном для вас виде mySQL, PostgreSQL, XLSX, CSV, TSV. Кроме этого данное решение позволяет хранить исторические данные, которые уже не доступны в API — обращайтесь через Telegram и мы сделаем нужную для вас настройку: t.me/mislawsky.

Выгрузка данных из OZON

Отчеты по рекламе Performance и Seller API, воронка продаж, аналитические отчеты, заказы, транзакции, отправления, остатки, номенклатура, РНП и др.

Выгрузка данных отчётов из Яндекс Маркет

Отчеты по рекламе, воронка продаж, заказы, отправления, остатки и др.

Выгрузка отчетов Wildberries по API

Отчеты по рекламе, воронка продаж, заказы, транзакции, отправления, остатки, номенклатура, РНП и др.

Синхронизация остатков по API МойСклад

Синхронизация данных Мойсклад с Маркетплейсами, Google Sheets или CRM

Выгрузка данных по API из AmoCRM, Битрикс24, Yclients

Выгрузка сделок по API из любых CRM систем в базу данных или Google Sheets

Анализ позиции конкурентов в поиске WB, OZON

Автоматизация обновления цен на сайте из прайса поставщика

Загрузка и обновление цен прайса поставщика на сайт с Wordpress по API:

Как выгрузить данные по рекламе из Ozon API

Описание процесса выгрузки данных по трафаретам и SEARCH_PROMO из OZON API

Как рассчитать себестоимость товара

Полный и при этом краткий гайд про себестоимость товара

Свой сервис управления маркетплейсом

Синхронизация остатков, создание штрихкодов, поставок, обработка заказов, автоматизация