1. Einführung
In diesem Codelab erstellen Sie ein interaktives Support Quick Portal, das direkt mit Google Workspace Studio interagiert. Sie erfahren, wie Sie sowohl einen benutzerdefinierten Starter-Schritt als auch einen benutzerdefinierten Aktionsschritt erstellen, die sofort getestet werden können, ohne dass eine Drittanbieterinfrastruktur erforderlich ist.
Wir verwenden Google Apps Script, um Folgendes zu erstellen:
- Eine Web-App mit einem übersichtlichen Formular, über das Nutzer Supportanfragen manuell einreichen können.
- Ein benutzerdefinierter Auslöser, der diese Web-App-Eingaben erfasst und einen Workspace Studio-Flow auslöst.
- Ein benutzerdefinierter Schritt, in dem die Beschreibung des eingehenden Tickets analysiert wird, um Dringlichkeitsstufen („Hoch“ oder „Normal“) zu ermitteln.
Lerninhalte
- So konfigurieren Sie Starter und Schritte in Ihrem
appsscript.json-Manifest. - So erstellen Sie die
notifyUriwährend der Registrierung als Starter. - Einen Workspace Studio-Flow programmatisch über externen Code mit
UrlFetchAppauslösen. - Ausgabevariablen in benutzerdefinierten Schritten erstellen, um Daten weiterzugeben
Vorbereitung
- Ein Google Workspace-Konto, in dem Google Workspace Studio aktiviert ist.
- Die Einstellung Nicht veröffentlichte (Test-) benutzerdefinierte Schritte zulassen ist in der Admin-Konsole Ihrer Domain aktiviert (unter Apps > Google Workspace > Workspace Studio > Einstellungen für benutzerdefinierte Schritte).
- Vertrautheit mit Google Apps Script
2. Apps Script-Projekt einrichten
Zuerst erstellen wir ein neues Apps Script-Projekt für unseren Code:
- Rufen Sie script.google.com auf und klicken Sie auf Neues Projekt.
- Geben Sie dem Projekt den Namen Support Quick Portal.
- Klicken Sie in der linken Seitenleiste auf
Projekteinstellungen.
- Klicken Sie das Kästchen an, um die Manifestdatei „appsscript.json“ im Editor anzeigen zu lassen.
- Kehren Sie zur
-Ansicht Editor zurück.
Standard-Google Cloud-Projekt verknüpfen
Standardmäßig sind Apps Script-Projekte mit einem verborgenen Google Cloud-Standardprojekt verknüpft. Wenn Sie die Google Workspace Studio API aufrufen und PERMISSION_DENIED-Fehler vermeiden möchten, müssen Sie Ihr Script auf ein Standard-Cloud-Projekt umstellen, die API aktivieren und die Google Auth Platform richtig konfigurieren.
- Projekt auswählen oder erstellen:Rufen Sie die Google Cloud Console auf und wählen Sie oben auf der Seite im Drop-down-Menü „Projekt“ ein vorhandenes Projekt aus oder erstellen Sie ein neues.
- API aktivieren:Wenn Ihr ausgewähltes Projekt in der oberen Leiste aktiv ist, öffnen Sie den Aktivierungsablauf für APIs und klicken Sie für die Workspace Studio API auf Weiter und Aktivieren.
- OAuth-Branding konfigurieren:Öffnen Sie die Seite „Google Auth Platform Branding“.
- Klicken Sie bei Aufforderung auf Jetzt starten. Wenn bereits konfiguriert, fahren Sie mit Schritt 4 fort.
- Geben Sie unter App-Informationen einen App-Namen und eine E-Mail-Adresse für den Nutzer-Support ein. Klicken Sie auf Weiter.
- Wählen Sie unter Zielgruppe die Option Intern (oder Extern, falls „Intern“ nicht verfügbar ist) aus und klicken Sie auf Weiter.
- Geben Sie die Kontaktdaten an, stimmen Sie der Datenrichtlinie zu und klicken Sie auf Erstellen.
- Datenzugriff konfigurieren:Öffnen Sie die Seite „Datenzugriff“ und klicken Sie auf Bereiche hinzufügen oder entfernen.
- Fügen Sie unter Bereiche manuell hinzufügen
https://www.googleapis.com/auth/workspace.studio.triggerein. - Klicken Sie auf Zur Tabelle hinzufügen, dann auf Aktualisieren und schließlich unten auf der Seite auf Speichern.
- Fügen Sie unter Bereiche manuell hinzufügen
- Rufen Sie IAM & Verwaltung > Einstellungen (oder das Cloud Console-Dashboard) auf und kopieren Sie die Projektnummer.
- Kehren Sie zu Ihrem Apps Script-Projekt zurück und klicken Sie in der linken Seitenleiste auf
Projekteinstellungen.
- Klicken Sie im Abschnitt Google Cloud Platform-Projekt (GCP) auf Projekt ändern.
- Geben Sie die GCP-Projektnummer ein, die Sie kopiert haben, und klicken Sie auf Projekt festlegen.
Manifest konfigurieren
Öffnen Sie die neu sichtbare Datei appsscript.json. Ersetzen Sie den Inhalt durch den unten stehenden Code. In diesem Manifest werden unsere erforderlichen OAuth-Bereiche explizit aufgeführt und unser Starter als workflowTrigger und unsere Aktion als workflowAction im Block studio.flows.workflowElements definiert.
{
"timeZone": "America/Los_Angeles",
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"webapp": {
"executeAs": "USER_ACCESSING",
"access": "MYSELF"
},
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/workspace.studio.trigger",
"https://www.googleapis.com/auth/script.storage",
"https://www.googleapis.com/auth/script.locale"
],
"urlFetchWhitelist": [
"https://workspacestudio.googleapis.com/"
],
"addOns": {
"common": {
"name": "Support Extension",
"logoUrl": "https://www.gstatic.com/images/branding/productlogos/buganizer/v1/192px.svg",
"useLocaleFromApp": true
},
"studio": {
"flows": {
"workflowElements": [
{
"id": "supportTicketTrigger",
"state": "ACTIVE",
"name": "New Support Ticket",
"description": "Fires when someone submits a ticket via the Web App.",
"workflowTrigger": {
"inputs": [],
"outputs": [
{
"id": "ticketTitle",
"description": "The title of the ticket",
"cardinality": "SINGLE",
"dataType": { "basicType": "STRING" }
},
{
"id": "ticketDescription",
"description": "The full description of the issue",
"cardinality": "SINGLE",
"dataType": { "basicType": "STRING" }
}
],
"onConfigFunction": "onConfigTrigger",
"onManageFunction": "onManageTrigger"
}
},
{
"id": "urgencyDetectorStep",
"state": "ACTIVE",
"name": "Detect Urgency",
"description": "Scans the ticket description to detect High or Normal urgency.",
"workflowAction": {
"inputs": [
{
"id": "ticketDescription",
"description": "The ticket description",
"cardinality": "SINGLE",
"dataType": { "basicType": "STRING" }
}
],
"outputs": [
{
"id": "urgencyLevel",
"description": "The urgency High/Normal",
"cardinality": "SINGLE",
"dataType": { "basicType": "STRING" }
}
],
"onConfigFunction": "onConfigUrgency",
"onExecuteFunction": "onExecuteUrgency"
}
}
]
}
}
}
}
3. Webanwendungs-UI erstellen
Damit wir unseren Starter visuell und testbar auslösen können, ohne Terminaltools oder Drittanbieter-Webhooks zu verwenden, erstellen wir eine Apps Script-Web-App.
Klicken Sie im Apps Script-Editor neben Dateien auf Datei hinzufügen und wählen Sie HTML aus. Nennen Sie sie
index.html. Die Erweiterung .html wird automatisch hinzugefügt.
Fügen Sie den folgenden vereinfachten UI-Code ein:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
body { font-family: Arial, sans-serif; padding: 20px; max-width: 500px; margin: auto; }
label { font-weight: bold; display: block; margin-top: 15px; }
input, textarea { width: 100%; margin-top: 5px; padding: 10px; box-sizing: border-box; }
button { background-color: #1a73e8; color: white; border: none; padding: 10px 15px; margin-top: 15px; font-weight: bold; cursor: pointer; border-radius: 4px; }
button:hover { background-color: #1557b0; }
#status { margin-top: 15px; color: green; font-weight: bold; }
</style>
</head>
<body>
<h2>Support Quick Portal</h2>
<p>Submit your issue below to trigger the Workspace Studio flow.</p>
<label for="title">Ticket Title</label>
<input type="text" id="title" placeholder="e.g. Broken monitor">
<label for="description">Issue Description</label>
<textarea id="description" rows="4" placeholder="Explain your issue (use words like 'urgent' to test the step!)..."></textarea>
<button onclick="submitTicket()">Submit Ticket</button>
<div id="status"></div>
<script>
function submitTicket() {
const title = document.getElementById('title').value;
const description = document.getElementById('description').value;
const statusEl = document.getElementById('status');
if (!title || !description) {
statusEl.style.color = "red";
statusEl.innerText = "Please fill out both fields.";
return;
}
statusEl.style.color = "green";
statusEl.innerText = "Submitting ticket...";
google.script.run
.withSuccessHandler(function(response) {
statusEl.innerText = response;
})
.withFailureHandler(function(error) {
statusEl.style.color = 'red';
statusEl.innerText = 'Error: ' + error.message;
})
.submitTicketToStudio(title, description);
}
</script>
</body>
</html>
4. Backend-Scripts erstellen
Jetzt müssen wir alles miteinander verbinden. Damit der Code lesbar bleibt, trennen wir die Logik für die Web-App, den Starter und den Aktionsschritt in drei verschiedene Skriptdateien.
WebApp.gs
Benennen Sie die Standarddatei Code.gs im Editor in WebApp.gs um, löschen Sie die Boilerplate-Datei myFunction und kopieren Sie den folgenden Block hinein. Diese Datei übernimmt das Web-App-Hosting:
/** --- WEB APP HOSTING --- **/
/**
* Serves the HTML UI when users visit the web app URL.
*/
function doGet() {
return HtmlService.createHtmlOutputFromFile('index')
.setTitle('Support Quick Portal')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
/**
* Called by the Web App form. It calls the Workspace Studio API.
*/
function submitTicketToStudio(title, description) {
const props = PropertiesService.getUserProperties();
const notifyUri = props.getProperty('notifyUri');
const triggerId = props.getProperty('triggerId');
if (!notifyUri || !triggerId) {
throw new Error('Trigger URL missing! Make sure the flow is enabled in Workspace Studio.');
}
// Use ScriptApp.getOAuthToken() (requires the workspace.studio.trigger scope in manifest)
const token = ScriptApp.getOAuthToken();
const requestId = Utilities.getUuid();
// Package our outputs mapped in appsscript.json
const payload = {
"name": "triggers/" + triggerId,
"outputs": {
"ticketTitle": { "stringValues": [title] },
"ticketDescription": { "stringValues": [description] }
},
"requestId": requestId
};
const options = {
"method": "POST",
"contentType": "application/json",
"headers": { "Authorization": "Bearer " + token },
"payload": JSON.stringify(payload),
"muteHttpExceptions": true
};
// Fire!
const response = UrlFetchApp.fetch(notifyUri, options);
if (response.getResponseCode() !== 200) {
console.error(response.getContentText());
throw new Error('Workspace Studio API Error: ' + response.getResponseCode());
}
return 'Ticket successfully routed to Workspace Studio!';
}
Starter.gs
Bewegen Sie den Mauszeiger als Nächstes auf Dateien, klicken Sie auf Datei hinzufügen, wählen Sie Script aus und geben Sie den Namen
Starter.gs ein. Kopieren Sie den folgenden Block und fügen Sie ihn ein. Diese Datei enthält die Starter-Konfiguration und die Workspace Studio-Lebenszyklusverwaltung:
/** --- STARTER LOGIC --- **/
/**
* Workspace Studio calls this to display the config UI when the user adds the starter.
* We just return a static message since there are no properties to configure.
*/
function onConfigTrigger() {
const section = CardService.newCardSection()
.setHeader("Configure Web App Starter")
.addWidget(CardService.newTextParagraph().setText("Ready to go! Once you enable this flow, deploy your Apps Script project as a Web App to submit tickets."));
return CardService.newCardBuilder().addSection(section).build();
}
/**
* Workspace Studio posts data here to manage the lifecycle (enable/disable the trigger).
* Critically, we must construct or save the `notifyUri` and `triggerId` to call it later.
*/
function onManageTrigger(event) {
const triggerCreation = event.workflow.triggerCreation;
const triggerDeletion = event.workflow.triggerDeletion;
const props = PropertiesService.getUserProperties();
if (triggerCreation) {
// Save the unique URL and ID when the flow is enabled
// Note: notifyUri might be omitted, so fallback to constructing it dynamically
const notifyUri = triggerCreation.notifyUri || `https://workspacestudio.googleapis.com/v1/triggers/${triggerCreation.triggerId}:fire`;
props.setProperty('notifyUri', notifyUri);
props.setProperty('triggerId', triggerCreation.triggerId);
} else if (triggerDeletion) {
// Cleanup if the user deletes the flow
props.deleteProperty('notifyUri');
props.deleteProperty('triggerId');
}
}
Action.gs
Bewegen Sie den Mauszeiger als Nächstes auf Dateien, klicken Sie auf Datei hinzufügen, wählen Sie Script aus und geben Sie den Namen
Action.gs ein. Kopieren Sie die Logik für den Dringlichkeits-Schritt unten und fügen Sie sie ein:
/** --- ACTION STEP LOGIC --- **/
/**
* Workspace Studio configuration card for the Step.
* We prompt the user to bind a variable to our "ticketDescription" input.
*/
function onConfigUrgency() {
const input = CardService.newTextInput()
.setFieldName("ticketDescription")
.setTitle("Source Description")
.setHint('Select the description variable outputted by the starter')
.setHostAppDataSource(
CardService.newHostAppDataSource().setWorkflowDataSource(CardService.newWorkflowDataSource().setIncludeVariables(true))
);
const section = CardService.newCardSection()
.setHeader("Urgency Detector Step")
.addWidget(input);
return CardService.newCardBuilder().addSection(section).build();
}
/**
* The synchronous logic executed during the Step.
*/
function onExecuteUrgency(event) {
// Read mapped inputs
let description = event.workflow.actionInvocation.inputs["ticketDescription"].stringValues[0];
if (!description) description = "";
const urgentKeywords = ['urgent', 'crash', 'broken', 'down', 'fire'];
let urgencyLevel = 'Normal';
if (urgentKeywords.some(keyword => description.toLowerCase().includes(keyword))) {
urgencyLevel = 'High';
}
// Package outputs correctly
const variableDataMap = {
"urgencyLevel": AddOnsResponseService.newVariableData().addStringValue(urgencyLevel)
};
return outputVariables(variableDataMap);
}
/**
* Helper strictly enforcing the expected Step object return type.
*/
function outputVariables(variableDataMap) {
const workflowAction = AddOnsResponseService.newReturnOutputVariablesAction()
.setVariableDataMap(variableDataMap);
const hostAppAction = AddOnsResponseService.newHostAppAction()
.setWorkflowAction(workflowAction);
return AddOnsResponseService.newRenderActionBuilder()
.setHostAppAction(hostAppAction)
.build();
}
5. Bereitstellen und testen
Nachdem wir den Code geschrieben haben, stellen wir das Projekt bereit und konfigurieren es.
Schritt 1: Skript neu autorisieren
Da Sie ein neues Standard-Google Cloud-Projekt verknüpft haben, müssen Sie die Bereiche des Skripts (z. B. script.external_request, das von UrlFetchApp verwendet wird) explizit für das neue Projekt autorisieren.
- Wählen Sie im Apps Script-Editor unter Dateien die Option
WebApp.gsaus und wählen Sie dann die FunktiondoGetaus dem Drop-down-Menü in der oberen Symbolleiste aus. - Klicken Sie auf Ausführen.
- Eine Aufforderung zur Autorisierung wird angezeigt. Klicken Sie auf Berechtigungen ansehen.
- Wählen Sie Ihr Konto aus und autorisieren Sie das Script. Wenn Sie eine Warnung zur „nicht bestätigten App“ sehen, klicken Sie auf Erweitert -> Support Quick Portal aufrufen, um die Warnung zu umgehen.
- Warten Sie, bis im Ausführungsprotokoll die Meldung Ausführung abgeschlossen angezeigt wird. Das bedeutet, dass das Skript jetzt vollständig autorisiert ist.
Schritt 2: Erweiterung und Web-App testen
Da in Ihrem appsscript.json sowohl ein Add-on als auch eine Web-App definiert sind, können Sie beide gleichzeitig konfigurieren.
- Klicken Sie im Apps Script-Editor oben rechts auf Bereitstellen > Deployments testen.
- Klicken Sie neben Typ auswählen auf
Bereitstellungstypen aktivieren und achten Sie darauf, dass Google Workspace-Add‑ons ausgewählt ist. Klicken Sie dann auf Installieren.
- Klicken Sie noch einmal auf
Bereitstellungstypen aktivieren, achten Sie darauf, dass Web-App ausgewählt ist, und kopieren Sie die URL (sie endet mit
/dev). Das ist die URL für die von Ihnen erstellte Support Quick Portal-Web-App. - Klicken Sie auf Fertig. Möglicherweise müssen Sie Ihren Browser aktualisieren, bevor das Add-on in Workspace Studio registriert wird.
Schritt 3: Studio-Flow konfigurieren
- Öffnen Sie Google Workspace Studio unter studio.workspace.google.com.
- Klicken Sie links auf
Tool hinzufügen und wählen Sie Flow aus.
- Klicken Sie zum Konfigurieren des Starters auf Auslöser auswählen und wählen Sie dann die installierte Support-Erweiterung > Neues Support-Ticket aus. Wenn die Meldung „Berechtigung erforderlich“ angezeigt wird, klicken Sie auf Berechtigung erteilen, damit das Add-on auf Ihre Daten zugreifen kann.
- Klicken Sie als Nächstes unter „Aktionen“ auf Schritt auswählen, scrollen Sie zu „Support Extension“ und wählen Sie den Schritt Detect Urgency (Dringlichkeit erkennen) aus.
- Klicken Sie unter Quellbeschreibung auf
Variablen und wählen Sie Schritt 1: Neues Support-Ticket > Die vollständige Beschreibung des Problems (
ticketDescription) aus. - Klicken Sie noch einmal auf Schritt auswählen und wählen Sie einen integrierten Schritt wie Gmail > E‑Mail senden oder Chat > Mich in Google Chat benachrichtigen aus.
- Wenn Sie Gmail ausgewählt haben
- :
- An: Geben Sie Ihre eigene E‑Mail-Adresse ein.
- Betreff: Ticket
ticketTitle, Priorität:urgencyLevel - Nachricht :
ticketDescription
- Wenn Sie „Chat“ ausgewählt haben
- Nachricht:Die Priorität des Tickets
ticketTitleisturgencyLevel.ticketDescription
- Nachricht:Die Priorität des Tickets
- Wenn Sie Gmail ausgewählt haben
- Aktivieren Sie den Workflow. Wenn Sie aufgefordert werden, den Flow umzubenennen, geben Sie einen Namen wie
Support Ticket Routerein und speichern Sie ihn. Dadurch wird deronManageTrigger-Lebenszyklus ausgelöst und dienotifyUriwird gespeichert.
Schritt 4: Simulation ausführen
- Öffnen Sie die Web-App-URL, die Sie zuvor in Schritt 2 auf dieser Seite kopiert haben, in einem neuen Browsertab (sie endet auf „/dev“).
- Füllen Sie das Formular aus. Achten Sie darauf, dass Sie in der Beschreibung ein Trigger-Keyword wie „dringend“ oder „Absturz“ verwenden.
- Klicken Sie auf Senden. Warten Sie auf die Meldung „Ticket erfolgreich weitergeleitet“.
- Sehen Sie in Ihrem Workspace Studio-Aktivitätsprotokoll, Ihrem Gmail-Posteingang oder in Google Chat nach (je nachdem, welche Aktion Sie ausgewählt haben). Sie sollten eine Nachricht oder E-Mail mit der Dringlichkeit Hoch sehen, die nativ über Ihre benutzerdefinierten Apps Script-Elemente eingebunden ist.
6. Bereinigen
Damit Ihr Arbeitsbereich und Ihr Google Cloud-Konto nicht überladen werden, können Sie die Ressourcen bereinigen, die Sie in diesem Codelab erstellt haben.
- Workspace Studio-Flow löschen
- :
- Rufen Sie studio.workspace.google.com auf.
- Finde deinen
Support Ticket Router-Flow. - Klicken Sie daneben auf das Dreipunkt-Menü und wählen Sie Löschen aus.
- Apps Script-Projekt löschen
- :
- Rufen Sie script.google.com auf.
- Suchen Sie das Projekt
Support Quick Portal. - Klicken Sie auf das Dreipunkt-Menü und wählen Sie Entfernen aus.
- Google Cloud-Projekt herunterfahren
- Öffnen Sie die Google Cloud Console:
- Achten Sie darauf, dass Ihr neues Projekt im Drop-down-Menü oben ausgewählt ist.
- Klicken Sie auf IAM & Verwaltung > Einstellungen und dann auf Herunterfahren.
7. Fazit
Sie haben erfolgreich ein vollständiges Ökosystem für benutzerdefinierte Google Workspace Studio-Erweiterungen erstellt, ohne auf externe Drittanbieterabos angewiesen zu sein.
Behandelte Themen:
- Verwenden Sie
workflowTriggerzusammen mitonManageFunction, um die Lebenszyklusereignisse von Google korrekt zu erfassen und zu verarbeiten. - Back-End-Anfragen mit
ScriptApp.getOAuthToken()für dieworkspacestudio.googleapis.com-API-Endpunkte authentifizieren. - Mit
workflowActionEingabevariablen synchron verarbeiten und Downstream-Ausgaben generieren.
Sie können diese Prinzipien jetzt horizontal skalieren, um sie in echte SaaS-Plattformen wie Jira, Salesforce oder Zendesk einzubinden. Dazu müssen Sie nur ändern, wo Ihre Web-App (oder der eingehende Webhook) ausgelöst wird.