Mengumpulkan dan memproses informasi dari pengguna Google Chat

Panduan ini menjelaskan cara aplikasi Google Chat dapat mengumpulkan dan memproses informasi dari pengguna dengan membuat input formulir di antarmuka berbasis kartu.

Dialog yang menampilkan berbagai widget yang berbeda.
Gambar 1: Aplikasi Chat contoh yang membuka dialog untuk mengumpulkan informasi kontak.

Aplikasi Chat meminta informasi dari pengguna untuk melakukan tindakan di dalam atau di luar Chat, termasuk dengan cara berikut:

  • Konfigurasi setelan. Misalnya, untuk mengizinkan pengguna menyesuaikan setelan notifikasi atau mengonfigurasi dan menambahkan aplikasi Chat ke satu atau beberapa ruang.
  • Membuat atau memperbarui informasi di aplikasi Google Workspace lainnya. Misalnya, izinkan pengguna membuat acara Google Kalender.
  • Mengizinkan pengguna mengakses dan memperbarui resource di aplikasi atau layanan web lain. Misalnya, aplikasi Chat dapat membantu pengguna memperbarui status tiket dukungan langsung dari ruang Chat.

Prasyarat

Node.js

Aplikasi Google Chat yang menerima dan merespons peristiwa interaksi. Untuk membuat aplikasi Chat interaktif menggunakan layanan HTTP, selesaikan panduan memulai ini.

Python

Aplikasi Google Chat yang menerima dan merespons peristiwa interaksi. Untuk membuat aplikasi Chat interaktif menggunakan layanan HTTP, selesaikan panduan memulai ini.

Java

Aplikasi Google Chat yang menerima dan merespons peristiwa interaksi. Untuk membuat aplikasi Chat interaktif menggunakan layanan HTTP, selesaikan panduan memulai ini.

Apps Script

Aplikasi Google Chat yang menerima dan merespons peristiwa interaksi. Untuk membuat aplikasi Chat interaktif di Apps Script, selesaikan panduan memulai ini.

Membuat formulir menggunakan kartu

Untuk mengumpulkan informasi, aplikasi Chat mendesain formulir dan inputnya, serta membangunnya ke dalam kartu. Untuk menampilkan kartu kepada pengguna, Aplikasi Chat dapat menggunakan antarmuka Chat berikut:

  • Pesan yang berisi satu atau beberapa kartu.
  • Halaman beranda, yang merupakan kartu yang muncul dari tab Beranda dalam pesan langsung dengan aplikasi Chat.
  • Dialog, yaitu kartu yang terbuka di jendela baru dari pesan dan halaman beranda.

Aplikasi Chat dapat membuat kartu menggunakan widget berikut:

  • Widget input formulir yang meminta informasi dari pengguna. Secara opsional, Anda dapat menambahkan validasi ke widget input formulir, untuk memastikan pengguna memasukkan dan memformat informasi dengan benar. Aplikasi chat dapat menggunakan widget input formulir berikut:

    • Input teks (textInput) untuk teks bebas atau teks yang disarankan.
    • Input pilihan (selectionInput) adalah elemen UI yang dapat dipilih seperti kotak centang, tombol pilihan, dan menu drop-down. Widget input pilihan juga dapat mengisi item dari sumber data statis atau dinamis. Misalnya, pengguna dapat memilih dari daftar ruang Chat tempat mereka menjadi anggota.
    • Pemilih tanggal waktu (dateTimePicker) untuk entri tanggal dan waktu.
  • Widget tombol agar pengguna dapat mengirimkan nilai yang telah mereka masukkan di kartu. Setelah pengguna mengklik tombol, aplikasi Chat kemudian dapat memproses informasi yang diterimanya.

Pada contoh berikut, kartu mengumpulkan informasi kontak menggunakan input teks, pemilih tanggal dan waktu, serta input pilihan:

Untuk contoh aplikasi Chat yang menggunakan formulir kontak ini, lihat kode berikut:

Node.js

node/contact-form-app/index.js
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

Python

python/contact-form-app/main.py
# The section of the contact card that contains the form input widgets. Used in a dialog and card message.
# To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": False
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": False
        }
      ]
    }
  }
]

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// The section of the contact card that contains the form input widgets. Used in a dialog and card message.
// To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
final static private List<GoogleAppsCardV1Widget> CONTACT_FORM_WIDGETS = List.of(
  new GoogleAppsCardV1Widget().setTextInput(new GoogleAppsCardV1TextInput()
    .setName("contactName")
    .setLabel("First and last name")
    .setType("SINGLE_LINE")),
  new GoogleAppsCardV1Widget().setDateTimePicker(new GoogleAppsCardV1DateTimePicker()
    .setName("contactBirthdate")
    .setLabel("Birthdate")
    .setType("DATE_ONLY")),
  new GoogleAppsCardV1Widget().setSelectionInput(new GoogleAppsCardV1SelectionInput()
    .setName("contactType")
    .setLabel("Contact type")
    .setType("RADIO_BUTTON")
    .setItems(List.of(
      new GoogleAppsCardV1SelectionItem()
        .setText("Work")
        .setValue("Work")
        .setSelected(false),
      new GoogleAppsCardV1SelectionItem()
        .setText("Personal")
        .setValue("Personal")
        .setSelected(false)))));

Apps Script

apps-script/contact-form-app/contactForm.gs
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

Untuk contoh widget interaktif lainnya yang dapat Anda gunakan untuk mengumpulkan informasi, lihat Mendesain kartu atau dialog interaktif.

Menerima data dari widget interaktif

Setiap kali pengguna mengklik tombol, aplikasi Chat akan menerima peristiwa interaksi yang bergantung pada lokasi tombol:

  • Jika tombol berada dalam pesan atau dialog, aplikasi Chat akan menerima peristiwa interaksi CARD_CLICKED yang berisi informasi tentang interaksi tersebut. Payload peristiwa interaksi CARD_CLICKED berisi objek common.formInputs dengan nilai apa pun yang dimasukkan pengguna.

    Anda dapat mengambil nilai dari objek common.formInputs.WIDGET_NAME, dengan WIDGET_NAME adalah kolom name yang Anda tentukan untuk widget. Nilai ditampilkan sebagai jenis data tertentu untuk widget (direpresentasikan sebagai objek Inputs).

    Berikut ini menunjukkan sebagian peristiwa interaksi CARD_CLICKED saat pengguna memasukkan nilai untuk setiap widget:

    HTTP

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "stringInputs": {
          "value": ["Kai 0"]
        }},
        "contactBirthdate": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }},
        "contactType": { "stringInputs": {
          "value": ["Personal"]
        }}
      }}
    }
    

    Apps Script

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    
  • Jika tombol ada di halaman beranda, aplikasi Chat menerima peristiwa interaksi SUBMIT_FORM. Payload peristiwa interaksi berisi objek commonEventObject.formInputs dengan nilai apa pun yang dimasukkan pengguna.

    Anda dapat mengambil nilai dari objek commonEventObject.formInputs.WIDGET_NAME, dengan WIDGET_NAME adalah kolom name yang Anda tentukan untuk widget. Nilai ditampilkan sebagai jenis data tertentu untuk widget (direpresentasikan sebagai objek Inputs).

    Berikut ini menunjukkan sebagian peristiwa interaksi SUBMIT_FORM saat pengguna memasukkan nilai untuk setiap widget:

    HTTP

    {
      "type": "SUBMIT_FORM",
      "commonEventObject": { "formInputs": {
        "contactName": { "stringInputs": {
          "value": ["Kai 0"]
        }},
        "contactBirthdate": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }},
        "contactType": { "stringInputs": {
          "value": ["Personal"]
        }}
      }}
    }
    

    Apps Script

    {
      "type": "SUBMIT_FORM",
      "commonEventObject": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    

Untuk menerima data, aplikasi Chat Anda menangani peristiwa interaksi untuk mendapatkan nilai yang dimasukkan pengguna ke dalam widget. Tabel berikut menunjukkan cara mendapatkan nilai untuk widget input formulir tertentu. Untuk setiap widget, tabel menampilkan jenis data yang diterima widget, tempat nilai disimpan dalam peristiwa interaksi, dan contoh nilai.

Widget input formulir Jenis data input Nilai input dari peristiwa interaksi Nilai contoh
textInput stringInputs event.common.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs Untuk mendapatkan nilai pertama atau satu-satunya, event.common.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker yang hanya menerima tanggal. dateInput event.common.formInputs.contactBirthdate.dateInput.msSinceEpoch. 1000425600000

Mentransfer data ke kartu lain

Setelah pengguna mengirimkan informasi dari kartu, Anda mungkin perlu menampilkan kartu tambahan untuk melakukan salah satu hal berikut:

  • Bantu pengguna mengisi formulir yang lebih panjang dengan membuat bagian yang berbeda.
  • Izinkan pengguna melihat pratinjau dan mengonfirmasi informasi dari kartu awal, sehingga mereka dapat meninjau jawaban sebelum mengirimkannya.
  • Isi bagian formulir yang tersisa secara dinamis. Misalnya, untuk meminta pengguna membuat janji temu, aplikasi Chat dapat menampilkan kartu awal yang meminta alasan janji temu, lalu mengisi kartu lain yang menyediakan waktu yang tersedia berdasarkan jenis janji temu.

Untuk mentransfer input data dari kartu awal, Anda dapat membuat widget button dengan actionParameters yang berisi name widget dan nilai yang dimasukkan pengguna, seperti yang ditunjukkan dalam contoh berikut:

Node.js

node/contact-form-app/index.js
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

Python

python/contact-form-app/main.py
'buttonList': { 'buttons': [{
  'text': "Submit",
  'onClick': { 'action': {
    'function': "submitForm",
    'parameters': [{
      'key': "contactName", 'value': name }, {
      'key': "contactBirthdate", 'value': birthdate }, {
      'key': "contactType", 'value': type
    }]
  }}
}]}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
  .setText("Submit")
  .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
    .setFunction("submitForm")
    .setParameters(List.of(
      new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
      new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
      new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))));

Apps Script

apps-script/contact-form-app/main.gs
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

Saat pengguna mengklik tombol, aplikasi Chat Anda akan menerima peristiwa interaksi CARD_CLICKED yang dapat Anda gunakan untuk menerima data.

Merespons pengiriman formulir

Setelah menerima data dari pesan kartu atau dialog, aplikasi Chat akan merespons dengan mengonfirmasi penerimaan atau menampilkan error.

Dalam contoh berikut, aplikasi Chat mengirim pesan teks untuk mengonfirmasi bahwa aplikasi tersebut telah berhasil menerima formulir yang dikirim dari pesan kartu atau dialog.

Node.js

node/contact-form-app/index.js
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

Python

python/contact-form-app/main.py
contact_name = event.get('common').get('parameters')["contactName"]
# Checks to make sure the user entered a contact name.
# If no name value detected, returns an error message.
error_message = "Don't forget to name your new contact!"
if contact_name == "" and "SUBMIT_DIALOG" == event.get('dialogEventType'):
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'actionStatus': {
      'statusCode': "INVALID_ARGUMENT",
      'userFacingMessage': error_message
    }}
  }}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
String contactName = event.at("/common/parameters/contactName").asText();
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
String errorMessage = "Don't forget to name your new contact!";
if (contactName.isEmpty() && event.at("/dialogEventType") != null && "SUBMIT_DIALOG".equals(event.at("/dialogEventType").asText())) {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setActionStatus(new ActionStatus()
      .setStatusCode("INVALID_ARGUMENT")
      .setUserFacingMessage(errorMessage))));
}

Apps Script

apps-script/contact-form-app/main.gs
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

Untuk memproses dan menutup dialog, Anda menampilkan objek ActionResponse yang menentukan apakah Anda ingin mengirim pesan konfirmasi, memperbarui pesan atau kartu asli, atau hanya menutup dialog. Untuk mengetahui langkah-langkahnya, lihat Menutup dialog.

Memecahkan masalah

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

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