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

HTTP

Add-on Google Workspace yang memperluas Google Chat. Untuk membuatnya, selesaikan HTTP quickstart.

Apps Script

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

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

    • 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 widget interaktif lainnya yang dapat Anda gunakan untuk mengumpulkan informasi, lihat Mendesain kartu atau dialog interaktif dalam dokumentasi Google Chat API.

Menambahkan menu pilihan multipel

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

Anda dapat mengisi item untuk menu pilihan ganda dari sumber data berikut:

  • Data Google Workspace, yang mencakup pengguna atau ruang Chat tempat pengguna menjadi anggota. Menu hanya mengisi item dari organisasi Google Workspace yang sama.
  • Sumber data eksternal, seperti database relasional. Misalnya, Anda dapat menggunakan menu pilihan ganda 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 menghilangkan objek SelectionItem, karena item pilihan ini bersumber secara dinamis dari Google Workspace.

Kode berikut menampilkan menu multi-pilihan 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 menampilkan menu pilihan ganda ruang Chat. Untuk mengisi ruang, input pilihan menentukan kolom hostAppDataSource. Menu pilihan multipel 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 pilihan ganda 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 pilihan ganda sebelum pengguna mengetik di menu. Misalnya, Anda dapat mengisi kontak yang baru saja ditelusuri untuk pengguna. Untuk mengisi item yang disarankan dari sumber data eksternal, tentukan objek SelectionItem statis.

Kode berikut menunjukkan menu pilihan ganda 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 mengkueri database eksternal. Untuk contoh lengkap yang menunjukkan cara menampilkan item yang disarankan, lihat bagian Menyarankan item multiselect.

Menerima data dari widget interaktif

Setiap kali pengguna mengklik tombol, tindakan aplikasi Chat akan dipicu dengan informasi tentang interaksi tersebut. 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 ini menunjukkan sebagian 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 aplikasi Chat menerima data, aplikasi tersebut dapat melakukan salah satu tindakan berikut:

  • Untuk kartu yang berisi menu pilihan ganda, isi atau sarankan item berdasarkan apa yang diketik pengguna ke dalam menu.
  • Mentransfer data ke kartu lain, sehingga pengguna dapat meninjau informasi mereka atau melanjutkan ke bagian formulir berikutnya.
  • Merespons pengguna untuk mengonfirmasi bahwa pengguna berhasil menyelesaikan formulir.

Menyarankan item pilihan ganda

Jika kartu berisi menu pilihan ganda 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-kota di Amerika Serikat, aplikasi Chat Anda dapat menyarankan otomatis Atlanta sebelum pengguna selesai mengetik. Aplikasi Chat dapat menyarankan hingga 100 item.

Untuk menyarankan dan mengisi item secara dinamis di menu multiselect, widget SelectionInput pada kartu harus menentukan fungsi yang membuat kueri sumber data eksternal. Untuk menampilkan item yang disarankan, fungsi 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 ditampilkan di kolom event.commonEventObject.parameters["autocomplete_widget_query"].
  3. Buat kueri sumber data menggunakan nilai input pengguna untuk mendapatkan satu atau beberapa SelectionItems untuk disarankan kepada pengguna.
  4. Tampilkan item yang disarankan dengan menampilkan tindakan RenderActions dengan objek modifyCard.

Contoh kode berikut menunjukkan cara aplikasi Chat menyarankan item secara dinamis di menu multi-pilihan pada kartu. Saat pengguna mengetik di 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 mengkueri 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 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
  };
}

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

{
  "buttonList": { "buttons": [{
    "text": "Submit",
    "onClick": { "action": {
      "function": "FUNCTION_URL", // Must be an `https` endpoint.
      "parameters": [
        {
          "key": "WIDGET_NAME",
          "value": "USER_INPUT_VALUE"
        },
        // Can specify multiple parameters
      ]
    }}
  }]}
}

Apps Script

{
  "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 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 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 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.