Permintaan ulang (Dialogflow)

Jelajahi di Dialogflow

Klik Continue untuk mengimpor contoh Reprompts di Dialogflow. Kemudian, ikuti langkah-langkah di bawah ini untuk men-deploy dan menguji contoh:

  1. Masukkan nama agen dan buat agen Dialogflow baru untuk contoh.
  2. Setelah agen selesai diimpor, klik Go to agent.
  3. Dari menu navigasi utama, buka Fulfillment.
  4. Aktifkan Inline Editor, lalu klik Deploy. Editor berisi contoh tersebut pada kode sumber.
  5. Dari menu navigasi utama, buka Integrations, lalu klik Google Asisten.
  6. Di jendela modal yang muncul, aktifkan Pratinjau perubahan secara otomatis, lalu klik Uji untuk membuka simulator Actions.
  7. Dalam simulator, masukkan Talk to my test app untuk menguji sampel.
Lanjutkan

Anda dapat menggunakan fitur berikut untuk menangani kasus yang tidak disediakan pengguna ke Tindakan Anda (error tanpa input):

  • Perintah ulang default sistem - Ini meminta ulang pengguna secara otomatis dengan {i>reprompt<i} pra-{i>template<i} yang umum untuk semua kasus.
  • Perintah ulang dinamis - Menyatakan bahwa Anda ingin menangani permintaan ulang di sendiri, dan menerima intent (Actions SDK) atau peristiwa (Dialogflow) setiap kali tidak ada input, jadi Anda dapat menanganinya berdasarkan kasus per kasus.

Perintah ulang default sistem

Secara default, saat Anda menampilkan respons ke Asisten, sistem akan menggunakan secara {i>default<i} meminta pengguna untuk mengulangi atau mengetik ulang input mereka.

Dialogflow

Dialogflow menerapkan maksimum gabungan tiga input tidak ada kecocokan dan tanpa input. Setelah percakapan mencapai tiga kali percobaan pengumpulan, agen Dialogflow Anda akan mengakhiri percakapan dengan respons default. Masukan yang tidak cocok di Dialogflow adalah saat salah satu intent penggantian dipicu.

Perintah ulang dinamis

Anda dapat menerima intent atau peristiwa Dialogflow setiap kali Action Anda gagal menerima input apa pun. Hal ini memungkinkan Anda memberikan respons yang berbeda berdasarkan beberapa logika, jika perlu, dan meminta ulang pengguna dengan tepat.

Dialogflow

Anda dapat membuat dua jenis intent tanpa input:

  • Intent normal - Metode ini tidak menerapkan konteks apa pun, sehingga akan dipicu jika tidak ada maksud lain yang lebih kontekstual untuk dipicu. Hal ini berguna untuk perintah ulang umum yang ingin Anda terapkan dalam banyak kasus.

  • Intent tindak lanjut - Intent lanjutan diterapkan melalui Dialogflow konteks, memastikan bahwa perintah ulang hanya dipicu setelah perubahan tertentu percakapan. Ini berguna untuk {i>reprompt<i} yang disesuaikan di mana Anda ingin menerapkan situasi tertentu.

Untuk menangani peristiwa tanpa input:

  1. Di navigasi sebelah kiri, klik Intent.
  2. Buat intent normal atau intent tindak lanjut.
    • Untuk intent normal: Klik ikon + di sebelah menu Intent dan beri nama intent Anda, seperti "Reprompt".

    • Untuk intent lanjutan: Arahkan kursor ke intent yang ingin menyesuaikan prompt ulang no-input untuk dan klik Add follow-up intent > kustom. Intent baru dibuat di bawah intent asli.

  3. Klik intent yang baru dibuat untuk membuka editor intent.
  4. Klik bagian Events dan masukkan "actions_intent_NO_INPUT" ke dalam Kolom Tambahkan peristiwa.
  5. Di bagian Tindakan, masukkan nama tindakan atau gunakan nama yang disediakan secara {i>default<i}. Untuk contoh ini, kita akan menggunakan "no.input".

  6. Klik Simpan.
  7. Di navigasi kiri, klik Integrations
  8. Pilih Asisten Google dan klik Uji untuk membuatnya memastikan perubahan tercermin dalam project Action Anda.

Setiap kali tidak ada input terjadi untuk intent ini, Anda bisa menggunakan fulfillment Anda untuk mengembalikan respons yang sesuai atau membuat yang baru di Dialogflow. Misalnya, berikut adalah beberapa kode penyelesaian yang menggunakan library klien untuk menangani intent no-input normal yang disebut "Reprompt".

Node.js

const {dialogflow} = require('actions-on-google');
const functions = require('firebase-functions');

const app = dialogflow({debug: true});

app.intent('Reprompt', (conv) => {
  const repromptCount = parseInt(conv.arguments.get('REPROMPT_COUNT'));
  if (repromptCount === 0) {
  conv.ask(`What was that?`);
  } else if (repromptCount === 1) {
  conv.ask(`Sorry I didn't catch that. Could you repeat yourself?`);
  } else if (conv.arguments.get('IS_FINAL_REPROMPT')) {
  conv.close(`Okay let's try this again later.`);
  }
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

Java

package com.example;

import com.google.actions.api.ActionRequest;
import com.google.actions.api.ActionResponse;
import com.google.actions.api.DialogflowApp;
import com.google.actions.api.ForIntent;
import com.google.actions.api.response.ResponseBuilder;

public class MyActionsApp extends DialogflowApp {

  @ForIntent("Reprompt")
  public ActionResponse reprompt(ActionRequest request) {
    ResponseBuilder responseBuilder = getResponseBuilder(request);
    int repromptCount = request.getRepromptCount();
    String response;
    if (repromptCount == 0) {
      response = "What was that?";
    } else if (repromptCount == 1) {
      response = "Sorry, I didn't catch that. Could you repeat yourself?";
    } else {
      responseBuilder.endConversation();
      response = "Okay let's try this again later.";
    }
    return responseBuilder.add(response).build();
  }
}

Minta JSON

Perlu diperhatikan bahwa JSON di bawah mendeskripsikan permintaan webhook.

{
  "responseId": "f26a9188-4998-42eb-ac16-d0e6e273b137-712767ed",
  "queryResult": {
    "queryText": "actions_intent_NO_INPUT",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "Webhook failed for intent: Reprompt",
    "fulfillmentMessages": [
      {
        "text": {
          "text": [
            "Webhook failed for intent: Reprompt"
          ]
        }
      }
    ],
    "outputContexts": [
      {
        "name": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA/contexts/actions_capability_media_response_audio"
      },
      {
        "name": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA/contexts/actions_capability_account_linking"
      },
      {
        "name": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA/contexts/actions_capability_audio_output"
      },
      {
        "name": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA/contexts/google_assistant_input_type_voice"
      },
      {
        "name": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA/contexts/actions_intent_no_input",
        "parameters": {
          "REPROMPT_COUNT": 2,
          "IS_FINAL_REPROMPT": true
        }
      }
    ],
    "intent": {
      "name": "projects/df-reprompts-kohler/agent/intents/75dfd97d-6368-4436-9533-70f05ae76c96",
      "displayName": "Reprompt"
    },
    "intentDetectionConfidence": 1,
    "languageCode": "en"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "user": {
        "locale": "en-US",
        "userVerificationStatus": "VERIFIED"
      },
      "conversation": {
        "conversationId": "ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA",
        "type": "ACTIVE",
        "conversationToken": "[]"
      },
      "inputs": [
        {
          "intent": "actions.intent.NO_INPUT",
          "rawInputs": [
            {
              "inputType": "VOICE"
            }
          ],
          "arguments": [
            {
              "name": "REPROMPT_COUNT",
              "intValue": "2"
            },
            {
              "name": "IS_FINAL_REPROMPT",
              "boolValue": true
            }
          ]
        }
      ],
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.ACCOUNT_LINKING"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          }
        ]
      },
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "session": "projects/df-reprompts-kohler/agent/sessions/ABwppHFi9Dpwy6KiEtS0UIPDNVfa7mlkrPIEZRlikFkjuN_4SGPixgX8OCatpXu38ln7VG43-nk-7veZWhds3nLljA"
}

JSON respons

Perlu diperhatikan bahwa JSON di bawah mendeskripsikan respons webhook.

{
  "payload": {
    "google": {
      "expectUserResponse": false,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Okay let's try this again later."
            }
          }
        ]
      }
    }
  }
}

Actions SDK

Untuk menangani intent tanpa input:

  1. Pada objek conversations di dalam paket tindakan, deklarasikan bahwa Anda ingin untuk menerima intent actions.intent.NO_INPUT setiap kali pengguna tidak memberikan input teks.
    {
      "actions": [
        {
          "description": "Default Welcome Intent",
          "name": "MAIN",
          "fulfillment": {
            "conversationName": "conversation_1"
          },
          "intent": {
            "name": "actions.intent.MAIN"
          }
        }
      ],
      "conversations": {
        "conversation_1": {
          "name": "conversation_1",
          "url": "YOUR_FULFILLMENT_URL",
          "inDialogIntents": [
            {
              "name": "actions.intent.NO_INPUT"
            }
          ]
        }
      }
    }
  2. Saat Asisten tidak menerima input apa pun dari pengguna, Anda akan menerima intent no-input dalam permintaan berikutnya ke fulfillment Anda. Anda kemudian dapat memproses intent dan mengembalikan respons prompt ulang yang sesuai. Berikut contohnya:

    Node.js

    const {actionssdk} = require('actions-on-google');
    const functions = require('firebase-functions');
    
    const app = actionssdk({debug: true});
    
    app.intent('actions.intent.MAIN', (conv) => {
      conv.ask(`Hi! Try this sample on a speaker device, ` +
        `and stay silent when the mic is open. If trying ` +
        `on the Actions console simulator, click the no-input ` +
        `button next to the text input field.`);
    });
    
    app.intent('actions.intent.TEXT', (conv, input) => {
      conv.ask(`You said ${input}`);
      conv.ask(`Try this sample on a speaker device, ` +
        `and stay silent when the mic is open. If trying ` +
        `on the Actions console simulator, click the no-input ` +
        `button next to the text input field.`);
    });
    
    app.intent('actions.intent.NO_INPUT', (conv) => {
      const repromptCount = parseInt(conv.arguments.get('REPROMPT_COUNT'));
      if (repromptCount === 0) {
        conv.ask(`What was that?`);
      } else if (repromptCount === 1) {
        conv.ask(`Sorry I didn't catch that. Could you repeat yourself?`);
      } else if (conv.arguments.get('IS_FINAL_REPROMPT')) {
        conv.close(`Okay let's try this again later.`);
      }
    });
    
    exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);

    Java

    package com.example;
    
    import com.google.actions.api.ActionRequest;
    import com.google.actions.api.ActionResponse;
    import com.google.actions.api.ActionsSdkApp;
    import com.google.actions.api.ConstantsKt;
    import com.google.actions.api.ForIntent;
    import com.google.actions.api.response.ResponseBuilder;
    import com.google.actions.api.response.helperintent.Confirmation;
    import com.google.actions.api.response.helperintent.DateTimePrompt;
    import com.google.actions.api.response.helperintent.Permission;
    import com.google.actions.api.response.helperintent.Place;
    import com.google.api.services.actions_fulfillment.v2.model.DateTime;
    import com.google.api.services.actions_fulfillment.v2.model.Location;
    
    public class MyActionsApp extends ActionsSdkApp {
    
      @ForIntent("actions.intent.MAIN")
      public ActionResponse welcome(ActionRequest request) {
        ResponseBuilder responseBuilder = getResponseBuilder(request);
        responseBuilder.add("Hi! Try this sample on a speaker device, and stay silent when the mic is open. If trying on the Actions console simulator, click the no-input button next to the text input field.");
        return responseBuilder.build();
      }
    
      @ForIntent("actions.intent.TEXT")
      public ActionResponse fallback(ActionRequest request) {
        ResponseBuilder responseBuilder = getResponseBuilder(request);
        responseBuilder.add("You said " + request.getRawInput().getQuery());
        responseBuilder.add("Try this sample on a speaker device, and stay silent when the mic is open. If trying on the Actions console simulator, click the no-input button next to the text input field.");
        return responseBuilder.build();
      }
    
      @ForIntent("actions.intent.NO_INPUT")
      public ActionResponse reprompt(ActionRequest request) {
        ResponseBuilder responseBuilder = getResponseBuilder(request);
        int repromptCount = request.getRepromptCount();
        String response;
        if (repromptCount == 0) {
          response = "What was that?";
        } else if (repromptCount == 1) {
          response = "Sorry, I didn't catch that. Could you repeat yourself?";
        } else {
          responseBuilder.endConversation();
          response = "Okay let's try this again later.";
        }
        return responseBuilder.add(response).build();
      }
    
    }

    Minta JSON

    Perlu diperhatikan bahwa JSON di bawah mendeskripsikan permintaan webhook.

    {
      "user": {
        "locale": "en-US",
        "userVerificationStatus": "VERIFIED"
      },
      "conversation": {
        "conversationId": "ABwppHEVDuKUPjdZ4Ud-F2yBXN5ssRg2funUp59hSHQheAi-B5Y3EzehAKFtVwMkduqMRWscUp77ScrDjYnYxISqAM-qOXuXEuCw",
        "type": "ACTIVE",
        "conversationToken": "{\"data\":{}}"
      },
      "inputs": [
        {
          "intent": "actions.intent.NO_INPUT",
          "rawInputs": [
            {
              "inputType": "VOICE"
            }
          ],
          "arguments": [
            {
              "name": "REPROMPT_COUNT",
              "intValue": "2"
            },
            {
              "name": "IS_FINAL_REPROMPT",
              "boolValue": true
            }
          ]
        }
      ],
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.ACCOUNT_LINKING"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          }
        ]
      },
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            }
          ]
        }
      ]
    }

    JSON respons

    Perlu diperhatikan bahwa JSON di bawah mendeskripsikan respons webhook.

    {
      "expectUserResponse": false,
      "finalResponse": {
        "richResponse": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Okay let's try this again later."
              }
            }
          ]
        }
      }
    }