【问题标题】:Google Apps Script: Automated reporting with Google AnalyticsGoogle Apps 脚本:使用 Google Analytics 自动生成报告
【发布时间】:2014-04-28 11:39:41
【问题描述】:

我正在尝试使用 Google Apps 脚本自动化一些自定义 Google Analytics 报告,并将数据输出到 Google 文档电子表格中。我按照教程进行操作,并使用以下代码:

    function runDemo() {
  try {

    var firstProfile = getFirstProfile();
    var results = getReportDataForProfile(firstProfile);
    outputToSpreadsheet(results);

  } catch(error) {
    Browser.msgBox(error.message);
  }
}

//traverse down the Management API hierarchy - Account >> Property ID >> View ID - returns TJ main site view (profile)

function getFirstProfile() {
  var accounts = Analytics.Management.Accounts.list();
  if (accounts.getItems()) {
    var firstAccountId = accounts.getItems()[0].getId();

    var webProperties = Analytics.Management.Webproperties.list(firstAccountId);
    if (webProperties.getItems()) {

      var firstWebPropertyId = webProperties.getItems()[25].getId(); // The property id for TJ is 26 but it is an array so 25 starting from 0
      var profiles = Analytics.Management.Profiles.list(firstAccountId, firstWebPropertyId);

      if (profiles.getItems()) {
        var firstProfile = profiles.getItems()[0];
        return firstProfile;

      } else {
        throw new Error('No views (profiles) found.');
      }
    } else {
      throw new Error('No webproperties found.');
    }
  } else {
    throw new Error('No accounts found.');
  }
}

// Querying for Google Analytics report data

function getReportDataForProfile(firstProfile) {

  var profileId = firstProfile.getId();
  var tableId = 'ga:' + profileId;
  var startDate = getLastNdays(7);   // Sets the start date to 7 days ago.
  var endDate = getLastNdays(1);      // Yesterday.

  var optArgs = {
   //'dimensions': 'ga:keyword',              // Comma separated list of dimensions.
   // 'sort': '-ga:sessions,ga:keyword',       // Sort by sessions descending, then keyword.
   // 'segment': 'dynamic::ga:isMobile==Yes',  // Process only mobile traffic.
   // 'filters': 'ga:source==google',          // Display only google traffic.
   // 'start-index': '1',
   // 'max-results': '250'                     // Display the first 250 results.
  };


  // Make a request to the API.
  var results = Analytics.Data.Ga.get(
      tableId,                    // Table id (format ga:xxxxxx).
      startDate,                  // Start-date (format yyyy-MM-dd).
      endDate,                    // End-date (format yyyy-MM-dd).
      'ga:sessions,ga:pageviews,ga:sessionDuration,ga:pageviewsPerSession,ga:bounceRate,ga:percentNewSessions', // Comma seperated list of metrics.
      optArgs);


  if (results.getRows()) {
    return results;

  } else {
    throw new Error('No views (profiles) found');
  }
}

function getLastNdays(nDaysAgo) {
  var today = new Date();
  var before = new Date();
  before.setDate(today.getDate() - nDaysAgo);
  return Utilities.formatDate(before, 'GMT', 'yyyy-MM-dd');
}


// Print on the sheet

function outputToSpreadsheet(results) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet();

  // Print the headers.
  var headerNames = [];
  for (var i = 0, header; header = results.getColumnHeaders()[i]; ++i) {
    headerNames.push(header.getName());
  }
  sheet.getRange(1, 1, 1, headerNames.length)
      .setValues([headerNames]);

  // Print the rows of data.
  sheet.getRange(2, 1, results.getRows().length, headerNames.length)
      .setValues(results.getRows());
}

这很好用,但是当我尝试查询 Google Analytics API 以获取第二组结果时,问题就出现了。我需要做的报告需要各种细分和过滤,所以我假设我需要创建多组要写入工作表的结果,但额外的代码不起作用 - 创建了第二张工作表,但写在上面的数据是来自 var 'results' 而不是 'results1' 的数据。代码如下:

function runDemo() {
  try {

    var firstProfile = getFirstProfile();
    var results = getReportDataForProfile(firstProfile);
    var results1 = getReportDataForProfile(firstProfile);
    outputToSpreadsheet(results);
    outputToSpreadsheet(results1);

  } catch(error) {
    Browser.msgBox(error.message);
  }
}

//traverse down the Management API hierarchy - Account >> Property ID >> View ID - returns TJ main site view (profile)

function getFirstProfile() {
  var accounts = Analytics.Management.Accounts.list();
  if (accounts.getItems()) {
    var firstAccountId = accounts.getItems()[0].getId();

    var webProperties = Analytics.Management.Webproperties.list(firstAccountId);
    if (webProperties.getItems()) {

      var firstWebPropertyId = webProperties.getItems()[25].getId(); // The property id for TJ is 26 but it is an array so 25 starting from 0
      var profiles = Analytics.Management.Profiles.list(firstAccountId, firstWebPropertyId);

      if (profiles.getItems()) {
        var firstProfile = profiles.getItems()[0];
        return firstProfile;

      } else {
        throw new Error('No views (profiles) found.');
      }
    } else {
      throw new Error('No webproperties found.');
    }
  } else {
    throw new Error('No accounts found.');
  }
}

// Querying for Google Analytics report data

function getReportDataForProfile(firstProfile) {

  var profileId = firstProfile.getId();
  var tableId = 'ga:' + profileId;
  var startDate = getLastNdays(7);   // Sets the start date to 7 days ago.
  var endDate = getLastNdays(1);      // Yesterday.


  //Optional Arguments - all commented out because the first one is empty
  var optArgs = {
   //'dimensions': 'ga:keyword',              // Comma separated list of dimensions.
   // 'sort': '-ga:sessions,ga:keyword',       // Sort by sessions descending, then keyword.
   // 'segment': 'dynamic::ga:isMobile==Yes',  // Process only mobile traffic.
   // 'filters': 'ga:source==google',          // Display only google traffic.
   // 'start-index': '1',
   // 'max-results': '250'                     // Display the first 250 results.
  };

  //Optional arguments - this time I need the organic only

  var optArgs1 = {

    'segment': 'gaid::-5'                   // Process only Non paid search traffic.

  };


  // Make the fist request to the API.
  var results = Analytics.Data.Ga.get(
      tableId,                    // Table id (format ga:xxxxxx).
      startDate,                  // Start-date (format yyyy-MM-dd).
      endDate,                    // End-date (format yyyy-MM-dd).
      'ga:sessions,ga:pageviews,ga:sessionDuration,ga:pageviewsPerSession,ga:bounceRate,ga:percentNewSessions', // Comma seperated list of metrics.
      optArgs);  //This time we pass the optArgs - ie the empty one

       // Make the second request to the API.
  var results1 = Analytics.Data.Ga.get(
      tableId,                    // Table id (format ga:xxxxxx).
      startDate,                  // Start-date (format yyyy-MM-dd).
      endDate,                    // End-date (format yyyy-MM-dd).
      'ga:sessions', // Comma separated list of metrics.
      optArgs1);  //This time we pass the optArgs1 - ie the one with segment=organic


  if (results.getRows()) {
    return results;

  } else {
    throw new Error('No views (profiles) found');
  }
}

function getLastNdays(nDaysAgo) {
  var today = new Date();
  var before = new Date();
  before.setDate(today.getDate() - nDaysAgo);
  return Utilities.formatDate(before, 'GMT', 'yyyy-MM-dd');
}


// Print on the sheet - 

function outputToSpreadsheet(results) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet();

  // Print the headers.
  var headerNames = [];
  for (var i = 0, header; header = results.getColumnHeaders()[i]; ++i) {
    headerNames.push(header.getName());
  }
  sheet.getRange(1, 1, 1, headerNames.length)
      .setValues([headerNames]);

  // Print the rows of data.
  sheet.getRange(2, 1, results.getRows().length, headerNames.length)
      .setValues(results.getRows());
}

// Print again, this time the data from results1 - ie the organic visits

function outputToSpreadsheet(results1) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet();

  // Print the headers.
  var headerNames = [];
  for (var i = 0, header; header = results1.getColumnHeaders()[i]; ++i) {
    headerNames.push(header.getName());
  }
  sheet.getRange(1, 1, 1, headerNames.length)
      .setValues([headerNames]);

  // Print the rows of data.
  sheet.getRange(2, 1, results1.getRows().length, headerNames.length)
      .setValues(results1.getRows());
}

我收到的错误消息是:“结果”未定义,工作表上没有写任何内容。我希望至少能得到第一个查询的结果,因为 var 'results' 的代码仍然相同。添加的是“results1”。

您可能已经猜到了,我不是开发人员,而且我对 JavaScript 的接触很少,所以我非常感谢任何帮助。提前致谢!

【问题讨论】:

  • 您的 getReportDataForProfile 函数无论如何都会返回结果变量,因此 results1 永远不会被实际使用。我的建议是不要重新发明轮子——谷歌提供了一个带有内置 GA 脚本的电子表格:chrome.google.com/webstore/detail/google-analytics/…,所以安装和配置脚本并设置触发器。这将需要大约十分钟(除非您当然想要学习体验,但看起来您更追求结果)。

标签: javascript google-apps-script google-analytics google-analytics-api google-spreadsheet-api


【解决方案1】:

我认为这是因为两件事: 您复制并粘贴整个函数 outputToSpreadsheet 两次。你不需要这样做。你可以删除第二个函数 outputToSpreadsheet。

第二件事是因为您在同一个函数 getReportDataForProfile 中调用了 API 两次,但您只返回了第一次调用的结果。 看看这些行:

  if (results.getRows()) {
    return results;

  } else {
    throw new Error('No views (profiles) found');
  }

在函数 getReportDataForProfile 中,您要求检查结果是否仅存在于 results 而不是 results1。

为了方便您,我更改了代码,基本上您的代码必须是:

function runDemo() {
  try {

    var firstProfile = getFirstProfile();

    //First Call
    var results = getReportDataForProfile(firstProfile);
    outputToSpreadsheet(results);

    //Second Call
    var results1 = getReportDataForProfile2(firstProfile);
    outputToSpreadsheet(results1);

  } catch(error) {
    Browser.msgBox(error.message);
  }
}

//traverse down the Management API hierarchy - Account >> Property ID >> View ID - returns TJ main site view (profile)

function getFirstProfile() {
  var accounts = Analytics.Management.Accounts.list();
  if (accounts.getItems()) {
    var firstAccountId = accounts.getItems()[0].getId();

    var webProperties = Analytics.Management.Webproperties.list(firstAccountId);
    if (webProperties.getItems()) {

      var firstWebPropertyId = webProperties.getItems()[25].getId(); // The property id for TJ is 26 but it is an array so 25 starting from 0
      var profiles = Analytics.Management.Profiles.list(firstAccountId, firstWebPropertyId);

      if (profiles.getItems()) {
        var firstProfile = profiles.getItems()[0];
        return firstProfile;

      } else {
        throw new Error('No views (profiles) found.');
      }
    } else {
      throw new Error('No webproperties found.');
    }
  } else {
    throw new Error('No accounts found.');
  }
}

// Querying for Google Analytics report data

function getReportDataForProfile(firstProfile) {

  var profileId = firstProfile.getId();
  var tableId = 'ga:' + profileId;
  var startDate = getLastNdays(7);   // Sets the start date to 7 days ago.
  var endDate = getLastNdays(1);      // Yesterday.


  //Optional Arguments - all commented out because the first one is empty
  var optArgs = {

  };

  // Make the fist request to the API.
  var results = Analytics.Data.Ga.get(
      tableId,                    // Table id (format ga:xxxxxx).
      startDate,                  // Start-date (format yyyy-MM-dd).
      endDate,                    // End-date (format yyyy-MM-dd).
      'ga:sessions,ga:pageviews,ga:sessionDuration,ga:pageviewsPerSession,ga:bounceRate,ga:percentNewSessions', // Comma seperated list of metrics.
      optArgs);  //This time we pass the optArgs - ie the empty one


  if (results.getRows()) {
    return results;

  } else {
    throw new Error('No views (profiles) found');
  }
}

function getReportDataForProfile2(firstProfile) {

  var profileId = firstProfile.getId();
  var tableId = 'ga:' + profileId;
  var startDate = getLastNdays(7);   // Sets the start date to 7 days ago.
  var endDate = getLastNdays(1);      // Yesterday.


  //Optional arguments - this time I need the organic only

  var optArgs1 = {

    'segment': 'gaid::-5'                   // Process only Non paid search traffic.

  };


  var results1 = Analytics.Data.Ga.get(
      tableId,                    // Table id (format ga:xxxxxx).
      startDate,                  // Start-date (format yyyy-MM-dd).
      endDate,                    // End-date (format yyyy-MM-dd).
      'ga:sessions', // Comma separated list of metrics.
      optArgs1);  //This time we pass the optArgs1 - ie the one with segment=organic


  if (results1.getRows()) {
    return results1;

  } else {
    throw new Error('No views (profiles) found');
  }
}

function getLastNdays(nDaysAgo) {
  var today = new Date();
  var before = new Date();
  before.setDate(today.getDate() - nDaysAgo);
  return Utilities.formatDate(before, 'GMT', 'yyyy-MM-dd');
}


// Print on the sheet - 

function outputToSpreadsheet(results) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet();

  // Print the headers.
  var headerNames = [];
  for (var i = 0, header; header = results.getColumnHeaders()[i]; ++i) {
    headerNames.push(header.getName());
  }
  sheet.getRange(1, 1, 1, headerNames.length)
      .setValues([headerNames]);

  // Print the rows of data.
  sheet.getRange(2, 1, results.getRows().length, headerNames.length)
      .setValues(results.getRows());
}

【讨论】:

    【解决方案2】:

    我知道这个问题很老,但这仍然可以帮助你。有一个谷歌分析插件可以完成所有繁重的工作。然后,您可以根据需要操作表格中的数据。您可以在下面的链接中查看文档。

    https://developers.google.com/analytics/solutions/google-analytics-spreadsheet-add-on

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-06
      • 1970-01-01
      • 2013-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-16
      • 2021-11-01
      相关资源
      最近更新 更多