# Admin SDK Groups via Apps Script [[TOC]] ## Groepen ophalen en doorzoeken De Admin SDK Groups service geeft je toegang tot alle Google Workspace groepen in je domein. Net als de Users service moet je de Admin SDK Advanced Service activeren in je project. Dit doe je via `Services` (het plusje) in de Apps Script editor, of in `appsscript.json` onder `dependencies.enabledAdvancedServices`. ```javascript function haalGroepenOp() { const opties = { domain: 'bedrijf.nl', maxResults: 200, }; let pageToken; const alleGroepen = []; do { if (pageToken) opties.pageToken = pageToken; const resultaat = AdminDirectory.Groups.list(opties); if (resultaat.groups) { alleGroepen.push(...resultaat.groups); } pageToken = resultaat.nextPageToken; } while (pageToken); alleGroepen.forEach(g => Logger.log(`${g.name}: ${g.email} (${g.directMembersCount} leden)`)); return alleGroepen; } ``` :::warn title="Je hebt admin-rechten nodig" De Groups service vereist een super-admin account of een gedelegeerde admin-rol met het privilege voor groepsbeheer. Een gewone gebruiker krijgt een `403`-fout. Test scripts daarom met een admin-account. ::: ## Groepen aanmaken en verwijderen ```javascript function maakGroepAan() { const nieuweGroep = { email: 'sales-team@bedrijf.nl', name: 'Sales Team', description: 'Alle medewerkers in de sales afdeling', }; const aangemaakt = AdminDirectory.Groups.insert(nieuweGroep); Logger.log(`Groep aangemaakt: ${aangemaakt.email} (ID: ${aangemaakt.id})`); return aangemaakt.id; } function verwijderGroep() { AdminDirectory.Groups.remove('sales-team@bedrijf.nl'); Logger.log('Groep verwijderd'); } function wijzigGroep() { AdminDirectory.Groups.update({ name: 'Sales & Marketing Team', description: 'Bijgewerkte beschrijving', }, 'sales-team@bedrijf.nl'); } ``` ## Leden beheren ```javascript function voegLidToe() { const groepEmail = 'sales-team@bedrijf.nl'; AdminDirectory.Members.insert({ email: 'nieuwlid@bedrijf.nl', role: 'MEMBER', }, groepEmail); AdminDirectory.Members.insert({ email: 'manager@bedrijf.nl', role: 'OWNER', }, groepEmail); Logger.log('Leden toegevoegd'); } function verwijderLid() { AdminDirectory.Members.delete('sales-team@bedrijf.nl', 'oudlid@bedrijf.nl'); } function controleerLidmaatschap() { try { const lid = AdminDirectory.Members.get('sales-team@bedrijf.nl', 'gebruiker@bedrijf.nl'); Logger.log(`Rol: ${lid.role}, Status: ${lid.status}`); return true; } catch(e) { Logger.log('Geen lid'); return false; } } ``` :::info title="Welke rollen bestaan er" De beschikbare rollen voor groepsleden zijn `MEMBER`, `MANAGER` en `OWNER`. Een `OWNER` kan leden beheren, rollen wijzigen en de groep verwijderen. Een `MANAGER` kan hetzelfde, maar kan geen leden tot `OWNER` maken en de groep niet verwijderen. Een `OWNER` moet altijd zelf lid van de groep zijn. ::: ## Alle leden van een groep ophalen ```javascript function haalLedenOp(groepEmail) { const opties = {maxResults: 200}; let pageToken; const alleleden = []; do { if (pageToken) opties.pageToken = pageToken; const resultaat = AdminDirectory.Members.list(groepEmail, opties); if (resultaat.members) { alleleden.push(...resultaat.members); } pageToken = resultaat.nextPageToken; } while (pageToken); return alleleden; } ``` ## Groepslidmaatschappen synchroniseren vanuit spreadsheet ```javascript function synchroniseerLidmaatschappen() { const blad = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Groepen'); const data = blad.getDataRange().getValues(); const groepEmail = 'projectteam-alpha@bedrijf.nl'; const gewensteLeden = new Set( data.slice(1) .filter(rij => rij[1] === 'Actief') .map(rij => rij[0].toLowerCase()) ); const huidigeLeden = new Set( haalLedenOp(groepEmail).map(l => l.email.toLowerCase()) ); gewensteLeden.forEach(email => { if (!huidigeLeden.has(email)) { try { AdminDirectory.Members.insert({email, role: 'MEMBER'}, groepEmail); Logger.log(`Toegevoegd: ${email}`); } catch(e) { Logger.log(`Fout toevoegen ${email}: ${e.message}`); } Utilities.sleep(100); } }); huidigeLeden.forEach(email => { if (!gewensteLeden.has(email)) { try { AdminDirectory.Members.delete(groepEmail, email); Logger.log(`Verwijderd: ${email}`); } catch(e) { Logger.log(`Fout verwijderen ${email}: ${e.message}`); } Utilities.sleep(100); } }); } ``` :::tip title="Voorkom timeouts en rate-limiting" Apps Script breekt af na zes minuten per uitvoering. Bij grote synchronisaties verwerk je leden in batches en sla je een voortgangsmarkering op met `PropertiesService`, zodat een volgende trigger verdergaat waar de vorige stopte. De `Utilities.sleep(100)` tussen schrijfacties houdt je onder de API-quota voor de Directory API. ::: ## Groepsinstellingen beheren ```javascript function beheerGroepsinstellingen() { const instellingen = AdminGroupsSettings.Groups.get('sales-team@bedrijf.nl'); Logger.log(JSON.stringify(instellingen)); AdminGroupsSettings.Groups.update({ whoCanPostMessage: 'ALL_IN_DOMAIN_CAN_POST', whoCanViewMembership: 'ALL_MEMBERS_CAN_VIEW', isArchived: 'true', }, 'sales-team@bedrijf.nl'); } ``` :::warn title="Aparte service vereist" Voor `AdminGroupsSettings` moet je de Groups Settings API als aparte Advanced Service activeren naast de Admin SDK. Zonder die activering krijg je een `ReferenceError` op `AdminGroupsSettings`. ::: :::faq ### Kan ik een gebruiker aan meerdere groepen tegelijk toevoegen? Je moet voor elke groep apart `Members.insert()` aanroepen. Er is geen bulk-API. Gebruik een lus met `Utilities.sleep(100)` tussen de aanroepen om rate-limiting te voorkomen. ### Hoe werken geneste groepen in Workspace? Je kunt een groep als lid toevoegen aan een andere groep. De leden van de subgroep erven dan effectief het lidmaatschap van de bovenliggende groep, bijvoorbeeld voor e-mailbezorging en toegangsrechten. ### Wat gebeurt er als ik een groep verwijder? De groep en alle lidmaatschappen worden permanent verwijderd. E-mails naar het groepsadres bouncen daarna. Maak met `Members.list()` eerst een back-up van de ledenlijst voordat je verwijdert. ### Hoe beperk ik wie er e-mail naar een groep kan sturen? Gebruik de Groups Settings API en stel `whoCanPostMessage` in op een van: `ANYONE_CAN_POST`, `ALL_IN_DOMAIN_CAN_POST`, `ALL_MEMBERS_CAN_POST`, `ALL_MANAGERS_CAN_POST` of `NONE_CAN_POST`. ### Waarom krijg ik een 403-fout bij Groups.list()? Meestal omdat het uitvoerende account geen admin-rechten heeft of de juiste OAuth-scope ontbreekt. Voer het script uit met een super-admin of gedelegeerde admin, en autoriseer het script opnieuw zodat de scope `admin.directory.group` wordt toegekend. ### Hoe vermijd ik dat mijn synchronisatie de zes-minutenlimiet raakt? Verwerk leden in batches, sla de voortgang op met `PropertiesService` en plan een time-driven trigger die de volgende batch oppakt. Zo blijf je binnen de uitvoeringslimiet van Apps Script. ::: :::howto title="Afdeling-groepen synchroniseren met HR-spreadsheet" 1. Sla de HR-data op in een spreadsheet met de kolommen `E-mail`, `Afdeling` en `Status`. 2. Loop door alle actieve medewerkers, gegroepeerd per afdeling. 3. Controleer met `Groups.get()` of de bijbehorende groep bestaat, en maak hem anders aan met `Groups.insert()`. 4. Haal de huidige leden op met `Members.list()`. 5. Voeg ontbrekende leden toe met `Members.insert()` en verwijder leden die niet meer in de afdeling zitten met `Members.delete()`. 6. Log alle wijzigingen naar een aparte audit-sheet voor controle. ::: Combineer de Groups service met de Users service voor volledig geautomatiseerd lifecycle management. Bij onboarding voeg je een nieuwe gebruiker direct toe aan de juiste groepen, en bij offboarding verwijder je hem of haar in één run uit alle groepen.