1. Introduzione
In questo codelab, creerai un Support Quick Portal interattivo che interagisce direttamente con Google Workspace Studio. Imparerai a creare un passaggio iniziale personalizzato e un passaggio di azione personalizzato che possono essere testati immediatamente senza fare affidamento su infrastrutture di terze parti.
Utilizzeremo Google Apps Script per creare:
- Un'app web con un modulo semplice per consentire agli utenti di inviare manualmente le richieste di assistenza.
- Un comando iniziale personalizzato che acquisisce gli invii dell'app web e attiva un flusso di Workspace Studio.
- Un passaggio personalizzato che analizza la descrizione del ticket in entrata per identificare i livelli di urgenza ("Elevata" o "Normale").
Obiettivi didattici
- Come configurare gli starter e i passaggi nel manifest
appsscript.json. - Come costruire il
notifyUridurante il ciclo di vita della registrazione iniziale. - Come attivare in modo programmatico un flusso di Workspace Studio da codice esterno utilizzando
UrlFetchApp. - Come creare variabili di output nei passaggi personalizzati per trasferire i dati a valle.
Prerequisiti
- Un account Google Workspace con Google Workspace Studio attivato.
- L'impostazione Consenti passaggi personalizzati non pubblicati (test) abilitata nella Console di amministrazione del tuo dominio (in App > Google Workspace > Workspace Studio > Impostazioni passaggi personalizzati).
- Familiarità con Google Apps Script.
2. Configura il progetto Apps Script
Innanzitutto, creiamo un nuovo progetto Apps Script per ospitare il nostro codice:
- Vai a script.google.com e fai clic su Nuovo progetto.
- Assegna al progetto il nome Support Quick Portal.
- Fai clic su
Impostazioni progetto nella barra laterale a sinistra.
- Seleziona la casella per Mostrare il file manifest appsscript.json nell'editor.
- Torna alla visualizzazione Editor
.
Collega un progetto Google Cloud standard
Per impostazione predefinita, i progetti Apps Script sono associati a un progetto Google Cloud predefinito nascosto. Per chiamare l'API Google Workspace Studio ed evitare errori PERMISSION_DENIED, devi passare lo script a un progetto Cloud standard, abilitare l'API e configurare correttamente la piattaforma Google Auth.
- Seleziona o crea un progetto:vai alla console Google Cloud e utilizza il menu a discesa del progetto nella parte superiore della pagina per scegliere un progetto esistente o crearne uno nuovo.
- Abilita l'API:una volta che il progetto scelto è attivo nella barra in alto, apri il flusso di abilitazione dell'API e fai clic su Avanti e Abilita per l'API Workspace Studio.
- Configura il branding OAuth:apri la pagina Branding della piattaforma Google Auth.
- Se richiesto, fai clic su Inizia. Se è già configurato, vai al passaggio 4.
- In Informazioni sull'app, inserisci un nome dell'app e un'email di assistenza utenti. Fai clic su Avanti.
- In Pubblico, seleziona Interno (o Esterno se Interno non è disponibile) e fai clic su Avanti.
- Fornisci i dati di contatto, accetta le Norme relative ai dati e fai clic su Crea.
- Configura l'accesso ai dati:apri la pagina Accesso ai dati e fai clic su Aggiungi o rimuovi ambiti.
- Nella sezione Aggiungi ambiti manualmente, incolla
https://www.googleapis.com/auth/workspace.studio.trigger. - Fai clic su Aggiungi alla tabella, poi su Aggiorna e infine su Salva in fondo alla pagina.
- Nella sezione Aggiungi ambiti manualmente, incolla
- Vai a IAM e amministrazione > Impostazioni (o alla dashboard della console Cloud) e copia il numero di progetto.
- Torna al progetto Apps Script e fai clic su
Impostazioni progetto nella barra laterale sinistra.
- Nella sezione Progetto Google Cloud (GCP), fai clic su Cambia progetto.
- Inserisci il numero di progetto Google Cloud che hai copiato e fai clic su Imposta progetto.
Configurare il manifest
Apri il file appsscript.json appena visibile. Sostituisci i contenuti con il codice che segue. Questo manifest elenca esplicitamente gli ambiti OAuth richiesti e definisce il nostro starter come workflowTrigger e la nostra azione come workflowAction nel blocco studio.flows.workflowElements.
{
"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. Crea l'UI dell'app web
Per fornire un modo visivo e testabile per attivare il nostro starter senza utilizzare strumenti terminali o webhook di terze parti, creeremo un'app web Apps Script.
Nell'editor di script di Apps Script, fai clic su Aggiungi un file accanto a File e seleziona HTML. Assegna il nome
index.html (l'estensione .html viene aggiunta automaticamente).
Incolla il seguente codice dell'interfaccia utente semplificata:
<!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. Crea gli script di backend
Ora colleghiamo tutto. Per mantenere il codice leggibile, separeremo la logica dell'app web, di Starter e del passaggio dell'azione in tre diversi file di script.
WebApp.gs
Rinomina il file Code.gs predefinito nell'editor in WebApp.gs, elimina il boilerplate myFunction e copia e incolla il blocco seguente. Questo file gestisce l'hosting dell'app web:
/** --- 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
Poi, passa il mouse sopra File, fai clic su Aggiungi un file, seleziona Script e assegnagli il nome
Starter.gs. Copia e incolla il blocco riportato di seguito. Questo file gestisce la configurazione dello starter e la gestione del ciclo di vita di Workspace Studio:
/** --- 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
Poi, passa il mouse sopra File, fai clic su Aggiungi un file, seleziona Script e assegnagli il nome
Action.gs. Copia e incolla la logica del passaggio Urgenza riportata di seguito:
/** --- 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. Deployment e test
Ora che abbiamo scritto il codice, eseguiamo il deployment del progetto e configuriamolo.
Passaggio 1: autorizza nuovamente lo script
Poiché hai collegato un nuovo progetto Google Cloud standard, devi autorizzare esplicitamente gli ambiti dello script (come script.external_request utilizzato da UrlFetchApp) rispetto al nuovo progetto.
- Nell'editor Apps Script, seleziona
WebApp.gsin File, poi seleziona la funzionedoGetdal menu a discesa della barra degli strumenti in alto. - Fai clic su Esegui.
- Verrà visualizzato il messaggio "Autorizzazione richiesta". Fai clic su Rivedi autorizzazioni.
- Scegli il tuo account e autorizza lo script. Se visualizzi l'avviso "App non verificata", fai clic su Avanzate -> Vai a Support Quick Portal per ignorarlo.
- Attendi che nel log di esecuzione venga visualizzato il messaggio Esecuzione completata, che conferma che lo script è ora completamente autorizzato.
Passaggio 2: testa l'estensione e l'app web
Poiché il tuo appsscript.json definisce sia un componente aggiuntivo sia un'app web, puoi configurarli entrambi contemporaneamente.
- Fai clic su Implementa > Test di implementazione nell'angolo in alto a destra di Apps Script.
- Accanto a Seleziona tipo, fai clic su
Attiva tipi di deployment e assicurati che Componenti aggiuntivi di Google Workspace sia selezionato, poi fai clic su Installa.
- Fai di nuovo clic su
Attiva tipi di deployment, assicurati che la casella App web sia selezionata e copia l'URL (terminerà con
/dev). Questo è l'URL dell'app web Support Quick Portal che hai creato. - Fai clic su Fine. Potrebbe essere necessario aggiornare il browser prima che Workspace Studio registri il componente aggiuntivo.
Passaggio 3: configura il flusso di Studio
- Apri Google Workspace Studio all'indirizzo studio.workspace.google.com.
- Fai clic su
Aggiungi strumento a sinistra e seleziona Flusso.
- Per configurare il comando iniziale, fai clic su Scegli un comando iniziale, quindi seleziona l'estensione di assistenza installata > Nuova richiesta di assistenza. Se viene visualizzato il messaggio "Autorizzazione richiesta", fai clic su Concedi autorizzazione per consentire al componente aggiuntivo di accedere ai tuoi dati.
- Poi, in Azioni, fai clic su Scegli un passaggio, scorri fino a "Estensione supporto" e seleziona il passaggio Rileva urgenza.
- In Descrizione origine, fai clic su
Variabili e seleziona Passaggio 1: nuovo ticket di assistenza > The full description of the issue (
ticketDescription). - Fai di nuovo clic su Scegli un passaggio e seleziona un passaggio integrato come Gmail > Invia un'email o Chat > Avvisami in Chat.
- Se hai scelto Gmail:
- A: inserisci il tuo indirizzo email.
- Oggetto: la priorità del ticket
ticketTitleèurgencyLevel - Messaggio:
ticketDescription
- Se hai scelto la chat:
- Messaggio: la priorità del ticket
ticketTitleèurgencyLevel.ticketDescription
- Messaggio: la priorità del ticket
- Se hai scelto Gmail:
- Attiva il workflow. Se ti viene chiesto di rinominare il flusso, inserisci un nome come
Support Ticket Routere salva. Questo attiva il ciclo di vita dionManageTrigger, salvandonotifyUri.
Passaggio 4: esegui la simulazione
- Apri l'URL dell'app web che hai copiato in precedenza nel passaggio 2 di questa pagina in una nuova scheda del browser (termina con /dev).
- Compila il modulo. Assicurati di includere una parola chiave di attivazione (ad esempio "urgente" o "arresto anomalo") nella descrizione.
- Fai clic su Invia. Attendi il messaggio "Ticket inviato correttamente".
- Controlla il log attività di Workspace Studio, la posta in arrivo di Gmail o Google Chat (a seconda dell'azione scelta). Dovresti visualizzare un messaggio o un'email contrassegnati come "Priorità alta" integrati in modo nativo utilizzando gli elementi Apps Script personalizzati.
6. Elimina
Per evitare di sovraccaricare il tuo spazio di lavoro e l'account Google Cloud, puoi liberare spazio dalle risorse che hai creato durante questo codelab.
- Elimina il flusso di Workspace Studio:
- Apri studio.workspace.google.com.
- Trova il tuo ritmo di
Support Ticket Router. - Fai clic sul menu con tre puntini accanto e seleziona Elimina.
- Elimina il progetto Apps Script:
- Vai alla pagina script.google.com.
- Trova il progetto
Support Quick Portal. - Fai clic sul menu con tre puntini e seleziona Rimuovi.
- Chiudi il progetto Google Cloud:
- Vai alla console Google Cloud.
- Assicurati che il nuovo progetto sia selezionato nel menu a discesa in alto.
- Vai a IAM e amministrazione > Impostazioni e fai clic su Chiudi.
7. Conclusione
Hai creato un ecosistema completo per le estensioni personalizzate di Google Workspace Studio senza fare affidamento su abbonamenti di terze parti esterni.
Argomenti trattati:
- Utilizzo di
workflowTriggerinsieme aonManageFunctionper acquisire e gestire correttamente gli eventi del ciclo di vita di Google. - Autenticazione delle richieste di backend utilizzando
ScriptApp.getOAuthToken()rispetto agli endpoint APIworkspacestudio.googleapis.com. - Utilizzo di
workflowActionper elaborare le variabili di input in modo sincrono e generare output downstream.
Ora puoi fare lo scale out di questi principi per connetterti a piattaforme SaaS reali come Jira, Salesforce o Zendesk modificando la posizione da cui viene attivata l'app web (o il webhook in entrata).