GA4 の Analytics Data API を使ってみた2

前回の続きで、Data API を使ったの改善版です。

追加でやったのは、

  • Dimension を複数設定する

  • Metric を複数設定する

  • ソートできるようにする

の3つです。早速ですが、スクリプトの内容は以下の通りです。

実行方法

※ 普段 GAS も JS も触っていないので、文法的には怪しい箇所が多数あります。自己責任でご参照ください。

/**
 * Runs a report of a Google Analytics 4 property ID. Creates a sheet with the
 * report.
 */

function main() {
  const SHEET_ID = 'hoge';
  const REPORT_CONFIG_SHEET = 'ReportConfig';
  // config シートから必要な情報を取得する。
  const spreadsheet = SpreadsheetApp.openById(SHEET_ID);
  const configs = getConfig(spreadsheet, REPORT_CONFIG_SHEET); 
  for (let i =0; i < configs.length; i++){
    getData(spreadsheet, configs[i]);
  }
}

function convertDate(date) {
  try {
    const dateType = Object.prototype.toString.call(date);
    if (dateType == '[object Date]') {
      return Utilities.formatDate(date, 'JST', 'yyyy-MM-dd');
    } else {
      return date;
    }
  } catch(e) {
    console.log('Failed convert date parameters with error: %s', e.error);
  }
}

/**
 * カンマ区切りの文字列を array に変換します。
 * @param {string} params
 * @return {array}
 */
function getArray(params) {
  let arrayParams = params.split(',');
  for (let i = 0; i < arrayParams.length; i++) {
    arrayParams[i] = arrayParams[i].trim();
  }
  return arrayParams;
}

/**
 * ソートのデータを変換します。
 * @param {string} params
 * @return {array}
 */
function getOrderBy(params) {
  let orderByParams = [];
  const arrayParams = params.split(',');
  for (let i = 0; i < arrayParams.length; i++) {
    const arrayParam = arrayParams[i].trim();
    const orderByParam = arrayParam.split(' ');
    if (orderByParam.length == 2 && orderByParam[1] == 'desc') {
      orderByParams.push({
        'dimensionName': orderByParam[0],
        'isDesc': true,
      })
    } else {
      orderByParams.push({
        'dimensionName': orderByParam[0],
        'isDesc': false,
      })
    }
  }
  return orderByParams;
}

function getConfig(spreadsheet, reportConfigSheet) {
  try {
    const sheet = spreadsheet.getSheetByName(reportConfigSheet);
    const lastRow = sheet.getLastRow();
    let rowNum = 2;
    let params = [];
    while (rowNum <= lastRow) {
      const range = sheet.getRange(Utilities.formatString('A%s:G%s', rowNum, rowNum));
      let values = range.getValues();
      values[0][2] = convertDate(values[0][2]);
      values[0][3] = convertDate(values[0][3]);
      values[0][4] = getArray(values[0][4]);
      values[0][5] = getArray(values[0][5]);
      values[0][6] = getOrderBy(values[0][6]);
      params.push({
        'propertyId': values[0][0],
        'sheetName': values[0][1],
        'startDate': values[0][2],
        'endDate': values[0][3],
        'metric': values[0][4],
        'dimension': values[0][5],
        'orderBy': values[0][6],
      });
      rowNum ++;
    }
    return params;
  } catch(e) {
    console.log('Failed reading parameters with error: %s', e.error);
  }
}

function getData(spreadsheet, config) {
  try {
    let metrics = [];
    for (let i = 0; i < config.metric.length; i++) {
      const metric = AnalyticsData.newMetric();
      metric.name = config.metric[i];
      metrics.push(metric);
    }

    let dimensions = [];
    for (let i = 0; i < config.dimension.length; i++) {
      const dimension = AnalyticsData.newDimension();
      dimension.name = config.dimension[i];
      dimensions.push(dimension);
    }

    const dateRange = AnalyticsData.newDateRange();
    dateRange.startDate = config.startDate;
    dateRange.endDate = config.endDate;

    let orderBys = [];
    for (let i = 0; i < config.orderBy.length; i++) {
      const orderBy = AnalyticsData.newOrderBy();
      const dimensionOrderBy = AnalyticsData.newDimensionOrderBy();
      dimensionOrderBy.dimensionName = config.orderBy[i].dimensionName;
      orderBy.dimension = dimensionOrderBy;
      orderBy.desc = config.orderBy[i].isDesc;
      orderBys.push(orderBy);
    }

    const request = AnalyticsData.newRunReportRequest();
    request.dimensions = dimensions;
    request.metrics = metrics;
    request.dateRanges = dateRange;
    request.orderBys = orderBys;

    const report = AnalyticsData.Properties.runReport(request,
        'properties/' + config.propertyId);
    if (!report.rows) {
      console.log('No rows returned.');
      return;
    }

    const sheets = spreadsheet.getSheets();
    var existFlg = 0;
    for (let i = 0; i < sheets.length; i++) {
      if (config.sheetName == sheets[i].getName()) {
        existFlg = 1;
      } 
    }
    if (existFlg == 0) {
      spreadsheet.insertSheet(config.sheetName);
    }

    const sheet = spreadsheet.getSheetByName(config.sheetName);
    sheet.clear();

    // Append the headers.
    const dimensionHeaders = report.dimensionHeaders.map(
        (dimensionHeader) => {
          return dimensionHeader.name;
        });
    const metricHeaders = report.metricHeaders.map(
        (metricHeader) => {
          return metricHeader.name;
        });
    const headers = [...dimensionHeaders, ...metricHeaders];

    sheet.appendRow(headers);

    // Append the results.
    const rows = report.rows.map((row) => {
      const dimensionValues = row.dimensionValues.map(
          (dimensionValue) => {
            return dimensionValue.value;
          });
      const metricValues = row.metricValues.map(
          (metricValues) => {
            return metricValues.value;
          });
      return [...dimensionValues, ...metricValues];
    });

    sheet.getRange(2, 1, report.rows.length, headers.length)
        .setValues(rows);

    console.log('Report spreadsheet created: %s',
        spreadsheet.getUrl());
  } catch (e) {
    // TODO (Developer) - Handle exception
    console.log('Failed with error: %s', e.error);
  }
}

内容として、やや難しかったのは

    let metrics = [];
    for (let i = 0; i < config.metric.length; i++) {
      const metric = AnalyticsData.newMetric();
      metric.name = config.metric[i];
      metrics.push(metric);
    }

で metric や dimension、orderBy で複数の項目を入れる時には、array にどんどん条件を格納していくというとこでした。
AnalyticsData.newMetric.name に項目を array にして項目を追加してもエラーになるので、かなり混乱しました。JS 的には普通の表現なのかもしれませんが。

ReportConfig は OrderBy の1列追加します。ここにソートをかけたい内容を入れます。
Metric、Dimension もカンマ(,)区切りで複数入れます。

ReportConfig の内容

PropertyID: GA4 の値を取得する property ID

  • SheetName: 出力先のシート名

  • StartDate: データを取得する開始日

  • EndData: データを取得する終了日

  • Metric: 取得したい指標

  • Dimension: 取得したい次元

  • OrderBy: Dimension でソートする次元

これで、最低限必要なデータは取れそうです。
いくつか触ってみて修正が必要な箇所が出てきたら、また追記します。


いいなと思ったら応援しよう!