Mengumpulkan dan memproses informasi dari pengguna Google Chat

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

Dialog yang menampilkan berbagai widget.
Gambar 1: Contoh aplikasi Chat 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 memungkinkan 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.
  • Izinkan 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 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.

Java

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.

Membuat formulir menggunakan kartu

Untuk mengumpulkan informasi, aplikasi Chat mendesain formulir dan inputnya, lalu mem-build-nya menjadi 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, yang merupakan 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 untuk membentuk widget input, guna 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 waktu tanggal (dateTimePicker) untuk entri tanggal dan waktu.
  • Widget tombol sehingga pengguna dapat mengirimkan nilai yang telah mereka masukkan di kartu. Setelah pengguna mengklik tombol, aplikasi Chat dapat memproses informasi yang diterimanya.

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

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 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 (diwakili sebagai objek Inputs).

Berikut adalah bagian dari peristiwa interaksi CARD_CLICKED tempat 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"]
    }}}
  }}
}

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 tindakan berikut:

  • Bantu pengguna menyelesaikan 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 memberikan waktu yang tersedia berdasarkan jenis janji temu.

Untuk mentransfer input data dari kartu awal, Anda dapat mem-build 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 atau dialog kartu, aplikasi Chat akan merespons dengan mengonfirmasi penerimaan atau menampilkan error.

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

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.
if (!contactName) {
  const errorMessage = "Don't forget to name your new contact!";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return { actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "INVALID_ARGUMENT",
        userFacingMessage: errorMessage
      }}
    }};
  } else {
    return {
      privateMessageViewer: event.user,
      text: 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.
if contact_name == "":
  error_message = "Don't forget to name your new contact!"
  if "SUBMIT_DIALOG" == event.get('dialogEventType'):
    return { 'actionResponse': {
      'type': "DIALOG",
      'dialogAction': { 'actionStatus': {
        'statusCode': "INVALID_ARGUMENT",
        'userFacingMessage': error_message
      }}
    }}
  else:
    return {
      'privateMessageViewer': event.get('user'),
      'text': 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.
if (contactName.isEmpty()) {
  String errorMessage = "Don't forget to name your new contact!";
  if (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))));
  } else {
    return new Message()
      .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
      .setText(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.
if (!contactName) {
  const errorMessage = "Don't forget to name your new contact!";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return { actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "INVALID_ARGUMENT",
        userFacingMessage: errorMessage
      }}
    }};
  } else {
    return {
      privateMessageViewer: event.user,
      text: errorMessage
    };
  }
}

Untuk memproses dan menutup dialog, tampilkan objek ActionResponse yang menentukan apakah Anda ingin mengirim pesan konfirmasi, mengupdate 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 menyatakan "Terjadi error". atau "Tidak dapat memproses permintaan Anda". Terkadang UI Chat tidak menampilkan pesan error, 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 saat logging error untuk aplikasi Chat diaktifkan. Untuk mendapatkan bantuan dalam melihat, men-debug, dan memperbaiki error, lihat Memecahkan masalah dan memperbaiki error Google Chat.