Skip to content

Using a DTMF grammar

Jean-Philippe Gariépy edited this page Apr 25, 2015 · 2 revisions

This example shows how to use a DTMF grammar to define what should be accepted during DTMF recognition.

Here a grammar that will accept all North-American valid phone number:

phone-number.grxml:

<?xml version="1.0" encoding="UTF-8"?>

<grammar version="1.0" xmlns="http://www.w3.org/2001/06/grammar" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.w3.org/2001/06/grammar http://www.w3.org/TR/speech-grammar/grammar.xsd" 
  mode="dtmf"
  tag-format="semantics/1.0" 
  root="phoneNumber">

  <!-- North-American phone number -->
  <!-- See http://en.wikipedia.org/wiki/North_American_Numbering_Plan -->
  <rule id="phoneNumber" scope="public">

    <!-- optional country code: 1 -->
    <item repeat="0-1">1</item>

    <!-- NPA (area code) -->
    <ruleref uri="#r2to9" />
    <ruleref uri="#r0to9" />
    <ruleref uri="#r0to9" />

    <!-- NXX -->
    <ruleref uri="#r2to9" />
    <ruleref uri="#r0to9" />
    <ruleref uri="#r0to9" />

    <!-- XXXX -->
    <ruleref uri="#r0to9" />
    <ruleref uri="#r0to9" />
    <ruleref uri="#r0to9" />
    <ruleref uri="#r0to9" />

  </rule>

  <rule id="r0to9" scope="public">
    <one-of>
      <item>0</item>
      <item>1</item>
      <item>2</item>
      <item>3</item>
      <item>4</item>
      <item>5</item>
      <item>6</item>
      <item>7</item>
      <item>8</item>
      <item>9</item>
    </one-of>
  </rule>

  <rule id="r2to9" scope="public">
    <one-of>
      <item>2</item>
      <item>3</item>
      <item>4</item>
      <item>5</item>
      <item>6</item>
      <item>7</item>
      <item>8</item>
      <item>9</item>
    </one-of>
  </rule>

</grammar>

Here's how this should be use in the dialogue:

Dialogue.java:

GrammarItem dtmfGrammar = new GrammarReference(context.getContextPath()
                                               + "/grammars/phone-number.grxml");
DtmfRecognition dtmfRecognition = new DtmfRecognition(dtmfGrammar);

Interaction interaction = interaction("get-phone-number")
        .addPrompt(new SpeechSynthesis("Enter your phone number."))
        .build(dtmfRecognition, Duration.seconds(5));

VoiceXmlInputTurn inputTurn = DialogueUtils.doTurn(interaction, context);

Since the grammar is very simple and it doesn't provide semantic interpration, the result can be obtain by getting the utterance property of the recognition result.

Dialogue.java:

Logger logger = context.getLogger();
if (inputTurn.getRecognitionInfo() != null) {
    JsonArray recognitionResult = inputTurn.getRecognitionInfo().getRecognitionResult();
    //Extracting the "utterance" of the first recognition hypothesis. 
    String phoneNumber = recognitionResult.getJsonObject(0).getString("utterance");
    logger.info("Phone number entered: " + phoneNumber);
} else if (VoiceXmlEvent.hasEvent(VoiceXmlEvent.NO_INPUT, inputTurn.getEvents())) {
    logger.info("Timeout.");
} else if (VoiceXmlEvent.hasEvent(VoiceXmlEvent.NO_MATCH, inputTurn.getEvents())) {
    logger.info("Invalid phone number");
}

Running this example

You can download or browse the complete code for this example at GitHub.This is a complete working application that you can build and run for yourself.

You can also clone the Rivr Cookbook repository and checkout this example:

git clone -b dtmf-grammar [email protected]:nuecho/rivr-cookbook.git

Then, to build and run it:

cd rivr-cookbook

./gradlew jettyRun

The VoiceXML dialogue should be available at http://localhost:8080/rivr-cookbook/dialogue

To stop the application, press Control-C in the console.