หน้านี้อธิบายวิธีตั้งค่าและตอบกลับคำสั่งเครื่องหมายทับสำหรับแอป Google Chat
คำสั่งเครื่องหมายทับเป็นวิธีทั่วไปที่ผู้ใช้เรียกใช้และโต้ตอบกับแอป Chat คำสั่งเครื่องหมายทับยังช่วยให้ผู้ใช้ค้นพบและใช้ฟีเจอร์หลักของแอป Chat ได้ด้วย
หากต้องการใช้คำสั่งเครื่องหมายทับ ผู้ใช้พิมพ์เครื่องหมายทับ (/
) แล้วตามด้วยคำสั่งข้อความสั้นๆ เช่น /about
เพื่อดูข้อมูลเกี่ยวกับแอป Chat
ผู้ใช้จะดูคำสั่งเครื่องหมายทับที่มีอยู่ได้โดยพิมพ์เครื่องหมายทับลงใน Google Chat ซึ่งจะแสดงหน้าต่างที่แสดงคำสั่งที่ใช้ได้กับแอป Chat ดังนี้
เมื่อผู้ใช้ส่งข้อความที่มีคำสั่งเครื่องหมายทับ จะมีเพียงผู้ใช้และแอป Chat เท่านั้นที่เห็นข้อความดังกล่าว
หากต้องการตัดสินใจว่าคุณควรตั้งค่าคําสั่งเครื่องหมายทับหรือไม่ และทําความเข้าใจวิธีออกแบบการโต้ตอบของผู้ใช้ โปรดดูกําหนดเส้นทางทั้งหมดของผู้ใช้
สิ่งที่ต้องดำเนินการก่อน
Node.js
- บัญชี Google Workspace ที่มีสิทธิ์เข้าถึง Google Chat
- แอป Chat หากต้องการสร้างแอป Chat ให้ทำตามquickstartนี้
Apps Script
- บัญชี Google Workspace ที่มีสิทธิ์เข้าถึง Google Chat
- แอป Chat หากต้องการสร้างแอป Chat ให้ทำตามquickstartนี้
Python
- บัญชี Google Workspace ที่มีสิทธิ์เข้าถึง Google Chat
- แอป Chat หากต้องการสร้างแอป Chat ให้ทำตามquickstartนี้
ตั้งค่าคำสั่งเครื่องหมายทับ
ส่วนนี้จะอธิบายวิธีทำตามขั้นตอนต่อไปนี้เพื่อตั้งค่าคำสั่งเครื่องหมายทับ
- สร้างชื่อสำหรับคำสั่งเครื่องหมายทับ
- กำหนดค่าคำสั่งเครื่องหมายทับใน Google Chat API
ตั้งชื่อคำสั่งเครื่องหมายทับ
ชื่อของคำสั่งเครื่องหมายทับคือสิ่งที่ผู้ใช้พิมพ์ในข้อความ Chat เพื่อเรียกใช้แอป Chat นอกจากนี้ คำอธิบายสั้นๆ จะปรากฏอยู่ใต้ชื่อเพื่อแจ้งให้ผู้ใช้เพิ่มเติมเกี่ยวกับวิธีใช้คำสั่ง ดังนี้
โปรดพิจารณาคำแนะนำต่อไปนี้เมื่อเลือกชื่อและคำอธิบายสำหรับคำสั่งเครื่องหมายทับ
วิธีตั้งชื่อคำสั่งเครื่องหมายทับ
- ใช้คำหรือวลีที่กระชับ สื่อความหมาย และนำไปใช้ได้จริงเพื่อทำให้คำสั่งชัดเจนและเข้าใจง่ายสำหรับผู้ใช้ ตัวอย่างเช่น แทนที่จะพูดว่า
/createAReminder
ให้ใช้/remindMe
- หากคำสั่งมีมากกว่า 1 คำ โปรดช่วยให้ผู้ใช้อ่านคำสั่งโดยใช้อักษรตัวพิมพ์เล็กทั้งหมดสำหรับคำแรก จากนั้นจึงใช้อักษรตัวพิมพ์ใหญ่ในอักษรตัวแรกของคำเพิ่มเติม ตัวอย่างเช่น แทนที่จะใช้
/updatecontact
ให้ใช้/updateContact
- พิจารณาว่าจะใช้ชื่อที่ไม่ซ้ำกันหรือชื่อทั่วไปสำหรับคำสั่ง หากคำสั่งของคุณอธิบายถึงการโต้ตอบหรือฟีเจอร์ทั่วไป คุณจะใช้ชื่อทั่วไปที่ผู้ใช้จดจำและคาดหวังได้ เช่น
/settings
หรือ/feedback
หรือลองใช้ชื่อคำสั่งที่ไม่ซ้ำกัน เพราะหากชื่อคำสั่งของคุณเหมือนกันสำหรับแอป Chat อื่นๆ ผู้ใช้ต้องกรองโดยใช้คำสั่งที่คล้ายกันเพื่อค้นหาและใช้คำสั่งของคุณ
- ใช้คำหรือวลีที่กระชับ สื่อความหมาย และนำไปใช้ได้จริงเพื่อทำให้คำสั่งชัดเจนและเข้าใจง่ายสำหรับผู้ใช้ ตัวอย่างเช่น แทนที่จะพูดว่า
วิธีอธิบายคำสั่งเครื่องหมายทับ
- เขียนคำอธิบายที่สั้นและชัดเจนเพื่อให้ผู้ใช้รู้ว่าจะเกิดอะไรขึ้นเมื่อเรียกใช้คำสั่ง
- แจ้งให้ผู้ใช้ทราบหากมีข้อกำหนดการจัดรูปแบบสำหรับคำสั่งดังกล่าว
ตัวอย่างเช่น หากคุณสร้างคำสั่ง
/remindMe
ที่ต้องใช้ข้อความอาร์กิวเมนต์ ให้ตั้งค่าคำอธิบายเป็นRemind me to do [something] at [time]
- แจ้งให้ผู้ใช้ทราบว่าแอป Chat ตอบกลับทุกคนในพื้นที่ทำงานหรือตอบกลับผู้ใช้ที่เรียกใช้คำสั่งนี้แบบส่วนตัว
เช่น สำหรับคำสั่งเครื่องหมายทับ
/about
คุณสามารถอธิบายเป็นLearn about this app (Only visible to you)
หากต้องการตอบกลับคำสั่งเครื่องหมายทับแบบส่วนตัว โปรดดูส่วนตอบกลับด้วยข้อความส่วนตัว
กำหนดค่าคำสั่งเครื่องหมายทับใน Google Chat API
หากต้องการสร้างคำสั่งเครื่องหมายทับ คุณต้องระบุข้อมูลเกี่ยวกับคำสั่งในการกำหนดค่าของแอป Chat สำหรับ Google Chat API
หากต้องการกำหนดค่าคำสั่งเครื่องหมายทับใน Google Chat API ให้ทำตามขั้นตอนต่อไปนี้
ในคอนโซล Google Cloud ให้คลิกเมนู > API และบริการ > API และบริการที่เปิดใช้ > Google Chat API
คลิกการกำหนดค่า
ในส่วนคำสั่งเครื่องหมายทับ ให้คลิกเพิ่มคำสั่งเครื่องหมายทับ
ป้อนชื่อ รหัสคำสั่ง และคำอธิบายคำสั่ง ดังนี้
- ชื่อ: ชื่อที่แสดงของคำสั่ง และสิ่งที่ผู้ใช้พิมพ์ เพื่อเรียกใช้แอปของคุณ ต้องขึ้นต้นด้วยเครื่องหมายทับ มีเฉพาะข้อความ และยาวไม่เกิน 50 อักขระ
- คำอธิบาย: ข้อความที่อธิบายวิธีใช้และจัดรูปแบบคำสั่ง โดยคำอธิบายต้องมีความยาวไม่เกิน 50 อักขระ
- รหัสคำสั่ง: ตัวเลขตั้งแต่ 1 ถึง 1000 ที่แอป Chat ใช้ในการจดจำคำสั่งเครื่องหมายทับและแสดงผลการตอบกลับ
ไม่บังคับ: หากต้องการให้แอป Chat ตอบกลับ คำสั่งด้วยกล่องโต้ตอบ ให้เลือกช่องทำเครื่องหมายเปิดกล่องโต้ตอบ
คลิกบันทึก
ตอนนี้มีการกำหนดค่าคำสั่งเครื่องหมายทับสำหรับแอป Chat แล้ว
ตอบกลับคำสั่งเครื่องหมายทับ
เมื่อผู้ใช้สร้างข้อความใน Chat ที่มีคำสั่งเครื่องหมายทับ แอป Chat จะได้รับเหตุการณ์การโต้ตอบ MESSAGE
เพย์โหลดของเหตุการณ์มีข้อมูลเกี่ยวกับคำสั่งเครื่องหมายทับ ซึ่งรวมถึงช่อง slashCommand
และ slashCommandMetadata
คุณใช้ช่องเหล่านี้เพื่อระบุรหัสคำสั่งและแสดงผลการตอบกลับที่กำหนดเองได้
ตัวอย่างต่อไปนี้แสดงเพย์โหลด JSON สำหรับเหตุการณ์การโต้ตอบ MESSAGE
ที่มีคำสั่งเครื่องหมายทับ /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"
}
}
}
]
}
}
หากต้องการตอบสนองต่อคำสั่งเครื่องหมายทับ คุณจะตรวจสอบได้ว่ามีช่อง slashCommand
อยู่ในเพย์โหลดเหตุการณ์หรือไม่ หากมี ก็ให้ตอบกลับคำสั่งนั้น
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีตอบกลับเหตุการณ์การโต้ตอบ MESSAGE
ที่มีคำสั่งเครื่องหมายทับ
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
หากต้องการใช้โค้ด ให้แทนที่รายการต่อไปนี้:
ID
: รหัสคำสั่งที่ระบุเมื่อกำหนดค่าคำสั่งเครื่องหมายทับใน Google Chat APIrunFunction
: ฟังก์ชันที่สร้างการตอบสนองต่อคำสั่งเครื่องหมายทับ
ไม่บังคับ: ตอบด้วยข้อความส่วนตัว
เฉพาะผู้ใช้ที่ส่งข้อความและแอป Chat ที่ได้รับคำสั่งเท่านั้นที่จะเห็นข้อความที่มีคำสั่งเครื่องหมายทับเท่านั้น หากคุณกำหนดค่าแอป Chat ให้เพิ่มไปยังพื้นที่ทำงานที่มีผู้ใช้หลายคน คุณอาจพิจารณาตอบกลับคำสั่งเครื่องหมายทับแบบส่วนตัวเพื่อรักษาความเป็นส่วนตัวระหว่างผู้ใช้และแอปใน Chat
ตัวอย่างเช่น หากทีมกำลังใช้แอป Chat ที่จัดการบริการสนับสนุนลูกค้า ผู้ใช้จะเรียกใช้คำสั่งเครื่องหมายทับ เช่น /myCases
เพื่อดูเคสขอรับความช่วยเหลือที่มอบหมายได้ หากทีมเพิ่มแอป Chat ไปยังพื้นที่ทำงาน ผู้ใช้ที่ใช้คำสั่งเครื่องหมายทับนี้ในพื้นที่ทำงานอาจต้องการให้แอป Chat ตอบกลับเท่านั้น แอป Chat จะตอบกลับแบบส่วนตัวได้ เพื่อหลีกเลี่ยงการโพสต์เคสขอรับความช่วยเหลือของผู้ใช้ถึงทุกคนในพื้นที่ทำงาน
หากต้องการตอบกลับคำสั่งเครื่องหมายทับแบบส่วนตัว โปรดดูหัวข้อส่งข้อความส่วนตัวไปยังผู้ใช้ Google Chat
ตัวอย่างทั้งหมด: ตั้งค่ารายชื่อติดต่อโดยใช้แอป Rolodex Chat
ตัวอย่างต่อไปนี้แสดงแอป Chat ที่ตอบสนองต่อคำสั่งเครื่องหมายทับต่อไปนี้
- คำสั่ง
/help
จะแสดงผล SMS อธิบายวิธีรับการสนับสนุนด้วยแอป Chat รหัสคำสั่งได้รับการตั้งค่าเป็น1
- คำสั่ง
/createContact
จะเปิดกล่องโต้ตอบที่ผู้ใช้สามารถป้อนรายละเอียดเกี่ยวกับรายชื่อติดต่อได้ ตั้งค่ารหัสคำสั่งเป็น2
แล้ว
ก่อนเรียกใช้ตัวอย่างนี้ ให้ทำตามขั้นตอนเพื่อกำหนดค่าคำสั่งเครื่องหมายทับใน Google Chat API
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
ตัวอย่างนี้จะส่งข้อความการ์ดโดยแสดงผล JSON ของการ์ด หรือจะใช้บริการการ์ด 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!"
}
}
}