Reprompts

You can use the following features to handle cases where users don't provide input to your Actions (no-input errors):

  • System-default reprompts - These reprompt the user automatically with pre-canned reprompts that are generic for all cases.
  • Dynamic reprompts - Declaring that you want to handle reprompting on your own, and receiving an intent (Actions SDK) or event (Dialogflow) every time a no-input occurs, so you can handle them on a case-by-case basis.

System-default reprompts

By default, when you return a response to the Assistant, the system uses default reprompts to ask users to repeat or retype their input.

Dialogflow

Dialogflow enforces a combined maximum of three no-match and no-input inputs. Once a conversation reaches three collection attempts, your Dialogflow agent will end the conversation with a default response. A no-match input in Dialogflow is when one of your fallback intents is triggered.

Dynamic reprompts

You can receive an intent or Dialogflow event every time your Action fails to receive any input. This allows you to return a different response based on some logic, if necessary, and reprompt the user appropriately.

Dialogflow

You can create two types of no-input intents:

  • Normal intent - This method doesn't apply any contexts, so will be triggered when there isn't another, more contextual intent to trigger. This is useful for general reprompts that you want to apply in most cases.

  • Follow-up intent - Follow-up intents are enforced through Dialogflow contexts, ensuring reprompts are triggered only after certain turns of the conversation. This is useful for tailored reprompts that you want to apply to specific situations.

To handle no-input events:

  1. In the left navigation, click Intents.
  2. Create a normal intent or follow-up intent.
    • For normal intents: Click on the + icon by the Intent menu item.

    • For follow-up intents: Hover over the intent that you want to customize the no-input reprompt for and click on Add follow-up intent > custom. A new intent is created below the original intent.

  3. Click on the newly created intent to open the intent editor.
  4. Click the Events section and enter "actions_intent_NO_INPUT" into the Add event field.
  5. In the Actions section, enter an action name or use the one provided by default. For this example, we'll use "no.input".

  6. Click Save.
  7. In the left navigation, click Integrations
  8. Choose Google Assistant and click TEST to make sure the changes are reflected in your Actions project.

Whenever a no-input occurs for this intent, you can use your fulfillment to return an appropriate response or create one in Dialogflow. For example, here's some fulfillment code that uses the client library to handle a no-input intent. Note that the JSON below describes a webhook request.

Node.js
app.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.`);
  }
});
Java
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();
Dialogflow JSON
{
  "responseId": "",
  "queryResult": {
    "queryText": "",
    "action": "",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "",
    "fulfillmentMessages": [],
    "outputContexts": [],
    "intent": {
      "name": "no_input",
      "displayName": "no_input"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": ""
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          }
        ]
      },
      "inputs": [
        {
          "rawInputs": [],
          "intent": "",
          "arguments": [
            {
              "name": "REPROMPT_COUNT",
              "textValue": "1",
              "value": 1
            }
          ]
        }
      ],
      "user": {},
      "conversation": {},
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "session": ""
}

Actions SDK

To handle no-input intents:

  1. In a conversations object inside your action package, declare that you want to receive the actions.intent.NO_INPUT intent whenever a user doesn't provide input.
    "conversations": {
      "conversationName": {
        "name": "conversationName",
        "url": "https://my.fulfillment.com/conversation",
        "inDialogIntents": [
          {
            "name": "actions.intent.NO_INPUT"
          }
        ]
      }
    }
  2. When the Assistant doesn't receive any input from the user, you'll receive the no-input intent in the next request to your fulfillment. You can then process the intent and return an appropriate reprompt response. Here's an example:
    Node.js
    app.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.`);
      }
    });
    Java
    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();
    Actions SDK JSON
    {
      "user": {},
      "device": {},
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          }
        ]
      },
      "conversation": {},
      "inputs": [
        {
          "rawInputs": [],
          "intent": "no_input",
          "arguments": [
            {
              "name": "REPROMPT_COUNT",
              "textValue": "1",
              "value": 1
            }
          ]
        }
      ],
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }