Webhook

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

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

Pemicu dan pengendali webhook

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

  • Setelah kecocokan intent pemanggilan
  • Selama tahap on enter scene
  • Setelah kondisi dievaluasi menjadi benar di tahap kondisi scene
  • Selama tahap pengisian slot scene
  • Setelah kecocokan intent terjadi di tahap input scene

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

Payload

Cuplikan berikut menunjukkan contoh permintaan yang dikirim Actions Anda ke fulfillment dan respons yang dikirim kembali oleh fulfillment Anda. Lihat dokumentasi referensi untuk mengetahui 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.

Mengirim perintah

Anda dapat membuat perintah dengan teks sederhana, teks kaya, kartu, dan bahkan perintah HTML lengkap yang didukung oleh aplikasi web dengan Interactive Canvas. Dokumentasi perintah memiliki 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 mencocokkan intent, runtime tersebut akan mengekstrak parameter yang ditentukan. Properti asli adalah input yang diberikan pengguna dan properti yang di-resolve adalah input yang di-resolve 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 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"
    ]
  }
}

Membaca dan menulis penyimpanan

Lihat dokumentasi penyimpanan untuk mengetahui 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

Jenis runtime memungkinkan Anda mengubah spesifikasi jenis saat runtime. Anda dapat menggunakan fitur ini untuk memuat data dari sumber lain guna mengisi nilai valid jenis. 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 memicu webhook dari Action yang memanggil pengendali di fulfillment Anda. Dari sana, Anda dapat mengisi parameter session.typeOverrides dalam respons kembali ke 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."
    }
  }
}

Memberikan bias ucapan

Bias ucapan memungkinkan Anda menentukan petunjuk ke NLU untuk meningkatkan kecocokan 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"
  }
}

Scene transisi

Selain menentukan transisi statis di project Actions, 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 scene

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 slotnya adalah datetime1. Untuk mendapatkan zona waktu, Anda akan 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 scene

Anda dapat membatalkan slot dan meminta 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 membuat dan men-deploy Cloud Function untuk Firebase langsung di konsol. Anda juga dapat membuat dan men-deploy fulfillment ke hosting pilihan Anda dan mendaftarkan endpoint fulfillment HTTPS sebagai pengendali webhook.

Editor sebaris

Untuk mengembangkan dengan editor Cloud Functions:

  1. Buka project Actions Anda dan buka tab Develop > Webhook > Change fulfillment method. Jendela Fulfillment methods akan muncul.
  2. Pilih Inline Cloud Functions dan klik Confirm.

Endpoint HTTPS eksternal

Bagian ini menjelaskan cara menyiapkan Cloud Functions for Firebase sebagai layanan fulfillment untuk Conversational Action 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. Siapkan dan lakukan 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 Actions Anda. Anda akan diminta untuk memilih fitur Firebase CLI yang ingin Anda siapkan untuk project Actions. 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 Actions Anda dengan memilihnya menggunakan tombol panah untuk menavigasi daftar project:

  6. Setelah memilih project, alat Firebase akan memulai penyiapan Functions dan menanyakan bahasa 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 ke 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 yang mirip dengan berikut ini. Anda akan memerlukan Function URL untuk dimasukkan 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

Untuk mendaftarkan endpoint Cloud Function Anda sebagai pengendali webhook:

  1. Di konsol Actions, klik Develop > Webhook.
  2. Klik Change fulfillment method. Jendela Fulfillment methods akan muncul.
  3. Pilih Webhook dan klik Confirm.
  4. Tempel URL layanan web Anda ke kolom Webhook.
  5. Klik Save.