คุณสามารถมอบสิทธิ์ตรรกะ ให้กับบริการเว็บ HTTPS (การดำเนินการตามคำสั่ง) เพื่อให้มีความยืดหยุ่นในการสร้าง Actions มากยิ่งขึ้น การดำเนินการของคุณสามารถทริกเกอร์เว็บฮุคที่ ส่งคำขอไปยังปลายทาง HTTPS ได้ ตัวอย่างสิ่งที่คุณทำได้ในการ จัดการคำสั่งซื้อมีดังนี้
- สร้างพรอมต์แบบไดนามิกตามข้อมูลที่ผู้ใช้ระบุ
- การสั่งซื้อในระบบภายนอกและการยืนยันว่าสำเร็จ
- การตรวจสอบความถูกต้องของช่องด้วยข้อมูลแบ็กเอนด์
ทริกเกอร์และตัวแฮนเดิลของเว็บฮุค
การดำเนินการของคุณสามารถทริกเกอร์เว็บฮุคภายใน Intent หรือฉากการเรียกใช้ ซึ่งจะส่งคำขอไปยังปลายทางการดำเนินการตามคำสั่ง การดำเนินการตามคำสั่งมีตัวแฮนเดิลเว็บฮุค ที่ประมวลผลเพย์โหลด JSON ในคำขอ คุณเรียกใช้เว็บฮุกได้ในกรณีต่อไปนี้
- หลังจากที่ Intent เรียกใช้ตรงกัน
- ในระหว่างที่ฉากเข้าสู่พื้นที่งาน
- หลังจากที่เงื่อนไขประเมินเป็นจริงในขั้นตอนเงื่อนไขของฉาก
- ในระหว่างขั้นตอนการป้อนข้อมูลในช่องของฉาก
- หลังจากที่การจับคู่ความตั้งใจเกิดขึ้นในขั้นตอนการป้อนข้อมูลของฉาก
เมื่อคุณทริกเกอร์เว็บฮุคใน Actions ของคุณ Google Assistant จะส่งคำขอ พร้อมเพย์โหลด JSON ไปยัง Fulfillment ซึ่งมี ชื่อของแฮนเดิลที่จะใช้ประมวลผลเหตุการณ์ ปลายทางการดำเนินการตามคำสั่งสามารถ กำหนดเส้นทางเหตุการณ์ไปยังแฮนเดิลที่เหมาะสมเพื่อดำเนินการตามตรรกะและส่งคืนการตอบกลับที่สอดคล้องกันพร้อมเพย์โหลด JSON
เพย์โหลด
ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างคำขอที่ Actions ของคุณส่งไปยัง การดำเนินการตามคำสั่ง และการตอบกลับที่การดำเนินการตามคำสั่งส่งกลับมา ดูข้อมูลเพิ่มเติมในเอกสารอ้างอิง
ตัวอย่างคำขอ
{
"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
ส่งพรอมต์
คุณสร้างพรอมต์ได้ด้วยข้อความธรรมดา Rich Text การ์ด และแม้แต่พรอมต์ HTML แบบเต็มที่ขับเคลื่อนโดยเว็บแอปที่มี Interactive Canvas เอกสารประกอบพรอมต์มีข้อมูลที่ครบถ้วนเกี่ยวกับวิธีสร้างพรอมต์เมื่อจัดการเหตุการณ์ 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 ตรงกับ Intent ระบบจะแยกพารามิเตอร์ที่กำหนด พร็อพเพอร์ตี้เดิมคือสิ่งที่ผู้ใช้ระบุเป็นอินพุต และพร็อพเพอร์ตี้ที่แก้ไขแล้วคือสิ่งที่ 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 จาก Action ที่เรียกใช้แฮนเดิลใน Fulfillment จากนั้นคุณจะป้อนพารามิเตอร์
session.typeOverrides ในการตอบกลับไปยัง Action ได้ โหมดที่ใช้ได้ ได้แก่ 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"
}
}
}
อ่านช่องฉาก
ในระหว่างการเติมข้อมูลช่อง คุณสามารถใช้การดำเนินการตามคำสั่งเพื่อตรวจสอบช่องหรือตรวจสอบ
สถานะของการเติมข้อมูลช่อง (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 ซึ่งช่วยให้คุณสร้างและทำให้ Cloud Function สำหรับ Firebase ใช้งานได้ในคอนโซลโดยตรง นอกจากนี้ คุณยังสร้างและทำให้ใช้งานได้การประมวลผลตามคำสั่งไปยังโฮสติ้งที่คุณเลือก และจดทะเบียนปลายทางการประมวลผลตามคำสั่ง HTTPS เป็นตัวแฮนเดิลเว็บฮุคได้ด้วย
ตัวแก้ไขอินไลน์
วิธีพัฒนาด้วยโปรแกรมแก้ไข Cloud Functions
- สร้างไฟล์
sdk/webhooks/ActionsOnGoogleFulfillment.yaml, และกำหนดตัวแฮนเดิลสำหรับ Action และฟังก์ชันระบบคลาวด์แบบอินไลน์ที่ใช้ สำหรับการดำเนินการตามคำสั่งhandlers: - name: questionOnEnterFunc - name: fruitSlotValidationFunc inlineCloudFunction: executeFunction: ActionsOnGoogleFulfillment - สร้างโฟลเดอร์
sdk/webhooks/ActionsOnGoogleFulfillmentและเพิ่มไฟล์index.jsที่ใช้ตัวแฮนเดิล ที่กำหนดไว้ก่อนหน้านี้ และไฟล์package.jsonที่กำหนดข้อกำหนด npm สำหรับโค้ด// index.js const {conversation} = require('@assistant/conversation'); const functions = require('firebase-functions'); const app = conversation(); app.handle('questionOnEnterFunc', conv => { conv.add('questionOnEnterFunc triggered on webhook'); }); app.handle('fruitSlotValidationFunc', conv => { conv.add('fruitSlotValidationFunc triggered on webhook'); }); exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
// package.json { "name": "ActionsOnGoogleFulfillment", "version": "0.1.0", "description": "Actions on Google fulfillment", "main": "index.js", "dependencies": { "@assistant/conversation": "^3.0.0", "firebase-admin": "^5.4.3", "firebase-functions": "^0.7.1" } }
ปลายทาง HTTPS ภายนอก
ส่วนนี้อธิบายวิธีตั้งค่า Cloud Functions for Firebase เป็นบริการ Fulfillment สำหรับการกระทำแบบสนทนา อย่างไรก็ตาม คุณสามารถติดตั้งใช้งาน การจัดการคำสั่งซื้อกับบริการโฮสติ้งที่คุณเลือกได้
ตั้งค่าสภาพแวดล้อม
เราขอแนะนำให้ใช้โครงสร้างโปรเจ็กต์ต่อไปนี้เมื่อใช้ Cloud Functions สำหรับ Firebase เป็นบริการ Fulfillment
ProjectFolder - Root folder for the project sdk - Actions project configuration files functions - Cloud functions for Firebase files
หากต้องการตั้งค่าสภาพแวดล้อม ให้ทำตามขั้นตอนต่อไปนี้
- ดาวน์โหลดและติดตั้ง Node.js
ตั้งค่าและเริ่มต้น Firebase CLI หากเรียกใช้คำสั่งต่อไปนี้ไม่สำเร็จโดยมีข้อผิดพลาด
EACCESคุณอาจต้องเปลี่ยนสิทธิ์ npmnpm install -g firebase-toolsตรวจสอบสิทธิ์เครื่องมือ Firebase ด้วยบัญชี Google โดยทำดังนี้
firebase loginเริ่มไดเรกทอรีโปรเจ็กต์ที่คุณบันทึกโปรเจ็กต์ Actions ระบบจะขอให้คุณเลือกฟีเจอร์ 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!ติดตั้งทรัพยากร Dependency @assistant/conversation
$ cd <ACTIONS_PROJECT_DIRECTORY>/functions $ npm install @assistant/conversation --saveรับทรัพยากร Dependency ของการดำเนินการตามคำสั่งและทำให้ฟังก์ชันการดำเนินการตามคำสั่งใช้งานได้
$ 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 การดำเนินการตามคำสั่งเพื่อใช้ในส่วนถัดไป
ลงทะเบียนตัวแฮนเดิลเว็บฮุค
- สร้างไฟล์
sdk/webhooks/ActionsOnGoogleFulfillment.yamlและกำหนด ตัวแฮนเดิลสำหรับ Action และ URL สำหรับคำขอ WebhookhttpsEndpoint: baseUrl: https://my.web.hook/ActionsOnGoogleFulfillment endpointApiVersion: 2 handlers: - name: questionOnEnterFunc - name: fruitSlotValidationFunc