在 Dialogflow 中探索
点击继续以在 Dialogflow 中导入我们的提示示例。然后,按照 部署和测试示例的步骤如下:
- 输入代理名称并为示例创建新的 Dialogflow 代理。
- 代理导入完成后,点击转到代理 (Go to agent)。
- 在主导航菜单中,前往 Fulfillment。
- 启用内嵌编辑器,然后点击部署。编辑器包含示例 代码。
- 在主导航菜单中,前往 Integrations(集成),然后点击 Google Google 助理。
- 在显示的模态窗口中,启用 Auto-preview changes(自动预览更改),然后点击 Test(测试) 打开 Actions 模拟器。
- 在模拟器中,输入
Talk to my test app
以测试该示例!
您可以使用以下功能来处理用户未提供 输入(无输入错误):
- 系统默认重新提示 - 自动重新提示用户 提供适用于所有情况的通用预制重复提示。
- 动态提示 - 声明您要在网页 并且在每次发生以下情况时接收 intent (Actions SDK) 或事件 (Dialogflow) 没有输入,因此您可以根据具体情况进行处理。
系统默认重新提示
默认情况下,当您向 Google 助理返回响应时,系统会使用 默认重新提示,要求用户重复输入或重新输入。
Dialogflow
Dialogflow 会强制执行最多三项非匹配和无输入输入。 当对话达到 3 次收集尝试次数后,您的 Dialogflow 代理 将以默认响应结束对话。非匹配输入, Dialogflow 是指触发您的某个后备意图。
动态提示
每当您的 Action 失败时,您都可以收到 intent 或 Dialogflow 事件 接收任何输入。这样,您可以根据某些信息返回不同的响应 逻辑(如有必要),并适当地重新提示用户。
Dialogflow
您可以创建两种类型的无输入意图:
普通 intent - 此方法不会应用任何上下文,因此将被触发 当没有触发其他更具情境性的意图时触发。有用 。
后续意图 - 通过 Dialogflow 强制执行后续意图 上下文,确保仅在 对话。这对于您要采纳的量身定制的重新提示非常有用 特定情况下
处理无输入事件:
- 在左侧导航栏中,点击意图。
- 创建正常意图或后续意图。
- 对于普通 intent:点击 Intent 菜单旁边的 + 图标
然后为您的意图命名,比如“Reprompt”。
- 对于后续意图:将鼠标悬停在您要
自定义无输入重新提示,然后点击添加后续意图 >
custom。系统会在原始意图下方创建一个新意图。
- 对于普通 intent:点击 Intent 菜单旁边的 + 图标
然后为您的意图命名,比如“Reprompt”。
- 点击新创建的 intent 以打开 intent 编辑器。
- 点击事件部分,然后输入“actions_intent_NO_INPUT”复制到 添加事件字段。
- 在操作部分中,输入操作名称或使用提供的名称
默认情况。在本示例中,我们将使用“no.input”。
- 点击保存。
- 在左侧导航栏中,点击集成
- 选择 Google 助理,然后点击测试 确保这些更改反映在您的 Actions 项目中。
每当此 intent 无输入时,您可以使用 您的 fulfillment 以返回适当的响应,或在 Dialogflow 中创建一个响应。 例如,下面是一些使用客户端库 处理一个名为“Reprompt”的常规无输入 intent。
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(); } }
请求 JSON
请注意,下面的 JSON 描述的是 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
请注意,下面的 JSON 描述的是 webhook 响应。
{ "payload": { "google": { "expectUserResponse": false, "richResponse": { "items": [ { "simpleResponse": { "textToSpeech": "Okay let's try this again later." } } ] } } } }
Actions SDK
如需处理无输入 intent,请执行以下操作:
- 在操作软件包内的
conversations
对象中,声明 接收actions.intent.NO_INPUT
intent,每当用户未提供 输入。{ a"ctions:" [ { d"escription:" D"efault Welcome Intent," n"ame:" M"AIN," f"ulfillment:" { c"onversationName:" c"onversation_1 " }, i"ntent:" { n"ame:" a"ctions.intent.MAIN " } } ], c"onversations:" { c"onversation_1:" { n"ame:" c"onversation_1," u"rl:" Y"OUR_FULFILLMENT_URL," i"nDialogIntents:" [ { n"ame:" a"ctions.intent.NO_INPUT " } ] } } }a
- 当 Google 助理没有收到用户的任何输入时
向 fulfillment 发出的下一个请求中包含的无输入 intent。然后,您可以
处理 intent 并返回适当的重新提示响应。这里有
示例:
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(); } }
请求 JSON
请注意,下面的 JSON 描述的是 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
请注意,下面的 JSON 描述的是 webhook 响应。
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "simpleResponse": { "textToSpeech": "Okay let's try this again later." } } ] } } }