Expects are useful for in conversations to users to capture their next response and force it to an intent.

For now you can only set one expects. We plan to have multiple expects in a future version.

module.exports = class HowOldAreYouIntent extends Intent {

  setup() {
    this.name = 'How old are you';
    this.train([
      'how old are you',
      'what is your age'
    ]);
  }

  response(request) {
    request.expect({
      action: 'reply',
      force: true
    });
    return [
      'I have no age, I am a bot!',
      'How old are you?'
    ];
  }

  reply(request) {
    return 'OK, you are '+request.input.text;
  }

}
How old are you?
I have no age, I am a bot!
How old are you?
30
OK, you are 30

The above example won’t check the user input so the following problem can happen…

How old are you?
I have no age, I am a bot!
How old are you?
Apples
OK, you are Apples
Key Required Default Description
key No expects Parameter key if set
action No response Action to use when the expected input has been matched
force No false If set to true what ever user input after will be directed to the same intent
fail No false If forced is true and the input is not matched the action is changed to the value of fail
save_answer No false If set to true the users input will be stored to their user record and can be used for slotfilling
expire No 60 Seconds for the expects to expire
entity No false User input will be parsed to get entity data. The result if matched will be set to a parameter key called expects. If entity is not set then data must be passed.
data No null If instead of using entity data it’s possible to manually set the data to be checked

Expects with an entity

You could handle lots of different exceptions in your reply method but you could also make an entity to parse and check for the information creating a better flow.

In this example key has not been set so the default value of ‘expects’ will be used to get the users reply.

module.exports = class FavoriteNumberIntent extends Intent {

  setup() {
    this.train([
      'what is your favorite number'
    ]);
  }

  response(request) {
    request.expect({
      action: 'reply',
      entity: 'App.Common.Entity.Number',
      force: true
    });
    return [
      'Not sure, what is your favorite number?'
    ];
  }

  reply(request) {
    var value = request.parameters.value('expects');
    if(value) {
      return 'I think '+value+' is a lucky number too!';
    }
    return 'That is not a number';
  }

}
What is your favorite number?
Not sure, what is your favorite number?
I love 60
I think 60 is a lucky number too!
What is your favorite number?
Not sure, what is your favorite number?
Bananas
That is not a number

Force with fail and manual data

module.exports = class FlowerMenuIntent extends Intent {

  setup() {
    this.train([
      'flowers'
    ]);

    this.menu = {
      1: 'Order flowers',
      2: 'Check your status',
      3: 'Contact us',
      4: 'Exit'
    };

    this.stop = false;
  }

  after_request(request) {
    if(this.stop) {
      this.stop = false;
      return false;
    }

    request.expect({
      force: true,
      action: 'chosen',
      fail: 'incorrect',
      data: {
        "1": {},
        "2": {},
        "3": {},
        "4": {
          "synonyms": ["exit"]
        }
      }
    });
  }

  response(request) {
    let output = [];
    for(var key in this.menu) {
      output.push(key+'. '+this.menu[key]);
    }
    return output;
  }

  chosen(request) {
    let val = request.parameters.value('expects');

    if(val == '4') {
      this.stop = true;
      return 'Thanks for shopping with us!';
    }

    return 'You chose "'+this.menu[val]+'"';
  }

  incorrect(request) {
    return 'Sorry, there is no menu option ' + request.input.text;
  }

}
Flowers
1. Order flowers
2. Check your status
3. Contact us
4. Exit
6
Sorry, there is no menu option 6
2
You chose "Check your status"
4
Thanks for shopping with us!

Save answer

Saving the users expected answer will store the information in the user session. This can then be used in any other intent the user calls.

This can be useful to build up contextual information about the user. In the example we are handling loading in the previously entered answer direct from the user record. It can also be used for parameter slot filling.

module.exports = class FootballQuestionIntent extends Intent {

  setup() {
    this.train([
      'do you like football?'
    ]);
  }

  response(request) {
    if(request.user.has('football')) {
      if(request.user.get('user.football') == 'yes') {
        return 'Yes I do and I know you love it too!';
      }
      else {
        return 'Yes I do and I know you don\'t enjoy it already';
      }
    }

    request.expect({
      key: 'football',
      action: 'reply',
      entity: 'App.Common.Entity.Confirm',
      save_answer: true
    });
    return [
      'Yes, I love football, do you?'
    ];
  }
  
  reply(request) {
    var value = request.parameters.value('football');
    if(value == 'yes') {
      return 'We will go to a game together soon!';
    }
    return 'Shame, not everyone enjoys it';
  }

}
Do you like football?
Yes, I love football, do you?
Yup
We will go to a game together soon!
Do you like football?
Yes I do and I know you don't enjoy it already

Expiring expects

By default when setting an expects it will expire in 60 seconds, or what is in your config.js file.

You can define the expiry seconds in the request.

//Expired in 10 seconds
request.expect({ expire: 10 });

//Expired in 1 hour
request.expect({ expire: 3600 });
Short memory
Do you like bananas?
Yes
I like bananas
Short memory
Do you like bananas?
5 seconds later
Yes
Not sure what you are saying yes to.

Cancelling expects

If the user is trapped in a conversation using expects they can use cancel keywords.

Take survey
Do you watch sports TV?
Yes
Which sports do you watch the most?
Stop
No problems!