เว็บฮุค

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

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

ทริกเกอร์และเครื่องจัดการเว็บฮุค

การดำเนินการสามารถทริกเกอร์เว็บฮุคภายใน Intent คำขอหรือฉาก ซึ่งจะส่งคำขอไปยังปลายทาง Fulfillment Fulfillment ของคุณมีเครื่องจัดการเว็บฮุคที่ประมวลผลเพย์โหลด JSON ในคำขอ คุณทริกเกอร์เว็บฮุคได้ในกรณีต่อไปนี้

  • หลังจากการจับคู่ Intent ของคำขอ
  • ระหว่างที่อยู่ในฉากบนเวที
  • หลังจากระบบประเมินเงื่อนไขเป็น "จริง" ในขั้นตอนเงื่อนไขของฉาก
  • ขณะที่อยู่ในระยะเติมช่องของฉาก
  • หลังจากการจับคู่ Intent เกิดขึ้นในขั้นตอนป้อนข้อมูลของฉาก

เมื่อคุณทริกเกอร์เว็บฮุคในการดำเนินการ Google Assistant จะส่งคำขอที่มีเพย์โหลด JSON ไปยัง Fulfillment ของคุณ ซึ่งจะมีชื่อเครื่องจัดการที่ใช้ประมวลผลเหตุการณ์ ปลายทางการดำเนินการตามคำสั่งซื้อจะกำหนดเส้นทางเหตุการณ์ไปยังเครื่องจัดการที่เหมาะสมเพื่อดำเนินการตรรกะและแสดงผลการตอบสนองที่สอดคล้องกันด้วยเพย์โหลด JSON

เพย์โหลด

ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างคำขอที่การดำเนินการส่งไปยัง 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"
    }
  }
}

การโต้ตอบในรันไทม์

ส่วนต่อไปนี้จะอธิบายงานทั่วไปที่คุณสามารถทำในเครื่องจัดการเว็บฮุคได้

ส่งข้อความแจ้ง

คุณสามารถสร้างพรอมต์ที่เป็นข้อความง่ายๆ, Rich Text, การ์ด รวมไปถึงพรอมต์ HTML แบบเต็มโดยเว็บแอปที่มี Interactive Canvas เอกสารประกอบเกี่ยวกับข้อความแจ้งมีข้อมูลครบถ้วนเกี่ยวกับวิธีสร้างข้อความแจ้งเมื่อจัดการเหตุการณ์เว็บฮุค ข้อมูลโค้ดต่อไปนี้จะแสดงข้อความแจ้งของการ์ด

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": ""
    }
  }
}

อ่านพารามิเตอร์ Intent

เมื่อรันไทม์ของ 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

การลบล้างประเภทรันไทม์

ประเภทรันไทม์ช่วยให้คุณแก้ไขข้อกำหนดประเภทในระหว่างรันไทม์ได้ คุณใช้ฟีเจอร์นี้เพื่อโหลดข้อมูลจากแหล่งที่มาอื่นๆ เพื่อเติมค่าที่ถูกต้องของประเภทได้ ตัวอย่างเช่น คุณสามารถใช้การลบล้างประเภทรันไทม์เพื่อเพิ่มตัวเลือกแบบไดนามิกในคำถามของแบบสำรวจ หรือเพื่อเพิ่มรายการประจำวันลงในเมนู

หากต้องการใช้ประเภทรันไทม์ คุณจะต้องทริกเกอร์เว็บฮุคจากการดำเนินการที่เรียกใช้แฮนเดิลใน 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 เพื่อปรับปรุงการจับคู่ Intent คุณสามารถระบุได้สูงสุด 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 ซึ่งช่วยให้คุณสร้างและทำให้ Cloud Function สำหรับ Firebase ใช้งานได้ในคอนโซลโดยตรง คุณยังสร้างและทำให้ Fulfillment ของโฮสต์ที่เลือกใช้งานได้และลงทะเบียนปลายทาง Fulfillment HTTPS เป็นตัวแฮนเดิลของเว็บฮุคได้อีกด้วย

การแก้ไขในบรรทัด

วิธีพัฒนาด้วยเครื่องมือแก้ไข Cloud Functions

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

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

ส่วนนี้จะอธิบายวิธีตั้งค่า Cloud Functions for Firebase เป็นบริการ Fulfillment สำหรับ Conversational Action แต่คุณทำให้ 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 กับโปรเจ็กต์การดำเนินการของคุณโดยเลือกเครื่องมือดังกล่าวโดยใช้ปุ่มลูกศรเพื่อไปยังรายการโปรเจ็กต์ ดังนี้

  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. รับทรัพยากร Dependency ของโปรเจ็กต์โดยพิมพ์ 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 ของ Fulfillment และทำให้ฟังก์ชัน Fulfillment ใช้งานได้ด้วยคำสั่งต่อไปนี้

    $ npm install
    $ firebase deploy --only functions
    

    การทำให้ใช้งานได้จะใช้เวลา 2-3 นาที เมื่อเสร็จสิ้นแล้ว คุณจะเห็นเอาต์พุตคล้ายกับตัวอย่างต่อไปนี้ คุณจะต้องใช้ 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 Function เป็นเครื่องจัดการเว็บฮุค

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