Lately, I’ve built a couple of applications for Alexa devices. I found out that a lot of people started to be interested in Alexa skill kit in terms of building or using the applications. If you will go to Alexa Skill Shop you can find a lot of apps starting on simple voice bot through smart home skills and ending with top music app players.
Let’s build an application that can tell a joke from icndb.
Alexa allows using HTTP webhooks or lambda functions as a communication between your system and end-user device. It is recommended to use lambda functions if the whole system is built on top of Amazon Services.
In this tutorial, I would like to show you how simple it is to create webhooks and pin them up in Alexa Skill console.
Install alexa-skill package to simplify Alexa usage:
pip install alexa-skill
Each Alexa skill needs to specify build-in intents.
from alexa_skill.intents import BuildInIntents
buildin_intents = BuildInIntents(
help_message='Say to Alexa: "tell me a joke"',
not_handled_message="Sorry, I don't understand you. Could you repeat?",
stop_message='stop',
cancel_message='cancel',
)
Implement a key intent which will return random joke using BaseIntents class:
import requests
from alexa_skill.intents import BaseIntents
class JokeIntents(BaseIntents):
@property
def mapper(self):
return {'random_joke': self.random_joke}
def random_joke(self):
joke_response = requests.get('http://api.icndb.com/jokes/random')
if joke_response.status_code != 200:
return self.response('Sorry, I did not find any joke. Please try again'), False
return self.response(joke_response['value']['joke']), True
Mapped methods should return Alexa response and True if the response was successfully handled, otherwise False.
This is very helpful when analytics tools need to be connected. For chatbots, I recommend to use Chatbase.
All requests which are coming from a platform should be handled by one webhook. To do this I will use falcon web framework:
# webhook.py
import logging
import alexa_skill
import falcon
class Fulfiller(object):
def on_post(self, req, resp):
get_response = alexa_skill.Processor(
req.media,
buildin_intents,
'Welcome to joke teller. Would you like to hear a joke?',
'Good bye',
JokeIntents(), # Add implemented intent
)
json_response, handled = get_response()
logging.info('Response was handled by system: {}'.format(handled))
resp.media = json_response
app = falcon.API(media_type=falcon.MEDIA_JSON)
app.add_route('/v1/alexa/fulfiller', Fulfiller())
Alexa requires an endpoint secured with https. To develop and test webhook served from a local machine I recommend to use ngrok. It simply exposes local servers behind NATs and firewalls to the public internet over secure tunnels.
Download https://ngrok.com/download
Setup local server
$ pip install gunicorn
$ gunicorn webhook:app
$ ./ngrok http 80
ngrok by @inconshreveable
Session Status online
Session Expires 7 hours, 59 minutes
Version 2.2.8
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://0374b9cf.ngrok.io -> localhost:8000
Forwarding https://0374b9cf.ngrok.io -> localhost:8000
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
Go to alexa console and create skill
Go to Intents tab and add new intent
Go to test tab and enable tests for a skill
From now on your webhook is ready to use
You can test it on simulator or Alexa device
Alexa skill development is very simple. All you need to know is basic Python Programming language knowledge, one of the web frameworks like Django, Flask, Falcon or other… and that is all!
You don’t need to know Amazon Web services to create a voice application but you can become AWS Alexa skill developer. You can easily develop and test your Alexa skill using ngrok which will expose your local Python server to the web without deploying it to the remote server.
A good idea, user-friendly utterances and well defined Alexa responses are the keys to success.