תמיכה בתיבות דו-שיח אינטראקטיביות

בדף הזה מוסבר איך אפליקציית Chat יכולה לפתוח תיבות דו-שיח כדי להגיב למשתמשים.

תיבות דו-שיח הן ממשקים מבוססי-כרטיסים שמוצגים בחלון ונפתחים ממרחב או מהודעה ב-Chat. תיבת הדו-שיח והתוכן שלה גלויים רק למשתמש שפתח אותה.

אפליקציות צ'אט יכולות להשתמש בתיבות דו-שיח כדי לבקש ולאסוף מידע ממשתמשי Chat, כולל טפסים מרובי שלבים. פרטים נוספים על יצירת קלט בטופס זמינים במאמר איסוף ועיבוד מידע ממשתמשים.

דרישות מוקדמות

Node.js

אפליקציית Google Chat שמקבלת אירועי אינטראקציה ומגיבה להם. כדי ליצור אפליקציה אינטראקטיבית ל-Chat באמצעות שירות HTTP, צריך לפעול לפי המדריך למתחילים.

Python

אפליקציית Google Chat שמקבלת אירועי אינטראקציה ומגיבה להם. כדי ליצור אפליקציה אינטראקטיבית ל-Chat באמצעות שירות HTTP, צריך לפעול לפי המדריך למתחילים.

Java

אפליקציית Google Chat שמקבלת אירועי אינטראקציה ומגיבה להם. כדי ליצור אפליקציה אינטראקטיבית ל-Chat באמצעות שירות HTTP, צריך לפעול לפי המדריך למתחילים.

Apps Script

אפליקציית Google Chat שמקבלת אירועי אינטראקציה ומגיבה להם. כדי ליצור אפליקציה אינטראקטיבית ל-Chat ב-Apps Script, צריך להשלים את המדריך להתחלה מהירה.

פתיחת תיבת דו-שיח

תיבת דו-שיח עם מגוון ווידג'טים שונים.
איור 1: דוגמה לאפליקציית Chat שפותחת תיבת דו-שיח לאיסוף פרטי איש קשר.

בקטע הזה מוסבר איך להגיב ולנהל דו-שיח באמצעות הפעולות הבאות:

  1. הפעלת בקשת תיבת הדו-שיח מאינטראקציה של משתמש.
  2. מטפלים בבקשה על ידי החזרה ופתיחה של תיבת דו-שיח.
  3. אחרי שהמשתמשים שולחים מידע, מעבדים את השליחה על ידי סגירת תיבת הדו-שיח או הצגת תיבת דו-שיח אחרת.

הפעלת בקשה לתיבת דו-שיח

אפליקציית Chat יכולה לפתוח תיבות דו-שיח רק כדי להגיב לאינטראקציה של משתמש, כמו פקודה או לחיצה על כפתור בהודעה בכרטיס.

כדי להגיב למשתמשים באמצעות תיבת דו-שיח, אפליקציית Chat צריכה ליצור אינטראקציה שמפעילה את בקשת תיבת הדו-שיח, כמו:

  • איך מגיבים לפקודה כדי להפעיל את הבקשה מפקודה, צריך לסמן את התיבה Opens a dialog כשמגדירים את הפקודה.
  • להגיב ללחיצה על לחצן בהודעה, כחלק מכרטיס או בתחתית ההודעה. כדי להפעיל את הבקשה באמצעות לחצן בהודעה, מגדירים את הפעולה של הלחצן onClick על ידי הגדרת interaction שלו ל-OPEN_DIALOG.
  • איך מגיבים ללחיצה על לחצן בדף הבית של אפליקציית Chat מידע על פתיחת תיבות דו-שיח מדפי הבית זמין במאמר יצירת דף בית לאפליקציה שלכם ב-Google Chat.
כפתור שמפעיל תיבת דו-שיח
איור 2: אפליקציה ל-Chat שולחת הודעה שמבקשת מהמשתמשים להשתמש בפקודת הלוכסן /addContact.
ההודעה כוללת גם לחצן שהמשתמשים יכולים ללחוץ עליו כדי להפעיל את הפקודה.

דוגמת הקוד הבאה מראה איך להפעיל בקשה לתיבת דו-שיח מלחצן בהודעת כרטיס. כדי לפתוח את תיבת הדו-שיח, השדה button.interaction מוגדר ל-OPEN_DIALOG:

Node.js

node/contact-form-app/index.js
buttonList: { buttons: [{
  text: "Add Contact",
  onClick: { action: {
    function: "openInitialDialog",
    interaction: "OPEN_DIALOG"
  }}
}]}

Python

python/contact-form-app/main.py
'buttonList': { 'buttons': [{
  'text': "Add Contact",
  'onClick': { 'action': {
    'function': "openInitialDialog",
    'interaction': "OPEN_DIALOG"
  }}
}]}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
.setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
  .setText("Add Contact")
  .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
    .setFunction("openInitialDialog")
    .setInteraction("OPEN_DIALOG"))))))));

Apps Script

בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת JSON של כרטיס. אפשר גם להשתמש בשירות הכרטיסים של Apps Script.

apps-script/contact-form-app/main.gs
buttonList: { buttons: [{
  text: "Add Contact",
  onClick: { action: {
    function: "openInitialDialog",
    interaction: "OPEN_DIALOG"
  }}
}]}

פתיחת תיבת הדו-שיח הראשונית

כשמשתמש מפעיל בקשה לתיבת דו-שיח, אפליקציית Chat מקבלת אירוע אינטראקציה שמיוצג כסוג event ב-Chat API. אם האינטראקציה מפעילה בקשה לתיבת דו-שיח, הערך של השדה dialogEventType באירוע מוגדר כ-REQUEST_DIALOG.

כדי לפתוח תיבת דו-שיח, אפליקציית Chat יכולה להגיב לבקשה על ידי החזרת אובייקט actionResponse עם הערך DIALOG במאפיין type ואובייקט Message. כדי לציין את התוכן של תיבת הדו-שיח, צריך לכלול את האובייקטים הבאים:

  • אובייקט actionResponse, עם type שמוגדר ל-DIALOG.
  • אובייקט dialogAction. השדה body מכיל את רכיבי ממשק המשתמש שיוצגו בכרטיס, כולל ווידג'טים מסוג sections. כדי לאסוף מידע מהמשתמשים, אפשר לציין ווידג'טים של קלט לטופס ו-ווידג'ט של לחצן. מידע נוסף על עיצוב שדות קלט בטפסים זמין במאמר איסוף ועיבוד מידע מהמשתמשים.

בדוגמת הקוד הבאה אפשר לראות איך אפליקציית Chat מחזירה תגובה שפותחת תיבת דו-שיח:

Node.js

node/contact-form-app/index.js
/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

Python

python/contact-form-app/main.py
def open_initial_dialog() -> dict:
  """Opens the initial step of the dialog that lets users add contact details."""
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'dialog': { 'body': { 'sections': [{
      'header': "Add new contact",
      'widgets': CONTACT_FORM_WIDGETS + [{
        'buttonList': { 'buttons': [{
          'text': "Review and submit",
          'onClick': { 'action': { 'function': "openConfirmation" }}
        }]}
      }]
    }]}}}
  }}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// Opens the initial step of the dialog that lets users add contact details.
Message openInitialDialog() {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setDialog(new Dialog().setBody(new GoogleAppsCardV1Card()
      .setSections(List.of(new GoogleAppsCardV1Section()
        .setHeader("Add new contact")
        .setWidgets(Stream.concat(
          CONTACT_FORM_WIDGETS.stream(),
          List.of(new GoogleAppsCardV1Widget()
            .setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
            .setText("Review and submit")
            .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
              .setFunction("openConfirmation"))))))).stream()).collect(Collectors.toList()))))))));
}

Apps Script

בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת JSON של כרטיס. אפשר גם להשתמש בשירות הכרטיסים של Apps Script.

apps-script/contact-form-app/main.gs
/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

טיפול בשליחת תיבת הדו-שיח

כשמשתמשים לוחצים על לחצן ששולח תיבת דו-שיח, אפליקציית הצ'אט שלכם מקבלת אירוע אינטראקציה מסוג CARD_CLICKED, שבו dialogEventType הוא SUBMIT_DIALOG. כדי להבין איך לאסוף ולעבד את המידע בתיבת הדו-שיח, אפשר לעיין במאמר איסוף ועיבוד מידע ממשתמשי Chat.

אפליקציית Chat צריכה להגיב לאירוע האינטראקציה באחת מהדרכים הבאות:

אופציונלי: חזרה לתיבת דו-שיח אחרת

אחרי שהמשתמשים שולחים את תיבת הדו-שיח הראשונית, אפליקציות ל-Chat יכולות להחזיר תיבות דו-שיח נוספות כדי לעזור למשתמשים לבדוק את המידע לפני השליחה, למלא טפסים מרובי שלבים או לאכלס את תוכן הטופס באופן דינמי.

כדי לעבד את הנתונים שהמשתמשים מזינים, אפליקציית Chat משתמשת באובייקט event.common.formInputs. מידע נוסף על אחזור ערכים מווידג'טים של קלט זמין במאמר איסוף ועיבוד מידע ממשתמשים.

כדי לעקוב אחרי נתונים שהמשתמשים מזינים בתיבת הדו-שיח הראשונית, צריך להוסיף פרמטרים לכפתור שפותח את תיבת הדו-שיח הבאה. פרטים נוספים זמינים במאמר העברת נתונים לכרטיס אחר.

בדוגמה הזו, אפליקציית Chat פותחת תיבת דו-שיח ראשונית שמובילה לתיבת דו-שיח שנייה לאישור לפני השליחה:

Node.js

node/contact-form-app/index.js
/**
 * Responds to CARD_CLICKED interaction events in Google Chat.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @return {Object} message responses specific to the dialog handling.
 */
function onCardClick(event) {
  // Initial dialog form page
  if (event.common.invokedFunction === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.common.invokedFunction === "openConfirmation") {
    return openConfirmation(event);
  // Submission dialog form page
  } else if (event.common.invokedFunction === "submitForm") {
    return submitForm(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

/**
 * Returns the second step as a dialog or card message that lets users confirm details.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} returns a dialog or private card message.
 */
function openConfirmation(event) {
  const name = fetchFormValue(event, "contactName") ?? "";
  const birthdate = fetchFormValue(event, "contactBirthdate") ?? "";
  const type = fetchFormValue(event, "contactType") ?? "";
  const cardConfirmation = {
    header: "Your contact",
    widgets: [{
      textParagraph: { text: "Confirm contact information and submit:" }}, {
      textParagraph: { text: "<b>Name:</b> " + name }}, {
      textParagraph: {
        text: "<b>Birthday:</b> " + convertMillisToDateString(birthdate)
      }}, {
      textParagraph: { text: "<b>Type:</b> " + type }}, {
      buttonList: { buttons: [{
        text: "Submit",
        onClick: { action: {
          function: "submitForm",
          parameters: [{
            key: "contactName", value: name }, {
            key: "contactBirthdate", value: birthdate }, {
            key: "contactType", value: type
          }]
        }}
      }]}
    }]
  };

  // Returns a dialog with contact information that the user input.
  if (event.isDialogEvent) {
    return { action_response: {
      type: "DIALOG",
      dialogAction: { dialog: { body: { sections: [ cardConfirmation ]}}}
    }};
  }

  // Updates existing card message with contact information that the user input.
  return {
    actionResponse: { type: "UPDATE_MESSAGE" },
    privateMessageViewer: event.user,
    cardsV2: [{
      card: { sections: [cardConfirmation]}
    }]
  }
}

Python

python/contact-form-app/main.py
def on_card_click(event: dict) -> dict:
  """Responds to CARD_CLICKED interaction events in Google Chat."""
  # Initial dialog form page
  if "openInitialDialog" == event.get('common').get('invokedFunction'):
    return open_initial_dialog()
  # Confirmation dialog form page
  elif "openConfirmation" == event.get('common').get('invokedFunction'):
    return open_confirmation(event)
  # Submission dialog form page
  elif "submitForm" == event.get('common').get('invokedFunction'):
    return submit_form(event)


def open_initial_dialog() -> dict:
  """Opens the initial step of the dialog that lets users add contact details."""
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'dialog': { 'body': { 'sections': [{
      'header': "Add new contact",
      'widgets': CONTACT_FORM_WIDGETS + [{
        'buttonList': { 'buttons': [{
          'text': "Review and submit",
          'onClick': { 'action': { 'function': "openConfirmation" }}
        }]}
      }]
    }]}}}
  }}


def open_confirmation(event: dict) -> dict:
  """Returns the second step as a dialog or card message that lets users confirm details."""
  name = fetch_form_value(event, "contactName") or ""
  birthdate = fetch_form_value(event, "contactBirthdate") or ""
  type = fetch_form_value(event, "contactType") or ""
  card_confirmation = {
    'header': "Your contact",
    'widgets': [{
      'textParagraph': { 'text': "Confirm contact information and submit:" }}, {
      'textParagraph': { 'text': "<b>Name:</b> " + name }}, {
      'textParagraph': {
        'text': "<b>Birthday:</b> " + convert_millis_to_date_string(birthdate)
      }}, {
      'textParagraph': { 'text': "<b>Type:</b> " + type }}, {
      'buttonList': { 'buttons': [{
        'text': "Submit",
        'onClick': { 'action': {
          'function': "submitForm",
          'parameters': [{
            'key': "contactName", 'value': name }, {
            'key': "contactBirthdate", 'value': birthdate }, {
            'key': "contactType", 'value': type
          }]
        }}
      }]}
    }]
  }

  # Returns a dialog with contact information that the user input.
  if event.get('isDialogEvent'): 
    return { 'action_response': {
      'type': "DIALOG",
      'dialogAction': { 'dialog': { 'body': { 'sections': [card_confirmation] }}}
    }}

  # Updates existing card message with contact information that the user input.
  return {
    'actionResponse': { 'type': "UPDATE_MESSAGE" },
    'privateMessageViewer': event.get('user'),
    'cardsV2': [{
      'card': { 'sections': [card_confirmation] }
    }]
  }

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// Responds to CARD_CLICKED interaction events in Google Chat.
Message onCardClick(JsonNode event) {
  String invokedFunction = event.at("/common/invokedFunction").asText();
  // Initial dialog form page
  if ("openInitialDialog".equals(invokedFunction)) {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if ("openConfirmation".equals(invokedFunction)) {
    return openConfirmation(event);
  // Submission dialog form page
  } else if ("submitForm".equals(invokedFunction)) {
    return submitForm(event);
  }
  return null; 
}

// Opens the initial step of the dialog that lets users add contact details.
Message openInitialDialog() {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setDialog(new Dialog().setBody(new GoogleAppsCardV1Card()
      .setSections(List.of(new GoogleAppsCardV1Section()
        .setHeader("Add new contact")
        .setWidgets(Stream.concat(
          CONTACT_FORM_WIDGETS.stream(),
          List.of(new GoogleAppsCardV1Widget()
            .setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
            .setText("Review and submit")
            .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
              .setFunction("openConfirmation"))))))).stream()).collect(Collectors.toList()))))))));
}

// Returns the second step as a dialog or card message that lets users confirm details.
Message openConfirmation(JsonNode event) {
  String name = fetchFormValue(event, "contactName") != null ?
    fetchFormValue(event, "contactName") : "";
  String birthdate = fetchFormValue(event, "contactBirthdate") != null ?
    fetchFormValue(event, "contactBirthdate") : "";
  String type = fetchFormValue(event, "contactType") != null ?
    fetchFormValue(event, "contactType") : "";
  GoogleAppsCardV1Section cardConfirmationSection = new GoogleAppsCardV1Section()
    .setHeader("Your contact")
    .setWidgets(List.of(
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("Confirm contact information and submit:")),
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("<b>Name:</b> " + name)),
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("<b>Birthday:</b> " + convertMillisToDateString(birthdate))),
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("<b>Type:</b> " + type)),
      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))))))))));

  // Returns a dialog with contact information that the user input.
  if (event.at("/isDialogEvent") != null && event.at("/isDialogEvent").asBoolean()) {
    return new Message().setActionResponse(new ActionResponse()
      .setType("DIALOG")
      .setDialogAction(new DialogAction().setDialog(new Dialog().setBody(new GoogleAppsCardV1Card()
        .setSections(List.of(cardConfirmationSection))))));
  }

  // Updates existing card message with contact information that the user input.
  return new Message()
    .setActionResponse(new ActionResponse()
      .setType("UPDATE_MESSAGE"))
    .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
    .setCardsV2(List.of(new CardWithId().setCard(new GoogleAppsCardV1Card()
      .setSections(List.of(cardConfirmationSection)))));
}

Apps Script

בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת JSON של כרטיס. אפשר גם להשתמש בשירות הכרטיסים של Apps Script.

apps-script/contact-form-app/main.gs
/**
 * Responds to CARD_CLICKED interaction events in Google Chat.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @return {Object} message responses specific to the dialog handling.
 */
function onCardClick(event) {
  // Initial dialog form page
  if (event.common.invokedFunction === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.common.invokedFunction === "openConfirmation") {
    return openConfirmation(event);
  // Submission dialog form page
  } else if (event.common.invokedFunction === "submitForm") {
    return submitForm(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

/**
 * Returns the second step as a dialog or card message that lets users confirm details.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} returns a dialog or private card message.
 */
function openConfirmation(event) {
  const name = fetchFormValue(event, "contactName") ?? "";
  const birthdate = fetchFormValue(event, "contactBirthdate") ?? "";
  const type = fetchFormValue(event, "contactType") ?? "";
  const cardConfirmation = {
    header: "Your contact",
    widgets: [{
      textParagraph: { text: "Confirm contact information and submit:" }}, {
      textParagraph: { text: "<b>Name:</b> " + name }}, {
      textParagraph: {
        text: "<b>Birthday:</b> " + convertMillisToDateString(birthdate)
      }}, {
      textParagraph: { text: "<b>Type:</b> " + type }}, {
      buttonList: { buttons: [{
        text: "Submit",
        onClick: { action: {
          function: "submitForm",
          parameters: [{
            key: "contactName", value: name }, {
            key: "contactBirthdate", value: birthdate }, {
            key: "contactType", value: type
          }]
        }}
      }]}
    }]
  };

  // Returns a dialog with contact information that the user input.
  if (event.isDialogEvent) {
    return { action_response: {
      type: "DIALOG",
      dialogAction: { dialog: { body: { sections: [ cardConfirmation ]}}}
    }};
  }

  // Updates existing card message with contact information that the user input.
  return {
    actionResponse: { type: "UPDATE_MESSAGE" },
    privateMessageViewer: event.user,
    cardsV2: [{
      card: { sections: [cardConfirmation]}
    }]
  }
}

סגירה של תיבת הדו-שיח

כשמשתמשים לוחצים על לחצן בתיבת דו-שיח, אפליקציית הצ'אט מבצעת את הפעולה שמשויכת ללחצן ומספקת את אובייקט האירוע עם המידע הבא:

אפליקציית Chat צריכה להחזיר אובייקט ActionResponse עם הערך DIALOG של type, ועם נתונים ב-dialogAction. אם הפעולה לא נכשלה, הערך של dialogAction.actionStatus צריך להיות OK, כמו בדוגמה הבאה:

Node.js

node/contact-form-app/index.js
// The Chat app indicates that it received form data from the dialog or card.
// Sends private text message that confirms submission.
const confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
if (event.dialogEventType === "SUBMIT_DIALOG") {
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "OK",
        userFacingMessage: "Success " + contactName
      }}
    }
  };
}

Python

python/contact-form-app/main.py
# The Chat app indicates that it received form data from the dialog or card.
# Sends private text message that confirms submission.
confirmation_message = "✅ " + contact_name + " has been added to your contacts.";
if "SUBMIT_DIALOG" == event.get('dialogEventType'):
  return {
    'actionResponse': {
      'type': "DIALOG",
      'dialogAction': { 'actionStatus': {
        'statusCode': "OK",
        'userFacingMessage': "Success " + contact_name
      }}
    }
  }

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// The Chat app indicates that it received form data from the dialog or card.
// Sends private text message that confirms submission.
String confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
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("OK")
      .setUserFacingMessage("Success " + contactName))));
}

Apps Script

בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת JSON של כרטיס. אפשר גם להשתמש בשירות הכרטיסים של Apps Script.

apps-script/contact-form-app/main.gs
// The Chat app indicates that it received form data from the dialog or card.
// Sends private text message that confirms submission.
const confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
if (event.dialogEventType === "SUBMIT_DIALOG") {
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "OK",
        userFacingMessage: "Success " + contactName
      }}
    }
  };
}

אופציונלי: הצגת התראה זמנית

כשסוגרים את תיבת הדו-שיח, אפשר גם להציג למשתמש הודעת טקסט זמנית בזמן האינטראקציה עם האפליקציה.

אפליקציית Chat יכולה להגיב בהתראה על הצלחה או על שגיאה על ידי החזרת ActionResponse עם הערך actionStatus.

בדוגמה הבאה נבדק אם הפרמטרים תקפים, ואם הם לא תקפים, תיבת הדו-שיח נסגרת ומוצגת הודעת טקסט:

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

בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת JSON של כרטיס. אפשר גם להשתמש בשירות הכרטיסים של 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
    }}
  }};
}

פרטים על העברת פרמטרים בין תיבות דו-שיח זמינים במאמר העברת נתונים לכרטיס אחר.

אופציונלי: שליחת הודעת אישור ב-Chat

כשסוגרים את תיבת הדו-שיח, אפשר גם לשלוח הודעה חדשה ב-Chat או לעדכן הודעה קיימת.

כדי לשלוח הודעה חדשה, מחזירים אובייקט ActionResponse עם הערך NEW_MESSAGE של המאפיין type. בדוגמה הבאה, תיבת הדו-שיח נסגרת עם הודעת אישור טקסט:

Node.js

node/contact-form-app/index.js
return {
  actionResponse: { type: "NEW_MESSAGE" },
  privateMessageViewer: event.user,
  text: confirmationMessage
};

Python

python/contact-form-app/main.py
return {
  'actionResponse': { 'type': "NEW_MESSAGE" },
  'privateMessageViewer': event.get('user'),
  'text': confirmation_message
}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
return new Message()
  .setActionResponse(new ActionResponse().setType("NEW_MESSAGE"))
  .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
  .setText(confirmationMessage);

Apps Script

בדוגמה הזו נשלחת הודעת כרטיס על ידי החזרת JSON של כרטיס. אפשר גם להשתמש בשירות הכרטיסים של Apps Script.

apps-script/contact-form-app/main.gs
return {
  actionResponse: { type: "NEW_MESSAGE" },
  privateMessageViewer: event.user,
  text: confirmationMessage
};

כדי לעדכן הודעה, מחזירים אובייקט actionResponse שמכיל את ההודעה המעודכנת ומגדירים את type לאחת מהאפשרויות הבאות:

פתרון בעיות

כשמוחזרת שגיאה מאפליקציית Google Chat או מכרטיס, בממשק של Chat מוצגת ההודעה 'משהו השתבש'. או 'לא ניתן לעבד את הבקשה שלך'. לפעמים בממשק המשתמש של Chat לא מוצגת הודעת שגיאה, אבל אפליקציית Chat או הכרטיס מפיקים תוצאה לא צפויה. לדוגמה, יכול להיות שהודעה בכרטיס לא תופיע.

יכול להיות שלא תוצג הודעת שגיאה בממשק המשתמש של Chat, אבל אם הפעלתם את רישום השגיאות באפליקציות של Chat, תוכלו לראות הודעות שגיאה ונתוני יומן שיעזרו לכם לתקן את השגיאות. לקבלת עזרה בצפייה בשגיאות, באיתור באגים ובתיקון שלהן, אפשר לעיין במאמר פתרון בעיות ותיקון שגיאות ב-Google Chat.