Skip to content

Instantly share code, notes, and snippets.

@emmaly
Last active May 13, 2022 10:11
Show Gist options
  • Save emmaly/eebac3b7c214dd1ba8a5d9b686920c92 to your computer and use it in GitHub Desktop.
Save emmaly/eebac3b7c214dd1ba8a5d9b686920c92 to your computer and use it in GitHub Desktop.
Google Workspace Group Query Utils

Google Workspace Group Query Utils

This will require Google Workspace Admin SDK API admin/AdminDirectory/directory_v1 service enabled. See appsscript.json.

{
"timeZone": "America/Los_Angeles",
"dependencies": {
"enabledAdvancedServices": [
{
"userSymbol": "AdminDirectory",
"version": "directory_v1",
"serviceId": "admin"
}
]
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
function buildArrayProcessorChain (rawArrayProcessors) {
const arrayProcessors = (typeof rawArrayProcessors !== "object" ? [] :
Array.isArray(rawArrayProcessors) ? rawArrayProcessors : [rawArrayProcessors])
.filter(v => (v.map === undefined && typeof v.filter === "function") || (v.filter === undefined && typeof v.map === "function"));
if (arrayProcessors.length === 0) return (a) => a; // nothing to do
return arrayProcessors.reduceRight((p, c) => {
// filter
if (typeof c.filter === "function") return (a) => typeof p !== "function" ? Array.prototype.filter.call(a, c.filter) : p(Array.prototype.filter.call(a, c.filter));
// map
if (typeof c.map === "function") return (a) => typeof p !== "function" ? Array.prototype.map.call(a, c.map) : p(Array.prototype.map.call(a, c.map));
// invalid item, skipping
return (a) => typeof p !== "function" ? a : p(a);
}, {});
}
function getPixelFanGroupDerivedMembership() {
const groups = getGroup("[email protected]", {
groupAssertion: v => v.adminCreated === true,
memberProcessors: [{
filter: v => v.type.toUpperCase() === "GROUP",
}, {
map: v => getGroup(v.email, {
groupAssertion: v => v.adminCreated === true,
listOptions: {
includeDerivedMembership: true,
},
memberProcessors: [{
filter: v => v.type.toUpperCase() === "USER",
}, {
map: v => v.email,
}],
}),
}],
});
Array(groups).forEach(v => Logger.log(JSON.stringify(v, null, '\t')));
}
function listGroups(opts) {
if (typeof opts !== "object") opts = {};
if (typeof opts.listOptions !== "object") opts.listOptions = {};
if (opts.listOptions.customer == undefined && opts.listOptions.domain == undefined) opts.listOptions.customer = "my_customer";
const groupProcessor = buildArrayProcessorChain(opts.groupProcessors);
const listOptions = opts.listOptions;
let pageToken;
let groups = [];
do {
const page = AdminDirectory.Groups.list({
...listOptions,
pageToken
});
groups.push(...groupProcessor(page.groups));
pageToken = page.nextPageToken;
} while(pageToken);
return groups;
}
function getGroup(groupKey, opts) {
let group = AdminDirectory.Groups.get(groupKey);
if (!group || !group.id) return null;
if (typeof opts.groupAssertion === "function" && !opts.groupAssertion(group)) return null;
const memberProcessor = buildArrayProcessorChain(opts.memberProcessors);
const listOptions = opts.listOptions;
let pageToken;
let members = [];
do {
const page = AdminDirectory.Members.list(groupKey, {
...listOptions,
pageToken
});
members.push(...memberProcessor(page.members));
pageToken = page.nextPageToken;
} while(pageToken);
return {
group,
members: members,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment