【问题标题】:Google Apps Script not outputting returned results to sheetGoogle Apps 脚本未将返回的结果输出到工作表
【发布时间】:2021-06-01 05:04:06
【问题描述】:

我有以下代码,其目的是尝试从 Google 获得对上次登录/活动信息的有用见解,因为“上次登录日期”指标并不是最可靠的。

const testState = true;

function generateUserReport() {
  let state;

  if ((test = true)) {
    state = "Frodo.Baggins@domain.com";
  } else if ((test = false)) {
    state = "all";
  } else {
    throw "State not defined";
  }

  Logger.log("Test State: "+ testState)

  const daysToCheck = 4;
  const now = new Date();
  const daysAgo = new Date(now.getTime() - daysToCheck * 24 * 60 * 60 * 1000);
  const timezone = Session.getScriptTimeZone();
  const date = Utilities.formatDate(daysAgo, timezone, "yyyy-MM-dd");
  const parameters = [
    "accounts:first_name",
    "accounts:last_name",
    "accounts:last_login_time",
    "gmail:timestamp_last_access",
    "gmail:timestamp_last_imap",
    "gmail:timestamp_last_interaction",
    "gmail:timestamp_last_pop",
    "gmail:timestamp_last_webmail",
    "drive:timestamp_last_active_usage"
  ];
  const rows = [];
  let pageToken;
  let page;

  do {
    page = AdminReports.UserUsageReport.get(state, date, {
      parameters: parameters.join(","),
      maxResults: 500,
      pageToken
    });

    if (page.warnings) {
      for (var i = 0; i < page.warnings.length; i++) {
        const warning = page.warnings[i];
        Logger.log(warning.message);
      }
    }

    const reports = page.usageReports;

    if (reports) {
      for (var i = 0; i < reports.length; i++) {
        const report = reports[i];
        const parameterValues = getParameterValues(report.parameters);
        const row = [
          report.date,
          report.entity.userEmail,
          parameterValues["accounts:first_name"],
          parameterValues["accounts:last_name"],
          parameterValues["accounts:last_login_time"],
          parameterValues["gmail:timestamp_last_access"],
          parameterValues["gmail:timestamp_last_imap"],
          parameterValues["gmail:timestamp_last_interaction"],
          parameterValues["gmail:timestamp_last_pop"],
          parameterValues["gmail:timestamp_last_webmail"],
          parameterValues["drive:timestamp_last_active_usage"]
        ];
        Logger.log("Logging row: \n"+row);
        rows.push(row);
        Logger.log("Logging rows after push: \n"+rows);
      }
    }

    pageToken = page.nextPageToken;
  } while (pageToken);

  if (rows.length > 0) {
    const spreadsheet = SpreadsheetApp.getActive();
    const sheet = spreadsheet.getSheetByName("User Access Report");
    sheet.clear(); // Append the headers.

    const headers = [
      "Date",
      "User",
      "First Name",
      "Last Name",
      "Account Last Login",
      "Email Last Access",
      "Email Interaction",
      "IMAP",
      "POP",
      "WEBMAIL",
      "DRIVE"
    ];
    sheet.appendRow(headers);
    
    // Append the results.
    sheet.getRange(2, 1, rows.length, rows[0].length).setValues(rows);
    Logger.log("Report spreadsheet completed");
    
    // Send notification email on completion
    MailApp.sendEmail({
      to: "my.email@domain.com",
      subject: "The account Usage Report has completed",
      htmlBody: `The script to get user account usage has completed.<br><br>Please click here view view it:<br>${spreadsheet.getUrl()}`,
      name: "Script Helper"
    });
  } else {
    Logger.log("No results returned.");
  }
}
/**
 * Gets a map of parameter names to values from an array of parameter objects.
 * @param {Array} parameters An array of parameter objects.
 * @return {Object} A map from parameter names to their values.
 */

function getParameterValues(parameters) {
  return parameters.reduce((result, parameter) => {
    const name = parameter.name; 
    
    let value;

    if (parameter.intValue !== undefined) {
      value = parameter.intValue;
    } else if (parameter.stringValue !== undefined) {
      value = parameter.stringValue;
    } else if (parameter.datetimeValue !== undefined) {
      value = new Date(parameter.datetimeValue);
    } else if (parameter.boolValue !== undefined) {
      value = parameter.boolValue;
    }

    result[name] = value;
    Logger.log(`${name} Result: ${result[name]}`);
    return result;
  }, {});
}

它可以部分工作 - 但由于某种原因,它不会将所有返回的信息都提取到电子表格中。

A - E 列(标题:日期、用户、名字、姓氏、帐户上次登录)都按预期填充在工作表中,但是 FK 列(标题:电子邮件上次访问、电子邮件交互、IMAP、POP、WEBMAIL , DRIVE) 根本不填充并由于某种原因返回 null(尽管日志显示它找到了值)。

我已经注销了getParameterValues 函数的每个调用,并且我可以看到它正在提取正确的信息,但是,当我注销行和行时它显示为空。据我所知,它应该可以工作......所以我很困惑,希望其他人可以提供帮助或提供一些建议?

在下面记录以显示结果:

3:50:24 PM  Notice  Execution started
3:50:24 PM  Info    Test State: true
3:50:25 PM  Info    accounts:first_name Result: Frodo
3:50:25 PM  Info    accounts:last_name Result: Baggins
3:50:25 PM  Info    accounts:last_login_time Result: Wed Feb 24 2021 04:57:24 GMT-0500 (Eastern Standard Time)
3:50:25 PM  Info    gmail:last_access_time Result: Sat Feb 27 2021 01:37:20 GMT-0500 (Eastern Standard Time)
3:50:25 PM  Info    gmail:last_interaction_time Result: Fri Feb 26 2021 04:07:14 GMT-0500 (Eastern Standard Time)
3:50:25 PM  Info    gmail:last_webmail_time Result: Fri Feb 26 2021 12:41:25 GMT-0500 (Eastern Standard Time)
3:50:25 PM  Info    drive:last_active_usage_time Result: Fri Feb 26 2021 12:37:31 GMT-0500 (Eastern Standard Time)
3:50:25 PM  Info    Logging row: 
2021-02-26,Frodo.Baggins@domain.co.uk,Frodo,Baggins,Wed Feb 24 2021 04:57:24 GMT-0500 (Eastern Standard Time),,,,,,
3:50:25 PM  Info    Logging rows after push: 
2021-02-26,Frodo.Baggins@domain.co.uk,Frodo,Baggins,Wed Feb 24 2021 04:57:24 GMT-0500 (Eastern Standard Time),,,,,,
3:50:27 PM  Info    Report spreadsheet completed
3:50:28 PM  Notice  Execution completed

【问题讨论】:

    标签: javascript google-apps-script google-sheets


    【解决方案1】:

    原来返回值的命名不同。

    这是为将来需要类似东西的人准备的完整脚本:

    //Set to true if developing/testing - if running a live version, set to false
    let testState = false;
    
    function generateUserReport() {
      let target; 
      
      //Check if dev or prod and change values as required
      if (testState == true) {
        target = "Frodo.Baggins@domain.com";
      } else if (testState == false) {
        target = "all";
      } else {
        throw "State not defined";
      }
    
      Logger.log("Test State: " + testState);
    
      const daysToCheck = 14;
      const now = new Date();
      const daysAgo = new Date(now.getTime() - daysToCheck * 24 * 60 * 60 * 1000);
      const timezone = Session.getScriptTimeZone();
      const date = Utilities.formatDate(daysAgo, timezone, "yyyy-MM-dd");
      const parameters = [
        "accounts:first_name",
        "accounts:last_name",
        "accounts:last_login_time",
        "gmail:timestamp_last_access",
        "gmail:timestamp_last_interaction",
        "gmail:timestamp_last_imap",
        "gmail:timestamp_last_pop",
        "gmail:timestamp_last_webmail",
        "drive:timestamp_last_active_usage"
      ];
      const rows = [];
      let pageToken;
      let page;
    
      Logger.log("Target for API call: " + target);
    
      do {
        page = AdminReports.UserUsageReport.get(target, date, {
          parameters: parameters.join(","),
          maxResults: 500,
          pageToken
        });
    
        if (page.warnings) {
          for (var i = 0; i < page.warnings.length; i++) {
            const warning = page.warnings[i];
            Logger.log(warning.message);
          }
        }
    
        const reports = page.usageReports;
    
        if (reports) {
          for (var i = 0; i < reports.length; i++) {
            const report = reports[i];
            const parameterValues = getParameterValues(report.parameters);
            const row = [
              report.date,
              report.entity.userEmail,
              parameterValues["accounts:first_name"],
              parameterValues["accounts:last_name"],
              parameterValues["accounts:last_login_time"],
              parameterValues["gmail:last_access_time"],
              parameterValues["gmail:last_interaction_time"],
              parameterValues["gmail:last_imap_time"],
              parameterValues["gmail:last_pop_time"],
              parameterValues["gmail:last_webmail_time"],
              parameterValues["drive:last_active_usage_time"]
            ];
    
            //If testing, log row
            if (testState == true) {
              Logger.log("Logging row: \n" + row);
            } else {
            }
    
            rows.push(row);
    
            //If testing, log rows
            if (testState == true) {
              Logger.log("Logging rows after push: \n" + rows);
            } else {
            }
          }
        }
    
        pageToken = page.nextPageToken;
      } while (pageToken);
    
      if (rows.length > 0) {
        const spreadsheet = SpreadsheetApp.getActive();
        const sheet = spreadsheet.getSheetByName("User Access Report");
        sheet.clear(); // Append the headers.
    
        const headers = [
          "Date",
          "User",
          "First Name",
          "Last Name",
          "Account Last Login",
          "Email Last Access",
          "Email Interaction",
          "IMAP",
          "POP",
          "WEBMAIL",
          "DRIVE"
        ];
        sheet.appendRow(headers);
        
        // Append the results.
        sheet.getRange(2, 1, rows.length, rows[0].length).setValues(rows);
        Logger.log("Report spreadsheet completed");
        
        // Send notification email on completion
        MailApp.sendEmail({
          to: "my.email@domain.com",
          subject: "The account Usage Report has completed",
          htmlBody: `The script to get user account usage has completed.<br><br>Please click here view view it:<br>${spreadsheet.getUrl()}`,
          name: "Script Helper"
        });
      } else {
        Logger.log("No results returned.");
      }
    }
    /**
     * Gets a map of parameter names to values from an array of parameter objects.
     * @param {Array} parameters An array of parameter objects.
     * @return {Object} A map from parameter names to their values.
     */
    
    function getParameterValues(parameters) {
      return parameters.reduce((result, parameter) => {
        const name = parameter.name;
        let value;
    
        if (parameter.intValue !== undefined) {
          value = parameter.intValue;
        } else if (parameter.stringValue !== undefined) {
          value = parameter.stringValue;
        } else if (parameter.datetimeValue !== undefined) {
          value = new Date(parameter.datetimeValue);
        } else if (parameter.boolValue !== undefined) {
          value = parameter.boolValue;
        }
    
        result[name] = value;
    
        //If testing, logout the results
        if (testState == true) {
          Logger.log(`${name} Result: ${result[name]}`);
        } else {
        }
    
        return result;
      }, {});
    }
    

    注意返回的值是“last_”的:

      parameterValues["gmail:last_access_time"],
      parameterValues["gmail:last_interaction_time"],
      parameterValues["gmail:last_imap_time"],
      parameterValues["gmail:last_pop_time"],
      parameterValues["gmail:last_webmail_time"],
      parameterValues["drive:last_active_usage_time"]
    

    而不是'timestamp_last_':

    "gmail:timestamp_last_access",
    "gmail:timestamp_last_interaction",
    "gmail:timestamp_last_imap",
    "gmail:timestamp_last_pop",
    "gmail:timestamp_last_webmail",
    "drive:timestamp_last_active_usage"
    

    正如我试图在我的原始脚本中使用的那样。

    所以如果其他人需要它,它有一个完整的版本。 这比仅使用 Google 的“上次登录”指标可靠得多。 我在 L 列的表格中添加了一个列,该列使用以下公式:=MAX(E2:K2) 来获取用户的最近日期。

    【讨论】:

      【解决方案2】:

      这很奇怪。 parameterValues 的键似乎有问题。

      如果您按以下方式构建行数组,则并非真正未定义并打印到工作表的值:

      示例:

      const row = [
          report.date,
          report.entity.userEmail
      ];
      Object.keys(parameterValues).forEach((key) => {
          row.push(parameterValues[key])
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多