تشرح هذه الصفحة كيفية إعداد أوامر الشرطة المائلة والاستجابة لها في تطبيق Google Chat
تُعد أمر الشرطة المائلة طريقة شائعة يقوم بها المستخدمون باستدعاء وتفاعل مع تطبيق Chat تساعد الأوامر التي تبدأ بشرطة مائلة المستخدمين على اكتشاف استخدام الميزات الرئيسية لتطبيق Chat.
لاستخدام أمر شرطة مائلة، يكتب المستخدمون شرطة مائلة (/
)، ثم أمرًا نصيًا قصيرًا،
مثل "/about
" للحصول على معلومات عن تطبيق Chat.
يمكن للمستخدمين اكتشاف الأوامر التي تبدأ بشرطة مائلة عن طريق كتابة شرطة مائلة في
Google Chat، الذي يعرض نافذة تسرد الأوامر المتاحة
تطبيق Chat:
![نافذة أوامر تبدأ بشرطة مائلة](https://developers.google.cn/static/workspace/chat/images/slash-command-window.png?authuser=8&hl=ar)
عندما يرسل المستخدم رسالة تحتوي على أمر شرطة مائلة، فإن الرسالة مرئية للمستخدم وتطبيق Chat.
لتحديد ما إذا كان ينبغي لك إعداد الأوامر التي تبدأ بشرطة مائلة، وفهم كيفية تصميم تفاعلات المستخدم، انظر تحديد جميع رحلات المستخدم:
المتطلبات الأساسية
Node.js
تطبيق Google Chat مفعَّل للميزات التفاعلية لإنشاء تطبيق Chat تفاعليًا باستخدام خدمة HTTP، أكمِل عملية البدء السريع هذه.
برمجة تطبيقات
تطبيق Google Chat مفعَّل للميزات التفاعلية لإنشاء تطبيق Chat التفاعلي في "برمجة تطبيقات Google"، أكمِل البدء السريع هذا.
Python
تطبيق Google Chat مفعَّل للميزات التفاعلية لإنشاء تطبيق Chat تفاعليًا باستخدام خدمة HTTP، أكمِل عملية البدء السريع هذه.
إعداد أمر شرطة مائلة
يوضّح هذا القسم كيفية إكمال الخطوات التالية لإعداد الشرطة المائلة :
- أنشئ اسمًا للأمر الذي يبدأ بشرطة مائلة.
- ضبط الأمر الشرطة المائلة في Google Chat API
إدخال اسم للأمر الذي يبدأ بشرطة مائلة
يكون اسم الأمر slash هو ما يكتبه المستخدمون في رسالة Chat. لاستدعاء تطبيق Chat. يحتوي الوصف الموجز أيضًا أسفل الاسم، لمطالبة المستخدمين بالمزيد حول كيفية استخدام الأمر:
![اسم الأمر الذي يبدأ بشرطة مائلة ووصفها](https://developers.google.cn/static/workspace/chat/images/slash-command-description.png?authuser=8&hl=ar)
عند اختيار اسم ووصف للأمر الذي يبدأ بشرطة مائلة، ضع في اعتبارك الاقتراحات التالية:
لتسمية الأمر الذي تبدأ بشرطة مائلة:
- استخدم كلمات أو عبارات قصيرة ووصفية وقابلة للتنفيذ لإنشاء
واضحة وبسيطة للمستخدم. على سبيل المثال، بدلاً من أن تقول
/createAReminder
، استخدِم/remindMe
. - إذا كان الأمر يحتوي على أكثر من كلمة، ساعِد المستخدمين على قراءة الأمر.
باستخدام الأحرف الصغيرة بالكامل في الكلمة الأولى ثم كتابة الكلمة الأولى بالحروف الكبيرة
حرف من الكلمات الإضافية. على سبيل المثال، بدلاً من
/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، انقر على "القائمة" > واجهات برمجة التطبيقات الخدمات > واجهات برمجة التطبيقات المفعّلة الخدمات > 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.
}
}
برمجة تطبيقات
/**
* 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
: معرّف الأمر الذي تحدّده عند إجراء ضبط الأمر slash في واجهة برمجة تطبيقات Google ChatrunFunction
: دالة تنشئ ردًا على أمر الشرطة المائلة.
اختياري: الرد برسالة خاصة
لا تظهر الرسائل التي تحتوي على أوامر شرطة مائلة إلا للمستخدم الذي أرسل وتطبيق Chat الذي يتلقّى الأمر في حال حذف لقد ضبطت تطبيق Chat لتتم إضافته إلى المساحات مع عدة أشخاص، فقد تفكر في الاستجابة للأمر الذي يبدأ بالشرطة المائلة بشكل خاص، للحفاظ على خصوصية التفاعل بين المستخدم تطبيق Chat
على سبيل المثال، إذا كان الفريق يستخدم تطبيق Chat يدير
لخدمة دعم العملاء، يمكن للمستخدمين استدعاء أمر شرطة مائلة مثل
/myCases
للاطّلاع على طلبات الحصول على الدعم التي تم تعيينها إليهم. إذا أضاف الفريق
تطبيق Chat على مساحة، وهو المستخدم الذي يستخدم أمر الشرطة المائلة هذا
في المساحة قد يحتاج تطبيق Chat إلى الردّ فقط على
معهم. لتجنُّب نشر طلبات الحصول على الدعم الخاصة بالمستخدم لكل فرد في المساحة،
يمكن لتطبيق Chat الردّ بخصوصية تامة.
للرد على أمر يبدأ بشرطة مائلة بخصوصية، يمكنك الاطلاع على إرسال رسائل خاصة إلى مستخدمي Google Chat
مثال كامل: إعداد جهات الاتصال باستخدام تطبيق Rolodex Chat
يوضّح المثال التالي تطبيق Chat يستجيب لـ الأوامر التي تبدأ بشرطة مائلة التالية:
- يعرض الأمر
/help
رسالة نصية توضح كيفية الحصول على الدعم مع تطبيق 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"
}
}
};
}
}
برمجة تطبيقات
يرسل هذا المثال رسالة بطاقة من خلال عرض بطاقة JSON. يمكنك أيضًا استخدام صفحة خدمة بطاقة "برمجة تطبيقات Google"
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!"
}
}
}