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.

Di Google Chat, add-on akan muncul kepada pengguna sebagai aplikasi Google Chat. Untuk mempelajari lebih lanjut, lihat Ringkasan memperluas Google Chat.

Dialog yang menampilkan berbagai widget.
Gambar 1: 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:

  • Konfigurasikan 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

Add-on Google Workspace yang berfungsi di Google Chat. Untuk membuatnya, selesaikan panduan memulai HTTP.

Apps Script

Add-on Google Workspace yang berfungsi di Google Chat. Untuk membuatnya, selesaikan panduan memulai Apps Script.

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 chat yang berisi satu atau beberapa kartu.
  • 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 dan menyarankan item dari data Google Workspace (seperti ruang Chat) atau sumber data dinamis. Untuk mengetahui detailnya, lihat bagian berikut Menambahkan menu multipilih.

    • Pemilih tanggal waktu (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 waktu, dan input pilihan:

Untuk contoh widget interaktif lainnya yang dapat Anda gunakan untuk mengumpulkan informasi, lihat Mendesain kartu atau dialog interaktif dalam dokumentasi Google Chat API.

Menambahkan menu multi-pilih

Untuk menyesuaikan item pilihan atau memungkinkan pengguna memilih item dari sumber data dinamis, aplikasi Chat dapat menggunakan menu multi-pilih, yang merupakan jenis widget SelectionInput. Misalnya, kartu berikut menampilkan menu multi-pilih tempat pengguna dapat memilih secara dinamis dari daftar kontak:

Anda dapat mengisi item untuk menu multi-pilih dari sumber data berikut:

  • Data Google Workspace, yang mencakup pengguna atau ruang Chat tempat pengguna tersebut menjadi anggota. Menu ini hanya mengisi item dari organisasi Google Workspace yang sama.
  • Sumber data eksternal, seperti database relasional. Misalnya, Anda dapat menggunakan menu multipilih untuk membantu pengguna memilih dari daftar prospek penjualan dari sistem pengelolaan hubungan pelanggan (CRM).

Mengisi item dari sumber data Google Workspace

Untuk menggunakan sumber data Google Workspace, tentukan kolom platformDataSource di widget SelectionInput. Tidak seperti jenis input pilihan lainnya, Anda menghapus objek SelectionItem, karena item pilihan ini bersumber secara dinamis dari Google Workspace.

Kode berikut menunjukkan menu multi-pilih pengguna Google Workspace. Untuk mengisi pengguna, input pilihan menetapkan commonDataSource ke USER:

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 5,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "commonDataSource": "USER"
    }
  }
}

Kode berikut menunjukkan menu multi-pilih ruang Chat. Untuk mengisi ruang, input pilihan menentukan kolom hostAppDataSource. Menu multi-pilih juga menetapkan defaultToCurrentSpace ke true, yang menjadikan ruang saat ini sebagai pilihan default di menu:

JSON

{
  "selectionInput": {
    "name": "spaces",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "hostAppDataSource": {
        "chatDataSource": {
          "spaceDataSource": {
            "defaultToCurrentSpace": true
          }
        }
      }
    }
  }
}

Mengisi item dari sumber data eksternal

Menu multipilih juga dapat mengisi item dari sumber data pihak ketiga atau eksternal. Untuk menggunakan sumber data eksternal, Anda menentukan kolom externalDataSource di widget SelectionInput yang berisi fungsi yang membuat kueri dan menampilkan item dari sumber data.

Untuk mengurangi permintaan ke sumber data eksternal, Anda dapat menyertakan item yang disarankan yang muncul di menu multipilih sebelum pengguna mengetik menu. Misalnya, Anda dapat mengisi kontak yang baru-baru ini ditelusuri untuk pengguna. Untuk mengisi item yang disarankan dari sumber data eksternal, tentukan objek SelectionItem statis.

Kode berikut menunjukkan menu multi-pilih yang membuat kueri dan mengisi item dari sumber data eksternal:

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "externalDataSource": { "function": "FUNCTION" },
    // Suggested items loaded by default.
    // The list is static here but it could be dynamic.
    "items": [FUNCTION]
  }
}

Ganti FUNCTION dengan URL HTTP atau nama fungsi Apps Script yang membuat kueri database eksternal. Untuk contoh lengkap yang menunjukkan cara menampilkan item yang disarankan, lihat bagian Menyarankan item multi-pilih.

Menerima data dari widget interaktif

Setiap kali pengguna mengklik tombol, tindakan aplikasi Chat-nya akan dipicu dengan informasi tentang interaksi. Dalam commonEventObject payload peristiwa, objek formInputs berisi 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.

Berikut adalah bagian dari objek peristiwa tempat pengguna memasukkan nilai untuk setiap widget:

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

Untuk menerima data, aplikasi Chat Anda menangani objek peristiwa 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 objek peristiwa, dan contoh nilai.

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

Setelah menerima data, aplikasi Chat dapat melakukan salah satu tindakan berikut:

  • Untuk kartu yang berisi menu multipilih, isi atau sarankan item berdasarkan apa yang diketik pengguna ke menu.
  • Transfer data ke kartu lain, sehingga pengguna dapat meninjau informasinya atau melanjutkan ke bagian formulir berikutnya.
  • Respons pengguna untuk mengonfirmasi bahwa pengguna berhasil menyelesaikan formulir.

Menyarankan item multi-pilih

Jika kartu berisi menu multipilih yang mengisi item dari sumber data eksternal, aplikasi Chat dapat menampilkan item yang disarankan berdasarkan apa yang diketik pengguna ke dalam menu. Misalnya, jika pengguna mulai mengetik Atl untuk menu yang mengisi kota di Amerika Serikat, aplikasi Chat Anda dapat menyarankan Atlanta secara otomatis sebelum pengguna selesai mengetik. Aplikasi Chat dapat menyarankan hingga 100 item.

Untuk menyarankan dan mengisi item secara dinamis di menu multipilih, widget SelectionInput di kartu harus menentukan fungsi yang membuat kueri sumber data eksternal. Untuk menampilkan item yang disarankan, fungsi ini harus melakukan hal berikut:

  1. Tangani objek peristiwa, yang diterima aplikasi Chat saat pengguna mengetik di menu.
  2. Dari objek peristiwa, dapatkan nilai yang diketik pengguna, yang diwakili di kolom event.commonEventObject.parameters["autocomplete_widget_query"].
  3. Buat kueri sumber data menggunakan nilai input pengguna untuk mendapatkan satu atau beberapa SelectionItems yang akan disarankan kepada pengguna.
  4. Tampilkan item yang disarankan dengan menampilkan tindakan RenderActions dengan objek modifyCard.

Contoh kode berikut menunjukkan cara aplikasi Chat secara dinamis menyarankan item di menu multi-pilihan pada kartu. Saat pengguna mengetik menu, fungsi atau endpoint yang disediakan di kolom externalDataSource widget akan membuat kueri sumber data eksternal, dan menyarankan item yang dapat dipilih pengguna.

Node.js

/**
 * Google Cloud Function that responds to events sent from a
 * Google Chat space.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.selectionInput = function selectionInput(req, res) {
  if (req.method === 'GET' || !req.body.chat) {
    return res.send('Hello! This function is meant to be used ' +
        'in a Google Chat Space.');
  }
  // Stores the Google Chat event
  const chatEvent = req.body.chat;

  // Handle user interaction with multiselect.
  if(chatEvent.widgetUpdatedPayload) {
    return res.send(queryContacts(req.body));
  }
  // Replies with a card that contains the multiselect menu.
  return res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "FUNCTION_URL" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}});
};

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the event object that contains the user's query
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a selection item in the menu.
 */
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

Ganti FUNCTION_URL dengan endpoint HTTP yang membuat kueri pada sumber data eksternal.

Apps Script

/**
* Responds to a Message trigger in Google Chat.
*
* @param {Object} event the event object from Google Chat
* @return {Object} Response from the Chat app.
*/
function onMessage(event) {
  // Replies with a card that contains the multiselect menu.
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "queryContacts" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact"3")]
        }
      }]}]}
    }]
  }}}}};
}

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the interactive event.
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
* Generate a suggested contact given an ID.
*
* @param {String} id The ID of the contact to return.
* @return {Object} The contact formatted as a selection item in the menu.
*/
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

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

{
  "buttonList": { "buttons": [{
    "text": "Submit",
    "onClick": { "action": {
      "function": "submitForm",
      "parameters": [
        {
          "key": "WIDGET_NAME",
          "value": "USER_INPUT_VALUE"
        },
        // Can specify multiple parameters
      ]
    }}
  }]}
}

Dengan WIDGET_NAME adalah name widget dan USER_INPUT_VALUE adalah input pengguna. Misalnya, untuk input teks yang mengumpulkan nama seseorang, nama widget adalah contactName dan contoh nilainya adalah Kai O.

Saat pengguna mengklik tombol, aplikasi Chat Anda akan menerima objek peristiwa 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 pesan kartu.

Node.js

/**
 * Google Cloud Function that handles all Google Workspace Add On events for
 * the contact manager app.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.contactManager = function contactManager(req, res) {
  const chatEvent = req.body.chat;
  const chatMessage = chatEvent.messagePayload.message;

  // Handle message payloads in the event object
  if(chatEvent.messagePayload) {
    return res.send(handleMessage(chatMessage, chatEvent.user));
  // Handle button clicks on the card
  } else if(chatEvent.buttonClickedPayload) {
    switch(req.body.commonEventObject.parameters.actionName) {
        case "openDialog":
            return res.send(openDialog());
        case "openNextCard":
            return res.send(openNextCard(req.body));
        case "submitForm":
            return res.send(submitForm(req.body));
    }
  }
};

/**
 * Submits information from a dialog or card message.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

Apps Script

/**
 * Sends private text message that confirms submission.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

Untuk memproses dan menutup dialog, Anda menampilkan objek RenderActions 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 Google Chat atau kartu menampilkan error, antarmuka Chat akan menampilkan pesan yang bertuliskan "Terjadi masalah". 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.