כדי להעניק לכם גמישות רבה יותר בבניית פעולות, אתם יכולים להקצות לוגיקה לשירותי אינטרנט של HTTPS (השלמת בקשות). הפעולות שלכם יכולות להפעיל webhooks ששולחים בקשות לנקודת קצה של HTTPS. דוגמאות לפעולות שאפשר לבצע בתהליך השלמת ההזמנה:
- יצירת הנחיה דינמית על סמך מידע שהמשתמש סיפק.
- ביצוע הזמנה במערכת חיצונית ואישור שהיא בוצעה בהצלחה.
- אימות משבצות באמצעות נתוני קצה עורפי.
מפעילים ומטפלים ב-webhook
הפעולות שלכם יכולות להפעיל webhook בתוך כוונות הפעלה או סצנות, ששולח בקשה לנקודת הקצה של ההשלמה. ההזמנה שלכם כוללת רכיבי handler של webhook שמבצעים עיבוד של מטען ייעודי (payload) מסוג JSON בבקשה. אפשר להפעיל וווב-הוקים במצבים הבאים:
- אחרי התאמה של כוונת הפעלה
- במהלך שלב הכניסה לסצנה
- אחרי שתנאי מסוים מקבל את הערך true בשלב התנאי של סצנה
- במהלך שלב מילוי המשבצות של סצנה
- אחרי שמתרחש התאמה של כוונת המשתמש בשלב הקלט של סצנה
כשמפעילים webhook בפעולות, Google Assistant שולחת בקשה עם מטען ייעודי (payload) בפורמט JSON אל מרכז הבקשות, שמכיל את שם ה-handler שמשמש לעיבוד האירוע. נקודת הקצה של תהליך השלמת ההזמנה יכולה להפנות את האירוע לטיפול המתאים כדי לבצע לוגיקה ולהחזיר תגובה תואמת עם מטען ייעודי (payload) של JSON.
מטענים ייעודיים (payloads)
בדוגמאות הקוד הבאות אפשר לראות בקשות לדוגמה שהפעולות שולחות ל-fulfillment ותגובה שה-fulfillment שולח בחזרה. מידע נוסף מופיע במאמרי העזרה.
דוגמה לבקשה
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "UNSPECIFIED",
"slots": {}
},
"session": {
"id": "example_session_id",
"params": {},
"typeOverrides": []
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED"
}
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
דוגמה לתשובה
{
"session": {
"id": "example_session_id",
"params": {}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "Hello World.",
"text": ""
}
},
"scene": {
"name": "SceneName",
"slots": {},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
}
}
אינטראקציות בזמן ריצה
בקטעים הבאים מתוארות משימות נפוצות שאפשר לבצע ב-webhook handlers.
שליחת הנחיות
אתם יכולים ליצור הנחיות עם טקסט פשוט, טקסט עשיר, כרטיסים ואפילו הנחיות HTML מלאות שמגובות באפליקציית אינטרנט עם לוח ציור אינטראקטיבי. במסמכי התיעוד בנושא הנחיות יש מידע מלא על יצירת הנחיה כשמטפלים באירוע של webhook. בקטעי הקוד הבאים מוצגת הנחיה בכרטיס:
Node.js
app.handle('rich_response', conv => {
conv.add('This is a card rich response.');
conv.add(new Card({
title: 'Card Title',
subtitle: 'Card Subtitle',
text: 'Card Content',
image: new Image({
url: 'https://developers.google.com/assistant/assistant_96.png',
alt: 'Google Assistant logo'
})
}));
});
תגובת JSON
{
"session": {
"id": "example_session_id",
"params": {}
},
"prompt": {
"override": false,
"content": {
"card": {
"title": "Card Title",
"subtitle": "Card Subtitle",
"text": "Card Content",
"image": {
"alt": "Google Assistant logo",
"height": 0,
"url": "https://developers.google.com/assistant/assistant_96.png",
"width": 0
}
}
},
"firstSimple": {
"speech": "This is a card rich response.",
"text": ""
}
}
}
קריאת פרמטרים של כוונת חיפוש
כשזמן הריצה של Assistant תואם לכוונת המשתמש, הוא מחלץ את כל הפרמטרים המוגדרים. המאפיין המקורי הוא מה שהמשתמש סיפק כקלט, והמאפיין שפוענח הוא מה ש-NLU פירש את הקלט על סמך סוג המפרט.
Node.js
conv.intent.params['param_name'].original
conv.intent.params['param_name'].resolved
בקשת JSON
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "intent_name",
"params": {
"slot_name": {
"original": "1",
"resolved": 1
}
},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "UNSPECIFIED",
"slots": {},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
},
"session": {
"id": "session_id",
"params": {},
"typeOverrides": []
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED"
}
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
קריאת הלוקאל של המשתמש
הערך הזה תואם להגדרת הלוקאל של המשתמש ב-Google Assistant.
Node.js
conv.user.locale
JSON
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "UNSPECIFIED",
"slots": {}
},
"session": {
"id": "session_id",
"params": {},
"typeOverrides": []
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED"
}
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
קריאה וכתיבה של נתוני אחסון
במאמר בנושא אחסון מוסבר בפירוט איך להשתמש בתכונות השונות של האחסון.
Node.js
//read
conv.session.params.key
conv.user.params.key
conv.home.params.key
// write
conv.session.params.key = value
conv.user.params.key = value
conv.home.params.key = value
בקשת JSON
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "UNSPECIFIED",
"slots": {}
},
"session": {
"id": "session_id",
"params": {
"key": "value"
},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED",
"key": "value"
}
},
"home": {
"params": {
"key": "value"
}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
תגובת JSON
{
"session": {
"id": "session_id",
"params": {
"key": "value"
}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "Hello world.",
"text": ""
}
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED",
"key": "value"
}
},
"home": {
"params": {
"key": "value"
}
}
}
בדיקת היכולות של המכשיר
אתם יכולים לבדוק את היכולות של המכשיר כדי לספק חוויות שונות או רצפים שונים של שיחות.
Node.js
const supportsRichResponse = conv.device.capabilities.includes("RICH_RESPONSE");
const supportsLongFormAudio = conv.device.capabilities.includes("LONG_FORM_AUDIO");
const supportsSpeech = conv.device.capabilities.includes("SPEECH");
const supportsInteractiveCanvas = conv.device.capabilities.includes("INTERACTIVE_CANVAS");
בקשת JSON
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "actions.intent.MAIN",
"params": {},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "UNSPECIFIED",
"slots": {}
},
"session": {
"id": "session_id",
"params": {},
"typeOverrides": [],
"languageCode": ""
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED"
}
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO",
"INTERACTIVE_CANVAS"
]
}
}
רשימה מלאה של היכולות של המשטחים זמינה במאמר Capability.
שינויים בסוג של סביבת זמן הריצה
סוגים של סביבת זמן הריצה מאפשרים לשנות את הגדרות הסוג בזמן הריצה. אתם יכולים להשתמש בתכונה הזו כדי לטעון נתונים ממקורות אחרים ולמלא את הערכים התקפים של סוג. לדוגמה, אפשר להשתמש בשינויים של סוג בזמן ריצה כדי להוסיף אפשרויות דינמיות לשאלון או כדי להוסיף פריט יומי לתפריט.
כדי להשתמש בסוגי נתונים בזמן ריצה, מפעילים webhook מהפעולה שקורא ל-handler ב-fulfillment. משם, אפשר לאכלס את הפרמטר session.typeOverrides בתגובה שחוזרת לפעולה. האפשרויות הזמינות כוללות TYPE_MERGE כדי לשמור את הערכים הקיימים של הסוגים או TYPE_REPLACE כדי להחליף את הערכים הקיימים בערכי ברירת המחדל.
Node.js
conv.session.typeOverrides = [{
name: type_name,
mode: 'TYPE_REPLACE',
synonym: {
entries: [
{
name: 'ITEM_1',
synonyms: ['Item 1', 'First item']
},
{
name: 'ITEM_2',
synonyms: ['Item 2', 'Second item']
},
{
name: 'ITEM_3',
synonyms: ['Item 3', 'Third item']
},
{
name: 'ITEM_4',
synonyms: ['Item 4', 'Fourth item']
},
]
}
}];
תגובת JSON
{
"session": {
"id": "session_id",
"params": {},
"typeOverrides": [
{
"name": "type_name",
"synonym": {
"entries": [
{
"name": "ITEM_1",
"synonyms": [
"Item 1",
"First item"
]
},
{
"name": "ITEM_2",
"synonyms": [
"Item 2",
"Second item"
]
},
{
"name": "ITEM_3",
"synonyms": [
"Item 3",
"Third item"
]
},
{
"name": "ITEM_4",
"synonyms": [
"Item 4",
"Fourth item"
]
}
]
},
"typeOverrideMode": "TYPE_REPLACE"
}
]
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "This is an example prompt.",
"text": "This is an example prompt."
}
}
}
הוספת הטיה לדיבור
הטיה של דיבור מאפשרת לכם לציין רמזים ל-NLU כדי לשפר את ההתאמה של הכוונות. אפשר לציין עד 1,000 רשומות.
Node.js
conv.expected.speech = ['value_1', 'value_2']
conv.expected.language = 'locale_string'
תגובת JSON
{
"session": {
"id": "session_id",
"params": {}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "This is an example prompt.",
"text": "This is an example prompt."
}
},
"expected": {
"speech": "['value_1', 'value_2']",
"language": "locale_string"
}
}
מעבר בין סצנות
בנוסף להגדרת מעברים סטטיים בפרויקט Actions, אפשר לגרום למעברים בין סצנות להתרחש בזמן הריצה.
Node.js
app.handle('transition_to_hidden_scene', conv => {
// Dynamic transition
conv.scene.next.name = "HiddenScene";
});
תגובת JSON
{
"session": {
"id": "session_id",
"params": {}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "This is an example prompt.",
"text": ""
}
},
"scene": {
"name": "SceneName",
"slots": {},
"next": {
"name": "HiddenScene"
}
}
}
קריאה של משבצות סצנה
במהלך אכלוס המשבצת, אפשר להשתמש ב-fulfillment כדי לאמת את המשבצת או לבדוק את הסטטוס של אכלוס המשבצת (SlotFillingStatus).
Node.js
conv.scene.slotFillingStatus // FINAL means all slots are filled
conv.scene.slots // Object that contains all the slots
conv.scene.slots['slot_name'].<property_name> // Accessing a specific slot's properties
לדוגמה, נניח שרוצים לחלץ את אזור הזמן מתשובה. בדוגמה הזו, שם המשבצת הוא datetime1. כדי לקבל את אזור הזמן, צריך להשתמש בפונקציה:
conv.scene.slots['datetime1'].value.time_zone.id
בקשת JSON
{
"handler": {
"name": "handler_name"
},
"intent": {
"name": "",
"params": {
"slot_name": {
"original": "1",
"resolved": 1
}
},
"query": ""
},
"scene": {
"name": "SceneName",
"slotFillingStatus": "FINAL",
"slots": {
"slot_name": {
"mode": "REQUIRED",
"status": "SLOT_UNSPECIFIED",
"updated": true,
"value": 1
}
},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
},
"session": {
"id": "session_id",
"params": {
"slot_name": 1
},
"typeOverrides": []
},
"user": {
"locale": "en-US",
"params": {
"verificationStatus": "VERIFIED"
}
},
"home": {
"params": {}
},
"device": {
"capabilities": [
"SPEECH",
"RICH_RESPONSE",
"LONG_FORM_AUDIO"
]
}
}
ביטול התוקף של משבצות בסצנה
אתם יכולים לבטל משבצות ולדרוש מהמשתמש לספק ערך חדש.
Node.js
conv.scene.slots['slot_name'].status = 'INVALID'
תגובת JSON
{
"session": {
"id": "session_id",
"params": {
"slot_name": 1
}
},
"prompt": {
"override": false,
"firstSimple": {
"speech": "This is an example prompt.",
"text": ""
}
},
"scene": {
"name": "SceneName",
"slots": {
"slot_name": {
"mode": "REQUIRED",
"status": "INVALID",
"updated": true,
"value": 1
}
},
"next": {
"name": "actions.scene.END_CONVERSATION"
}
}
}
אפשרויות למפתחים
ב-Actions Builder יש עורך מוטבע שנקרא Cloud Functions editor, שמאפשר ליצור ולפרוס פונקציה של Cloud Functions for Firebase ישירות במסוף. אפשר גם ליצור ולפרוס את הפולפילמנט באירוח שתבחרו ולרשום את נקודת הקצה של הפולפילמנט מסוג HTTPS כמטפל ב-webhook.
עורך במקום
כדי לפתח באמצעות העורך של Cloud Functions:
- פותחים את פרויקט הפעולות ועוברים אל כרטיסיית הפיתוח > Webhook > שינוי שיטת ההשלמה. יופיע החלון Fulfillment methods (שיטות אספקה).
- בוחרים באפשרות Inline Cloud Functions (פונקציות Cloud Functions מוטבעות) ולוחצים על Confirm (אישור).
נקודת קצה (endpoint) חיצונית של HTTPS
בקטע הזה מוסבר איך להגדיר את Cloud Functions for Firebase כשירות לביצוע הזמנות לפעולה לשיחה. עם זאת, אתם יכולים לפרוס את הפונקציה של ניהול ההזמנות בשירות אירוח שתבחרו.
הגדרת הסביבה
כדי להגדיר את הסביבה, מבצעים את השלבים הבאים:
- הורדה והתקנה של Node.js.
מגדירים ומפעילים את Firebase CLI. אם הפקודה הבאה נכשלת ומוצגת שגיאת
EACCES, יכול להיות שתצטרכו לשנות את ההרשאות של npm.npm install -g firebase-toolsמאמתים את כלי Firebase באמצעות חשבון Google:
firebase loginמפעילים את ספריית הפרויקט שבה שמרתם את פרויקט הפעולות. תתבקשו לבחור אילו תכונות של Firebase CLI אתם רוצים להגדיר לפרויקט Actions. בוחרים באפשרות
Functionsובתכונות אחרות שאולי תרצו להשתמש בהן, כמו Firestore, ואז מקישים על Enter כדי לאשר ולהמשיך:$ cd <ACTIONS_PROJECT_DIRECTORY> $ firebase initמשייכים את הכלי של Firebase לפרויקט Actions על ידי בחירתו באמצעות מקשי החיצים כדי לנווט ברשימת הפרויקטים:
אחרי שבוחרים את הפרויקט, כלי Firebase מתחיל בהגדרת הפונקציות ושואל באיזו שפה רוצים להשתמש. בוחרים באמצעות מקשי החיצים ומקישים על Enter כדי להמשיך.
=== Functions Setup A functions directory will be created in your project with a Node.js package pre-configured. Functions can be deployed with firebase deploy. ? What language would you like to use to write Cloud Functions? (Use arrow keys) > JavaScript TypeScript
בוחרים אם להשתמש ב-ESLint כדי לזהות באגים אפשריים ולאכוף סגנון על ידי הקלדת Y או N:
? Do you want to use ESLint to catch probable bugs and enforce style? (Y/n)
כדי לקבל את יחסי התלות של הפרויקט, מקלידים Y בהנחיה:
? Do you want to install dependencies with npm now? (Y/n)
אחרי שההגדרה תסתיים, יוצג פלט שדומה לזה שמופיע בדוגמה הבאה:
✔ Firebase initialization complete!מתקינים את יחסי התלות של @assistant/conversation:
$ cd <ACTIONS_PROJECT_DIRECTORY>/functions $ npm install @assistant/conversation --saveמקבלים את יחסי התלות של המילוי ופורסים את פונקציית המילוי:
$ npm install $ firebase deploy --only functionsהפריסה נמשכת כמה דקות. אחרי שתשלימו את הפעולה, יוצג פלט שדומה לזה שמופיע בהמשך. תצטרכו את כתובת ה-URL של הפונקציה כדי להזין אותה ב-Dialogflow.
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/<PROJECT_ID>/overview Function URL (<FUNCTION_NAME>): https://us-central1-<PROJECT_ID>.cloudfunctions.net/<FUNCTION_NAME>מעתיקים את כתובת ה-URL של ה-fulfillment כדי להשתמש בה בקטע הבא.
רישום handler של webhook
כדי לרשום את נקודת הקצה של Cloud Functions כמטפל ב-webhook:
- במסוף Actions, לוחצים על Develop > Webhook.
- לוחצים על שינוי שיטת המשלוח. מופיע החלון שיטות אספקה.
- בוחרים באפשרות Webhook ולוחצים על אישור.
- מדביקים את כתובת ה-URL של שירות האינטרנט בשדה Webhook.
- לוחצים על שמירה.