Lời nhắc lại (Dialogflow)

Khám phá trong Dialogflow

Nhấp vào Tiếp tục để nhập mẫu Lời nhắc của chúng tôi vào Dialogflow. Sau đó, hãy làm theo các bước bên dưới để triển khai và kiểm thử mẫu:

  1. Nhập tên nhân viên hỗ trợ rồi tạo một nhân viên hỗ trợ Dialogflow mới cho mẫu.
  2. Sau khi nhập xong nhân viên hỗ trợ, hãy nhấp vào Chuyển đến nhân viên hỗ trợ.
  3. Trên trình đơn điều hướng chính, hãy chuyển đến mục Thực hiện đơn hàng.
  4. Bật Inline Editor (Trình chỉnh sửa cùng dòng), sau đó nhấp vào Deploy (Triển khai). Trình chỉnh sửa chứa mã mẫu.
  5. Trên trình đơn điều hướng chính, hãy chuyển đến phần Tích hợp, rồi nhấp vào Trợ lý Google.
  6. Trong cửa sổ phụ xuất hiện, hãy bật tính năng Auto-preview changes (Tự động xem trước các thay đổi) rồi nhấp vào Test (Kiểm thử) để mở Trình mô phỏng hành động.
  7. Trong trình mô phỏng, hãy nhập Talk to my test app để kiểm tra mẫu!

Bạn có thể sử dụng các tính năng sau để xử lý trường hợp người dùng không cung cấp dữ liệu đầu vào cho Hành động của bạn (lỗi không có dữ liệu đầu vào):

  • Lời nhắc lại theo mặc định của hệ thống – Các lời nhắc lại này tự động cho người dùng bằng các lời nhắc tạo trước, được dùng chung cho mọi trường hợp.
  • Lời nhắc lại động – Khai báo rằng bạn muốn tự mình xử lý việc nhắc lại và nhận ý định (SDK Hành động) hoặc sự kiện (Dialogflow) mỗi khi không có hoạt động đầu vào, nhờ đó bạn có thể xử lý theo từng trường hợp.

Lời nhắc lại theo mặc định của hệ thống

Theo mặc định, khi bạn trả lời câu trả lời cho Trợ lý, hệ thống sẽ sử dụng lời nhắc mặc định để yêu cầu người dùng lặp lại hoặc nhập lại nội dung họ đã nhập.

Dialogflow

Dialogflow thực thi tối đa 3 đầu vào không khớp và không có đầu vào. Sau khi một cuộc trò chuyện đạt 3 lần thử thu thập, nhân viên hỗ trợ Dialogflow của bạn sẽ kết thúc cuộc trò chuyện bằng một phản hồi mặc định. Giá trị đầu vào không khớp trong Dialogflow là khi một trong các ý định dự phòng của bạn được kích hoạt.

Lời nhắc lại linh động

Bạn có thể nhận một ý định hoặc sự kiện Dialogflow mỗi khi Hành động của bạn không nhận được dữ liệu đầu vào. Điều này cho phép bạn trả về một phản hồi khác dựa trên một số logic (nếu cần) và nhắc lại người dùng một cách thích hợp.

Dialogflow

Bạn có thể tạo 2 loại ý định không có dữ liệu đầu vào:

  • Ý định thông thường – Phương thức này không áp dụng bất kỳ ngữ cảnh nào, vì vậy sẽ được kích hoạt khi không có ý định khác có ngữ cảnh nhiều hơn để kích hoạt. Việc này rất hữu ích cho các lời nhắc chung mà bạn muốn áp dụng trong hầu hết các trường hợp.

  • Ý định tiếp nối – Ý định theo dõi được thực thi thông qua ngữ cảnh Dialogflow, đảm bảo lời nhắc chỉ được kích hoạt sau một số lượt trò chuyện nhất định. Điều này rất hữu ích đối với các lời nhắc được thiết kế riêng cho các tình huống cụ thể.

Cách xử lý các sự kiện không có dữ liệu đầu vào:

  1. Trong bảng điều hướng bên trái, hãy nhấp vào Ý định.
  2. Tạo một ý định thông thường hoặc ý định tiếp nối.
    • Đối với các ý định thông thường: Nhấp vào biểu tượng dấu + bên cạnh mục trong trình đơn Ý định rồi đặt tên cho ý định, chẳng hạn như "Lời nhắc lại".

    • Đối với ý định theo dõi: Di chuột qua ý định mà bạn muốn tuỳ chỉnh lời nhắc không cần nhập rồi nhấp vào Thêm ý định theo dõi > tuỳ chỉnh. Một ý định mới sẽ được tạo bên dưới ý định ban đầu.

  3. Nhấp vào ý định mới tạo để mở trình chỉnh sửa ý định.
  4. Nhấp vào phần Sự kiện rồi nhập "actions_intent_NO_INPUT" vào trường Thêm sự kiện.
  5. Trong phần Hành động, hãy nhập tên hành động hoặc sử dụng tên được cung cấp theo mặc định. Trong ví dụ này, chúng tôi sẽ sử dụng "no.input".

  6. Nhấp vào Lưu.
  7. Trong bảng điều hướng bên trái, hãy nhấp vào Các công cụ tích hợp
  8. Chọn Trợ lý Google rồi nhấp vào Test (Kiểm thử) để đảm bảo các thay đổi được phản ánh trong dự án Actions của bạn.

Bất cứ khi nào không có dữ liệu nhập vào cho ý định này, bạn có thể sử dụng phương thức thực hiện để trả về phản hồi thích hợp hoặc tạo một phản hồi trong Dialogflow. Ví dụ: đây là một số mã phương thức thực hiện dùng thư viện ứng dụng để xử lý ý định không có đầu vào thông thường có tên là "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();
  }
}

Yêu cầu JSON

Xin lưu ý rằng JSON ở bên dưới mô tả một yêu cầu 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"
}

Định dạng JSON của phản hồi

Xin lưu ý rằng JSON dưới đây mô tả phản hồi webhook.

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

SDK Hành động

Cách xử lý các ý định không có dữ liệu đầu vào:

  1. Trong đối tượng conversations bên trong gói hành động, hãy khai báo rằng bạn muốn nhận ý định actions.intent.NO_INPUT bất cứ khi nào người dùng không cung cấp dữ liệu đầu vào.
    
    {
      "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. Khi Trợ lý không nhận được bất kỳ dữ liệu đầu vào nào từ người dùng, bạn sẽ nhận được ý định không nhập trong yêu cầu tiếp theo đến phương thức thực hiện của bạn. Sau đó, bạn có thể xử lý ý định và trả về phản hồi nhắc lại thích hợp. Ví dụ như sau:

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

    Yêu cầu JSON

    Xin lưu ý rằng JSON ở bên dưới mô tả một yêu cầu 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"
            }
          ]
        }
      ]
    }

    Định dạng JSON của phản hồi

    Xin lưu ý rằng JSON dưới đây mô tả phản hồi webhook.

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