In questa pagina viene spiegato come configurare i comandi slash per l'app Google Chat.
Un comando slash è un modo comune con cui gli utenti richiamano e interagiscono con un'app di Chat. I comandi slash consentono inoltre agli utenti di scoprire e utilizzare le funzionalità chiave di un'app di Chat.
Per utilizzare un comando slash, gli utenti digitano una barra (/
) seguito da un breve comando di testo,
come /about
per ottenere informazioni sull'app Chat.
Gli utenti possono scoprire i comandi slash disponibili digitando una barra in
Google Chat, che mostra una finestra che elenca i comandi disponibili per
l'app Chat:

Per decidere se configurare i comandi slash e per capire come progettare le interazioni degli utenti, consulta i principi di progettazione di Google Chat.
Prerequisiti
Node.js
- Un account Google Workspace con accesso a Google Chat.
- Un'app di chat. Per creare un'app di chat, segui questa quickstart.
Apps Script
- Un account Google Workspace con accesso a Google Chat.
- Un'app di chat. Per creare un'app di chat, segui questa quickstart.
Python
- Un account Google Workspace con accesso a Google Chat.
- Un'app di chat. Per creare un'app di chat, segui questa quickstart.
Configura un comando slash
Per impostare un comando slash, completa i seguenti passaggi:
- Crea un nome per il comando slash.
- Configura il comando slash nell'API Google Chat.
- Crea una risposta per il comando slash, ad esempio un messaggio di testo o scheda.
Questa sezione illustra i passaggi per impostare un comando slash.
Assegna un nome al comando slash
Il nome di un comando slash è il nome che gli utenti digitano in un messaggio di Chat per richiamare l'app Chat. Una breve descrizione viene visualizzata anche sotto il nome, per suggerire agli utenti ulteriori informazioni su come utilizzare il comando:

Quando scegli un nome e una descrizione per il comando slash, prendi in considerazione i seguenti suggerimenti:
Per assegnare un nome al comando slash:
- Utilizza parole o frasi brevi, descrittive e strategiche per rendere i comandi chiari e semplici per l'utente. Ad esempio, anziché dire
/createAReminder
, usa/remindMe
. - Se il comando contiene più di una parola, aiuta gli utenti a leggerlo utilizzando tutto il minuscolo per la prima parola e poi mettendo in maiuscolo la prima lettera delle parole aggiuntive. Ad esempio, anziché
/updatecontact
, utilizza/updateContact
. - Valuta se utilizzare un nome univoco o comune per il comando. Se il tuo comando descrive un'interazione o una funzionalità tipica, puoi utilizzare un nome comune che gli utenti riconoscono e si aspettano, come
/settings
o/feedback
. In caso contrario, prova a utilizzare nomi di comando univoci perché, se il nome del comando è lo stesso per altre app di chat, l'utente deve filtrare i comandi simili per trovare e utilizzare il tuo.
- Utilizza parole o frasi brevi, descrittive e strategiche per rendere i comandi chiari e semplici per l'utente. Ad esempio, anziché dire
Per descrivere il comando slash:
- Mantieni la descrizione breve e chiara in modo che gli utenti sappiano cosa aspettarsi quando richiamano il comando.
- Comunica agli utenti se sono previsti requisiti di formattazione per il comando.
Ad esempio, se crei un comando
/remindMe
che richiede testo di argomento, imposta la descrizione su un valore comeRemind me to do [something] at [time]
.
Configurare il comando slash nell'API Google Chat
Per creare un comando slash, devi specificare le informazioni sul comando nella configurazione dell'app Chat per l'API Google Chat.
Per configurare un comando slash nell'API Google Chat, completa i seguenti passaggi:
Nella console Google Cloud, fai clic su Menu > API e servizi > API e servizi abilitati > API Google Chat
Fai clic su Configurazione.
In Comandi slash, fai clic su Aggiungi un comando slash.
Inserisci un nome, l'ID comando e una descrizione per il comando:
- Nome: il nome visualizzato del comando e il testo digitato dagli utenti per richiamare la tua app. Deve iniziare con una barra, contenere solo testo e avere una lunghezza massima di 50 caratteri.
- Descrizione: il testo che descrive come utilizzare e formattare il comando. Le descrizioni possono contenere fino a 50 caratteri.
- ID comando: un numero da 1 a 1000 utilizzato dall'app Chat per riconoscere il comando slash e restituire una risposta.
(Facoltativo) Se vuoi che l'app Chat risponda al comando con una finestra di dialogo, seleziona la casella di controllo Apri una finestra di dialogo.
Fai clic su Salva.
Il comando slash è ora configurato per l'app Chat.
Rispondere a un comando slash
Quando gli utenti creano un messaggio di Chat che contiene un comando slash,
l'app Chat riceve un evento di interazione MESSAGE
.
Il payload dell'evento contiene informazioni sul comando slash,
inclusi i campi slashCommand
e slashCommandMetadata
. Puoi utilizzare questi campi per identificare l'ID comando e restituire una risposta personalizzata.
L'esempio seguente mostra il payload JSON per un evento di interazione MESSAGE
che include il comando slash /vote
:
{
...
"message": {
...
"text": "/vote yes",
"argumentText": " yes",
"slashCommand": {
"commandId": 2
},
"annotations": [
{
"length": 5,
"startIndex": 0,
"type": "SLASH_COMMAND",
"slashCommand": {
"commandName":"/vote",
"commandId":1,
"type": "INVOKE",
"bot": {
"avatarUrl": "https://www.example.com/images/vote-app-icon.png",
"displayName": "Voter Chat App",
"name": "users/1234567890987654321",
"type": "BOT"
}
}
}
]
}
}
Per rispondere a un comando slash, puoi rilevare se il campo slashCommand
è presente nel payload degli eventi e, in questo caso, restituire una risposta al comando.
Il seguente esempio di codice mostra come rispondere a un evento di interazione MESSAGE
contenente un comando slash:
Node.js
/**
* Responds to a MESSAGE event in Google Chat.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} function in response to a slash command.
*/
exports.onMessage = function onMessage(req, res) {
// Stores the Google Chat event as a variable.
var event = req.body;
// Checks for the presence of event.message.slashCommand.
if (event.message.slashCommand) {
switch (event.message.slashCommand.commandId) {
case ID: // The ID for your slash command
res.runFunction; // The response to the slash command.
}
}
Apps Script
/**
* Responds to a MESSAGE event in Google Chat.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} function in response to a slash command.
*/
function onMessage(event) {
// Checks for the presence of event.message.slashCommand
if (event.message.slashCommand) {
switch (event.message.slashCommand.commandId) {
case ID: // The ID for your slash command
return runFunction; // The response to the slash command.
}
}
}
Python
from typing import Any, Mapping
import flask
import functions_framework
@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
"""Responds to a MESSAGE event in Google Chat that includes a slash command.
Args:
req (flask.Request): the event object from Chat API.
Returns:
Mapping[str, Any]: function in response to a slash command.
"""
if req.method == 'GET':
return 'Sorry, this function must be called from a Google Chat.'
request = req.get_json(silent=True)
if slash_command := request.get('message', dict()).get('slashCommand'):
command_id = slash_command['commandId']
if command_id == ID:
return runFunction
Per utilizzare il codice, sostituisci quanto segue:
ID
: l'ID comando specificato quando configuri il comando slash nell'API Google Chat.runFunction
: una funzione che crea una risposta al comando slash.
Esempio completo: configurare i contatti utilizzando l'app Rolodex Chat
L'esempio seguente mostra un'app di chat che risponde ai seguenti comandi slash:
- Il comando
/help
restituisce un messaggio che spiega come ricevere assistenza con l'app Chat. L'ID comando è impostato su1
. - Il comando
/createContact
apre una finestra di dialogo in cui gli utenti possono inserire i dettagli di un contatto. L'ID comando è impostato su2
.
Prima di eseguire questo esempio, segui i passaggi per configurare i comandi slash nell'API Google Chat.
Node.js
/**
* Responds to messages that have links whose URLs
* match URL patterns configured for link previews.
*
* @param {Object} event The event object from Chat
* API.
*
* @return {Object} Response from the Chat app
* attached to the message with the previewed link.
*/
exports.onMessage = function onMessage(req, res) {
// Store the Google Chat event as a variable.
const event = req.body;
if (req.method === "GET" || !event.message) {
res.send("Hello! This function is meant to be used in a Google Chat " +
"Space.");
}
// Checks for the presence of event.message.slashCommand.
// If the slash command is "/help", responds with a text message.
// If the slash command is "/createContact", opens a dialog.
if (event.message.slashCommand) {
switch (event.message.slashCommand.commandId) {
case 1: // /help
res.json({"text": "Contact bot helps you update your address book!"});
case 2: // /createContact
res.openDialog(event);
}
}
// If the Chat app doesn"t detect a slash command, it responds
// with a card that prompts the user to add a contact
else {
res.json({
"cardsV2": [{
"cardId": "addContact",
"card": {
"header": {
"title": "Rolodex",
"subtitle": "Manage your contacts!",
"imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
"imageType": "CIRCLE"
},
"sections": [
{
"widgets": [
{
"buttonList": {
"buttons": [
{
"text": "Add Contact",
"onClick": {
"action": {
"function": "openDialog",
"interaction": "OPEN_DIALOG"
}
}
}
]
}
}
]
}
]
}
}]
});
}
// Respond to button clicks on attached cards
if (event.type === "CARD_CLICKED") {
if (event.common.invokedFunction === "openDialog") {
res.openDialog(event);
}
if (event.common.invokedFunction === "openSequentialDialog") {
res.openSequentialDialog(event);
}
if (event.common.invokedFunction === "confirmDialogSuccess") {
res.confirmDialogSuccess(event);
}
}
};
/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
res.json({
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Name",
"type": "SINGLE_LINE",
"name": "name"
}
},
{
"textInput": {
"label": "Address",
"type": "MULTIPLE_LINE",
"name": "address"
}
},
{
"decoratedText": {
"text": "Add to favorites",
"switchControl": {
"controlType": "SWITCH",
"name": "saveFavorite"
}
}
},
{
"decoratedText": {
"text": "Merge with existing contacts",
"switchControl": {
"controlType": "SWITCH",
"name": "mergeContact",
"selected": true
}
}
},
{
"buttonList": {
"buttons": [
{
"text": "Next",
"onClick": {
"action": {
"function": "openSequentialDialog"
}
}
}
]
}
}
]
}
]
}
}
}
}
});
};
/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openSequentialDialog(event) {
res.json({
"action_response": {
"type": "DIALOG",
"dialog_action": {
"dialog": {
"body": {
"sections": [
{
"header": "Add new contact",
"widgets": [
{
"textInput": {
"label": "Notes",
"type": "MULTIPLE_LINE",
"name": "notes"
}
},
{
"selectionInput": {
"type": "RADIO_BUTTON",
"label": "Contact type",
"name": "contactType",
"items": [
{
"text": "Work",
"value": "Work",
"selected": false
},
{
"text": "Personal",
"value": "Personal",
"selected": false
}
]
}
},
{
"buttonList": {
"buttons": [
{
"text": "Submit",
"onClick": {
"action": {
"function": "confirmDialogSuccess",
"parameters": [
{
"key": "confirmDialogSuccess",
"value": "confirmDialogSuccess"
}
]
}
}
}
]
},
"horizontalAlignment": "END"
}
]
}
]
}
}
}
}
});
}
/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function receiveDialog(event) {
// Checks to make sure the user entered a name
// in a dialog. If no name value detected, returns
// an error message.
if (event.common.formInputs.contactName.stringInputs.value[0] === "") {
return {
"actionResponse": {
"type": "DIALOG",
"dialogAction": {
"actionStatus": {
"statusCode": "OK",
"userFacingMessage": "Don't forget to name your new contact!"
}
}
}
};
// Otherwise the app indicates that it received
// form data from the dialog. Any value other than "OK"
// gets returned as an error. "OK" is interpreted as
// code 200, and the dialog closes.
} else {
res.json({
"actionResponse": {
"type": "DIALOG",
"dialogAction": {
"actionStatus": "OK"
}
}
});
}
}
Apps Script
Python
from typing import Any, Mapping
import flask
import functions_framework
@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
"""Responds to a MESSAGE event in Google Chat that includes the /createContact
slash command by opening a dialog.
Args:
req (flask.Request): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
if req.method == 'GET':
return 'Sorry, this function must be called from a Google Chat.'
request = req.get_json(silent=True)
if request.get('type') == 'CARD_CLICKED':
invoked_function = request.get('common', dict()).get('invokedFunction')
if invoked_function == 'open_dialog':
return open_dialog(request)
elif invoked_function == 'open_sequential_dialog':
return open_dialog(request)
elif invoked_function == "receive_dialog":
return receive_dialog(request)
else:
return {
'cardsV2': [{
'cardId': 'addContact',
'card': {
'header': {
'title': 'Rolodex',
'subtitle': 'Manage your contacts!',
'imageUrl': 'https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png',
'imageType': 'CIRCLE'
},
'sections': [
{
'widgets': [
{
'buttonList': {
'buttons': [
{
'text': 'Add Contact',
'onClick': {
'action': {
'function': 'open_dialog',
'interaction': 'OPEN_DIALOG'
}
}
}
]
}
}
]
}
]
}
}]
}
def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
"""Opens a dialog in Google Chat.
Args:
request (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
return {
'action_response': {
'type': 'DIALOG',
'dialog_action': {
'dialog': {
'body': {
'sections': [
{
'header': 'Add new contact',
'widgets': [
{
'textInput': {
'label': 'Name',
'type': 'SINGLE_LINE',
'name': 'name'
}
},
{
'textInput': {
'label': 'Address',
'type': 'MULTIPLE_LINE',
'name': 'address'
}
},
{
'decoratedText': {
'text': 'Add to favorites',
'switchControl': {
'controlType': 'SWITCH',
'name': 'saveFavorite'
}
}
},
{
'decoratedText': {
'text': 'Merge with existing contacts',
'switchControl': {
'controlType': 'SWITCH',
'name': 'mergeContact',
'selected': True
}
}
},
{
'buttonList': {
'buttons': [
{
'text': 'Next',
'onClick': {
'action': {
'function': 'open_sequential_dialog'
}
}
}
]
}
}
]
}
]
}
}
}
}
}
def open_sequential_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
"""Opens a second dialog that lets users add more contact details.
Args:
request (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: open a Dialog in response to a card's button click.
"""
return {
'action_response': {
'type': 'DIALOG',
'dialog_action': {
'dialog': {
'body': {
'sections': [
{
'header': 'Add new contact',
'widgets': [
{
'textInput': {
'label': 'Notes',
'type': 'MULTIPLE_LINE',
'name': 'notes'
}
},
{
'selectionInput': {
'type': 'RADIO_BUTTON',
'label': 'Contact type',
'name': 'contactType',
'items': [
{
'text': 'Work',
'value': 'Work',
'selected': False
},
{
'text': 'Personal',
'value': 'Personal',
'selected': False
}
]
}
},
{
'buttonList': {
'buttons': [
{
'text': 'Submit',
'onClick': {
'action': {
'function': 'receive_dialog',
'parameters': [
{
'key': 'receiveDialog',
'value': 'receiveDialog'
}
]
}
}
}
]
},
'horizontalAlignment': 'END'
}
]
}
]
}
}
}
}
}
def receive_dialog(event: Mapping[str, Any]) -> Mapping[str, Any]:
"""Checks for a form input error, the absence of a "name" value, and returns
an error if absent. Otherwise, confirms successful receipt of a dialog.
Args:
event (Mapping[str, Any]): the event object from Chat API.
Returns:
Mapping[str, Any]: the response.
"""
if event.get('common', dict()) \
.get('formInputs', dict()).get('contactName', dict()) \
.get('stringInputs').get('value', list()):
return {
'actionResponse': {
'type': 'DIALOG',
'dialogAction': {
'actionStatus': 'OK'
}
}
}
else:
return {
'actionResponse': {
'type': 'DIALOG',
'dialogAction': {
'actionStatus': "Don't forget to name your new contact!"
}
}
}