Trang này giải thích cách thiết lập và phản hồi lệnh dấu gạch chéo cho Ứng dụng Google Chat.
Lệnh gạch chéo là một cách phổ biến mà người dùng gọi và tương tác với Ứng dụng Chat. Lệnh dấu gạch chéo cũng giúp người dùng khám phá và sử dụng các tính năng chính của ứng dụng Chat.
Để sử dụng lệnh dấu gạch chéo, người dùng nhập một dấu gạch chéo (/
) rồi nhập một lệnh văn bản ngắn,
chẳng hạn như /about
để nhận thông tin về ứng dụng Chat.
Người dùng có thể khám phá các lệnh dấu gạch chéo có sẵn bằng cách nhập dấu gạch chéo vào
Google Chat: hiển thị một cửa sổ liệt kê các lệnh hiện có để
Ứng dụng Chat:
![Cửa sổ lệnh dấu gạch chéo](https://developers-dot-devsite-v2-prod.appspot.com/static/workspace/chat/images/slash-command-window.png?authuser=5&hl=vi)
Khi người dùng gửi thông báo có chứa lệnh dấu gạch chéo, thông báo đó sẽ chỉ mà người dùng và ứng dụng Chat nhìn thấy.
Để quyết định xem bạn có nên thiết lập lệnh dấu gạch chéo hay không và để biết cách thiết kế tương tác người dùng, xem Xác định tất cả hành trình của người dùng.
Điều kiện tiên quyết
Node.js
Một ứng dụng Google Chat đã bật các tính năng tương tác. Để tạo một ứng dụng Chat tương tác bằng dịch vụ HTTP, hãy hoàn thành phần bắt đầu nhanh này.
Apps Script
Một ứng dụng Google Chat đã bật các tính năng tương tác. Để tạo một ứng dụng Chat tương tác trong Apps Script, hãy hoàn thành phần bắt đầu nhanh này.
Python
Một ứng dụng Google Chat đã bật các tính năng tương tác. Để tạo một ứng dụng Chat tương tác bằng dịch vụ HTTP, hãy hoàn thành phần bắt đầu nhanh này.
Thiết lập lệnh dấu gạch chéo
Phần này giải thích cách hoàn thành các bước sau để thiết lập dấu gạch chéo :
- Tạo tên cho lệnh dấu gạch chéo.
- Định cấu hình lệnh dấu gạch chéo trong API Google Chat.
Đặt tên cho lệnh dấu gạch chéo
Tên của lệnh dấu gạch chéo là tên mà người dùng nhập trong tin nhắn trong Chat để gọi ứng dụng Chat. Thêm một đoạn mô tả ngắn xuất hiện bên dưới tên để nhắc người dùng thêm về cách sử dụng lệnh:
![Tên và nội dung mô tả của lệnh dấu gạch chéo](https://developers-dot-devsite-v2-prod.appspot.com/static/workspace/chat/images/slash-command-description.png?authuser=5&hl=vi)
Khi chọn tên và mô tả cho lệnh dấu gạch chéo, hãy cân nhắc các đề xuất sau:
Cách đặt tên cho lệnh dấu gạch chéo:
- Hãy sử dụng các từ hoặc cụm từ ngắn, mô tả và hữu ích để khiến
các lệnh rõ ràng và đơn giản đối với người dùng. Ví dụ: thay vì nói
/createAReminder
, sử dụng/remindMe
. - Nếu lệnh của bạn chứa nhiều từ, hãy giúp người dùng đọc lệnh đó
bằng cách sử dụng toàn bộ chữ thường cho từ đầu tiên, sau đó viết hoa chữ cái đầu tiên
chữ cái của từ bổ sung. Ví dụ: thay vì
/updatecontact
, sử dụng/updateContact
. - Hãy cân nhắc xem nên sử dụng tên riêng biệt hay tên thông dụng cho lệnh của bạn. Nếu
lệnh của bạn mô tả một tương tác hoặc tính năng thông thường, bạn có thể sử dụng
tên thông dụng mà người dùng nhận ra và mong đợi, chẳng hạn như
/settings
hoặc/feedback
. Nếu không, hãy cố gắng sử dụng các tên lệnh duy nhất, vì nếu tên lệnh giống với các ứng dụng khác trong Chat, người dùng phải lọc qua các lệnh tương tự để tìm và sử dụng lệnh của bạn.
- Hãy sử dụng các từ hoặc cụm từ ngắn, mô tả và hữu ích để khiến
các lệnh rõ ràng và đơn giản đối với người dùng. Ví dụ: thay vì nói
Để mô tả lệnh dấu gạch chéo, hãy làm như sau:
- Mô tả ngắn gọn và rõ ràng để người dùng biết thông tin có thể mong đợi khi chúng gọi lệnh.
- Hãy cho người dùng biết nếu lệnh này có yêu cầu nào về định dạng.
Ví dụ: nếu bạn tạo một lệnh
/remindMe
yêu cầu đối số văn bản, hãy đặt nội dung mô tả thànhRemind me to do [something] at [time]
. - Cho người dùng biết liệu ứng dụng Chat có trả lời
mọi người trong không gian hoặc ở chế độ riêng tư đối với người dùng yêu cầu lệnh.
Ví dụ: đối với lệnh dấu gạch chéo
/about
, bạn có thể mô tả lệnh này làLearn about this app (Only visible to you)
. Để trả lời riêng cho một lệnh dấu gạch chéo, hãy xem phần Phản hồi bằng tin nhắn riêng tư.
Định cấu hình lệnh dấu gạch chéo trong API Google Chat
Để tạo lệnh dấu gạch chéo, bạn cần chỉ định thông tin về lệnh trong cấu hình ứng dụng Chat của bạn cho API Google Chat.
Để định cấu hình lệnh dấu gạch chéo trong API Google Chat, hãy hoàn thành các bước sau các bước:
Trong bảng điều khiển Google Cloud, hãy nhấp vào biểu tượng Trình đơn > API và Dịch vụ > API đã bật và Dịch vụ > API Google Chat
Nhấp vào Cấu hình.
Trong phần Lệnhlash, hãy nhấp vào Thêm lệnh dấu gạch chéo.
Nhập tên, mã lệnh và nội dung mô tả cho lệnh đó:
- Tên: tên hiển thị cho lệnh và nội dung người dùng nhập để gọi ứng dụng của bạn. Phải bắt đầu bằng dấu gạch chéo, chỉ chứa văn bản và có thể tối đa 50 ký tự.
- Mô tả: văn bản mô tả cách sử dụng và định dạng lệnh. Nội dung mô tả có thể dài tối đa 50 ký tự.
- Command ID: một số từ 1 đến 1000 mà bạn Ứng dụng Chat dùng để nhận dạng lệnh dấu gạch chéo và trả về phản hồi.
Không bắt buộc: Nếu bạn muốn ứng dụng Chat phản hồi lệnh có hộp thoại, hãy chọn Mở hộp thoại.
Nhấp vào Lưu.
Lệnh dấu gạch chéo hiện đã được định cấu hình cho ứng dụng Chat.
Phản hồi lệnh dấu gạch chéo
Khi người dùng tạo một tin nhắn trong Chat có chứa lệnh dấu gạch chéo,
ứng dụng Chat của bạn sẽ nhận được một sự kiện tương tác MESSAGE
.
Tải trọng sự kiện chứa thông tin về lệnh dấu gạch chéo,
bao gồm slashCommand
và slashCommandMetadata
mới. Bạn sử dụng các trường này để xác định mã lệnh và trả về một giá trị tuỳ chỉnh
của bạn.
Ví dụ sau đây cho thấy tải trọng JSON cho một sự kiện tương tác MESSAGE
bao gồm lệnh dấu gạch chéo /vote
:
{
...
"message": {
...
"text": "/vote yes",
"argumentText": " yes",
"slashCommand": {
"commandId": 2
},
"annotations": [
{
"length": 5,
"startIndex": 0,
"type": "SLASH_COMMAND",
"slashCommand": {
"commandName":"/vote",
"commandId":1,
"type": "INVOKE",
"bot": {
"avatarUrl": "https://www.example.com/images/vote-app-icon.png",
"displayName": "Voter Chat App",
"name": "users/1234567890987654321",
"type": "BOT"
}
}
}
]
}
}
Để phản hồi lệnh dấu gạch chéo, bạn có thể xác định xem trường slashCommand
có trong tải trọng sự kiện và nếu có, hãy trả về phản hồi cho lệnh.
Mã mẫu sau đây cho biết cách phản hồi một sự kiện tương tác MESSAGE
có chứa lệnh dấu gạch chéo:
Node.js
/**
* Responds to a MESSAGE event in Google Chat.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} function in response to a slash command.
*/
exports.onMessage = function onMessage(req, res) {
// Stores the Google Chat event as a variable.
var event = req.body;
// Checks for the presence of event.message.slashCommand.
if (event.message.slashCommand) {
switch (event.message.slashCommand.commandId) {
case ID: // The ID for your slash command
res.json(runFunction); // The response to the slash command.
}
}
Apps Script
/**
* Responds to a MESSAGE event in Google Chat.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} function in response to a slash command.
*/
function onMessage(event) {
// Checks for the presence of event.message.slashCommand
if (event.message.slashCommand) {
switch (event.message.slashCommand.commandId) {
case ID: // The ID for your slash command
return runFunction; // The response to the slash command.
}
}
}
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 a slash command.
Args:
req (flask.Request): the event object from Chat API.
Returns:
Mapping[str, Any]: function 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 == ID:
return runFunction
Để sử dụng mã, hãy thay thế các nội dung sau:
ID
: mã lệnh mà bạn chỉ định khi định cấu hình lệnh dấu gạch chéo trong API Google Chat.runFunction
: một hàm tạo phản hồi cho lệnh dấu gạch chéo.
Không bắt buộc: Trả lời bằng tin nhắn riêng tư
Thông báo chứa lệnh dấu gạch chéo chỉ hiển thị cho người dùng đã gửi tin nhắn và ứng dụng Chat nhận lệnh. Nếu bạn đã thiết lập để ứng dụng Chat thêm vào không gian với nhiều người, bạn có thể cân nhắc phản hồi lệnh dấu gạch chéo tính riêng tư, để giữ sự tương tác riêng tư giữa người dùng và Ứng dụng Chat.
Ví dụ: nếu một nhóm đang dùng ứng dụng Chat quản lý
dịch vụ hỗ trợ khách hàng, người dùng có thể gọi lệnh dấu gạch chéo như
/myCases
để xem các yêu cầu hỗ trợ được chỉ định cho họ. Nếu nhóm thêm
Ứng dụng nhắn tin với một không gian, người dùng sử dụng lệnh dấu gạch chéo này
trong không gian có thể muốn ứng dụng Chat chỉ phản hồi
chúng. Để tránh việc đăng yêu cầu hỗ trợ của người dùng cho mọi người trong không gian,
Ứng dụng Chat có thể trả lời riêng tư.
Để phản hồi riêng một lệnh dấu gạch chéo, hãy xem Gửi tin nhắn riêng tư cho người dùng Google Chat.
Ví dụ đầy đủ: Thiết lập danh bạ bằng ứng dụng Rolodex Chat
Ví dụ sau đây cho thấy một ứng dụng Chat phản hồi các lệnh dấu gạch chéo sau:
- Lệnh
/help
trả về một tin nhắn văn bản giải thích cách tải bằng ứng dụng Chat. Mã lệnh đã được đặt đến1
. - Lệnh
/createContact
sẽ mở ra một hộp thoại trong đó người dùng có thể nhập thông tin chi tiết về một địa chỉ liên hệ. Mã lệnh được đặt thành2
.
Trước khi bạn chạy mẫu này, hãy làm theo các bước để định cấu hình lệnh dấu gạch chéo trong API Google 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
res.json(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") {
res.json(openDialog(event));
}
if (event.common.invokedFunction === "openSequentialDialog") {
res.json(openSequentialDialog(event));
}
if (event.common.invokedFunction === "confirmDialogSuccess") {
res.json(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) {
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": "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": {
"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.
if (event.common.formInputs.contactName.stringInputs.value[0] === "") {
return {
"actionResponse": {
"type": "DIALOG",
"dialogAction": {
"actionStatus": {
"statusCode": "OK",
"userFacingMessage": "Don't forget to name your new contact!"
}
}
}
};
// Otherwise the 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": "OK"
}
}
};
}
}
Apps Script
Ví dụ này gửi thông báo thẻ bằng cách quay lại tệp JSON của thẻ. Bạn cũng có thể sử dụng Dịch vụ thẻ Apps Script.
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!"
}
}
}