เว็บฮุค

คุณสามารถมอบสิทธิ์ตรรกะ ให้กับบริการเว็บ HTTPS (การดำเนินการตามคำสั่ง) เพื่อให้มีความยืดหยุ่นในการสร้าง Actions มากยิ่งขึ้น การดำเนินการของคุณสามารถทริกเกอร์เว็บฮุคที่ ส่งคำขอไปยังปลายทาง HTTPS ได้ ตัวอย่างสิ่งที่คุณทำได้ในการ จัดการคำสั่งซื้อมีดังนี้

  • สร้างพรอมต์แบบไดนามิกตามข้อมูลที่ผู้ใช้ระบุ
  • การสั่งซื้อในระบบภายนอกและการยืนยันว่าสำเร็จ
  • การตรวจสอบความถูกต้องของช่องด้วยข้อมูลแบ็กเอนด์
รูปที่ 1 Intent การเรียกใช้และฉากสามารถทริกเกอร์ Webhook ได้

ทริกเกอร์และตัวแฮนเดิลของเว็บฮุค

การดำเนินการของคุณสามารถทริกเกอร์เว็บฮุคภายใน 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

  1. เปิดโปรเจ็กต์ Actions แล้วไปที่แท็บพัฒนา > เว็บฮุก > เปลี่ยน วิธีการจัดการคำสั่งซื้อ หน้าต่างวิธีการจัดการคำสั่งซื้อจะปรากฏขึ้น
  2. เลือก Cloud Functions แบบอินไลน์ แล้วคลิกยืนยัน

ปลายทาง HTTPS ภายนอก

ส่วนนี้อธิบายวิธีตั้งค่า Cloud Functions for Firebase เป็นบริการ Fulfillment สำหรับการกระทำแบบสนทนา อย่างไรก็ตาม คุณสามารถติดตั้งใช้งาน การจัดการคำสั่งซื้อกับบริการโฮสติ้งที่คุณเลือกได้

ตั้งค่าสภาพแวดล้อม

หากต้องการตั้งค่าสภาพแวดล้อม ให้ทำตามขั้นตอนต่อไปนี้

  1. ดาวน์โหลดและติดตั้ง Node.js
  2. ตั้งค่าและเริ่มต้น Firebase CLI หากเรียกใช้คำสั่งต่อไปนี้ไม่สำเร็จโดยมีข้อผิดพลาด EACCES คุณอาจต้องเปลี่ยนสิทธิ์ npm

    npm install -g firebase-tools
    
  3. ตรวจสอบสิทธิ์เครื่องมือ Firebase ด้วยบัญชี Google โดยทำดังนี้

    firebase login
    
  4. เริ่มไดเรกทอรีโปรเจ็กต์ที่คุณบันทึกโปรเจ็กต์ Actions ระบบจะขอให้คุณเลือกฟีเจอร์ Firebase CLI ที่ต้องการตั้งค่าสำหรับโปรเจ็กต์ Actions เลือก Functions และฟีเจอร์อื่นๆ ที่คุณอาจต้องการใช้ เช่น Firestore จากนั้นกด Enter เพื่อยืนยันและดำเนินการต่อ

    $ cd <ACTIONS_PROJECT_DIRECTORY>
    $ firebase init
    
  5. เชื่อมโยงเครื่องมือ Firebase กับโปรเจ็กต์ Actions โดยเลือกเครื่องมือดังกล่าวโดยใช้ปุ่มลูกศรเพื่อไปยังรายการโปรเจ็กต์

  6. หลังจากเลือกโปรเจ็กต์แล้ว เครื่องมือ 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
    
  7. เลือกว่าต้องการใช้ ESLint เพื่อตรวจหาข้อบกพร่องที่อาจเกิดขึ้นและบังคับใช้รูปแบบโดยพิมพ์ Y หรือ N

    ? Do you want to use ESLint to catch probable bugs and enforce style? (Y/n)
  8. รับการอ้างอิงของโปรเจ็กต์โดยพิมพ์ Y ในพรอมต์

    ? Do you want to install dependencies with npm now? (Y/n)

    เมื่อตั้งค่าเสร็จแล้ว คุณจะเห็นเอาต์พุตคล้ายกับตัวอย่างต่อไปนี้

    ✔  Firebase initialization complete!
    
  9. ติดตั้งทรัพยากร Dependency @assistant/conversation

    $ cd <ACTIONS_PROJECT_DIRECTORY>/functions
    $ npm install @assistant/conversation --save
    
  10. รับทรัพยากร 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>
  11. คัดลอก URL การดำเนินการตามคำสั่งเพื่อใช้ในส่วนถัดไป

ลงทะเบียนตัวแฮนเดิลเว็บฮุค

วิธีลงทะเบียนปลายทาง Cloud Functions เป็นตัวแฮนเดิล Webhook

  1. ในคอนโซล Actions ให้คลิกพัฒนา > เว็บฮุก
  2. คลิกเปลี่ยนวิธีการจัดการคำสั่งซื้อ หน้าต่างวิธีการจัดการคำสั่งซื้อจะปรากฏขึ้น
  3. เลือก Webhook แล้วคลิกยืนยัน
  4. วาง URL ของเว็บเซอร์วิสลงในช่องเว็บฮุค
  5. คลิกบันทึก