เปิดและตอบกล่องโต้ตอบ

หน้านี้อธิบายวิธีเปิดแอป Chat และ ตอบสนองต่อกล่องโต้ตอบ

กล่องโต้ตอบเป็นอินเทอร์เฟซที่ทำงานบนการ์ดในโหมดหน้าต่าง ซึ่ง แอปแชทจะเปิดขึ้นเพื่อโต้ตอบกับผู้ใช้ เพื่อช่วยให้ผู้ใช้ดำเนินการ ซึ่งหลายขั้นตอน แอป Chat จะเปิดตามลำดับได้ กล่องโต้ตอบ

กล่องโต้ตอบมีประโยชน์สำหรับการโต้ตอบของผู้ใช้ประเภทต่อไปนี้

  • การรวบรวมข้อมูลจากผู้ใช้
  • การตรวจสอบสิทธิ์ผู้ใช้ด้วยบริการเว็บ
  • การกําหนดการตั้งค่าแอปใน Chat

การเปิด ส่ง หรือยกเลิกกล่องโต้ตอบต้องใช้การตอบกลับแบบพร้อมกัน จากแอป Chat ที่มี DialogEventType แอป Chat ไม่รองรับกล่องโต้ตอบ สร้างขึ้นด้วยสถาปัตยกรรมแบบอะซิงโครนัส เช่น Pub/Sub หรือ create ข้อความ หากแอป Chat ใช้แบบไม่พร้อมกัน สถาปัตยกรรม ให้ใช้ ข้อความในการ์ด แทนกล่องโต้ตอบ

ข้อกำหนดเบื้องต้น

Node.js

แอป Google Chat ที่เปิดใช้ฟีเจอร์แบบอินเทอร์แอกทีฟ วิธีสร้าง แอป Chat แบบอินเทอร์แอกทีฟที่ใช้บริการ HTTP ให้ทำการเริ่มต้นอย่างรวดเร็วนี้ให้เสร็จสมบูรณ์

Apps Script

แอป Google Chat ที่เปิดใช้ฟีเจอร์แบบอินเทอร์แอกทีฟ วิธีสร้าง แอป Chat แบบอินเทอร์แอกทีฟใน Apps Script โปรดกรอกข้อมูลในการเริ่มต้นอย่างรวดเร็วนี้

Python

แอป Google Chat ที่เปิดใช้ฟีเจอร์แบบอินเทอร์แอกทีฟ วิธีสร้าง แอป Chat แบบอินเทอร์แอกทีฟที่ใช้บริการ HTTP ให้ทำการเริ่มต้นอย่างรวดเร็วนี้ให้เสร็จสมบูรณ์

เปิดกล่องโต้ตอบ

แอป Chat สามารถเปิดกล่องโต้ตอบเพื่อตอบผู้ใช้ได้ คลิกปุ่ม ใน ข้อความในการ์ด

คลิกปุ่มบนการ์ดเพื่อเปิดกล่องโต้ตอบ
ภาพที่ 1: การคลิกปุ่มบนการ์ดเพื่อเปิดกล่องโต้ตอบ

แอป Chat สามารถเปิดกล่องโต้ตอบเพื่อตอบผู้ใช้ได้ การออก คำสั่งเครื่องหมายทับ

คลิกปุ่มบนการ์ดเพื่อเปิดกล่องโต้ตอบ
รูปที่ 2: การใช้คำสั่งเครื่องหมายทับเพื่อเปิดกล่องโต้ตอบ

เมื่อผู้ใช้เปิดกล่องโต้ตอบ แอป Chat ของคุณจะได้รับ CANNOT TRANSLATE เหตุการณ์การโต้ตอบต่อไปนี้ ข้อมูล:

  • isDialogEvent คือtrue
  • DialogEventType ระบุ ผู้ใช้ดำเนินการอย่างใดอย่างหนึ่งต่อไปนี้

    • REQUEST_DIALOG: เปิดกล่องโต้ตอบ
    • SUBMIT_DIALOG: คลิกปุ่มในกล่องโต้ตอบ
    • CANCEL_DIALOG: ยกเลิกกล่องโต้ตอบ

เช่น เมื่อผู้ใช้เปิดกล่องโต้ตอบ แอป Chat ของคุณ ได้รับเหตุการณ์การโต้ตอบที่คล้ายกับตัวอย่างต่อไปนี้

JSON

{
  "type": enum (EventType),
  "eventTime": string,
  "threadKey": string,
  "message": {
    object (Message)
  },
  "user": {
    object (User)
  },
  "space": {
    object (Space)
  },
  "action": {
    object (FormAction)
  },
  "configCompleteRedirectUrl": string,
  "isDialogEvent": true,
  "dialogEventType": "REQUEST_DIALOG",
  "common": {
    object (CommonEventObject)
  }
}

แอป Chat จะเปิดกล่องโต้ตอบได้โดยการส่งคืน ActionResponse ของ "type": "DIALOG" ที่มี DialogAction ที่มีคำอธิบาย JSON ของกล่องโต้ตอบ:

JSON

{
  "action_response": {
    "type": "DIALOG",
    "dialog_action": {
      "dialog": {
        "body": {
          "sections": [
            {
              "header": "Add new contact",
              "widgets": [
                {
                  "textInput": {
                    "label": "Name",
                    "type": "SINGLE_LINE",
                    "name": "contactName"
                  }
                },
                {
                  "textInput": {
                    "label": "Address",
                    "type": "MULTIPLE_LINE",
                    "name": "address"
                  }
                },
                {
                  "decoratedText": {
                    "text": "Add to favorites",
                    "switchControl": {
                      "controlType": "SWITCH",
                      "name": "saveFavorite"
                    }
                  }
                },
                {
                  "decoratedText": {
                    "text": "Merge with existing contacts",
                    "switchControl": {
                      "controlType": "SWITCH",
                      "name": "mergeContact",
                      "selected": true
                    }
                  }
                },
                {
                  "buttonList": {
                    "buttons": [
                      {
                        "text": "Next",
                        "onClick": {
                          "action": {
                            "function": "openSequentialDialog"
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      }
    }
  }
}

เปิดกล่องโต้ตอบเพื่อตอบสนองต่อการคลิกปุ่มการ์ด

หากต้องการให้ปุ่มการ์ดเปิดกล่องโต้ตอบ ให้ระบุสิ่งต่อไปนี้

  • onClick.action.function ในชื่อ ชื่อของฟังก์ชันที่เปิดกล่องโต้ตอบ
  • onClick.action.interaction ในชื่อ OPEN_DIALOG พร็อพเพอร์ตี้นี้จะแจ้ง Chat ว่า แอป Chat ต้องการเปิดกล่องโต้ตอบ

เมื่อผู้ใช้คลิกปุ่มบนการ์ด แอป Chat ของคุณ ได้รับเหตุการณ์การโต้ตอบที่มีข้อมูลต่อไปนี้

  • EventType คือ CARD_CLICKED
  • DialogEventType คือ REQUEST_DIALOG
  • common.invokedFunction คือชื่อของฟังก์ชันจากพร็อพเพอร์ตี้ onClick ของการคลิกที่ ปุ่มการ์ด

หากต้องการเปิดกล่องโต้ตอบ ให้ตอบกลับดังนี้

  • CANNOT TRANSLATE ActionResponse จาก "type": "DIALOG"
  • DialogAction ที่มีคำอธิบาย JSON ของกล่องโต้ตอบ

ในตัวอย่างนี้ แอป Chat จะตอบสนองต่อ MESSAGE เหตุการณ์การโต้ตอบกับการ์ดที่มีปุ่มที่เปิดกล่องโต้ตอบ

Node.js

/**
* Responds to messages that have links whose URLs
* match URL patterns configured for link previews.
*
* @param {Object} event The event object from Chat
* API.
*
* @return {Object} Response from the Chat app
* attached to the message with the previewed link.
*/
exports.onMessage = function onMessage(req, res) {

  // Store the Google Chat event as a variable.
  const event = req.body;

  if (req.method === "GET" || !event.message) {
    res.send("Hello! This function is meant to be used in a Google Chat " +
      "Space.");
  }

  // Responds with a card that prompts the user to add a contact
  else {
    res.json({
      "cardsV2": [{
        "cardId": "addContact",
        "card": {
          "header": {
            "title": "Rolodex",
            "subtitle": "Manage your contacts!",
            "imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
            "imageType": "CIRCLE"
          },
          "sections": [
            {
              "widgets": [
                {
                  "buttonList": {
                    "buttons": [
                      {
                        "text": "Add Contact",
                        "onClick": {
                          "action": {
                            "function": "openDialog",
                            "interaction": "OPEN_DIALOG"
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      }]

    });
  }

  // Respond to button clicks on attached cards
  if (event.type === "CARD_CLICKED") {

    if (event.common.invokedFunction === "openDialog") {
      openDialog(event);
    };

    /**
    * Opens and starts a dialog that lets users add details about a contact.
    *
    * @param {object} event the event object from Google Chat.
    *
    * @return {object} open a dialog.
    */
    function openDialog(event) {
      res.json({
        "action_response": {
          "type": "DIALOG",
          "dialog_action": {
            "dialog": {
              "body": {
                "sections": [
                  {
                    "header": "Add new contact",
                    "widgets": [
                      {
                        "textInput": {
                          "label": "Name",
                          "type": "SINGLE_LINE",
                          "name": "name"
                        }
                      },
                      {
                        "textInput": {
                          "label": "Address",
                          "type": "MULTIPLE_LINE",
                          "name": "address"
                        }
                      },
                      {
                        "decoratedText": {
                          "text": "Add to favorites",
                          "switchControl": {
                            "controlType": "SWITCH",
                            "name": "saveFavorite"
                          }
                        }
                      },
                      {
                        "decoratedText": {
                          "text": "Merge with existing contacts",
                          "switchControl": {
                            "controlType": "SWITCH",
                            "name": "mergeContact",
                            "selected": true
                          }
                        }
                      },
                      {
                        "buttonList": {
                          "buttons": [
                            {
                              "text": "Next",
                              "onClick": {
                                "action": {
                                  "function": "openSequentialDialog"
                                }
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                ]
              }
            }
          }
        }
      });
    };
  }
}

Apps Script

ตัวอย่างนี้ส่งข้อความการ์ดโดยการส่งคืน JSON ของการ์ด คุณยังสามารถใช้ บริการการ์ด Apps Script

/**
* Responds to a MESSAGE event in Google Chat with a card with a button
* that opens a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in response to a card's button click.
*/
function onMessage(event) {
  return {
    "cardsV2": [{
      "cardId": "addContact",
      "card": {
        "header": {
          "title": "Rolodex",
          "subtitle": "Manage your contacts!",
          "imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
          "imageType": "CIRCLE"
        },
        "sections": [
          {
            "widgets": [
              {
                "buttonList": {
                  "buttons": [
                    {
                      "text": "Add Contact",
                      "onClick": {
                        "action": {
                          "function": "openDialog",
                          "interaction": "OPEN_DIALOG"
                        }
                      }
                    }
                  ]
                },
                "horizontalAlignment": "CENTER"
              }
            ]
          }
        ]
      }
    }]
  };
}

/**
* Responds to a CARD_CLICKED event in Google Chat.
*
* @param {Object} event the event object from Google Chat
*/
function onCardClick(event) {
  if (event.common.invokedFunction === "openDialog") {
    return openDialog(event);
  }
}

/**
* Opens a dialog in Google Chat.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function openDialog(event) {
  return {
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Name",
                      "type": "SINGLE_LINE",
                      "name": "contactName"
                    }
                  },
                  {
                    "textInput": {
                      "label": "Address",
                      "type": "MULTIPLE_LINE",
                      "name": "address"
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Add to favorites",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "saveFavorite"
                      }
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Merge with existing contacts",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "mergeContact",
                        "selected": true
                      }
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Next",
                          "onClick": {
                            "action": {
                              "function": "openSequentialDialog"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  };
}

Python

from typing import Any, Mapping

import flask
import functions_framework

@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
  """Responds to a MESSAGE event in Google Chat that includes the /createContact
     slash command by opening a dialog.

  Args:
      req (flask.Request): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """

  if req.method == 'GET':
    return 'Sorry, this function must be called from a Google Chat.'

  request = req.get_json(silent=True)

  if request.get('type') == 'CARD_CLICKED':
    if request.get('common', dict()).get('invokedFunction') == 'open_dialog':
      return open_dialog(request)

  else:
    return {
      'cardsV2': [{
        'cardId': 'addContact',
        'card': {
          'header': {
            'title': 'Rolodex',
            'subtitle': 'Manage your contacts!',
            'imageUrl': 'https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png',
            'imageType': 'CIRCLE'
          },
          'sections': [
            {
              'widgets': [
                {
                  'buttonList': {
                    'buttons': [
                      {
                        'text': 'Add Contact',
                        'onClick': {
                          'action': {
                            'function': 'open_dialog',
                            'interaction': 'OPEN_DIALOG'
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      }]
    }

def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a dialog in Google Chat.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return {
    'action_response': {
      'type': 'DIALOG',
      'dialog_action': {
        'dialog': {
          'body': {
            'sections': [
              {
                'header': 'Add new contact',
                'widgets': [
                  {
                    'textInput': {
                      'label': 'Name',
                      'type': 'SINGLE_LINE',
                      'name': 'name'
                    }
                  },
                  {
                    'textInput': {
                      'label': 'Address',
                      'type': 'MULTIPLE_LINE',
                      'name': 'address'
                    }
                  },
                  {
                    'decoratedText': {
                      'text': 'Add to favorites',
                      'switchControl': {
                        'controlType': 'SWITCH',
                        'name': 'saveFavorite'
                      }
                    }
                  },
                  {
                    'decoratedText': {
                      'text': 'Merge with existing contacts',
                      'switchControl': {
                        'controlType': 'SWITCH',
                        'name': 'mergeContact',
                        'selected': True
                      }
                    }
                  },
                  {
                    'buttonList': {
                      'buttons': [
                        {
                          'text': 'Next',
                          'onClick': {
                            'action': {
                              'function': 'open_sequential_dialog'
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }

เปิดกล่องโต้ตอบเพื่อตอบกลับคำสั่งเครื่องหมายทับ

เมื่อผู้ใช้เปิดกล่องโต้ตอบที่มี คำสั่งเครื่องหมายทับที่กำหนดค่าไว้สำหรับการเปิดกล่องโต้ตอบ แอป Chat ได้รับเหตุการณ์การโต้ตอบกับแท็ก ข้อมูลต่อไปนี้

หากต้องการเปิดกล่องโต้ตอบ คุณต้องกำหนดค่าคำสั่งเครื่องหมายทับ โดยเลือกช่องทำเครื่องหมายเปิดกล่องโต้ตอบ จากนั้นตอบคำถามต่อไปนี้

  • CANNOT TRANSLATE ActionResponse จาก "type": "DIALOG"
  • DialogAction ที่มีคำอธิบาย JSON ของกล่องโต้ตอบ

ในตัวอย่างนี้ แอป Chat จะตอบสนองต่อ /createContact โดยใช้คำสั่งเครื่องหมายทับโดยเปิดกล่องโต้ตอบ ดังนี้

Node.js

/**
* Responds to messages that have links whose URLs
* match URL patterns configured for link previews.
*
* @param {Object} event The event object from Chat
* API.
*
* @return {Object} Response from the Chat app
* attached to the message with the previewed link.
*/
exports.onMessage = function onMessage(req, res) {

  // Store the Google Chat event as a variable.
  const event = req.body;

  if (req.method === "GET" || !event.message) {
    res.send("Hello! This function is meant to be used in a Google Chat " +
      "Space.");
  }

  // Checks for the presence of event.message.slashCommand.
  // If the slash command is "/help", responds with a text message.
  // If the slash command is "/createContact", opens a dialog.
  if (event.message.slashCommand) {
    switch (event.message.slashCommand.commandId) {
      case 1: // /help
        res.json({"text": "Contact bot helps you update your address book!"});
      case 2:  // /createContact
        openDialog(event);
    }
  }
};

/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
  res.json({
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Name",
                      "type": "SINGLE_LINE",
                      "name": "name"
                    }
                  },
                  {
                    "textInput": {
                      "label": "Address",
                      "type": "MULTIPLE_LINE",
                      "name": "address"
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Add to favorites",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "saveFavorite"
                      }
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Merge with existing contacts",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "mergeContact",
                        "selected": true
                      }
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Next",
                          "onClick": {
                            "action": {
                              "function": "openSequentialDialog"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  });
};

Apps Script

ตัวอย่างนี้ส่งข้อความการ์ดโดยการส่งคืน JSON ของการ์ด คุณยังสามารถใช้ บริการการ์ด Apps Script

/**
* Responds to a MESSAGE event in Google Chat that includes the /createContact
* slash command by opening a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in response to a slash command.
*/
function onMessage(event) {

  // Checks for the presence of event.message.slashCommand.
  // If the slash command is "/help", responds with a text message.
  // If the slash command is "/createContact", opens a dialog.
  if (event.message.slashCommand) {
    switch (event.message.slashCommand.commandId) {
      case 1: // /help
        return {"text": "Contact bot helps you update your address book!"}
      case 2:  // /createContact
        return openDialog(event);
    }
  }
}

/**
* Opens a dialog in Google Chat.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function openDialog(event) {
  return {
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Name",
                      "type": "SINGLE_LINE",
                      "name": "contactName"
                    }
                  },
                  {
                    "textInput": {
                      "label": "Address",
                      "type": "MULTIPLE_LINE",
                      "name": "address"
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Add to favorites",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "saveFavorite"
                      }
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Merge with existing contacts",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "mergeContact",
                        "selected": true
                      }
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Next",
                          "onClick": {
                            "action": {
                              "function": "openSequentialDialog"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  };
}

Python

from typing import Any, Mapping

import flask
import functions_framework

@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
  """Responds to a MESSAGE event in Google Chat that includes the /createContact
     slash command by opening a dialog.

  Args:
      req (flask.Request): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a slash command.
  """
  if req.method == 'GET':
    return 'Sorry, this function must be called from a Google Chat.'

  request = req.get_json(silent=True)

  if slash_command := request.get('message', dict()).get('slashCommand'):
    command_id = slash_command['commandId']
    if command_id == 1:
      return {'text': 'Contact bot helps you update your address book!'}

    elif command_id == 2:
      return open_dialog(request)

def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a dialog in Google Chat.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a slash command.
  """
  return {
    'action_response': {
      'type': 'DIALOG',
      'dialog_action': {
        'dialog': {
          'body': {
            'sections': [
              {
                'header': 'Add new contact',
                'widgets': [
                  {
                    'textInput': {
                      'label': 'Name',
                      'type': 'SINGLE_LINE',
                      'name': 'name'
                    }
                  },
                  {
                    'textInput': {
                      'label': 'Address',
                      'type': 'MULTIPLE_LINE',
                      'name': 'address'
                    }
                  },
                  {
                    'decoratedText': {
                      'text': 'Add to favorites',
                      'switchControl': {
                        'controlType': 'SWITCH',
                        'name': 'saveFavorite'
                      }
                    }
                  },
                  {
                    'decoratedText': {
                      'text': 'Merge with existing contacts',
                      'switchControl': {
                        'controlType': 'SWITCH',
                        'name': 'mergeContact',
                        'selected': True
                      }
                    }
                  },
                  {
                    'buttonList': {
                      'buttons': [
                        {
                          'text': 'Next',
                          'onClick': {
                            'action': {
                              'function': 'open_sequential_dialog'
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }

เปิดกล่องโต้ตอบตามลำดับ

หากการโต้ตอบของผู้ใช้ต้องใช้กล่องโต้ตอบมากกว่า 1 กล่องโต้ตอบ คุณจะเปิดกล่องโต้ตอบอื่นได้ โดยแสดงผลกล่องโต้ตอบถัดไปในลำดับตาม SUBMIT_DIALOG DialogEventType

กล่องโต้ตอบที่มีวิดเจ็ตต่างๆ มากมาย
รูปที่ 3: กล่องโต้ตอบที่เปิดอยู่เพื่อแจ้งให้ผู้ใช้เพิ่มรายชื่อติดต่อ

ในปุ่มการ์ดที่อัปเดตกล่องโต้ตอบ ให้ย้อนกลับ onClick.action.function เป็น ชื่อของฟังก์ชันที่เปิดกล่องโต้ตอบถัดไปและ ไม่ระบุ onClick.action.interaction

กล่องโต้ตอบที่มีวิดเจ็ตต่างๆ มากมาย
รูปที่ 4: กล่องโต้ตอบที่ 2 แจ้งให้ผู้ใช้ขอข้อมูลเพิ่มเติม

เมื่อทำเสร็จแล้ว แอป Chat จะได้รับค่าที่ผู้ใช้ ป้อนลงในกล่องโต้ตอบเป็น JSON แจ้งให้ผู้ใช้ทราบว่าการโต้ตอบสําเร็จด้วยการ ตอบกลับด้วย SMS หรือข้อความในการ์ด

เมื่อผู้ใช้คลิกปุ่มในกล่องโต้ตอบ แอป Chat ของคุณ ได้รับเหตุการณ์การโต้ตอบที่มีข้อมูลต่อไปนี้

ในตัวอย่างนี้ แอป Chat ตอบสนองต่อ CARD_CLICKED เหตุการณ์การโต้ตอบจากการคลิกปุ่มกล่องโต้ตอบโดยการเปิดเหตุการณ์อื่น กล่องโต้ตอบ:

Node.js

// Respond to button clicks on attached cards
if (event.type === "CARD_CLICKED") {

  // Open the first dialog.
  if (event.common.invokedFunction === "openDialog") {
    openDialog(event);
  }

  // Open the second dialog.
  if (event.common.invokedFunction === "openSequentialDialog") {
    openSequentialDialog(event);
  }
}

/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
  res.json({
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Name",
                      "type": "SINGLE_LINE",
                      "name": "name"
                    }
                  },
                  {
                    "textInput": {
                      "label": "Address",
                      "type": "MULTIPLE_LINE",
                      "name": "address"
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Add to favorites",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "saveFavorite"
                      }
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Merge with existing contacts",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "mergeContact",
                        "selected": true
                      }
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Next",
                          "onClick": {
                            "action": {
                              "function": "openSequentialDialog"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  });
};

/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openSequentialDialog(event) {
  res.json({
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Notes",
                      "type": "MULTIPLE_LINE",
                      "name": "notes"
                    }
                  },
                  {
                    "selectionInput": {
                      "type": "RADIO_BUTTON",
                      "label": "Contact type",
                      "name": "contactType",
                      "items": [
                        {
                          "text": "Work",
                          "value": "Work",
                          "selected": false
                        },
                        {
                          "text": "Personal",
                          "value": "Personal",
                          "selected": false
                        }
                      ]
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Submit",
                          "onClick": {
                            "action": {
                              "function": "confirmDialogSuccess",
                              "parameters": [
                                {
                                  "key": "confirmDialogSuccess",
                                  "value": "confirmDialogSuccess"
                                }
                              ]
                            }
                          }
                        }
                      ]
                    },
                    "horizontalAlignment": "END"
                  }
                ]
              }
            ]
          }
        }
      }
    }
  });
}

Apps Script

ตัวอย่างนี้ส่งข้อความการ์ดโดยการส่งคืน JSON ของการ์ด คุณยังสามารถใช้ บริการการ์ด Apps Script

/**
* Responds to a CARD_CLICKED event in Google Chat.
*
* @param {Object} event the event object from Google Chat
*/
function onCardClick(event) {

  // When a user clicks a card, the Chat app checks to see which function to run.
  if (event.common.invokedFunction === "openDialog") {
    return openDialog(event);
  }

  if (event.common.invokedFunction === "openSequentialDialog") {
    return openSequentialDialog(event);
  }
}

/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
  return {
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Name",
                      "type": "SINGLE_LINE",
                      "name": "contactName"
                    }
                  },
                  {
                    "textInput": {
                      "label": "Address",
                      "type": "MULTIPLE_LINE",
                      "name": "address"
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Add to favorites",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "saveFavorite"
                      }
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Merge with existing contacts",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "mergeContact",
                        "selected": true
                      }
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Next",
                          "onClick": {
                            "action": {

                              // Specifies which function to run
                              // in response to the card click.
                              "function": "openSequentialDialog"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  };
}

/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openSequentialDialog(event) {
  return {
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Notes",
                      "type": "MULTIPLE_LINE",
                      "name": "notes"
                    }
                  },
                  {
                    "selectionInput": {
                      "type": "RADIO_BUTTON",
                      "label": "Contact type",
                      "name": "contactType",
                      "items": [
                        {
                          "text": "Work",
                          "value": "Work",
                          "selected": false
                        },
                        {
                          "text": "Personal",
                          "value": "Personal",
                          "selected": false
                        }
                      ]
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Submit",
                          "onClick": {
                            "action": {

                              // Specifies which function to run
                              // in response to the card click.
                              "function": "receiveDialog",
                              "parameters": [
                                {
                                  "key": "receiveDialog",
                                  "value": "receiveDialog"
                                }
                              ]
                            }
                          }
                        }
                      ]
                    },
                    "horizontalAlignment": "END"
                  }
                ]
              }
            ]
          }
        }
      }
    }
  };
}

Python

from typing import Any, Mapping

import flask
import functions_framework

@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
  """Responds to a MESSAGE event in Google Chat that includes the /createContact
     slash command by opening a dialog.

  Args:
      req (flask.Request): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """

  if req.method == 'GET':
    return 'Sorry, this function must be called from a Google Chat.'

  request = req.get_json(silent=True)

  if request.get('type') == 'CARD_CLICKED':
    if invoked_function := request.get('common', dict()).get('invokedFunction'):
      if invoked_function == 'open_dialog':
        return open_dialog(request)

      elif invoked_function == 'open_sequential_dialog':
        return open_dialog(request)

def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a dialog in Google Chat.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return {
    'action_response': {
      'type': 'DIALOG',
      'dialog_action': {
        'dialog': {
          'body': {
            'sections': [
              {
                'header': 'Add new contact',
                'widgets': [
                  {
                    'textInput': {
                      'label': 'Name',
                      'type': 'SINGLE_LINE',
                      'name': 'name'
                    }
                  },
                  {
                    'textInput': {
                      'label': 'Address',
                      'type': 'MULTIPLE_LINE',
                      'name': 'address'
                    }
                  },
                  {
                    'decoratedText': {
                      'text': 'Add to favorites',
                      'switchControl': {
                        'controlType': 'SWITCH',
                        'name': 'saveFavorite'
                      }
                    }
                  },
                  {
                    'decoratedText': {
                      'text': 'Merge with existing contacts',
                      'switchControl': {
                        'controlType': 'SWITCH',
                        'name': 'mergeContact',
                        'selected': True
                      }
                    }
                  },
                  {
                    'buttonList': {
                      'buttons': [
                        {
                          'text': 'Next',
                          'onClick': {
                            'action': {
                              'function': 'open_sequential_dialog'
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }

def open_sequential_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a second dialog that lets users add more contact details.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return {
    'action_response': {
      'type': 'DIALOG',
      'dialog_action': {
        'dialog': {
          'body': {
            'sections': [
              {
                'header': 'Add new contact',
                'widgets': [
                  {
                    'textInput': {
                      'label': 'Notes',
                      'type': 'MULTIPLE_LINE',
                      'name': 'notes'
                    }
                  },
                  {
                    'selectionInput': {
                      'type': 'RADIO_BUTTON',
                      'label': 'Contact type',
                      'name': 'contactType',
                      'items': [
                        {
                          'text': 'Work',
                          'value': 'Work',
                          'selected': False
                        },
                        {
                          'text': 'Personal',
                          'value': 'Personal',
                          'selected': False
                        }
                      ]
                    }
                  },
                  {
                    'buttonList': {
                      'buttons': [
                        {
                          'text': 'Submit',
                          'onClick': {
                            'action': {
                              'function': 'receiveDialog',
                              'parameters': [
                                {
                                  'key': 'receiveDialog',
                                  'value': 'receiveDialog'
                                }
                              ]
                            }
                          }
                        }
                      ]
                    },
                    'horizontalAlignment': 'END'
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }

เปิดกล่องโต้ตอบเพื่อตอบสนองการโต้ตอบในหน้าแรกของแอป

สำหรับหน้าแรกของแอปเท่านั้น ใช้ render_actions แทน action_response เพื่อเปิดกล่องโต้ตอบ:

Apps Script

ตัวอย่างนี้ส่งข้อความการ์ดโดยการส่งคืน JSON ของการ์ด คุณยังสามารถใช้ บริการการ์ด Apps Script

function openDialog() {
  return {
    render_actions: {
      action: {
        navigations: [{
          update_card: {
            "sections": [
            {
              "header": "Add new contact",
              "widgets": [
              {
                "textInput": {
                  "label": "Name",
                  "type": "SINGLE_LINE",
                  "name": "contactName"
                }
              },
              {
                "textInput": {
                  "label": "Address",
                  "type": "MULTIPLE_LINE",
                  "name": "address"
                }
              },
              {
                "decoratedText": {
                  "text": "Add to favorites",
                  "switchControl": {
                    "controlType": "SWITCH",
                    "name": "saveFavorite"
                  }
                }
              },
              {
                "decoratedText": {
                  "text": "Merge with existing contacts",
                  "switchControl": {
                    "controlType": "SWITCH",
                    "name": "mergeContact",
                    "selected": true
                  }
                }
              },
              {
                "buttonList": {
                  "buttons": [
                    {
                      "text": "Next",
                      "onClick": {
                        "action": {
                          "function": "openSequentialDialog"
                        }
                      }
                    }
                  ]
                }
              }]
            }]
          }
        }]
      }
    }
  }
}

รับข้อมูลแบบฟอร์มจากกล่องโต้ตอบ

เมื่อผู้ใช้คลิกปุ่มในกล่องโต้ตอบ ระบบจะส่งข้อมูลที่ป้อนไปยัง แอป Chat และ แอป Chat ได้รับเหตุการณ์การโต้ตอบกับ ข้อมูลต่อไปนี้

ข้อมูลที่ผู้ใช้ป้อนในกล่องโต้ตอบจะแสดงในเหตุการณ์การโต้ตอบแบบ Event.common.formInputs แมปที่คีย์คือรหัสสตริงที่กำหนดให้กับวิดเจ็ตและค่าของกล่องโต้ตอบแต่ละรายการ แสดงถึงข้อมูลจากผู้ใช้สำหรับวิดเจ็ตแต่ละรายการ วัตถุที่ต่างกันแสดงไม่เหมือนกัน ประเภทข้อมูลอินพุต ตัวอย่างเช่น Event.common.formInputs.stringInputs แทนอินพุตสตริง

เมื่อผู้ใช้ส่งกล่องโต้ตอบ แอป Chat ของคุณจะได้รับ เหตุการณ์การโต้ตอบแบบนี้จาก Chat:

JSON

{
  "type": enum (EventType),
  "eventTime": string,
  "threadKey": string,
  "message": {
    object (Message)
  },
  "user": {
    object (User)
  },
  "space": {
    object (Space)
  },
  "action": {
    object (FormAction)
  },
  "configCompleteRedirectUrl": string,

  // Indicates that this event is dialog-related.
  "isDialogEvent": true,

  // Indicates that a user clicked a button, and all data
  // they entered in the dialog is included in Event.common.formInputs.
  "dialogEventType": "SUBMIT_DIALOG",
  "common": {
    "userLocale": string,
    "hostApp": enum (HostApp),
    "platform": enum (Platform),
    "timeZone": {
      object (TimeZone)
    },

    // Represents user data entered in a dialog.
    "formInputs": {

      // Represents user data entered for a specific field in a dialog.
      "NAME": {

        // Represents string data entered in a dialog, like text input fields
        // and check boxes.
        "stringInputs": {

          // An array of strings entered by the user in a dialog.
          "value": [
            string
          ]
        }
      }
    },
    "parameters": {
      string: string,
      ...
    },
    "invokedFunction": string
  }
}

แอปใน Chat จะเข้าถึงค่าแรกที่ผู้ใช้ป้อนได้ เวลา event.common.formInputs.NAME.stringInputs.value[0] โดยที่ NAME คือฟิลด์ name ของ วิดเจ็ต TextInput

หลังจากได้รับข้อมูลจากฟอร์มกล่องโต้ตอบแล้ว แอป Chat ควรตอบกลับด้วย ActionResponse

  • หากต้องการตอบรับว่าได้รับใบเสร็จแล้ว โปรดตอบกลับเป็น ActionResponse ที่มี "actionStatus": "OK" การทำเช่นนี้จะปิดกล่องโต้ตอบโดยไม่โพสต์ คำตอบ
  • หากต้องการตอบกลับด้วยข้อความหรือข้อความการ์ด ให้ตอบกลับด้วย ActionResponse ที่มี ResponseType จาก NEW_MESSAGE, UPDATE_MESSAGE หรือ UPDATE_USER_MESSAGE_CARDS สำหรับข้อมูลเพิ่มเติม ดูข้อมูลได้ที่ ตอบกลับกล่องโต้ตอบ
  • หากต้องการส่งคืนข้อผิดพลาด โปรดตอบกลับด้วย ActionResponse ที่มี "actionStatus": "ERROR MESSAGE"

ตัวอย่างต่อไปนี้จะตรวจหาค่า name ที่มีอยู่ หากขาดข้อมูลดังกล่าว แอป Chat แสดงข้อผิดพลาด หากมี ค่า แอป Chat รับทราบข้อมูลในแบบฟอร์มและ ปิดกล่องโต้ตอบ

Node.js

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {Object} open a Dialog in Google Chat.
*/
function receiveDialog(event) {

  // Checks to make sure the user entered a name
  // in a dialog. If no name value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.WIDGET_NAME.stringInputs.value[0] === "") {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "Don't forget to name your new contact!"
        }
      }
    });

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    });
  }
}

Apps Script

ตัวอย่างนี้ส่งข้อความการ์ดโดยการส่งคืน JSON ของการ์ด คุณยังสามารถใช้ บริการการ์ด Apps Script

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function receiveDialog(event) {

  // Checks to make sure the user entered a name
  // in a dialog. If no name value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.WIDGET_NAME[""].stringInputs.value[0] === "") {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "Don't forget to name your new contact!"
        }
      }
    };

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    };
  }
}

Python

def receive_dialog(event: Mapping[str, Any]) -> Mapping[str, Any]:
  """Checks for a form input error, the absence of a "name" value, and returns
     an error if absent. Otherwise, confirms successful receipt of a dialog.

  Args:
      event (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: the response.
  """

  if common := event.get('common'):
    if form_inputs := common.get('formInputs'):
      if contact_name := form_inputs.get('WIDGET_NAME'):
        if string_inputs := contact_name.get('stringInputs'):
          if name := string_inputs.get('value')[0]:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'OK'
                }
              }
            }
          else:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'Don\'t forget to name your new contact!'
                }
              }
            }

ตอบกลับกล่องโต้ตอบ

คุณสามารถตอบกลับกล่องโต้ตอบด้วยข้อความใหม่หรือการอัปเดต ข้อความที่มีอยู่

ตอบกลับกล่องโต้ตอบด้วยข้อความใหม่

หากต้องการตอบกลับการส่งแบบฟอร์มกล่องโต้ตอบด้วยข้อความใหม่ ฟิลด์ แอป Chat แสดง ActionResponse ประเภท NEW_MESSAGE พร้อมด้วย มาร์กอัป เพื่อระบุเนื้อหาของข้อความใหม่ เมื่อได้รับการตอบกลับนี้แล้ว กล่องโต้ตอบจะปิดลงและมีการโพสต์ข้อความใหม่

โค้ดต่อไปนี้เป็นตัวอย่างของการตอบสนอง JSON ไปยังกล่องโต้ตอบที่ส่งโดย วิธีสร้างข้อความตอบกลับใหม่ในแอป Chat

JSON

{
  "actionResponse": {
    "type": "NEW_MESSAGE",
  },
  "text": "This message is a reply to a dialog form submission.",
  "cardsV2": [
    {
      "cardId": "reply-card-id",
      "card": {
        "header": {
          "title": "Reply card title"
        },
        "sections": [
          {
            "widgets": [
              {
                "textParagraph": {
                  "text": "Reply card message"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

แอป Chat ยังสามารถตอบกลับแบบไม่พร้อมกันด้วย ข้อความ หรือ การ์ด

ตอบกลับกล่องโต้ตอบด้วยข้อความที่อัปเดต

เมื่อตอบกลับกล่องโต้ตอบที่มีข้อความที่อัปเดตแล้ว คุณจะอัปเดต ข้อความแอปใน Chat เดิมหรืออัปเดตตัวอย่างลิงก์

ข้อความแอปใน Chat

หากต้องการตอบกลับการส่งแบบฟอร์มโต้ตอบที่มีการอัปเดตข้อความที่มีอยู่ ที่ส่งโดยแอป Chat จะแสดงผล ActionResponse ประเภท UPDATE_MESSAGE คำตอบประกอบด้วย มาร์กอัป ซึ่งระบุเนื้อหาของข้อความที่ได้รับการอัปเดต เมื่อได้รับ การตอบกลับ กล่องโต้ตอบจะปิดลงและข้อความจะอัปเดตด้วยเนื้อหาใหม่

โค้ดต่อไปนี้เป็นตัวอย่างของการตอบสนอง JSON ไปยังกล่องโต้ตอบที่ส่งโดย แอป Chat เพื่ออัปเดต ข้อความแอป Chat:

JSON

{
  "actionResponse": {
    "type": "UPDATE_MESSAGE",
  },
  "text": "This message has been updated with new content in response to a dialog form submission.",
  "cardsV2": [
    {
      "cardId": "updated-card-id",
      "card": {
        "header": {
          "title": "Updated card title"
        },
        "sections": [
          {
            "widgets": [
              {
                "textParagraph": {
                  "text": "Updated card message"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

นอกจากนี้ แอป Chat ยังทำงานแบบไม่พร้อมกัน อัปเดตข้อความแอปใน Chat โดยใช้ Google Chat API

เพื่ออัปเดต ตัวอย่างลิงก์ ด้วยเนื้อหาใหม่ตามการส่งแบบฟอร์มโต้ตอบ แอป Chat แสดง ActionResponse ประเภท UPDATE_USER_MESSAGE_CARDS คำตอบประกอบด้วย มาร์กอัป สำหรับข้อความการ์ดใหม่ที่ใช้อัปเดตตัวอย่างลิงก์ หลัง เมื่อได้รับการตอบกลับนี้ ระบบจะปิดกล่องโต้ตอบและอัปเดตตัวอย่างลิงก์ ด้วยข้อความการ์ดใหม่

ตัวอย่างการตอบกลับ JSON ต่อไปนี้อัปเดตตัวอย่างลิงก์ด้วยการ์ดใหม่ ข้อความ:

JSON

{
  "actionResponse": "UPDATE_USER_MESSAGE_CARDS",
  "cardsV2": [
    {
      "cardId" : "updated-card-id",
      "card" : {
        "header": {
          "title": "Updated card title"
        },
        "sections": [
          {
            "widgets" : [
              {
                "textParagraph": {
                  "text": "Updated card message"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

ตอบสนองต่อกล่องโต้ตอบที่ปรากฏในหน้าแรกของแอป

สำหรับหน้าแรกของแอปเท่านั้น มี 2 วิธีในการปิดกล่องโต้ตอบ ดังนี้

  • CLOSE_DIALOG: ปิดกล่องโต้ตอบและกลับไปที่การ์ดหน้าแรกของแอป
  • CLOSE_DIALOG_AND_EXECUTE: ปิดกล่องโต้ตอบและรีเฟรชหน้าแรกของแอป

Python

ตัวอย่างโค้ดต่อไปนี้ใช้ CLOSE_DIALOG เพื่อปิดกล่องโต้ตอบและกลับไปที่ การ์ดหน้าแรกของแอป

def close_dialog():
  """Handles dismiss dialog request from Chat."""
  return {
      'render_actions': {
          'action': {
              'navigations': [{
                'end_navigation': {'action': 'CLOSE_DIALOG'}
              }]
          }
      }
  }

Apps Script

ตัวอย่างนี้ส่งข้อความการ์ดโดยการส่งคืน JSON ของการ์ด คุณยังสามารถใช้ บริการการ์ด Apps Script

ตัวอย่างโค้ดต่อไปนี้ใช้ CLOSE_DIALOG เพื่อปิดกล่องโต้ตอบและกลับไปที่ การ์ดหน้าแรกของแอป

function closeDialog(event) {
  return {
    render_actions: {
      action:{
        navigations:[{
          end_navigation:{
            action: "CLOSE_DIALOG"
          }
        }]
      }
    }
  };
}

ตัวอย่างที่สมบูรณ์: Rolodex ผู้ติดต่อที่จัดการแอปแชท

ในตัวอย่างนี้ แอป Chat จะเปิดกล่องโต้ตอบเพื่อให้ผู้ใช้ สามารถเพิ่มรายละเอียดเกี่ยวกับรายชื่อติดต่อ เช่น ชื่อ อีเมล และที่อยู่ได้โดยทำดังนี้

Node.js

/**
* Responds to messages that have links whose URLs
* match URL patterns configured for link previews.
*
* @param {Object} event The event object from Chat
* API.
*
* @return {Object} Response from the Chat app
* attached to the message with the previewed link.
*/
exports.onMessage = function onMessage(req, res) {

  // Store the Google Chat event as a variable.
  const event = req.body;

  if (req.method === "GET" || !event.message) {
    res.send("Hello! This function is meant to be used in a Google Chat " +
      "Space.");
  }

  // Checks for the presence of event.message.slashCommand.
  // If the slash command is "/help", responds with a text message.
  // If the slash command is "/createContact", opens a dialog.
  if (event.message.slashCommand) {
    switch (event.message.slashCommand.commandId) {
      case 1: // /help
        res.json({"text": "Contact bot helps you update your address book!"});
      case 2:  // /createContact
        openDialog(event);
    }
  }

  // If the Chat app doesn"t detect a slash command, it responds
  // with a card that prompts the user to add a contact
  else {
    res.json({
      "cardsV2": [{
        "cardId": "addContact",
        "card": {
          "header": {
            "title": "Rolodex",
            "subtitle": "Manage your contacts!",
            "imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
            "imageType": "CIRCLE"
          },
          "sections": [
            {
              "widgets": [
                {
                  "buttonList": {
                    "buttons": [
                      {
                        "text": "Add Contact",
                        "onClick": {
                          "action": {
                            "function": "openDialog",
                            "interaction": "OPEN_DIALOG"
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      }]
    });
  }

  // Respond to button clicks on attached cards
  if (event.type === "CARD_CLICKED") {

    if (event.common.invokedFunction === "openDialog") {
      openDialog(event);
    }

    if (event.common.invokedFunction === "openSequentialDialog") {
      openSequentialDialog(event);
    }

    if (event.common.invokedFunction === "confirmDialogSuccess") {
      confirmDialogSuccess(event);
    }

  }
};

/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
  res.json({
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Name",
                      "type": "SINGLE_LINE",
                      "name": "name"
                    }
                  },
                  {
                    "textInput": {
                      "label": "Address",
                      "type": "MULTIPLE_LINE",
                      "name": "address"
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Add to favorites",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "saveFavorite"
                      }
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Merge with existing contacts",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "mergeContact",
                        "selected": true
                      }
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Next",
                          "onClick": {
                            "action": {
                              "function": "openSequentialDialog"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  });
};

/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openSequentialDialog(event) {
  res.json({
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Notes",
                      "type": "MULTIPLE_LINE",
                      "name": "notes"
                    }
                  },
                  {
                    "selectionInput": {
                      "type": "RADIO_BUTTON",
                      "label": "Contact type",
                      "name": "contactType",
                      "items": [
                        {
                          "text": "Work",
                          "value": "Work",
                          "selected": false
                        },
                        {
                          "text": "Personal",
                          "value": "Personal",
                          "selected": false
                        }
                      ]
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Submit",
                          "onClick": {
                            "action": {
                              "function": "confirmDialogSuccess",
                              "parameters": [
                                {
                                  "key": "confirmDialogSuccess",
                                  "value": "confirmDialogSuccess"
                                }
                              ]
                            }
                          }
                        }
                      ]
                    },
                    "horizontalAlignment": "END"
                  }
                ]
              }
            ]
          }
        }
      }
    }
  });
}

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function receiveDialog(event) {

  // Checks to make sure the user entered a name
  // in a dialog. If no name value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.contactName.stringInputs.value[0] === "") {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "Don't forget to name your new contact!"
        }
      }
    });

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    });
  }
}

Apps Script

ตัวอย่างนี้ส่งข้อความการ์ดโดยการส่งคืน JSON ของการ์ด คุณยังสามารถใช้ บริการการ์ด Apps Script

apps-script/dialogs/rolodex.gs
/**
* Responds to a MESSAGE event in Google Chat.
*
* @param {Object} event the event object from Chat API.
*
* @return {Object} open a Dialog in response to a slash command
* or a card"s button click.
*/
function onMessage(event) {

  // Checks for the presence of event.message.slashCommand.
  // If the slash command is "/help", responds with a text message.
  // If the slash command is "/createContact", opens a dialog.
  if (event.message.slashCommand) {
    switch (event.message.slashCommand.commandId) {
      case 1: // /help
        return {"text": "Contact bot helps you update your address book!"}
      case 2:  // /createContact
        return openDialog(event);
    }
  }

  // If the Chat app doesn"t detect a slash command, it responds
  // with a card that prompts the user to add a contact
  else {
    return {
      "cardsV2": [{
        "cardId": "addContact",
        "card": {
          "header": {
            "title": "Rolodex",
            "subtitle": "Manage your contacts!",
            "imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
            "imageType": "CIRCLE"
          },
          "sections": [
            {
              "widgets": [
                {
                  "buttonList": {
                    "buttons": [
                      {
                        "text": "Add Contact",
                        "onClick": {
                          "action": {
                            "function": "openDialog",
                            "interaction": "OPEN_DIALOG"
                          }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      }]

    };
  }
}

/**
* Responds to a CARD_CLICKED event in Google Chat.
*
* @param {Object} event the event object from Google Chat
*/
function onCardClick(event) {

  if (event.common.invokedFunction === "openDialog") {
    return openDialog(event);
  }

  if (event.common.invokedFunction === "openSequentialDialog") {
    const contactName = fetchFormValue(event, "contactName");
    const address = fetchFormValue(event, "address");
    return openSequentialDialog(contactName, address);
  }

  if (event.common.invokedFunction === "receiveDialog") {
    const parameters = event.common.parameters;
    parameters["contactType"] = fetchFormValue(event, "contactType");
    parameters["notes"] = fetchFormValue(event, "notes");
    return receiveDialog(parameters);
  }
}

/**
 * Extracts form input value for a given widget
 * 
 * @param {Object} event the event object from Google Chat
 * @param {String} widgetName the widget name
 * @returns the form input value for the widget
 */
function fetchFormValue(event, widgetName) {
  const widget = event.common.formInputs[widgetName];
  if (widget) {
    return widget[""]["stringInputs"]["value"][0];
  }
}

/**
* Opens and starts a dialog that lets users add details about a contact.
*
*
* @return {Object} open a dialog.
*/
function openDialog(event) {
  return {
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Name",
                      "type": "SINGLE_LINE",
                      "name": "contactName"
                    }
                  },
                  {
                    "textInput": {
                      "label": "Address",
                      "type": "MULTIPLE_LINE",
                      "name": "address"
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Add to favorites",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "saveFavorite"
                      }
                    }
                  },
                  {
                    "decoratedText": {
                      "text": "Merge with existing contacts",
                      "switchControl": {
                        "controlType": "SWITCH",
                        "name": "mergeContact",
                        "selected": true
                      }
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Next",
                          "onClick": {
                            "action": {
                              "function": "openSequentialDialog"
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  };
}

/**
* Opens a second dialog that lets users add more contact details.
*
* @param {String} contactName the contact name from the previous dialog.
* @param {String} address the address from the previous dialog.
*
* @return {Object} open a dialog.
*/
function openSequentialDialog(contactName, address) {
  return {
    "action_response": {
      "type": "DIALOG",
      "dialog_action": {
        "dialog": {
          "body": {
            "sections": [
              {
                "header": "Add new contact",
                "widgets": [
                  {
                    "textInput": {
                      "label": "Notes",
                      "type": "MULTIPLE_LINE",
                      "name": "notes"
                    }
                  },
                  {
                    "selectionInput": {
                      "type": "RADIO_BUTTON",
                      "label": "Contact type",
                      "name": "contactType",
                      "items": [
                        {
                          "text": "Work",
                          "value": "Work",
                          "selected": false
                        },
                        {
                          "text": "Personal",
                          "value": "Personal",
                          "selected": false
                        }
                      ]
                    }
                  },
                  {
                    "buttonList": {
                      "buttons": [
                        {
                          "text": "Submit",
                          "onClick": {
                            "action": {
                              "function": "receiveDialog",
                              "parameters": [
                                {
                                  "key": "contactName",
                                  "value": contactName
                                },
                                {
                                  "key": "address",
                                  "value": address
                                }
                              ]
                            }
                          }
                        }
                      ]
                    },
                    "horizontalAlignment": "END"
                  }
                ]
              }
            ]
          }
        }
      }
    }
  };
}

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} parameters the form input values.
*
* @return {Object} open a Dialog in Google Chat.
*/
function receiveDialog(parameters) {

  // Checks to make sure the user entered a name
  // in a dialog. If no name value detected, returns
  // an error message.
  if (!parameters.contactName) {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": {
            "statusCode": "INVALID_ARGUMENT",
            "userFacingMessage": "Don't forget to name your new contact!"
          }
        }
      }
    };

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. Any value other than "OK"
    // gets returned as an error. "OK" is interpreted as
    // code 200, and the dialog closes.
  } else {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": {
            "statusCode": "OK",
            "userFacingMessage": "Success " + JSON.stringify(parameters)
          }
        }
      }
    };
  }
}

Python

from typing import Any, Mapping

import flask
import functions_framework

@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
  """Responds to a MESSAGE event in Google Chat that includes the /createContact
     slash command by opening a dialog.

  Args:
      req (flask.Request): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """

  if req.method == 'GET':
    return 'Sorry, this function must be called from a Google Chat.'

  request = req.get_json(silent=True)

  if request.get('type') == 'CARD_CLICKED':
    invoked_function = request.get('common', dict()).get('invokedFunction')
    if invoked_function == 'open_dialog':
      return open_dialog(request)

    elif invoked_function == 'open_sequential_dialog':
      return open_dialog(request)

    elif invoked_function == "receive_dialog":
      return receive_dialog(request)

  else:
    return {
      'cardsV2': [{
        'cardId': 'addContact',
        'card': {
          'header': {
            'title': 'Rolodex',
            'subtitle': 'Manage your contacts!',
            'imageUrl': 'https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png',
            'imageType': 'CIRCLE'
          },
          'sections': [
            {
              'widgets': [
                {
                  'buttonList': {
                    'buttons': [
                      {
                        'text': 'Add Contact',
                        'onClick': {
                                'action': {
                                  'function': 'open_dialog',
                                  'interaction': 'OPEN_DIALOG'
                                }
                        }
                      }
                    ]
                  }
                }
              ]
            }
          ]
        }
      }]
    }

def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a dialog in Google Chat.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return {
    'action_response': {
      'type': 'DIALOG',
      'dialog_action': {
        'dialog': {
          'body': {
            'sections': [
              {
                'header': 'Add new contact',
                'widgets': [
                  {
                    'textInput': {
                      'label': 'Name',
                      'type': 'SINGLE_LINE',
                      'name': 'name'
                    }
                  },
                  {
                    'textInput': {
                      'label': 'Address',
                      'type': 'MULTIPLE_LINE',
                      'name': 'address'
                    }
                  },
                  {
                    'decoratedText': {
                      'text': 'Add to favorites',
                      'switchControl': {
                        'controlType': 'SWITCH',
                        'name': 'saveFavorite'
                      }
                    }
                  },
                  {
                    'decoratedText': {
                      'text': 'Merge with existing contacts',
                      'switchControl': {
                        'controlType': 'SWITCH',
                        'name': 'mergeContact',
                        'selected': True
                      }
                    }
                  },
                  {
                    'buttonList': {
                      'buttons': [
                        {
                          'text': 'Next',
                          'onClick': {
                            'action': {
                              'function': 'open_sequential_dialog'
                            }
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }

def open_sequential_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a second dialog that lets users add more contact details.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return {
    'action_response': {
      'type': 'DIALOG',
      'dialog_action': {
        'dialog': {
              'body': {
                'sections': [
                  {
                    'header': 'Add new contact',
                    'widgets': [
                      {
                        'textInput': {
                          'label': 'Notes',
                          'type': 'MULTIPLE_LINE',
                          'name': 'notes'
                        }
                      },
                      {
                        'selectionInput': {
                          'type': 'RADIO_BUTTON',
                          'label': 'Contact type',
                          'name': 'contactType',
                          'items': [
                            {
                              'text': 'Work',
                              'value': 'Work',
                              'selected': False
                            },
                            {
                              'text': 'Personal',
                              'value': 'Personal',
                              'selected': False
                            }
                          ]
                        }
                      },
                      {
                        'buttonList': {
                          'buttons': [
                            {
                              'text': 'Submit',
                              'onClick': {
                                'action': {
                                  'function': 'receive_dialog',
                                  'parameters': [
                                    {
                                      'key': 'receiveDialog',
                                      'value': 'receiveDialog'
                                    }
                                  ]
                                }
                              }
                            }
                          ]
                        },
                        'horizontalAlignment': 'END'
                      }
                    ]
                  }
                ]
              }
        }
      }
    }
  }

def receive_dialog(event: Mapping[str, Any]) -> Mapping[str, Any]:
  """Checks for a form input error, the absence of a "name" value, and returns
     an error if absent. Otherwise, confirms successful receipt of a dialog.

  Args:
      event (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: the response.
  """

  if event.get('common', dict()) \
      .get('formInputs', dict()).get('contactName', dict()) \
          .get('stringInputs').get('value', list()):
    return {
      'actionResponse': {
        'type': 'DIALOG',
        'dialogAction': {
          'actionStatus': 'OK'
        }
      }
    }
  else:
    return {
      'actionResponse': {
        'type': 'DIALOG',
        'dialogAction': {
          'actionStatus': "Don't forget to name your new contact!"
        }
      }
    }

แก้ปัญหา

เมื่อแอป Google Chat หรือ card จะแสดงผลข้อผิดพลาด อินเทอร์เฟซ Chat แสดงข้อความว่า "เกิดข้อผิดพลาด" หรือ "ไม่สามารถดำเนินการตามคำขอของคุณ" บางครั้ง UI ของ Chat ไม่แสดงข้อความแสดงข้อผิดพลาดใดๆ แต่แอป Chat หรือ ทำให้เกิดผลลัพธ์ที่ไม่คาดคิด เช่น ข้อความในการ์ดอาจ ปรากฏขึ้น

แม้ว่าข้อความแสดงข้อผิดพลาดอาจไม่แสดงใน UI ของแชท มีข้อความแสดงข้อผิดพลาดและข้อมูลบันทึกที่สื่อความหมายเพื่อช่วยคุณแก้ไขข้อผิดพลาด เมื่อมีการเปิดข้อผิดพลาดในการบันทึกสำหรับแอป Chat หากต้องการความช่วยเหลือในการดู การแก้ไขข้อบกพร่องและการแก้ไขข้อผิดพลาด โปรดดู แก้ปัญหาข้อผิดพลาดของ Google Chat