为什么此嵌套循环在Google Apps脚本Sheets / Admin中不起作用并且没有引发任何错误? 参考

问题描述

我正在尝试寻找一种简化的方法,以根据Google表格工作簿中已有的信息使约100个Google组中的成员保持最新状态。一张纸上有1700名学生的列表,其中有用于学生电子邮件和组电子邮件的列。另一张纸上仅列出了组名和组电子邮件。根据我发现的代码,似乎可以使用Google Apps脚本。不幸的是,我以前没有使用Apps Script的经验,也没有javascript的经验。我一直在尝试组装一个看起来像这样的过程。

  1. 删除组中所有当前成员。
  2. 上传正确的成员。
  3. 冲洗并重复。

不是最优雅,但似乎可行。

这是我到目前为止所做的,我碰到了墙。

我发现这两个功能的组合将删除1个组中的所有成员:

//Function to Remove 1 group member from 1 group
  function removeGroupMember(groupEmail,userEmail) {
  Logger.log(userEmail)
  userEmail = userEmail.trim();
  AdminDirectory.Members.remove(groupEmail,userEmail);
}
//Remove all Members from 1 group
function removeAllMembers() {
  var groupEmail = 'groupemail@mydomain.org';
  var members = AdminDirectory.Members.list(groupEmail).members;

  for (var m in members) {
    var member = members[m];
    var email = member.email;
    removeGroupMember(groupEmail,email)
  }
}

我想我可以嵌套另一个循环,以使其与从工作表中获取群组电子邮件代码配对。

//get all of the groups from the spreadsheet
function getGroupsFromSpreadsheet(){
  const ss = SpreadsheetApp.getActive();
  const sheet = ss.getSheetByName('google_groups');
  const data = sheet.getRange(2,2,100).getValues();
  return data;
  logger.log(data)
}

这是经过几次尝试和错误后我想到的。它是从脚本编辑器运行的,执行日志显示该操作成功,但是随后在Google Admin中实际上什么也没发生-它们仍在组中。

function removeAllMembers() {
  var groups =  [getGroupsFromSpreadsheet()];
  var groupEmail =  [getGroupsFromSpreadsheet()];
  var members = AdminDirectory.Members.list(groupEmail).members;
  
  for (var element in groups) {
  
    for (var m in members) {
      var member = members[m];
      var email = member.email;
      removeGroupMember(groupEmail,email);
    }
  }
}

解决方法

未经测试,因为我没有G Suite帐户。从未使用过AdminDirectory API,所以我不知道下面是执行此操作的最佳方法。


function* getGroupEmailsFromSpreadsheet() {
  // Should allow caller to access each "group" with a 
  // simple for-of loop. Generator used here,but could
  // have used anything that would flatten the nested array
  // that Range.getValues() returns.
  
  const ss = SpreadsheetApp.GetActiveSpreadsheet();
  const sheet = ss.getSheetByName('google_groups');
  const data = sheet.getRange(2,2,100).getValues();
  
  for (let rowIndex = 0; rowIndex < data.length; ++rowIndex) {
    for (let columnIndex = 0; columnIndex < data[0].length; ++columnIndex) {
      // Maybe do some validation here e.g. making sure email is a string,contains an "@" character
      yield data[rowIndex][columnIndex];
    }
  }
}


function* getAllMembersInGroup(groupKeyOrEmail) {
  // Should allow caller to access each "member" with a simple
  // for-of loop. Generator used here,so that call site
  // doesn't need to deal with handling pagination.
  
  const options = {
    maxResults: 200
  };
  
  // https://developers.google.com/admin-sdk/directory/v1/reference/members/list#request
  let groupMembers = AdminDirectory.Members.list(groupKeyOrEmail,options);
  do {
    for (const member of groupMembers.members) {
      yield member;
    }
    options.pageToken = groupMembers.nextPageToken;
    groupMembers = AdminDirectory.Members.list(groupKeyOrEmail,options)
  } while (groupMembers.nextPageToken);
}


function removeAllMembersFromAllGroups() {
  // Should remove all "members" in the "groups" on the sheet.
  for (const groupEmail of getGroupEmailsFromSpreadsheet()) {
    for (const member of getAllMembersInGroup(groupEmail)) {
      Logger.log(`Going to try and remove member ${member.email} from group ${groupEmail}.`);
      AdminDirectory.Members.remove(groupEmail,member.email);
    }
  }
}

运行removeAllMembersFromAllGroups函数之前:

  1. 如果您从工作表中随机选择一个组(someGroup),然后随机选择该组中的一个成员(someMember),然后创建/运行一个包含{{1 }}-用您选择的实际值替换AdminDirectory.Members.remove(someGroup,someMember)someGroup。然后检查该成员是否实际上已从组中删除。这应该证明代码是否可以实际上从组中删除成员(或者即使在这种简单情况下也存在问题)。
  2. 再次检查脚本是否已授予所有必要的权限。
  3. 然后在someMember的{​​{1}}循环内设置一个断点,因为do-while循环未经测试。然后调试getAllMembersInGroup函数。您需要检查do-while是否生成有限数量的“成员”序列(并且不会永远循环)。
,

您的代码中的问题实际上是由代码中的groupsgroupEmail变量引起的。因此,我建议您尝试以下方法:

function getGroups() {
   var ss = SpreadsheetApp.openById('SPREADSHEET_ID').getSheetByName('SHEET_NAME');
   var groups = ss.getRange(2,100).getValues();
   return groups;
}

function removeGroupMember(groupEmail,userEmail) {
   userEmail = userEmail.trim();
   AdminDirectory.Members.remove(groupEmail,userEmail);
}

function removeAllMembers() {
   var groups = getGroups();
   for (var i = 0; i < groups.length; i++) {
      var members = AdminDirectory.Members.list(theGroups[i][0]).members;
      for (var j = 0; j < members.length; j++) 
         removeGroupMember(theGroups[i][0],members[j].email);
   }
}

参考

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...