インタラクティブなダイアログを開く

このページでは、Google Chat アプリでダイアログを開いてユーザー インターフェース(UI)を表示し、ユーザーに応答する方法について説明します。

Google Chat では、アドオンは Google Chat アプリとしてユーザーに表示されます。詳細については、Google Chat の拡張機能の概要をご覧ください。

ダイアログは、Chat スペースまたはメッセージから開く、カードベースのウィンドウ インターフェースです。ダイアログとその内容は、開いたユーザーにのみ表示されます。

チャットアプリは、ダイアログを使用して、マルチステップ フォームなど、Chat ユーザーから情報をリクエストして収集できます。フォーム入力の作成の詳細については、ユーザーから情報を収集して処理するをご覧ください。

前提条件

Node.js

Google Chat を拡張する Google Workspace アドオン。ビルドするには、HTTP クイックスタートを完了します。

Apps Script

Google Chat を拡張する Google Workspace アドオン。作成するには、Apps Script のクイックスタートを完了します。

ダイアログを開く

さまざまなウィジェットを備えたダイアログ。
図 1: ダイアログを開いて連絡先情報を収集するチャットアプリ。

このセクションでは、次の手順で応答してダイアログを設定する方法について説明します。

  1. ユーザー操作からダイアログ リクエストをトリガーします。
  2. ダイアログを返して開き、リクエストを処理します。
  3. ユーザーが情報を送信したら、ダイアログを閉じるか、別のダイアログを返して送信を処理します。

ダイアログ リクエストをトリガーする

Chat アプリは、スラッシュ コマンドやカード内のメッセージからのボタンクリックなど、ユーザー操作に応答するためにダイアログを開くことができます。

ダイアログでユーザーに応答するには、Chat アプリでダイアログ リクエストをトリガーするインタラクションを作成する必要があります。次に例を示します。

  • スラッシュ コマンドに返信する。スラッシュ コマンドからリクエストをトリガーするには、コマンドを構成するときに [Opens a dialog] チェックボックスをオンにする必要があります。
  • メッセージ内のボタンクリックに応答します。カードの一部として、またはメッセージの下部に配置します。メッセージ内のボタンからリクエストをトリガーするには、ボタンの interactionOPEN_DIALOG に設定して、ボタンの onClick アクションを構成します。
ダイアログをトリガーするボタン
図 2: Chat アプリが、/addContact スラッシュ コマンドの使用を求めるメッセージを送信しています。
メッセージには、ユーザーがクリックしてコマンドをトリガーできるボタンも含まれています。

次の JSON は、カード メッセージのボタンからダイアログ リクエストをトリガーする方法を示しています。ダイアログを開くには、ボタンのフィールド onClick.action.interactionOPEN_DIALOG に設定します。

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

ここで、BUTTON_TEXT はボタンに表示されるテキストで、ACTION_FUNCTION は初期ダイアログを開くために実行される関数です。

最初のダイアログを開く

ユーザーがダイアログ リクエストをトリガーすると、Chat アプリは、dialogEventType オブジェクトを REQUEST_DIALOG として指定するペイロードを含むイベント オブジェクトを受け取ります。

ダイアログを開くには、Chat アプリがリクエストに応答して、カードを表示するナビゲーション pushCard を含む RenderActions オブジェクトを返します。カードには、1 つ以上の sections[] ウィジェットなど、ユーザー インターフェース(UI)要素を含める必要があります。ユーザーから情報を収集するには、フォーム入力ウィジェットとボタン ウィジェットを指定します。フォーム入力の設計の詳細については、ユーザーから情報を収集して処理するをご覧ください。

次の JSON は、Chat アプリがダイアログを開くレスポンスを返す方法を示しています。

{
  "action": { "navigations": [{ "pushCard": { "sections": [{ "widgets": [{
    WIDGETS,
    { "buttonList": { "buttons": [{
      "text": "BUTTON_TEXT",
      "onClick": {
        "action": { "function": "ACTION_FUNCTION" }
      }
    }]}}
  }]}]}}]}
}

ここで、BUTTON_TEXT はボタンに表示されるテキスト(NextSubmit など)、WIDGETS は 1 つ以上のフォーム入力ウィジェットを表し、ACTION_FUNCTION はユーザーがボタンをクリックしたときに実行されるアクションのコールバック関数です。

ダイアログの送信を処理する

ユーザーがダイアログを送信するボタンをクリックすると、Chat アプリは ButtonClickedPayload オブジェクトを含むイベント オブジェクトを受け取ります。ペイロードでは、dialogEventTypeSUBMIT_DIALOG に設定されます。

Chat アプリは、次のいずれかを行うことでイベント オブジェクトを処理する必要があります。

省略可: 別のダイアログを返す

ユーザーが最初のダイアログを送信すると、Chat アプリは 1 つ以上の追加ダイアログを返すことができます。これにより、ユーザーは送信前に情報を確認したり、複数のステップからなるフォームを完了したり、フォームのコンテンツを動的に入力したりできます。

ユーザーが入力したデータを処理するため、Chat アプリはイベントの commonEventObject.formInputs オブジェクト内のデータに対応します。入力ウィジェットから値を取得する方法については、ユーザーから情報を収集して処理するをご覧ください。

ユーザーが最初のダイアログから入力したデータを追跡するには、次のダイアログを開くボタンにパラメータを追加する必要があります。詳しくは、別のカードにデータを移行するをご覧ください。

この例では、Chat アプリが最初のダイアログを開き、送信前に確認を求める 2 番目のダイアログが表示されます。

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;
  // Handle MESSAGE events
  if(chatEvent.messagePayload) {
    return res.send(handleMessage(req.body));
  // Handle button clicks
  } else if(chatEvent.buttonClickedPayload) {
    switch(req.body.commonEventObject.parameters.actionName) {
        case "openInitialDialog":
            return res.send(openInitialDialog(req.body));
        case "openConfirmationDialog":
            return res.send(openConfirmationDialog(req.body));
        case "submitDialog":
            return res.send(submitDialog(req.body));
    }
  }
};

/**
 * Responds to a message in Google Chat.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} response that handles dialogs.
 */
function handleMessage(event) {
  // Reply with a message that contains a button to open the initial dialog
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "To add a contact, use the `ADD CONTACT` button below.",
    accessoryWidgets: [{ buttonList: { buttons: [{
      text: "ADD CONTACT",
      onClick: { action: {
        // Use runtime environment variable set with self URL
        function: process.env.BASE_URL,
        parameters: [{ key: "actionName", value: "openInitialDialog" }],
        interaction: "OPEN_DIALOG"
      }}
    }]}}]
  }}}}};
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} open the dialog.
 */
function openInitialDialog(event) {
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    textInput: {
      name: "contactName",
      label: "First and last name",
      type: "SINGLE_LINE"
    }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: {
        // Use runtime environment variable set with self URL
        function: process.env.BASE_URL,
        parameters: [{ key: "actionName", value: "openConfirmationDialog" }]
      }}
    }]}}
  ]}]}}]}};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} update the dialog.
 */
function openConfirmationDialog(event) {
  // Retrieve the form input values
  const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    // Display the input values for confirmation
    textParagraph: { text: "<b>Name:</b> " + name }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "SUBMIT",
      onClick: { action: {
        // Use runtime environment variable set with self URL
        function: process.env.BASE_URL,
        parameters: [{
          key: "actionName", value: "submitDialog" }, {
          // Pass input values as parameters for last dialog step (submission)
          key: "contactName", value: name
        }]
      }}
    }]}}]
  }]}}]}};
}

Apps Script

この例では、カード JSON を返すことでカード メッセージを送信します。Apps Script カード サービスを使用することもできます。

/**
 * Responds to a message in Google Chat.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} response that handles dialogs.
 */
function onMessage(event) {
  // Reply with a message that contains a button to open the initial dialog
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "To add a contact, use the `ADD CONTACT` button below.",
    accessoryWidgets: [{ buttonList: { buttons: [{
      text: "ADD CONTACT",
      onClick: { action: {
        function: "openInitialDialog",
        interaction: "OPEN_DIALOG"
      }}
    }]}}]
  }}}}};
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} open the dialog.
 */
function openInitialDialog(event) {
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    textInput: {
      name: "contactName",
      label: "First and last name",
      type: "SINGLE_LINE"
    }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: { function : "openConfirmationDialog" }}
    }]}}
  ]}]}}]}};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} update the dialog.
 */
function openConfirmationDialog(event) {
  // Retrieve the form input values
  const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [{
    // Display the input values for confirmation
    textParagraph: { text: "<b>Name:</b> " + name }},
    WIDGETS, {
    buttonList: { buttons: [{
      text: "SUBMIT",
      onClick: { action: {
        function: "submitDialog",
        // Pass input values as parameters for last dialog step (submission)
        parameters: [{ key: "contactName", value: name }]
      }}
    }]}}]
  }]}}]}};
}

ここで、WIDGETS は他のフォーム入力ウィジェットを表します。

ダイアログを閉じる

ユーザーがダイアログの送信ボタンをクリックすると、Chat アプリは関連するアクションを実行し、buttonClickedPayload が次のように設定されたイベント オブジェクトを返します。

  • isDialogEventtrue である。
  • dialogEventTypeSUBMIT_DIALOG である。

Chat アプリは、EndNavigationCLOSE_DIALOG に設定された RenderActions オブジェクトを返します。

省略可: 通知を表示する

ダイアログを閉じるときにテキスト通知を表示することもできます。

通知を表示するには、フィールド notification が設定された RenderActions オブジェクトを返します。

次の例では、パラメータが有効であることを確認して、結果に応じてテキスト通知でダイアログを閉じます。

Node.js

/**
 * Handles submission and closes the dialog.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} close the dialog with a status in text notification.
 */
function submitDialog(event) {
  // Validate the parameters.
  if (!event.commonEventObject.parameters["contactName"]) {
    return { action: {
      navigations: [{ endNavigation: "CLOSE_DIALOG"}],
      notification: { text: "Failure, the contact name was missing!" }
    }};
  }

  return { action: {
    navigations: [{ endNavigation: "CLOSE_DIALOG"}],
    notification: { text: "Success, the contact was added!" }
  }};
}

Apps Script

/**
 * Handles submission and closes the dialog.
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 * @return {Object} close the dialog with a status in text notification.
 */
function submitDialog(event) {
  // Validate the parameters.
  if (!event.commonEventObject.parameters["contactName"]) {
    return { action: {
      navigations: [{ endNavigation: "CLOSE_DIALOG"}],
      notification: { text: "Failure, the contact name was missing!" }
    }};
  }

  return { action: {
    navigations: [{ endNavigation: "CLOSE_DIALOG"}],
    notification: { text: "Success, the contact was added!" }
  }};
}

ダイアログ間でパラメータを渡す方法については、別のカードにデータを転送するをご覧ください。

省略可: 確認メッセージを送信する

ダイアログを閉じるときに、新しいメッセージを送信したり、既存のメッセージを更新したりすることもできます。

新しいメッセージを送信するには、フィールド CreateMessageAction に新しいメッセージを設定した DataActions オブジェクトを返します。たとえば、ダイアログを閉じてテキスト メッセージを送信するには、次のように返します。

{ "hostAppDataAction": { "chatDataAction": { "createMessageAction": { "message": {
  "text": "Your information has been submitted."
}}}}}

ユーザーがダイアログを送信した後にメッセージを更新するには、次のいずれかのアクションを含む DataActions オブジェクトを返します。

トラブルシューティング

Google Chat アプリまたはカードからエラーが返されると、Chat インターフェースに「エラーが発生しました」というメッセージが表示されます。または「リクエストを処理できません」というメッセージが表示されます。Chat UI にエラー メッセージが表示されない場合でも、Chat アプリまたはカードで予期しない結果が生成されることがあります(カード メッセージが表示されないなど)。

チャット UI にエラー メッセージが表示されない場合でも、チャットアプリのエラー ロギングがオンになっている場合は、エラーの修正に役立つ説明的なエラー メッセージとログデータが利用できます。エラーの表示、デバッグ、修正については、Google Chat エラーのトラブルシューティングと修正をご覧ください。