Skill Discovery & CanFulfillIntentRequest in Alexa.NET

Amazon have released a fabulous new update to the way Alexa works. If a user makes a request without a skill name and Alexa can’t handle it, machine learning kicks in and some of the most likely skills to handle it are sent a new kind of request asking if they could handle it. Based on the responses from those skills the most appropriate can then be used to handle the request. This post is showing you how to enable your skill to take advantage of this new functionality with the latest Alexa.NET.

For more details you can always check out the Alexa blog article

This feature is currently in Beta with Amazon & Alexa, and as it alters the structure of the core response object – I felt the change required a beta of Alexa.NET until we’re sure of the changes. To that end, this post was written after we released Alexa.NET v1.5.5-pre and will hopefully be updated once the feature comes out of Beta

The new request type

So to allow for this new skill discovery process, your skill will receive a new request, of type CanFulfillIntentRequest. The request structure is pretty much the same as an intent request, with all the usual information.

This is on purpose, as Amazon want this extra set of data to require as little alteration as possible to your existing skill code (it’s that code that made them pick your skill a a candidate after all!)

Depending on the logic you could handle the same thing with similar logic.

switch(input.Request)
{
    case CanFulfillIntentRequest fulfillRequest:
        var response = ProcessIntent(fulfillRequest.Intent,false);
        return response;
    case IntentRequest intentRequest:
        var response = ProcessIntent(intentRequest.Intent,true);
        return response;
}
...
private SkillResponse ProcessIntent(Intent intent, bool actuallyRunCode)
{
 //Here you would run the method or just see if you could
}

Adding fulfillment information to your response

So you’ve checked the intent data, you know if you can handle it or not – how do you let Amazon know?

Fulfillment is expressed by use of a new property against the response body, alongside card and output, CanFulfillIntent. This describes whether or not your skill can handle the information, were it sent as part of a real request. The final response in the JSON looks like this

{
"canFulfill": "YES",
"slots": {
"slotName": {
"canUnderstand": "YES",
"canFulfill": "NO"
}
}
}

CanFulfill

This is your confidence on whether or not you can actually handle this request.
Yes: Totally, not a problem, it’s an intent I understand and all the slots make sense
Maybe: I get it, it’s an intent I get, but maybe the customer would need to answer some more questions, link their account, do some more work to really know.
No: No idea what you’re talking about, why are we still talking?

Slots

Each slot has an entry as well, which you can optionally fill in to show what you can and can’t handle:
canUnderstand: The confidence your skill has about understanding the slot value. It’s a yes/no/maybe situation, but there are a lot of specific rules on this one, so I’d recommend checking out the docs
canFulfill: Just because your skill understands the value, doesn’t mean you can deal with it. So this is a yes/no value that says whether or not you can do something with the value to fulfill the intent.

So you send this response, using code like the following:

var skillResponse = GetResponse();
var fulfillment = new CanFulfillIntent{
  CanFulfill = CanFulfill.YES,
  Slots = new Dictionary<string,string>{
  {
      {"slotName",new SlotFulfillment
          {
              CanFulfill = SlotCanFulfill.NO,
                CanUnderstand = CanUnderstand.YES
          }
        }
    }
}

skillResponse.Response.CanFulfill = fulfillment;
return skillResponse

and then Amazon can decide whether or not to use your skill for the real request (yeah, I’m going to try and write a Pull Request to tidy that up a bit, but you see how it maps – right?)

I think this a great move and should allow well crafted skills to gain more traction by themselves.

3 thoughts on “Skill Discovery & CanFulfillIntentRequest in Alexa.NET

  1. Nik

    Thanks for this code. The code has some issues (i.e it doesn’t compile). I was easily able to fix that. But when I post a sample Alexa request as outlined here => https://developer.amazon.com/docs/custom-skills/implement-canfulfillintentrequest-for-name-free-interaction.html and try to read the slots passed, the Intent object is always null.

    Basically, I am trying to read the slots like this (same code which reads slots for regular intents). I also dumped out a log and see the JSON has all the slots in it. The json always has the values, but the code blows up because var slot = intent.Intent (the intent.Intent object is null!!!!). Will you able to post sample JSON request you used to test this with?

    protected string GetVariable(IntentRequest intent, string key, string defaultValue = null)
    {
    try
    {
    var json = JsonConvert.SerializeObject(intent);
    Console.WriteLine(“GetVariable => JSON => ” + json);
    var slot = intent.Intent.Slots[key];
    if (slot == null || slot.Value == null)
    {
    return defaultValue;
    }
    else
    {
    return slot.Value;
    }
    }
    catch (Exception ex)
    {
    Console.WriteLine($”Blew up in GetVariable({key}. Returning defaultValue=>{defaultValue}. Exception=> {ex.Message})”);
    return defaultValue;
    }
    }

    Reply
    1. Steven Pears Post author

      Hi there

      Sorry you had trouble with the code.

      The Amazon documentation on this feature has got some issues, but the requests seem pretty clean. If you go to the Alexa.NET GitHub repo there is an example request in the tests folder, but that’s just a copy of the request body used In the documentation

      That JSON in the docs also isn’t a complete request, a few of the standard fields have been truncated for easy reading, but you can see at what level the Intent is shown and that’s represented by the JSON file in the repo. The test correctly deserializes, so there shouldn’t be any trouble if your request matches that structure.

      Happy to continue helping with the GitHub issue you’ve already raised.

      Thank you!

      Reply
      1. Nik

        Got it to work. Thanks! Tried it with JSOn using Alexa Simulator and skill responds with correct reply as expected. The skill update also passed certification in the Alexa store, but when I try telling my Alexa (which has the skill installed) an “intent” which I know for sure that my skill can handle, Alexa conveniently tells me “I don’t know that one”, instead of pinging my Skill’s CanFulfillIntentRequest handler. Definitely not your problem, but wondering if you were able to try it out in real life and saw results as expected?

        Reply

Leave a Reply

Your email address will not be published. Required fields are marked *