Dialogflow에서 살펴보기
계속을 클릭하여 Dialogflow에서 Reprompts 샘플을 가져옵니다. 그런 다음 다음 단계에 따라 샘플을 배포하고 테스트합니다.
- 에이전트 이름을 입력하고 샘플의 새 Dialogflow 에이전트를 만듭니다.
- 에이전트 가져오기가 완료되면 Go to agent를 클릭합니다.
- 기본 탐색 메뉴에서 fulfillment로 이동합니다.
- 인라인 편집기를 사용 설정한 다음 배포를 클릭합니다. 편집기에 샘플 파일이 포함되어 있고 있습니다.
- 기본 탐색 메뉴에서 Integrations로 이동한 다음 Google을 클릭합니다. 어시스턴트를 탭합니다.
- 모달 창이 나타나면 변경사항 자동 미리보기를 사용 설정하고 테스트를 클릭합니다. 작업 시뮬레이터를 엽니다.
- 시뮬레이터에서
Talk to my test app
를 입력하여 샘플을 테스트합니다.
다음 기능을 사용하여 사용자가 이러한 기능을 제공하지 않는 케이스를 처리할 수 있습니다. 해야 합니다 (입력 없음 오류).
- 시스템 기본 재메시지 표시 - 사용자에게 자동으로 메시지를 다시 표시합니다. 미리 준비된 프롬프트를 사용하여 모든 케이스에 일반적으로 적용할 수 있습니다
- 동적 재요청 - 실행할 때마다 인텐트 (Actions SDK) 또는 이벤트 (Dialogflow)를 수신하여 입력이 없기 때문에 사례별로 처리할 수 있습니다.
시스템 기본 메시지 표시
기본적으로 어시스턴트에 응답을 반환할 때 시스템은 기본적으로 사용자에게 입력을 반복하거나 다시 입력하도록 요청합니다.
Dialogflow
Dialogflow는 일치하는 항목 없음 및 입력 없음 입력을 결합하여 최대 3개를 적용합니다. 대화에서 수집 시도가 3회에 도달하면 Dialogflow 에이전트는 기본 응답으로 대화를 종료합니다. 일치하지 않는 입력은 Dialogflow는 대체 인텐트 중 하나가 트리거되는 시점입니다.
동적 재메시지
작업이 실패할 때마다 인텐트 또는 Dialogflow 이벤트를 수신할 수 있습니다. 데이터를 수신할 수 없습니다. 이렇게 하면 사용자가 제공한 응답 데이터를 기준으로 다시 작성하며 사용자에게 적절히 메시지를 표시합니다.
Dialogflow
다음과 같은 두 가지 유형의 노입력 인텐트를 만들 수 있습니다.
일반 인텐트 - 이 메서드는 컨텍스트를 적용하지 않으므로 트리거됩니다. 트리거할 다른 상황별 인텐트가 없을 때 발생합니다. 유용함 을 사용하세요.
후속 조치 인텐트 - Dialogflow를 통해 후속 조치 인텐트 적용 다시 프롬프트가 트리거되도록 있습니다. 이는 새 제안에 적용하려는 맞춤 재프롬프트에 확인할 수 있습니다
입력이 없는 이벤트를 처리하려면 다음 안내를 따르세요.
- 왼쪽 탐색 메뉴에서 인텐트를 클릭합니다.
- 일반 인텐트 또는 후속 조치 인텐트를 만듭니다.
- 일반 인텐트: 인텐트 메뉴에서 + 아이콘을 클릭합니다. 항목을 선택하고 인텐트에 'Reprompt'와 같은 이름을 지정합니다.
- 후속 조치 인텐트: 원하는 인텐트 위로 마우스를 가져갑니다. 비입력 재프롬프트를 맞춤설정하고 후속 조치 인텐트 추가 > 커스텀을 선택합니다. 원래 인텐트 아래에 새 인텐트가 생성됩니다.
- 새로 생성된 인텐트를 클릭하여 인텐트 편집기를 엽니다.
- 이벤트 섹션을 클릭하고 'actions_intent_NO_INPUT'을 입력합니다 를 이벤트 추가 필드를 이용하세요.
- 작업 섹션에서 작업 이름을 입력하거나 제공된 이름을 사용합니다. 기본적으로 제공됩니다 이 예에서는 'no.input'을 사용합니다.
- 저장을 클릭합니다.
- 왼쪽 탐색 메뉴에서 Integrations(통합)를 클릭합니다.
- 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
입력 없는 인텐트를 처리하려면 다음 안내를 따르세요.
- 작업 패키지 내의
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" } ] } } }
- 어시스턴트가 사용자로부터 어떠한 입력도 받지 못하면
비입력 인텐트를 처리하세요. 그런 다음
인텐트를 처리하고 적절한 재요청 응답을 반환합니다. 예를 들면 다음과 같습니다.
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." } } ] } } }