Externe Dienste in ScriptEngine-Funktionen
Microsoft 365 (Graph) und Google Workspace direkt aus einer Funktion ansprechen — mit nativen Modulen statt mühsamer HTTP-Aufrufe.
Was du in diesem Tutorial tust
Du nutzt die eingebauten Module der ScriptEngine (graphapi, googlemail, googlecalendar, googledrive, googleapi), richtest den jeweiligen OAuth-/App-Zugang ein und baust typische Mail-/Drive-Workflows als sichere Funktionsmuster.
Voraussetzung: E3 (ScriptEngine-Funktionen), C5 (HTTP/Funktionen/MCP); E7 für den Secret-Betrieb empfohlen. Abgrenzung: C5/E3 = Grundlagen & eigene HTTP-Bausteine; D2/E4/E5 = Konnektor/Teams/Filesync auf Org-Ebene; E6 = funktionsnaher Zugriff aus JavaScript.
Quellen und Stand
Geprüft gegen das AuxData-Programmierhandbuch (Stand Juni 2026): MS Graph API Modul, Google Workspace Module & Zugriff einrichten, Beispiel-Skripte, Hilfsmodule; ergänzend Admin-Handbuch Kap. 7.2. Alle IDs/Secrets sind Platzhalter.
Warum eingebaute Module
Statt Graph-/Google-APIs per HTTP selbst zu bauen.
1Die Module der ScriptEngine
Die ScriptEngine kapselt externe Systeme in fertigen Modulen — das spart Boilerplate und liefert geprüfte Signaturen. (PH „Verfügbare Module")
graphapi- Microsoft Graph / Microsoft 365.
googlemail·googlecalendar·googledrive·googleapi- Google Workspace (Mail, Kalender, Drive, generisch).
- Hilfsmodule
aiservice,user,organisation,log,docdb.
Jedes Modul wird per getModule("name") initialisiert; danach stehen seine Funktionen global bereit:
getModule("graphapi");
getModule("log");
log_info("Graph-Modul initialisiert");

graphapi oder googlemail einbindest.✓ Das hast du jetzt verstanden
Microsoft 365: graphApiConfig
Das Credential-Objekt für Graph.
1Das Konfigurationsobjekt
Das M365-Modul wird mit getModule("graphapi") geladen; die Zugangsdaten trägt das Objekt graphApiConfig. (PH „MS Graph API Modul")
var graphApiConfig = new Object(); graphApiConfig["TenantId"] = tenant_id; graphApiConfig["ClientId"] = client_id; graphApiConfig["ClientSecret"] = client_secret; // aus Umgebungsvariable (E7) graphApiConfig["Account"] = "user@contoso.onmicrosoft.com";
- TenantId
- Verzeichnis-/Tenant-ID aus Entra ID.
- ClientId
- Application/Client-ID der App-Registrierung.
- ClientSecret
- Secret (oder Zertifikat-Äquivalent) — nicht hart codieren.
- Account
- UPN der Mailbox/des Users, in dessen Namen gearbeitet wird.
ClientSecret gehört in eine Umgebungsvariable (siehe E7), nie in den Funktionscode — und niemals ins Log.Account allein nicht, wenn TenantId, ClientId oder Admin-Consent fehlen?✓ Das hast du jetzt verstanden
Entra ID, Permissions & Fehlerbilder
Client-Credentials-Flow, kein User-Login.
1App-Registrierung in 6 Schritten
M365-Zugriff nutzt den Client-Credentials-Flow: kein interaktiver Login — AuxData authentifiziert sich als konfigurierte App. (PH „Microsoft 365 Zugriff einrichten")
- App-Registrierung in Microsoft Entra ID anlegen.
- Client Secret oder Zertifikat erzeugen.
- Microsoft-Graph-Berechtigungen als Application Permissions setzen.
- Tenant-Admin-Consent erteilen.
- Optional: Zugriff per Application Access Policy auf bestimmte Mailboxen einschränken.
- Werte in der ScriptEngine-Konfiguration hinterlegen.
2Beispiel-Permissions
- Mail lesen/verschieben/verwalten
Mail.ReadWrite- Mail versenden
Mail.Send- Kalender
Calendars.ReadWrite- OneDrive-/SharePoint-Dateien
Files.ReadWrite.All- SharePoint Sites
Sites.ReadWrite.All- User-Sync
User.Read.All
401/invalid_client = Secret abgelaufen oder Tenant/Client vertauscht · 403/Authorization_RequestDenied = Permission oder Admin-Consent fehlt · 404 = falscher Account oder Access Policy schließt Postfach aus · MailboxNotEnabledForRESTAPI = Postfach nicht in Exchange Online nutzbar.✓ Das hast du jetzt verstanden
Microsoft 365 nutzen
Mail-Kategorien, Dateien, Ressourcen.
1Graph-Funktionen
- Ressourcen
graphapi_getResource/postResource/putResource/deleteResource(config, url[, body])graphapi_send,getNewFromInbox,getNewFromFolder,move,delete- Kategorien (Outlook-Labels)
setLabel(überschreibt) ·addLabel(additiv) ·removeLabel(no-op wenn nicht gesetzt) ·getLabels
getModule("graphapi");
getModule("log");
var mails = graphapi_getNewFromInbox(graphApiConfig, 10);
for (var i = 0; i < mails.length; i++) {
graphapi_addLabel(graphApiConfig, mails[i].MailServerId, "AuxData-geprüft");
}
log_info("Mails verarbeitet: " + mails.length);
return String(mails.length);
MailServerId und die Rückgabeobjekte vor dem Produktivbetrieb gegen die konkrete Instanz prüfen.graphapi_setLabel, wann graphapi_addLabel?✓ Das hast du jetzt verstanden
Google Workspace konfigurieren
Zwei Wege, ein Credential-Objekt.
1Variante A — Service Account (empfohlen)
Für Workspace-Tenants: Service Account mit Domain-wide Delegation — zentral, ohne Einzel-Login. (PH „Google Workspace Zugriff einrichten")
var creds = {
Account: "user@example.com",
ServiceAccountJson: google_service_account_json
};
Voraussetzungen: Google-Cloud-Projekt · APIs aktivieren (Gmail, Calendar, Drive) · Service Account + JSON-Schlüssel · Domain-wide Delegation im Admin Center · Scopes whitelisten (gmail.modify, calendar, drive).
2Variante B — OAuth2 mit Refresh-Token
Für einzelne Accounts oder Consumer-Gmail:
var creds = {
Account: "user@example.com",
ClientId: google_client_id,
ClientSecret: google_client_secret,
RefreshToken: google_refresh_token
};
gmail.modify und drive sind besonders anspruchsvoll (CASA kann relevant werden).access_type=offline und prompt=consent gesetzt sein, sonst kommt kein Refresh-Token; er wird nur beim allerersten Consent zurückgegeben, der Authorization-Code ist Single-Use (~10 min), der Token-Tausch braucht x-www-form-urlencoded. Scope-Kategorien: non-sensitive / sensitive / restricted (mit CASA-Audit). Workspace-Abkürzung: User Type = Internal umgeht Verification/CASA. (Programmierhandbuch · OAuth2)✓ Das hast du jetzt verstanden
Google-Module nutzen
Mail, Kalender, Drive.
1Funktionen je Modul
googlemailgetNewFromInbox,getByCriteria,move,changeReadState,createDraftgooglecalendargetEventsInRange,findFreeSlots,createEvent,updateEvent,getEventById,findMeetingTimes(liefert konstant Confidence 100),deleteEvent,acceptEvent/declineEvent/tentativelyAcceptEventgoogledrivelistFiles,findFolderByPath,getFileContent,uploadFile,exportFilegoogleapi- generisch:
getResource/postResource/putResource/deleteResource
getModule("googlemail");
var newMails = googlemail_getNewFromInbox(creds, 25);
for (var i = 0; i < newMails.length; i++) {
var mail = newMails[i];
if (mail.Subject.toLowerCase().indexOf("invoice") !== -1) {
googlemail_move(creds, mail.MailServerId, "Processed/Invoices");
googlemail_changeReadState(creds, mail.MailServerId, true);
}
}
return String(newMails.length);
getFileContent liefert Base64, uploadFile erwartet Base64. Native Google Docs/Sheets/Slides brauchen googledrive_exportFile(...) statt getFileContent — sonst scheitert der Lesezugriff.googledrive_findFolderByPath(creds, "Documents/Reports/2026") → getFileContent → atob(...) (Base64→Text) → aiservice_executeByName("text-summarizer", {…}) → btoa(...) → uploadFile. atob/btoa stehen als JS-Standardhelfer bereit; googledrive_exportFile(creds, fileId, exportMimeType) liefert Google-Docs in einem Ziel-MIME (z. B. application/pdf). (Programmierhandbuch · Beispiel-Skripte)googledrive_getFileContent bei einem Google Doc scheitern?✓ Das hast du jetzt verstanden
Hilfsmodule, Secrets & Betrieb
Sauber und sicher betreiben.
1Hilfsmodule
user- aktueller Benutzer.
organisation- Org-Konfiguration über
organisation_getOrganisation(). loglog_info/log_warn/log_error/log_fatal.docdb- Dokumente in DocumentDB laden/speichern/löschen.
organisation-Modul kann sensible Werte im Klartext liefern (Env, EnvConfidential, ADConfig.MsgraphClientSecret, TeamsBotConfig.MsAppPassword). Diese Werte nicht loggen, zurückgeben oder ungesichert senden. Mehr dazu in E7.timeout: Funktionen, die viele oder aufwendige AI-Services bzw. Graph-/Drive-Aufrufe machen, profitieren von einem höheren timeout (Default 600 s / 10 min; nur an der Funktion wirksam). Details in E7. (Programmierhandbuch)Externe Dienste angebunden
Du sprichst M365 und Google Workspace aus ScriptEngine-Funktionen an. Weiter mit E7 — Umgebungsvariablen & Secrets: Konfiguration und Geheimnisse sauber vom Code trennen.
organisation_getOrganisation() nie ungefiltert geloggt werden?✓ Das hast du jetzt erledigt
Sitzt der externe Zugriff?
8 Fragen aus den Stufen 1–7. Kein Zertifikat — zur Selbstkontrolle. Beliebig oft wiederholbar.