Interaktive Dialogfelder öffnen

In diesem Leitfaden wird beschrieben, wie Sie Dialogfelder für Ihre Chat-App implementieren.

Dialogfelder sind kartenbasierte Fenster im Fenstermodus, die Chat-Apps öffnen, um mit Nutzern zu interagieren. Apps können sequenzielle Dialogfelder öffnen, um Nutzern dabei zu helfen, mehrstufige Prozesse auszuführen.

Dialogfelder sind für viele Arten von Nutzerinteraktionen hilfreich, darunter:

  • Informationen von Nutzern erfassen
  • Nutzer mit Webdiensten authentifizieren
  • Einstellungen der Chat App konfigurieren

Vorbereitung

Node.js

Apps Script

Python

So funktionieren Dialogfelder

Wenn ein Nutzer auf einer Karte auf eine Schaltfläche klickt oder einen Slash-Befehl ausgibt, kann die Chat-App ein Dialogfeld öffnen, um mit dem Nutzer zu interagieren.

Klicken Sie auf einer Karte auf eine Schaltfläche, um ein Dialogfeld zu öffnen.
Abbildung 1: Klick auf eine Schaltfläche auf einer Karte, um ein Dialogfeld zu öffnen
Klicken Sie auf einer Karte auf eine Schaltfläche, um ein Dialogfeld zu öffnen.
Abbildung 2: Slash-Befehl zum Öffnen eines Dialogfelds ausführen

Das Dialogfeld erleichtert die Nutzerinteraktion, da Nutzer Informationen über Widgets eingeben können, z. B. Texteingabefelder. Wenn Sie viele Informationen von Nutzern erfassen, können Chat-Apps sequenzielle Dialogfelder öffnen.

Ein Dialogfeld mit einer Vielzahl verschiedener Widgets.
Abbildung 3: Ein offenes Dialogfeld, in dem der Nutzer aufgefordert wird, einen Kontakt hinzuzufügen.
Ein Dialogfeld mit einer Vielzahl verschiedener Widgets.
Abbildung 4: Ein zweites Dialogfeld fordert den Nutzer auf, weitere Informationen zu erhalten.

Wenn Sie fertig sind, empfängt die Chat-App die Werte, die Nutzer im Dialogfeld als JSON eingegeben haben. Mit einer SMS oder einer Karte kannst du Nutzern mitteilen, dass ihre Interaktion erfolgreich war.

Dialogfeld öffnen

Ihre Chat-App kann als Reaktion auf einen Nutzer ein Dialogfeld öffnen:

Wenn ein Nutzer ein Dialogfeld anfordert, erhält Ihre Chat-App ein Google Chat-Event, in dem:

  • isDialogEvent liegt bei true.
  • DialogEventType gibt an, ob ein Nutzer ein Dialogfeld öffnet (REQUEST_DIALOG), auf eine Schaltfläche in einem Dialogfeld (SUBMIT_DIALOG) klickt oder ein Dialogfeld beendet (CANCEL_DIALOG).

Wenn ein Nutzer beispielsweise ein Dialogfeld öffnet, erhält Ihre Chat-App einen Event von Google Chat:

JSON

{
  "type": enum (EventType),
  "eventTime": string,
  "threadKey": string,
  "message": {
    object (Message)
  },
  "user": {
    object (User)
  },
  "space": {
    object (Space)
  },
  "action": {
    object (FormAction)
  },
  "configCompleteRedirectUrl": string,
  "isDialogEvent": true,
  "dialogEventType": "REQUEST_DIALOG",
  "common": {
    object (CommonEventObject)
  }
}

Ihre Chat-App kann ein Dialogfeld öffnen, indem ein ActionResponse von "type": "DIALOG" mit einem DialogAction zurückgegeben wird, das eine JSON-Beschreibung des Dialogfelds enthält:

JSON

{
  "action_response": {
    "type": "DIALOG",
    "dialog_action": {
      "dialog": {
        "body": {
          "sections": [
            {
              "header": "Add new contact",
              "widgets": [
                {
                  "textInput": {
                    "label": "Name",
                    "type": "SINGLE_LINE",
                    "name": "contactName"
                  }
                },
                {
                  "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"
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      }
    }
  }
}

Ein Dialogfeld öffnen, das durch Klicken auf eine Schaltfläche auf einer Karte geöffnet wird

Wenn ein Nutzer auf eine Schaltfläche auf einer Karte klickt, erhält Ihre App ein Event, wobei Folgendes gilt:

Geben Sie Folgendes an, um ein Dialogfeld zu öffnen:

In diesem Beispiel antwortet eine Chat-App auf eine MESSAGE Event mit einer Karte mit einer Schaltfläche, die ein Dialogfeld öffnet:

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.
  var event = req.body;

  if (req.method === "GET" || !event.message) {
    res.send("Hello! This function is meant to be used in a Google Chat " +
      "Space.");
  }

  // 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);
};

/**
 * Opens and starts a dialog that allows users to 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"
                              }
                            }
                          }
                        ]
                      }
                    }
                  ]
                }
              ]
            }
          }
        }
    }
  });
};

Apps Script

/**
 * Responds to a MESSAGE event in Google Chat with a card with a button
 * that opens a dialog.
 *
 * @param {Object} event the event object from Chat API.
 *
 * @return {object} open a Dialog in response to a card's button click.
 */
function onMessage(event) {
  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": "openDialog",
                          "interaction": "OPEN_DIALOG"
                        }
                      }
                    }
                  ]
                },
                "horizontalAlignment": "CENTER"
              }
            ]
          }
        ]
      }
    }]
  };
}

/**
 * Responds to a CARD_CLICKED event in Google Chat.
 *
 * @param {Object} event the event object from Google Chat
 */
function onCardClick(event) {
  if (event.common.invokedFunction == "openDialog") {
    return openDialog(event);
  }
}

/**
 * Opens a dialog in Google Chat.
 *
 * @param {Object} event the event object from Chat API.
 *
 * @return {object} open a Dialog in Google Chat.
 */
function openDialog(event) {
  return {
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Name",
                      "type": "SINGLE_LINE",
                      "name": "contactName"
                    }
                  },
                  {
                    "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"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  };
}

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':
    if request.get('common', dict()).get('invokedFunction') == 'open_dialog':
      return open_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'
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }

Dialogfeld als Antwort auf einen Slash-Befehl öffnen

Wenn ein Nutzer ein Dialogfeld mit einem Slash-Befehl öffnet, erhält Ihre Anwendung eine Event. Dabei gilt Folgendes:

Zum Öffnen eines Dialogfelds antworten Sie mit:

In diesem Beispiel reagiert eine Chat-App auf den Slash-Befehl /createContact durch Öffnen eines Dialogfelds:

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.
  var 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);
    }
  }
};

/**
 * Opens and starts a dialog that allows users to 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"
                              }
                            }
                          }
                        ]
                      }
                    }
                  ]
                }
              ]
            }
          }
        }
    }
  });
};

Apps Script

/**
 * Responds to a MESSAGE event in Google Chat that includes the /createContact
 * slash command by opening a dialog.
 *
 * @param {Object} event the event object from Chat API.
 *
 * @return {object} open a Dialog in response to a slash command.
 */
function onMessage(event) {

  // 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
        return {"text": "Contact bot helps you update your address book!"}
      case 2:  // /createContact
        return openDialog(event);
    }
  }
}

/**
 * Opens a dialog in Google Chat.
 *
 * @param {Object} event the event object from Chat API.
 *
 * @return {object} open a Dialog in Google Chat.
 */
function openDialog(event) {
  return {
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Name",
                      "type": "SINGLE_LINE",
                      "name": "contactName"
                    }
                  },
                  {
                    "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"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  };
}

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 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 == 1:
      return {'text': 'Contact bot helps you update your address book!'}

    elif command_id == 2:
      return open_dialog(request)

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 slash command.
  """
  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'
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }

Mehrere Kartenschnittstellen aneinanderreihen

Wenn Nutzerinteraktionen mehr als eine Karte erfordern, können Sie eine neue Karte über dasselbe Dialogfeld öffnen, indem Sie ein weiteres Dialogfeld zurückgeben.

Wenn Nutzer auf eine Schaltfläche in einem Dialogfeld klicken, erhält Ihre Anwendung eine Event, wobei Folgendes gilt:

Da ein Dialogfeld bereits geöffnet ist, geben Sie nicht onClick.action.interaction an, wie beim Öffnen eines Dialogfelds über eine Karte mit Unterhaltungsthreads. Geben Sie stattdessen nur onClick.action.function als Namen einer Funktion zurück, die ein Dialogfeld öffnet.

In diesem Beispiel reagiert eine Chat-App auf eine CARD_CLICKED Event über einen Klick auf eine Schaltfläche, indem ein weiteres Dialogfeld geöffnet wird:

Node.js

// Respond to button clicks on attached cards
if(event.type === "CARD_CLICKED") {

  // Open the first dialog.
  if (event.common.invokedFunction == "openDialog") {
    res.openDialog(event);
  }

  // Open the second dialog.
  if (event.common.invokedFunction == "openSequentialDialog") {
    res.openSequentialDialog(event);
  }
}

/**
* Opens and starts a dialog that allows users to 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 allows users to 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"
                  }
                ]
              }
            ]
          }
        }
      }
  }
});

Apps Script

/**
 * Responds to a CARD_CLICKED event in Google Chat.
 *
 * @param {Object} event the event object from Google Chat
 */
function onCardClick(event) {

  // When a user clicks a card, the app checks to see which function to run.
  if (event.common.invokedFunction == "openDialog") {
    return openDialog(event);
  }

  if (event.common.invokedFunction == "openSequentialDialog") {
    return openSequentialDialog(event);
  }
}

/**
 * Opens and starts a dialog that allows users to add details about a contact.
 *
 * @param {object} event the event object from Google Chat.
 *
 * @return {object} open a dialog.
 */
function openDialog(event) {
  return {
    "action_response": {
        "type": "DIALOG",
        "dialog_action": {
          "dialog": {
            "body": {
              "sections": [
                {
                  "header": "Add new contact",
                  "widgets": [
                    {
                      "textInput": {
                        "label": "Name",
                        "type": "SINGLE_LINE",
                        "name": "contactName"
                      }
                    },
                    {
                      "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": {

                                // Specifies which function to run
                                // in response to the card click.
                                "function": "openSequentialDialog"
                              }
                            }
                          }
                        ]
                      }
                    }
                  ]
                }
              ]
            }
          }
        }
    }
  };
}

/**
 * Opens a second dialog that allows users to add more contact details.
 *
 * @param {object} event the event object from Google Chat.
 *
 * @return {object} open a dialog.
 */
function openSequentialDialog(event) {
  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": {

                                // Specifies which function to run
                                // in response to the card click.
                                "function": "receiveDialog",
                                "parameters": [
                                  {
                                    "key": "receiveDialog",
                                    "value": "receiveDialog"
                                  }
                                ]
                              }
                            }
                          }
                        ]
                      },
                      "horizontalAlignment": "END"
                    }
                  ]
                }
              ]
            }
          }
        }
    }
  };
}

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':
    if 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)

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 allows users to 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': 'receiveDialog',
                              'parameters': [
                                {
                                  'key': 'receiveDialog',
                                  'value': 'receiveDialog'
                                }
                              ]
                            }
                          }
                        }
                      ]
                    },
                    'horizontalAlignment': 'END'
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }

Formulardaten aus Dialogfeldern erhalten

Wenn Nutzer auf eine Schaltfläche in einem Dialogfeld klicken, werden die von ihnen eingegebenen Daten an die Chat-App gesendet und die Anwendung erhält eine Event. Dabei gilt Folgendes:

Die Daten, die Nutzer im Dialogfeld eingeben, sind in der Event als Event.common.formInputs verfügbar. Bei dieser Zuordnung handelt es sich bei den Schlüsseln um String-IDs, die jedem Dialogfeld-Widget zugewiesen sind. Die Werte stellen die Nutzereingaben für jedes Widget dar. Verschiedene Objekte stehen für unterschiedliche Eingabedatentypen. Event.common.formInputs.stringInputs stellt beispielsweise Stringeingaben dar.

Wenn ein Nutzer ein Dialogfeld sendet, empfängt Ihre Chat-App eine Event von Google Chat:

JSON

{
  "type": enum (EventType),
  "eventTime": string,
  "threadKey": string,
  "message": {
    object (Message)
  },
  "user": {
    object (User)
  },
  "space": {
    object (Space)
  },
  "action": {
    object (FormAction)
  },
  "configCompleteRedirectUrl": string,

  // Indicates that this event is dialog-related.
  "isDialogEvent": true,

  // Indicates that a user clicked a button, and all data
  // they entered in the dialog is included in Event.common.formInputs.
  "dialogEventType": "SUBMIT_DIALOG",
  "common": {
    "userLocale": string,
    "hostApp": enum (HostApp),
    "platform": enum (Platform),
    "timeZone": {
      object (TimeZone)
    },

    // Represents user data entered in a dialog
    "formInputs": {

      // Represents string data entered in a dialog, like text input fields
      // and check boxes
      "stringInputs": {

        // An array of strings entered by the user in a dialog.
        "value": [
          string
        ]
      }
    },
    "parameters": {
      string: string,
      ...
    },
    "invokedFunction": string
  }
}

Deine App kann auf den ersten vom Nutzer eingegebenen Wert unter event.common.formInputs.NAME.stringInputs.value[0] zugreifen, wobei NAME das Feld name eines TextInput-Widgets ist.

Nachdem Sie die Daten des Dialogfeldformulars erhalten haben, sollte die Chat-App entweder eine Empfangsbestätigung, eine SMS oder eine Karte oder eine Fehlermeldung zurückgeben. All dies geschieht mithilfe einer ActionResponse:

  • Wenn Sie den Erhalt bestätigen möchten, antworten Sie mit einer ActionResponse, die "actionStatus": "OK" enthält.
  • Um mit einer SMS oder einer Karte zu antworten, antworte mit einer ActionResponse mit einer ResponseType von NEW_MESSAGE, UPDATE_MESSAGE oder UPDATE_USER_MESSAGE_CARDS. Weitere Informationen
  • Um einen Fehler zurückzugeben, antworten Sie mit einer ActionResponse, die "actionStatus": "ERROR MESSAGE" enthält.

Im folgenden Beispiel wird geprüft, ob ein „name“-Wert vorhanden ist. Wenn sie nicht vorhanden ist, gibt die App einen Fehler zurück. Falls vorhanden, wird in der App der Empfang der Formulardaten bestätigt und das Dialogfeld geschlossen.

Node.js

/**
 * 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.WIDGET_NAME.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

/**
 * 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.WIDGET_NAME[""].stringInputs.value[0]) {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "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 {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    };
  }
}

Python

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 common := event.get('common'):
    if form_inputs := common.get('formInputs'):
      if contact_name := form_inputs.get('WIDGET_NAME'):
        if string_inputs := contact_name.get('stringInputs'):
          if name := string_inputs.get('value')[0]:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'OK'
                }
              }
            }
          else:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'Don\'t forget to name your new contact!'
                }
              }
            }

Auf Dialog reagieren

Sie können auf ein Dialogfeld mit einer neuen Nachricht oder einer Aktualisierung einer vorhandenen Nachricht antworten.

Auf Dialog mit einer neuen Nachricht antworten

Wenn Sie auf ein Dialogfeld mit einer neuen Nachricht antworten möchten, gibt die Chat-App ein ActionResponse vom Typ NEW_MESSAGE sowie Markups zurück, die den Inhalt der neuen Nachricht angeben. Nach Erhalt dieser Antwort wird das Dialogfeld geschlossen und die neue Nachricht gepostet.

Der folgende Code ist ein Beispiel für eine JSON-Antwort auf ein Dialogfeld, das von einer Chat-App zum Erstellen einer neuen Antwortnachricht gesendet wird:

JSON

{
  "actionResponse": "NEW_MESSAGE",
  "text": "This message is a reply to a dialog form submission.",
  "cardsV2": [
    {
      "cardId" : "reply-card-id",
      "card" : {
        "header": {
          "title": "Reply card title"
        },
        "sections": [
          {
            "widgets" : [
              {
                "textParagraph": {
                  "text": "Reply card message"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Die Chat App kann auch asynchron mit einer einfachen SMS oder einer Karte antworten. Dazu müssen Sie sich mit einem Dienstkonto authentifizieren und dann eine asynchrone Antwort senden. Dazu rufen Sie spaces.messages.create über die Google Chat API auf.

Auf ein Dialogfeld mit einer Nachrichtenaktualisierung reagieren

Wenn Sie auf ein Dialogfeld mit einer aktualisierten Nachricht antworten, können Sie eine vorhandene App-Nachricht oder eine Linkvorschau aktualisieren.

App-Nachrichten

Wenn Sie auf ein Dialogfeld mit einer Aktualisierung einer vorhandenen Nachricht antworten, die von der Chat App gesendet wurde, wird ein ActionResponse vom Typ UPDATE_MESSAGE zurückgegeben. Die Antwort enthält Markup für den Inhalt der aktualisierten Nachricht. Nach Erhalt dieser Antwort wird das Dialogfeld geschlossen und die Nachricht mit dem neuen Inhalt aktualisiert.

Der folgende Code ist ein Beispiel für eine JSON-Antwort auf ein Dialogfeld, das von einer Chat-App zum Aktualisieren einer vorhandenen App-Nachricht gesendet wird:

JSON

{
  "actionResponse": "UPDATE_MESSAGE",
  "text": "This message has been updated with new content in response to a dialog form submission.",
  "cardsV2": [
    {
      "cardId" : "updated-card-id",
      "card" : {
        "header": {
          "title": "Updated card title"
        },
        "sections": [
          {
            "widgets" : [
              {
                "textParagraph": {
                  "text": "Updated card message"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Die Chat-App kann auch asynchron eine Anwendungsnachricht aktualisieren, indem Sie die Google Chat API verwenden.

Zum Aktualisieren von Linkvorschauen mit neuen Inhalten als Reaktion auf eingereichte Formulare im Dialogfeld gibt die Chat-App einen ActionResponse vom Typ UPDATE_USER_MESSAGE_CARDS zurück. Die Antwort enthält Markup für die neuen Karten, mit denen die Linkvorschau aktualisiert wird. Nach Erhalt dieser Antwort wird das Dialogfeld geschlossen und die Linkvorschau mit den neuen Karten aktualisiert.

Der folgende Code ist ein Beispiel für eine JSON-Antwort auf ein Dialogfeld, das von einer Chat-App gesendet wird. Es wird verwendet, um eine Linkvorschau mit einer neuen Karte zu aktualisieren:

JSON

{
  "actionResponse": "UPDATE_USER_MESSAGE_CARDS",
  "cardsV2": [
    {
      "cardId" : "updated-card-id",
      "card" : {
        "header": {
          "title": "Updated card title"
        },
        "sections": [
          {
            "widgets" : [
              {
                "textParagraph": {
                  "text": "Updated card message"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Vollständiges Beispiel: Rolodex, der Kontakt, der die Chat-App verwaltet

In diesem Beispiel öffnet eine Chat-App ein Dialogfeld, in dem der Nutzer Details zu einem Kontakt wie Name, E-Mail-Adresse und Adresse hinzufügen kann:

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.
  var 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 allows users to 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 allows users to 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

/**
 * Responds to a MESSAGE event in Google Chat.
 *
 * @param {Object} event the event object from Chat API.
 *
 * @return {object} open a Dialog in response to a slash command
 * or a card"s button click.
 */
function onMessage(event) {

  // 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
        return {"text": "Contact bot helps you update your address book!"}
      case 2:  // /createContact
        return 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 {
    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": "openDialog",
                            "interaction": "OPEN_DIALOG"
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      }]

    };
  }
}

/**
 * Responds to a CARD_CLICKED event in Google Chat.
 *
 * @param {Object} event the event object from Google Chat
 */
function onCardClick(event) {

  if (event.common.invokedFunction == "openDialog") {
    return openDialog(event);
  }

  if (event.common.invokedFunction == "openSequentialDialog") {
    return openSequentialDialog(event);
  }

  if (event.common.invokedFunction == "receiveDialog") {
    return receiveDialog(event);
  }
}

/**
 * Opens and starts a dialog that allows users to add details about a contact.
 *
 *
 * @return {object} open a dialog.
 */
function openDialog(event) {
  return {
    "action_response": {
        "type": "DIALOG",
        "dialog_action": {
          "dialog": {
            "body": {
              "sections": [
                {
                  "header": "Add new contact",
                  "widgets": [
                    {
                      "textInput": {
                        "label": "Name",
                        "type": "SINGLE_LINE",
                        "name": "contactName"
                      }
                    },
                    {
                      "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 allows users to add more contact details.
 *
 * @param {object} event the event object from Google Chat.
 *
 * @return {object} open a dialog.
 */
function openSequentialDialog(event) {
  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": "receiveDialog",
                                "parameters": [
                                  {
                                    "key": "receiveDialog",
                                    "value": "receiveDialog"
                                  }
                                ]
                              }
                            }
                          }
                        ]
                      },
                      "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": "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 {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    };
  }
}

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 allows users to 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!"
        }
      }
    }

Limits und Überlegungen

Beachten Sie die folgenden Beschränkungen und Hinweise:

  • Karten Version 1, die eingestellt wurden, werden von Dialogfeldern nicht mehr unterstützt. Verwende stattdessen cards v2.
  • Servergenerierte Vorschläge für die automatische Vervollständigung werden nicht unterstützt, Vorschläge, die mit der Dialogfeldantwort zurückgegeben werden.
  • onChangeAction: Ein Attribut einiger Karten-Widgets wie SwitchControl, das ein Action angibt, das ausgeführt werden soll, wenn das Widget geändert wird, z. B. ein Schalter umschalten.

Dialogfelder zur Fehlerbehebung

Wenn Sie Dialogfelder implementieren, müssen Sie möglicherweise Ihre Chat-App debuggen, indem Sie die Logs der App lesen. Rufen Sie zum Lesen der Logs den Log-Explorer in der Google Cloud Console auf.