재프롬프트 (Dialogflow)

Dialogflow에서 살펴보기

계속을 클릭하여 Dialogflow에서 Reprompts 샘플을 가져옵니다. 그런 다음 다음 단계에 따라 샘플을 배포하고 테스트합니다.

  1. 에이전트 이름을 입력하고 샘플의 새 Dialogflow 에이전트를 만듭니다.
  2. 에이전트 가져오기가 완료되면 Go to agent를 클릭합니다.
  3. 기본 탐색 메뉴에서 fulfillment로 이동합니다.
  4. 인라인 편집기를 사용 설정한 다음 배포를 클릭합니다. 편집기에 샘플 파일이 포함되어 있고 있습니다.
  5. 기본 탐색 메뉴에서 Integrations로 이동한 다음 Google을 클릭합니다. 어시스턴트를 탭합니다.
  6. 모달 창이 나타나면 변경사항 자동 미리보기를 사용 설정하고 테스트를 클릭합니다. 작업 시뮬레이터를 엽니다.
  7. 시뮬레이터에서 Talk to my test app를 입력하여 샘플을 테스트합니다.
<ph type="x-smartling-placeholder"></ph> 계속

다음 기능을 사용하여 사용자가 이러한 기능을 제공하지 않는 케이스를 처리할 수 있습니다. 해야 합니다 (입력 없음 오류).

  • 시스템 기본 재메시지 표시 - 사용자에게 자동으로 메시지를 다시 표시합니다. 미리 준비된 프롬프트를 사용하여 모든 케이스에 일반적으로 적용할 수 있습니다
  • 동적 재요청 - 실행할 때마다 인텐트 (Actions SDK) 또는 이벤트 (Dialogflow)를 수신하여 입력이 없기 때문에 사례별로 처리할 수 있습니다.
를 통해 개인정보처리방침을 정의할 수 있습니다.

시스템 기본 메시지 표시

기본적으로 어시스턴트에 응답을 반환할 때 시스템은 기본적으로 사용자에게 입력을 반복하거나 다시 입력하도록 요청합니다.

Dialogflow

Dialogflow는 일치하는 항목 없음 및 입력 없음 입력을 결합하여 최대 3개를 적용합니다. 대화에서 수집 시도가 3회에 도달하면 Dialogflow 에이전트는 기본 응답으로 대화를 종료합니다. 일치하지 않는 입력은 Dialogflow는 대체 인텐트 중 하나가 트리거되는 시점입니다.

동적 재메시지

작업이 실패할 때마다 인텐트 또는 Dialogflow 이벤트를 수신할 수 있습니다. 데이터를 수신할 수 없습니다. 이렇게 하면 사용자가 제공한 응답 데이터를 기준으로 다시 작성하며 사용자에게 적절히 메시지를 표시합니다.

Dialogflow

다음과 같은 두 가지 유형의 노입력 인텐트를 만들 수 있습니다.

  • 일반 인텐트 - 이 메서드는 컨텍스트를 적용하지 않으므로 트리거됩니다. 트리거할 다른 상황별 인텐트가 없을 때 발생합니다. 유용함 을 사용하세요.

  • 후속 조치 인텐트 - Dialogflow를 통해 후속 조치 인텐트 적용 다시 프롬프트가 트리거되도록 있습니다. 이는 새 제안에 적용하려는 맞춤 재프롬프트에 확인할 수 있습니다

입력이 없는 이벤트를 처리하려면 다음 안내를 따르세요.

  1. 왼쪽 탐색 메뉴에서 인텐트를 클릭합니다.
  2. 일반 인텐트 또는 후속 조치 인텐트를 만듭니다.
    • 일반 인텐트: 인텐트 메뉴에서 + 아이콘을 클릭합니다. 항목을 선택하고 인텐트에 'Reprompt'와 같은 이름을 지정합니다.

    • 후속 조치 인텐트: 원하는 인텐트 위로 마우스를 가져갑니다. 비입력 재프롬프트를 맞춤설정하고 후속 조치 인텐트 추가 > 커스텀을 선택합니다. 원래 인텐트 아래에 새 인텐트가 생성됩니다.

  3. 새로 생성된 인텐트를 클릭하여 인텐트 편집기를 엽니다.
  4. 이벤트 섹션을 클릭하고 'actions_intent_NO_INPUT'을 입력합니다 를 이벤트 추가 필드를 이용하세요.
  5. 작업 섹션에서 작업 이름을 입력하거나 제공된 이름을 사용합니다. 기본적으로 제공됩니다 이 예에서는 'no.input'을 사용합니다.

  6. 저장을 클릭합니다.
  7. 왼쪽 탐색 메뉴에서 Integrations(통합)를 클릭합니다.
  8. Google Assistant를 선택하고 Test를 클릭하여 확인합니다. 변경사항이 작업 프로젝트에 반영되었는지 확인하세요.

이 인텐트에 대해 입력이 없으면 다음을 사용할 수 있습니다. 처리를 사용하여 적절한 응답을 반환하거나 Dialogflow에서 응답을 생성할 수 있습니다. 다음은 클라이언트 라이브러리를 사용하여 요청을 처리하는 '재프롬프트'라는 일반적인 비입력 인텐트를 처리할 수 있습니다.

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

자바

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

JSON 요청

아래 JSON은 웹훅 요청을 설명합니다.

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

아래 JSON은 웹훅 응답을 설명합니다.

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

Actions SDK

입력 없는 인텐트를 처리하려면 다음 안내를 따르세요.

  1. 작업 패키지 내의 conversations 객체에서 다음을 원한다고 선언합니다. 사용자가 제공하지 않는 경우 actions.intent.NO_INPUT 인텐트 수신 있습니다.
    {
      "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. 어시스턴트가 사용자로부터 어떠한 입력도 받지 못하면 비입력 인텐트를 처리하세요. 그런 다음 인텐트를 처리하고 적절한 재요청 응답을 반환합니다. 예를 들면 다음과 같습니다.

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

    자바

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

    JSON 요청

    아래 JSON은 웹훅 요청을 설명합니다.

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

    아래 JSON은 웹훅 응답을 설명합니다.

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