Skill Discovery & CanFulfillIntentRequest in Alexa.NET

Posted by Steven Pears on June 09, 2018 · 5 mins read

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.