Webhook

Untuk memberi Anda fleksibilitas yang lebih besar dalam membuat Action, Anda dapat mendelegasikan logika ke layanan web HTTPS (fulfillment). Action Anda dapat memicu webhook yang membuat permintaan ke endpoint HTTPS. Beberapa contoh hal yang dapat Anda lakukan di pemenuhan pesanan meliputi:

  • Membuat prompt dinamis berdasarkan informasi yang diberikan oleh pengguna.
  • Melakukan pemesanan di sistem eksternal dan mengonfirmasi keberhasilan.
  • Memvalidasi slot dengan data backend.
Gambar 1. Intent dan scene pemanggilan dapat memicu webhook.

Pemicu dan pengendali webhook

Action Anda dapat memicu webhook dalam scene atau intent pemanggilan, yang mengirimkan permintaan ke endpoint fulfillment Anda. fulfillment Anda berisi webhook yang memproses payload JSON dalam permintaan. Anda dapat memicu webhook dalam situasi berikut:

  • Setelah intent pemanggilan cocok
  • Selama adegan berada di dalam panggung
  • Setelah kondisi dievaluasi ke benar (true) dalam tahap kondisi scene
  • Selama tahap pengisian slot dalam adegan
  • Setelah pencocokan intent terjadi dalam tahap input scene

Saat Anda memicu webhook di Action, Asisten Google akan mengirimkan permintaan dengan payload JSON ke fulfillment Anda, yang berisi nama pengendali yang akan digunakan untuk memproses peristiwa. Endpoint fulfillment Anda dapat merutekan peristiwa ke pengendali yang sesuai untuk menjalankan logika dan menampilkan respons yang terkait dengan payload JSON.

Payload

Cuplikan berikut menunjukkan contoh permintaan yang dikirim Action Anda ke pemenuhan dan respons yang dikirim kembali oleh {i>fulfillment<i} Anda. Lihat dokumentasi referensi untuk mengetahui tidak akurat atau tidak sesuai.

Contoh Permintaan

{
  "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"
    ]
  }
}

Contoh respons

{
  "session": {
    "id": "example_session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "Hello World.",
      "text": ""
    }
  },
  "scene": {
    "name": "SceneName",
    "slots": {},
    "next": {
      "name": "actions.scene.END_CONVERSATION"
    }
  }
}

Interaksi runtime

Bagian berikut menjelaskan tugas umum yang dapat Anda lakukan di web.

Kirim perintah

Anda dapat membuat prompt dengan teks sederhana, rich text, kartu, dan bahkan Perintah HTML yang didukung oleh aplikasi web dengan Canvas Interaktif. Dokumentasi perintah telah informasi lengkap tentang cara membuat perintah saat menangani peristiwa webhook. Cuplikan berikut menunjukkan perintah kartu:

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'
    })
  }));
});

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

Membaca parameter intent

Saat runtime Asisten cocok dengan intent, runtime tersebut akan mengekstrak apa pun yang ditentukan parameter. Properti asli adalah apa yang pengguna berikan sebagai input dan properti diselesaikan adalah tempat NLU menyelesaikan input berdasarkan jenis spesifikasi pendukung.

Node.js

conv.intent.params['param_name'].original
conv.intent.params['param_name'].resolved

Meminta 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"
    ]
  }
}

Membaca lokalitas pengguna

Nilai ini sesuai dengan setelan lokalitas pengguna untuk Asisten Google.

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

Membaca dan menulis penyimpanan

Lihat dokumentasi penyimpanan untuk informasi lengkap tentang cara menggunakan berbagai fitur penyimpanan.

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 

Meminta 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"
    ]
  }
}

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

Memeriksa kemampuan perangkat

Anda dapat memeriksa kemampuan perangkat untuk memberikan berbagai pengalaman atau percakapan berjalan.

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");

Meminta 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"
    ]
  }
}

Untuk daftar lengkap kemampuan platform, lihat Capability alamat IP internal.

Penggantian jenis runtime

Jenis runtime memungkinkan Anda mengubah spesifikasi jenis pada runtime. Anda dapat menggunakan untuk memuat data dari sumber lain guna mengisi nilai valid suatu jenis. Sebagai Anda dapat menggunakan penggantian jenis runtime untuk menambahkan opsi dinamis ke survei pertanyaan atau untuk menambahkan item harian ke menu.

Untuk menggunakan jenis runtime, Anda memicu webhook dari Action yang memanggil dalam fulfillment Anda. Dari sana, Anda dapat mengisi session.typeOverrides dalam respons kembali terhadap Action Anda. Tersedia mencakup TYPE_MERGE untuk mempertahankan entri jenis yang ada atau TYPE_REPLACE untuk mengganti entri yang ada dengan penggantian.

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']
        },
    ]
  }
}];

Tanggapan 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."
    }
  }
}

Memberikan pembiasan ucapan

Pembiasan ucapan memungkinkan Anda menentukan petunjuk bagi NLU untuk meningkatkan pencocokan intent. Anda dapat menentukan hingga 1000 entri.

Node.js

conv.expected.speech = ['value_1', 'value_2']
conv.expected.language = 'locale_string'

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

Adegan transisi

Selain menentukan transisi statis dalam project Action, Anda bisa menyebabkan transisi scene terjadi pada runtime.

Node.js

app.handle('transition_to_hidden_scene', conv => {
  // Dynamic transition
  conv.scene.next.name = "HiddenScene";
});

Tanggapan JSON

{
  "session": {
    "id": "session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "This is an example prompt.",
      "text": ""
    }
  },
  "scene": {
    "name": "SceneName",
    "slots": {},
    "next": {
      "name": "HiddenScene"
    }
  }
}

Membaca slot adegan

Selama pengisian slot, Anda bisa menggunakan fulfillment untuk memvalidasi slot atau memeriksa status pengisian slot (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

Misalnya, Anda ingin mengekstrak zona waktu dari respons. Di beberapa contoh ini, nama slotnya adalah datetime1. Untuk mendapatkan zona waktu, Anda perlu gunakan:

conv.scene.slots['datetime1'].value.time_zone.id

Meminta 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"
    ]
  }
}

Membatalkan slot adegan

Anda dapat membatalkan slot dan membuat pengguna memberikan nilai baru.

Node.js

conv.scene.slots['slot_name'].status = 'INVALID'

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

Opsi pengembangan

Actions Builder menyediakan editor inline yang disebut editor Cloud Functions, yang memungkinkan Anda membangun dan men-deploy Cloud Function for Firebase secara langsung di konsol. Anda juga dapat membangun dan men-deploy fulfillment ke hosting pilihan Anda dan daftarkan endpoint fulfillment HTTPS sebagai pengendali webhook Anda.

Editor sebaris

Untuk mengembangkan aplikasi dengan editor Cloud Functions:

  1. Buat file sdk/webhooks/ActionsOnGoogleFulfillment.yaml, dan menentukan pengendali untuk Action Anda dan fungsi cloud inline yang digunakan untuk pemenuhan pesanan.
    handlers:
    - name: questionOnEnterFunc
    - name: fruitSlotValidationFunc
    inlineCloudFunction:
      executeFunction: ActionsOnGoogleFulfillment
        
  2. Buat folder sdk/webhooks/ActionsOnGoogleFulfillment, dan tambahkan file index.js yang menerapkan pengendali yang telah ditentukan sebelumnya dan file package.json yang menentukan npm persyaratan untuk kode Anda.
    // 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"
      }
    }
        

Endpoint HTTPS eksternal

Bagian ini menjelaskan cara menyiapkan Cloud Functions for Firebase sebagai fulfillment untuk Action Percakapan Anda. Namun, Anda dapat men-deploy ke layanan {i>hosting <i}pilihan Anda.

Lingkungan penyiapan

Kami merekomendasikan struktur project berikut saat Anda menggunakan Cloud Functions untuk Firebase sebagai layanan fulfillment:

ProjectFolder        - Root folder for the project
  sdk                - Actions project configuration files
  functions          - Cloud functions for Firebase files

Untuk menyiapkan lingkungan, ikuti langkah-langkah berikut:

  1. Download dan instal Node.js.
  2. Menyiapkan dan melakukan inisialisasi Firebase CLI. Jika perintah berikut gagal dengan error EACCES, Anda mungkin perlu mengubah izin npm.

    npm install -g firebase-tools
    
  3. Autentikasi alat firebase dengan Akun Google Anda:

    firebase login
    
  4. Mulai direktori project tempat Anda menyimpan project Action. Anda akan diminta untuk memilih fitur Firebase CLI yang ingin Anda siapkan project Actions Anda. Pilih Functions dan fitur lainnya yang mungkin Anda inginkan gunakan, seperti Firestore, lalu tekan Enter untuk mengonfirmasi dan melanjutkan:

    $ cd <ACTIONS_PROJECT_DIRECTORY>
    $ firebase init
    
  5. Kaitkan alat Firebase dengan project Actions Anda dengan memilihnya menggunakan tombol panah untuk membuka daftar project:

  6. Setelah memilih project, alat Firebase memulai Functions dan menanyakan bahasa apa yang ingin Anda gunakan. Pilih menggunakan tombol panah dan tekan Enter untuk melanjutkan.

    === 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. Pilih apakah Anda ingin menggunakan ESLint untuk menangkap kemungkinan bug dan menerapkan gaya dengan mengetik Y atau N:

    ? Do you want to use ESLint to catch probable bugs and enforce style? (Y/n)
  8. Dapatkan dependensi project dengan mengetik Y pada perintah:

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

    Setelah penyiapan selesai, Anda akan melihat output yang mirip dengan berikut ini:

    ✔  Firebase initialization complete!
    
  9. Instal dependensi @assistant/conversation:

    $ cd <ACTIONS_PROJECT_DIRECTORY>/functions
    $ npm install @assistant/conversation --save
    
  10. Dapatkan dependensi fulfillment dan deploy fungsi fulfillment:

    $ npm install
    $ firebase deploy --only functions
    

    Deployment memerlukan waktu beberapa menit. Setelah selesai, Anda akan melihat output serupa sebagai berikut. Anda memerlukan URL Fungsi untuk masuk di 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. Salin URL fulfillment untuk digunakan di bagian berikutnya.

Mendaftarkan pengendali webhook

  1. Buat file sdk/webhooks/ActionsOnGoogleFulfillment.yaml, lalu tentukan pengendali untuk Action Anda dan URL untuk permintaan webhook.
    httpsEndpoint:
      baseUrl: https://my.web.hook/ActionsOnGoogleFulfillment
      endpointApiVersion: 2
    handlers:
    - name: questionOnEnterFunc
    - name: fruitSlotValidationFunc