问题描述
我正在尝试寻找一种简化的方法,以根据Google表格工作簿中已有的信息使约100个Google组中的成员保持最新状态。一张纸上有1700名学生的列表,其中有用于学生电子邮件和组电子邮件的列。另一张纸上仅列出了组名和组电子邮件。根据我发现的代码,似乎可以使用Google Apps脚本。不幸的是,我以前没有使用Apps Script的经验,也没有javascript的经验。我一直在尝试组装一个看起来像这样的过程。
不是最优雅,但似乎可行。
这是我到目前为止所做的,我碰到了墙。
//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
函数之前:
- 如果您从工作表中随机选择一个组(
someGroup
),然后随机选择该组中的一个成员(someMember
),然后创建/运行一个包含{{1 }}-用您选择的实际值替换AdminDirectory.Members.remove(someGroup,someMember)
和someGroup
。然后检查该成员是否实际上已从组中删除。这应该证明代码是否可以实际上从组中删除成员(或者即使在这种简单情况下也存在问题)。 - 再次检查脚本是否已授予所有必要的权限。
- 然后在
someMember
的{{1}}循环内设置一个断点,因为do-while
循环未经测试。然后调试getAllMembersInGroup
函数。您需要检查do-while
是否生成有限数量的“成员”序列(并且不会永远循环)。
您的代码中的问题实际上是由代码中的groups
和groupEmail
变量引起的。因此,我建议您尝试以下方法:
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);
}
}