Membuka dialog interaktif

Halaman ini menjelaskan cara aplikasi Chat Anda dapat membuka dialog untuk menanggapi pengguna.

Dialog adalah antarmuka berbasis kartu dan berjendela yang akan terbuka dari ruang atau pesan Chat. Dialog dan konten hanya dapat dilihat oleh pengguna yang membukanya.

Aplikasi Chat dapat menggunakan dialog untuk meminta dan mengumpulkan informasi dari Pengguna chat, termasuk formulir multi-langkah. Untuk detail selengkapnya saat membuat input formulir, lihat Mengumpulkan dan memproses informasi dari pengguna.

Prasyarat

Node.js

  • Aplikasi Google Chat yang diaktifkan untuk fitur interaktif. Untuk membuat aplikasi Chat interaktif menggunakan layanan HTTP, selesaikan panduan memulai ini.

Python

  • Aplikasi Google Chat yang diaktifkan untuk fitur interaktif. Untuk membuat aplikasi Chat interaktif menggunakan layanan HTTP, selesaikan panduan memulai ini.

Apps Script

  • Aplikasi Google Chat yang diaktifkan untuk fitur interaktif. Untuk membuat aplikasi Chat interaktif di Apps Script, selesaikan panduan memulai ini.

Membuka dialog

Dialog yang menampilkan berbagai widget yang berbeda.
Gambar 1: Dialog yang mengumpulkan informasi kontak.

Bagian ini menjelaskan cara merespons dan menyiapkan dialog dengan melakukan hal berikut:

  1. Memicu permintaan dialog dari interaksi pengguna.
  2. Tangani permintaan dengan menampilkan dan membuka dialog.
  3. Setelah pengguna mengirimkan informasi, proses pengiriman dengan menutup dialog atau menampilkan dialog lain.

Memicu permintaan dialog

Aplikasi Chat hanya dapat membuka dialog untuk merespons pengguna interaksi pengguna, seperti perintah garis miring atau klik tombol dari pesan di kartu.

Untuk merespons pengguna dengan dialog, aplikasi Chat harus membangun interaksi yang memicu permintaan dialog, seperti berikut ini:

  • Respons perintah garis miring. Untuk memicu permintaan dari perintah garis miring, Anda harus mencentang kotak Opens a dialog saat mengonfigurasi perintah.
  • Merespons klik tombol dalam pesan, sebagai bagian dari kartu atau di bagian bawah pesan. Untuk memicu permintaan dari tombol dalam pesan, Anda mengonfigurasi onClick tombol tindakan tersebut dengan menetapkan interaction-nya ke OPEN_DIALOG.
  • Merespons klik tombol di halaman beranda aplikasi Chat. Untuk mempelajari cara membuka dialog dari halaman beranda, lihat Membuat halaman beranda untuk aplikasi Google Chat.
Tombol yang memicu dialog
Gambar 2: Aplikasi Chat mengirim pesan yang meminta pengguna untuk menggunakan perintah garis miring /addContact.
Pesan ini juga menyertakan tombol yang dapat diklik pengguna untuk memicu perintah.

JSON berikut menunjukkan cara memicu permintaan dialog dari tombol dalam pesan kartu. Untuk membuka dialog, button.interaction kolom disetel ke OPEN_DIALOG:

{
  "buttonList": { "buttons": [{
    "text": "BUTTON_TEXT",
    "onClick": { "action": {
      "function": "FUNCTION_NAME",
      "interaction": "OPEN_DIALOG"
    }}
  }]}
}

Dengan BUTTON_TEXT adalah teks yang ditampilkan di tombol dan FUNCTION_NAME adalah fungsi yang berjalan untuk membuka dialog.

Membuka dialog awal

Saat pengguna memicu permintaan dialog, aplikasi Chat Anda menerima peristiwa interaksi, yang direpresentasikan sebagai event ketik API Chat. Jika interaksi itu memicu permintaan dialog, metode Kolom dialogEventType disetel ke REQUEST_DIALOG.

Untuk membuka dialog, aplikasi Chat Anda dapat merespons permintaan dengan mengembalikan actionResponse dengan type disetel ke DIALOG dan Message . Untuk menetapkan konten dialog, Anda harus menyertakan hal-hal berikut objek:

  • actionResponse dengan type ditetapkan ke DIALOG.
  • dialogAction . Kolom body berisi elemen antarmuka pengguna (UI) untuk ditampilkan di kartu, termasuk satu atau beberapa sections widget. Untuk mengumpulkan informasi dari pengguna, Anda dapat menentukan widget input formulir dan widget tombol. Untuk mempelajari lebih lanjut cara mendesain input formulir, lihat Kumpulkan dan proses informasi dari pengguna.

JSON berikut menunjukkan cara aplikasi Chat menampilkan respons yang membuka dialog:

{ "actionResponse": {
  "type": "DIALOG",
  "dialogAction": { "dialog": { "body": { "sections": [{
    "widgets": [{
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "BUTTON_TEXT",
        "onClick": {
          "action": {"function": "FUNCTION_NAME"}
        }
      }]}}
    }]
  }]}}}
}}

Dengan BUTTON_TEXT adalah teks yang ditampilkan di tombol (seperti Next atau Submit), WIDGETS mewakili satu atau beberapa widget input formulir, dan FUNCTION_NAME adalah fungsi yang berjalan saat pengguna mengklik tombol.

Menangani pengiriman dialog

Saat pengguna mengeklik tombol yang mengirimkan dialog, Aplikasi Chat menerima interaksi CARD_CLICKED peristiwa di mana dialogEventType adalah SUBMIT_DIALOG.

Aplikasi Chat Anda harus menangani peristiwa interaksi dengan melakukan salah satu hal berikut:

  • Tampilkan dialog lain untuk mengisi kartu lain atau formulir.
  • Tutup dialog setelah memvalidasi data yang dikirimkan pengguna, dan (opsional), kirim pesan konfirmasi.

Opsional: Menampilkan dialog lain

Setelah pengguna mengirimkan dialog awal, aplikasi Chat dapat menampilkan satu atau beberapa dialog tambahan untuk membantu pengguna meninjau informasi sebelum mengirimkan formulir, mengisi formulir multi-langkah, atau mengisi konten formulir secara dinamis.

Untuk memuat data apa pun yang dimasukkan pengguna dari dialog awal, Anda harus menambahkan parameter ke tombol yang membuka dialog berikutnya, atau meneruskan Peristiwa interaksi CARD_CLICKED dari dialog awal. Untuk mengetahui detailnya, lihat Mentransfer data ke kartu lain.

Dalam contoh ini, aplikasi Chat membuka dialog yang menampilkan dialog kedua sebelum mengirimkan. Untuk memuat data input, metode Aplikasi Chat meneruskan peristiwa interaksi CARD_CLICKED sebagai parameter untuk fungsi yang membuka dialog berikutnya:

Node.js

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

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

  // Open the second dialog.
  if (event.common.invokedFunction === "openNextDialog") {
    openNextDialog(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({ "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "openNextDialog"
        }}
      }]}}
    ]}]}}}
  }});
};

/**
* 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 openNextDialog(event) {
  res.json({ "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submitDialog"
          }}
        }]}
      }
    ]}]}}}
  }});
}

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_next_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 { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "open_next_dialog"
        }}
      }]}}
    ]}]}}}
  }}

def open_next_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 { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submit_dialog"
          }}
        }]}
      }
    ]}]}}}
  }}

Apps Script

Contoh ini mengirimkan pesan kartu dengan mengembalikan JSON kartu. Anda juga dapat menggunakan Layanan kartu 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 Chat app checks to see which function to run.
  if (event.common.invokedFunction === "openDialog") {
    return openDialog(event);
  }

  if (event.common.invokedFunction === "openNextDialog") {
    return openNextDialog(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) {
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "openNextDialog"
        }}
      }]}}
    ]}]}}}
  }};
}

/**
* 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 openNextDialog(event) {
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submitDialog"
          }}
        }]}
      }
    ]}]}}}
  }};
}

Dengan WIDGETS mewakili satu atau beberapa widget input formulir.

Tutup dialog

Saat pengguna mengeklik tombol pada dialog, Aplikasi Chat menerima peristiwa interaksi dengan informasi berikut:

Bagian berikut menjelaskan cara memvalidasi data yang dimasukkan pengguna dan menutup dialog.

Validasi data input pengguna dan tutup dialog

Untuk memproses data yang dimasukkan pengguna, aplikasi Chat menggunakan event.common.formInputs . Untuk mempelajari lebih lanjut cara mengambil nilai dari widget input, lihat Kumpulkan dan proses informasi dari pengguna.

Jika pengguna menghilangkan kolom wajib diisi, atau memasukkan nilai yang salah, Aplikasi Chat dapat merespons dengan error dengan menampilkan ActionResponse yang memiliki "actionStatus": "ERROR MESSAGE".

Contoh berikut memeriksa apakah pengguna memasukkan nilai untuk widget yang menerima string (stringInputs), seperti widget textInput. Jika tidak ada, Aplikasi Chat menampilkan error. Jika ada, aplikasi Chat mengonfirmasi pengiriman dialog dan menutup dialog:

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 submitDialog(event) {

  // Checks to make sure the user entered a value
  // in a dialog. If no value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.WIDGET_NAME.stringInputs.value[0] === "") {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "ERROR_MESSAGE"
        }
      }
    });

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    res.json({
      "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': 'ERROR_MESSAGE'
                }
              }
            }

Apps Script

Contoh ini mengirimkan pesan kartu dengan mengembalikan JSON kartu. Anda juga dapat menggunakan Layanan kartu 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 submitDialog(event) {

  // Checks to make sure the user entered a value
  // in a dialog. If no value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.WIDGET_NAME[""].stringInputs.value[0] === "") {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "ERROR_MESSAGE"
        }
      }
    };

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    };
  }
}

Dalam contoh ini, WIDGET_NAME mewakili kolom name dari kolom (seperti contactName) dan ERROR_MESSAGE mewakili isi pesan error (seperti Don't forget to name your contact). Untuk mengetahui detail tentang cara memproses data input dari widget, lihat Menerima data dari widget interaktif.

Opsional: Mengirim pesan konfirmasi

Saat menutup dialog, Anda juga dapat mengirimkan pesan baru, atau memperbarui yang sudah ada.

Untuk mengirim pesan baru, tampilkan ActionResponse dengan type ditetapkan ke NEW_MESSAGE. Misalnya, untuk menutup dialog lalu kirim SMS, tampilkan respons berikut:

  {
    "actionResponse": {
      "type": "NEW_MESSAGE",
    },
    "text": "Your information has been submitted."
  }

Untuk memperbarui pesan, tampilkan objek actionResponse yang berisi pesan yang diperbarui dan menyetel type ke salah satu dari berikut:

Memecahkan masalah

Saat aplikasi Google Chat atau kartu menampilkan error, Antarmuka Chat menampilkan pesan yang bertuliskan "Terjadi masalah". atau "Tidak dapat memproses permintaan Anda". Terkadang UI Chat tidak menampilkan pesan error apa pun, tetapi aplikasi Chat atau memberikan hasil yang tidak diharapkan; misalnya, pesan kartu mungkin tidak akan muncul.

Meskipun pesan error mungkin tidak ditampilkan di UI Chat, pesan error deskriptif dan data log tersedia untuk membantu Anda memperbaiki error saat logging error untuk aplikasi Chat diaktifkan. Untuk bantuan melihat, men-debug, dan memperbaiki error, melihat Memecahkan masalah dan memperbaiki error Google Chat.