Great! Once we start the local server, start ngrok, and provide our ngrok HTTPS endpoint to our skill, we can use the Service Simulator to test a basic interaction. Or, if you have an Alexa device registered to your account, you can test the connection using any Alexa-enabled hardware.

Struggling to remember how to set up a local, tunneled environment with Alexa? Check out the guide in the first module.

Connecting Them Together

When we ask:

Alexa, ask Number Facts about 42

Alexa responds with:

The number 42 is pretty cool.

We have a connection! Now, let’s upgrade our Ruby code to give us an interesting fact about the number 42.

Connect to the Number Facts API

In our Ruby code, let’s make a call to the Numbers API to grab an interesting fact about the number 42:

require 'sinatra'
require 'json'
# Since we're making a call to an external API,
# we need Ruby's Net::HTTP library.
require 'net/http'
post '/' do
# First, we encode the Numbers API as a URI
number_facts_uri = URI("http://numbersapi.com/42")
# Then we make a request to the API
number_fact = Net::HTTP.get(number_facts_uri)
{
version: "1.0",
response: {
outputSpeech: {
type: "PlainText",
# We provide the fact we received as
# plain text in our response to Amazon.
text: number_fact
}
}
}.to_json
end

Head to the Service Simulator (or any Alexa-enabled device) and see that you can now make a request to Number Facts for random trivia about the number 42. This is a great start! But what about trivia for other numbers?

2. Using Built-In Slots to Pass Parameters to Our Application

In section 1, we weren't able to pass any parameters to our application. As a result, we could only ask Number Facts to tell us about 42. If a user wanted to know about any other number, Alexa would just tell them about 42.

We’d like our users to receive trivia facts for all sorts of numbers. Users should be able to ask:

Alexa, ask Number Facts about {Number}

where {Number} is any number.

Our users should hear a response concerning that number, and that number only.

To do this, we need to provide a parameter to our intent and utterance. In Alexa terminology, we provide parameters as slots. Slots need a name and a type.

Using Built-In Slots to Pass a Number

Let's start from the utterance, or what we want our users to be able to say. To reference a slot in an utterance, we use curly brackets ({}) around the name we will use for that slot.

NumberFact about {Number}

Now let's add that slot into our intent schema with the same name we're referencing in our utterance: number.

We’ve chosen the AMAZON.NUMBER type, which will convert any spoken numbers to digits. So this:

Alexa, ask Number Facts about fifteen

becomes this:

Alexa, ask Number Facts about 15

There are many built-in slot types. You can also define custom slot types (we’ll do this in the next section).

Built-in slot types are handy for capturing user input for common use cases such as numbers, dates, cities, and so on.

Handling the Slot Value in Sinatra

Before we change any Ruby code, let’s observe how adding a slot modifies the incoming request from Amazon’s Service Simulator. We can log the incoming request in our Sinatra application using request.body.read within our post '/' route.

Using the Service Simulator, let's prompt Amazon to send a request by using the phrase:

Alexa, ask Number Facts about 4

In our Sinatra application, notice the slot value passed in the request:

At the moment, we're not doing anything other than logging the value for this slot; we're always returning information about the number 42. In our Sinatra application, let’s grab the slot value out of Amazon’s request and pass that to the Numbers API:

Testing in the Service Simulator shows users can now provide an arbitrary number to our Number Facts skill and receive trivia about that number. Great!

Let’s make one final upgrade: asking for facts of a specific type.

3. Using Custom Slots

So far, users can ask Alexa:

Alexa, ask Number Facts about {Number}

where {Number} is any number. Users will hear an interesting fact about any given number.

However, the Numbers API can provide two different kinds of facts: trivia facts and math facts. We’d like users to be able to ask:

Alexa, ask Number Facts to tell me a {FactType} fact about {Number}

{FactType} is either a “trivia” fact or a “math” fact.

Using a Custom Slot to Pass in a Fact Type

Because we’re passing another piece of variable information to our intent, we’ll need to define another slot.

Slots do not restrict user input to certain values. Instead, they guide interpretation of the user's words toward those terms.

However, where the built-in AMAZON.NUMBER slot restricted us to just numbers, there are no built-in slots that will restrict us to the words “trivia” or “math.” We have to make our own.

Let's head to the interaction model pane in the Alexa Developer Console and add a new custom slot type. We'll call this custom slot type FACT_TYPE. There are two possible values for this custom slot type: trivia and math. They must be separated by a newline, like so:

trivia
math

These values act as training data for Alexa's voice recognition. They don't restrict users to just the given words; users can say different words in addition to these two. For instance, if a user said, "Alexa, ask Number Facts to tell me a bicycle fact about 42," the word “bicycle” would be sent as part of the request.

Now that we've defined our custom slot type, we can go ahead and rewrite our utterance to include the slot:

2. Remember that slot values do not list the possible values a user can enter; it only lists the valid values your application accepts. Since users can say whatever they like in addition to "trivia" and "math," upgrade your Sinatra application to handle cases where a user asks for a fact type you don't recognise.

Build a Skill, Get a Shirt

The Alexa Skills Kit (ASK) enables developers to build capabilities, called skills, for Alexa. ASK is a collection of self-service APIs, documentation, templates, and code samples that make it fast and easy for anyone to add skills to Alexa.