Webhook

Untuk memberikan 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 dalam fulfillment meliputi:

  • Menghasilkan dialog dinamis berdasarkan informasi yang diberikan oleh pengguna.
  • Memesan 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 intent atau scene pemanggilan, yang mengirimkan permintaan ke endpoint fulfillment Anda. Fulfillment Anda berisi pengendali web yang memproses payload JSON dalam permintaan. Anda dapat memicu webhook dalam situasi berikut:

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

Saat Anda memicu webhook di Actions, 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 mengarahkan peristiwa ke pengendali yang sesuai untuk menjalankan logika dan menampilkan respons dengan payload JSON yang sesuai.

Payload

Cuplikan berikut menunjukkan contoh permintaan yang dikirim Action Anda ke fulfillment dan respons yang dikirimkan kembali fulfillment Anda. Lihat dokumentasi referensi untuk informasi selengkapnya.

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 pengendali webhook.

Kirim perintah

Anda dapat membuat perintah dengan teks sederhana, rich text, kartu, dan bahkan perintah HTML lengkap yang didukung oleh aplikasi web dengan Canvas Interaktif. Dokumentasi prompt memiliki informasi lengkap tentang cara membuat perintah saat menangani peristiwa webhook. Cuplikan berikut menampilkan dialog 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 Asisten akan mengekstrak parameter apa pun yang ditentukan. Properti asli adalah properti yang diberikan pengguna sebagai input, dan properti yang diselesaikan adalah properti yang di-resolve input oleh NLU berdasarkan spesifikasi jenis.

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

Baca dan tulis 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 pengalaman atau alur percakapan yang berbeda.

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 mengetahui daftar lengkap kemampuan platform, lihat referensi Capability.

Penggantian jenis runtime

Dengan jenis runtime, Anda dapat mengubah spesifikasi jenis saat runtime. Anda dapat menggunakan fitur ini untuk memuat data dari sumber lain guna mengisi nilai jenis yang valid. Misalnya, Anda dapat menggunakan penggantian jenis runtime untuk menambahkan opsi dinamis ke pertanyaan survei atau menambahkan item harian ke menu.

Untuk menggunakan jenis runtime, Anda dapat memicu webhook dari Action yang memanggil pengendali dalam fulfillment Anda. Dari sana, Anda dapat mengisi parameter session.typeOverrides sebagai respons kembali terhadap Action Anda. Mode yang 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."
    }
  }
}

Menyediakan pembiasan ucapan

Pembiasan ucapan memungkinkan Anda menentukan petunjuk ke NLU guna meningkatkan pencocokan intent. Anda dapat menentukan hingga 1.000 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 di project Action, Anda dapat menyebabkan transisi scene terjadi saat 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 dapat 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. Dalam contoh ini, nama slot adalah datetime1. Untuk mendapatkan zona waktu, Anda harus menggunakan:

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 langsung di konsol. Anda juga dapat mem-build dan men-deploy fulfillment ke hosting pilihan Anda serta mendaftarkan endpoint fulfillment HTTPS sebagai pengendali webhook Anda.

Editor sebaris

Untuk mengembangkan aplikasi dengan editor Cloud Functions:

  1. Buka project Action Anda, lalu buka tab Pengembangan > Webhook > Ubah metode fulfillment. Jendela Fulfillment Methods akan muncul.
  2. Pilih Inline Cloud Functions, lalu klik Confirm.

Endpoint HTTPS eksternal

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

Lingkungan penyiapan

Untuk menyiapkan lingkungan Anda, 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 disiapkan untuk project Action Anda. Pilih Functions dan fitur lain yang mungkin ingin Anda gunakan, seperti Firestore, lalu tekan Enter untuk mengonfirmasi dan melanjutkan:

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

  6. Setelah memilih project, alat Firebase akan memulai penyiapan 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 mirip seperti berikut:

    ✔  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 mirip seperti berikut ini. Anda memerlukan URL Fungsi untuk masuk ke 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

Untuk mendaftarkan endpoint Cloud Function Anda sebagai pengendali webhook:

  1. Di konsol Actions, klik Develop > Webhook.
  2. Klik Ubah metode fulfillment. Jendela Fulfillment methods akan muncul.
  3. Pilih Webhook, lalu klik Confirm.
  4. Tempelkan URL layanan web Anda ke kolom Webhook.
  5. Klik Simpan.