1. Нам треба створити чисту Google таблицю.
  2. Треба відкрити таблицю для загального користування, як на прикладі

image.png

  1. Після чого, переходимо в розділ “скрипти” в Google Ads

image.png

  1. Після цього, вставляємо наш скрипт, який буде нижче і не забуваємо додати посилання на свою таблицю.
function main() {
  const SHEET_URL = "Вставляємо посилання на свою таблицю";
  const ss = SpreadsheetApp.openByUrl(SHEET_URL);

  const today = new Date();
  const currentYear = today.getFullYear();

  const startDate = `${currentYear}-01-01`;
  const endDate = `${currentYear}-12-31`;

  const query = `
    SELECT
      segments.date,
      metrics.impressions,
      metrics.clicks,
      metrics.ctr,
      metrics.average_cpc,
      metrics.cost_micros,
      metrics.conversions,
      metrics.conversions_value
    FROM
      customer
    WHERE
      segments.date BETWEEN '${startDate}' AND '${endDate}'`;

  const report = AdsApp.report(query);
  const rows = report.rows();

  const DATA = new Map();

  while (rows.hasNext()) {
    const row = rows.next();

    const date = formatDate(row["segments.date"]);
    const cost = Math.round(parseFloat(row["metrics.cost_micros"]) / 1000000);
    const conversions = Math.round(parseFloat(row["metrics.conversions"]));
    const conversionValue = Math.round(parseFloat(row["metrics.conversions_value"]));
    const costPerConversion = conversions > 0 ? Math.round(cost / conversions) : "";
    const roas = cost > 0 ? Math.round((conversionValue / cost) * 100) : "";

    const month = date.split(".")[1] + "." + date.split(".")[2];
    if (!DATA.has(month)) {
      DATA.set(month, []);
    }

    DATA.get(month).push([
      date,
      formatNumber(cost) + " UAH",
      formatNumber(parseInt(row["metrics.impressions"] || 0)),
      formatNumber(parseInt(row["metrics.clicks"] || 0)),
      (parseFloat(row["metrics.ctr"]) * 100).toFixed(2) || "",
      (parseFloat(row["metrics.average_cpc"]) / 1000000).toFixed(2) + " UAH",
      conversions || "",
      formatNumber(conversionValue) + " UAH",
      costPerConversion > 0 ? formatNumber(costPerConversion) + " UAH" : "",
      roas > 0 ? roas + " %" : ""
    ]);
  }

  DATA.forEach((monthData, month) => {
    let monthSheet = ss.getSheetByName(month);
    if (!monthSheet) {
      monthSheet = ss.insertSheet(month);
      monthSheet.appendRow([
        "Дата",
        "Бюджет (UAH)",
        "Показы",
        "Клики",
        "CTR (%)",
        "Средняя цена за клик (UAH)",
        "Конверсии",
        "Ценность конверсий (UAH)",
        "Цена за конверсию (UAH)",
        "ROAS (%)"
      ]);
      monthSheet.getRange(1, 1, 1, 10).setBackground("#ADD8E6").setHorizontalAlignment("center");
    }

    const lastRow = monthSheet.getLastRow();
    if (lastRow > 1) {
      monthSheet.getRange(2, 1, lastRow - 1, 10).clearContent();
    }

    const daysInMonth = new Date(currentYear, parseInt(month.split(".")[0]), 0).getDate();
    for (let day = 1; day <= daysInMonth; day++) {
      const date = `${String(day).padStart(2, "0")}.${month}`;
      if (!monthData.some(row => row[0] === date)) {
        monthData.push([date, "", "", "", "", "", "", "", "", ""]);
      }
    }

    monthData.sort((a, b) => new Date(a[0].split(".").reverse().join("-")) - new Date(b[0].split(".").reverse().join("-")));

    const range = monthSheet.getRange(2, 1, monthData.length, 10);
    range.setValues(monthData);
    range.setHorizontalAlignment("center").setFontWeight("normal");

    const totalBudget = monthData.reduce((sum, row) => sum + parseFloat(row[1]?.replace(" UAH", "").replace(/\\s/g, "") || 0), 0);
    const totalImpressions = monthData.reduce((sum, row) => sum + parseInt(row[2] || 0), 0);
    const totalClicks = monthData.reduce((sum, row) => sum + parseInt(row[3] || 0), 0);
    const totalConversions = monthData.reduce((sum, row) => sum + parseInt(row[6] || 0), 0);
    const totalConversionValue = monthData.reduce((sum, row) => sum + parseFloat(row[7]?.replace(" UAH", "").replace(/\\s/g, "") || 0), 0);
    const averageCpc = totalClicks > 0 ? (totalBudget / totalClicks).toFixed(2) : 0;
    const averageCostPerConversion = totalConversions > 0 ? (totalBudget / totalConversions).toFixed(2) : 0;
    const averageRoas = totalBudget > 0 ? Math.round((totalConversionValue / totalBudget) * 100) : 0;

    const totalRow = [
      "Загально",
      formatNumber(totalBudget) + " UAH",
      formatNumber(totalImpressions),
      formatNumber(totalClicks),
      "",
      averageCpc > 0 ? averageCpc + " UAH" : "",
      formatNumber(totalConversions),
      formatNumber(totalConversionValue) + " UAH",
      averageCostPerConversion > 0 ? averageCostPerConversion + " UAH" : "",
      averageRoas + " %"
    ];

    monthSheet.appendRow(totalRow);
    const totalRowRange = monthSheet.getRange(monthSheet.getLastRow(), 1, 1, totalRow.length);
    totalRowRange.setFontWeight("bold").setBackground("#FFFACD").setHorizontalAlignment("center"); // Нежно-желтая заливка

    // Добавление границ
    monthSheet.getRange(1, 1, monthSheet.getLastRow(), monthSheet.getLastColumn()).setBorder(true, true, true, true, true, true);
  });

  Logger.log("Данные успешно обновлены.");
}

function formatNumber(number) {
  if (number === "" || number === 0 || isNaN(number)) return "";
  return number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, " ");
}

function formatDate(date) {
  const parts = date.split("-");
  return `${parts[2]}.${parts[1]}.${parts[0]}`;
}

  1. Запускаємо скрипт і дивимося, що відображено в Google таблиці.
  2. Додатково не забуваємо встановити розклад для автоматичного оновлення скрипта

image.png

  1. Скрипт буде самостійно додавати нові дати. Якщо почнеться новий місяць - він також повинен додати нову вкладку і почати заповнювати дані саме там. Реалізовано саме під екомерс проекти.