Hardware components | ||||||
| × | 1 | ||||
Software apps and online services | ||||||
|
I love jokes. I love Amazon, and Alexa skills. I wanted to create something that combines my passions of humor and technology into a cohesive, simple product that makes people laugh.
Alexa Random Joke is pretty simple (mainly built for me learning how to use the Skills API). Say "Tell me a joke" or "Random joke!" and Alexa will read back to you a random joke using a RESTful API.
To build my app, I first created and set up an Alexa skill. Then, I built the interaction model that would call a specific intent/function (JokeIntent) after certain phrases were said, such as "tell me a joke." After that I developed an AWS Lambda function that would essentially return the speech output for a random joke after retrieving it from the API. I then did testing, debugging, and finally once everything worked, published it! Although there were many obstacles, bugs, and a couple issues that prevented publication, I eventually fixed them and the skill is now live on Amazon!
from __future__ import print_function
import urllib2
import requests
import json
# --------------- Helpers that build all of the responses ----------------------
def build_speechlet_response(title, output, reprompt_text, should_end_session):
return {
'outputSpeech': {
'type': 'PlainText',
'text': output
},
'card': {
'type': 'Simple',
'title': title,
'content': output
},
'reprompt': {
'outputSpeech': {
'type': 'PlainText',
'text': reprompt_text
}
},
'shouldEndSession': should_end_session
}
def build_response(session_attributes, speechlet_response):
return {
'version': '1.0',
'sessionAttributes': session_attributes,
'response': speechlet_response
}
# --------------- Functions that control the skill's behavior ------------------
def get_welcome_response():
""" If we wanted to initialize the session to have some attributes we could
add those here
"""
session_attributes = {}
card_title = "Welcome"
speech_output = "Welcome to Random Joke!" \
"To hear a random joke, just say tell me a joke!"
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = "Please say tell me a joke."
should_end_session = False
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def handle_session_end_request():
card_title = "Session Ended"
speech_output = "Thank you for hearing random jokes!"
# Setting this to true ends the session and exits the skill.
should_end_session = True
return build_response({}, build_speechlet_response(
card_title, speech_output, None, should_end_session))
def randomJoke(intent, session):
card_title = intent['name']
session_attributes = {}
should_end_session = False
try:
url = "http://tambal.azurewebsites.net/joke/random"
jokeJSON = requests.get(url)
jokeJSON = jokeJSON.json()
joke = jokeJSON["joke"]
speech_output = str(joke)
reprompt_text = "Hope you laughed!"
should_end_session = True
return build_response (session_attributes, build_speechlet_response(card_title, speech_output, reprompt_text, should_end_session))
except:
speech_output = "Oops! Please try again by asking for a joke."
reprompt_text = "Please ask for a joke."
should_end_session = False
return build_response (session_attributes, build_speechlet_response(card_title, speech_output, reprompt_text, should_end_session))
# --------------- Events ------------------
def on_session_started(session_started_request, session):
""" Called when the session starts """
print("on_session_started requestId=" + session_started_request['requestId']
+ ", sessionId=" + session['sessionId'])
def on_launch(launch_request, session):
""" Called when the user launches the skill without specifying what they
want
"""
print("on_launch requestId=" + launch_request['requestId'] +
", sessionId=" + session['sessionId'])
# Dispatch to your skill's launch
return get_welcome_response()
def on_intent(intent_request, session):
""" Called when the user specifies an intent for this skill """
print("on_intent requestId=" + intent_request['requestId'] +
", sessionId=" + session['sessionId'])
intent = intent_request['intent']
intent_name = intent_request['intent']['name']
# Dispatch to your skill's intent handlers
if intent_name == "JokeIntent":
return randomJoke(intent, session)
elif intent_name == "AMAZON.HelpIntent":
return get_welcome_response()
elif intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent":
return handle_session_end_request()
else:
raise ValueError("Invalid intent")
def on_session_ended(session_ended_request, session):
""" Called when the user ends the session.
Is not called when the skill returns should_end_session=true
"""
print("on_session_ended requestId=" + session_ended_request['requestId'] +
", sessionId=" + session['sessionId'])
# add cleanup logic here
# --------------- Main handler ------------------
def lambda_handler(event, context):
""" Route the incoming request based on type (LaunchRequest, IntentRequest,
etc.) The JSON body of the request is provided in the event parameter.
"""
print("event.session.application.applicationId=" +
event['session']['application']['applicationId'])
"""
Uncomment this if statement and populate with your skill's application ID to
prevent someone else from configuring a skill that sends requests to this
function.
"""
# if (event['session']['application']['applicationId'] !=
# "amzn1.echo-sdk-ams.app.[unique-value-here]"):
# raise ValueError("Invalid Application ID")
if event['session']['new']:
on_session_started({'requestId': event['request']['requestId']},
event['session'])
if event['request']['type'] == "LaunchRequest":
return on_launch(event['request'], event['session'])
elif event['request']['type'] == "IntentRequest":
return on_intent(event['request'], event['session'])
elif event['request']['type'] == "SessionEndedRequest":
return on_session_ended(event['request'], event['session'])
{
"intents": [
{
"intent": "JokeIntent",
"slots": [
]
},
{
"intent": "AMAZON.HelpIntent"
},
{
"intent": "AMAZON.CancelIntent"
}
]
}
JokeIntent Tell me a joke
JokeIntent Joke
JokeIntent Tell a joke
JokeIntent Say a joke
JokeIntent Tell me a random joke
JokeIntent Random joke
JokeIntent Tell a random joke
JokeIntent Say a random joke
AMAZON.CancelIntent Quit
AMAZON.CancelIntent Leave
AMAZON.CancelIntent Cancel
AMAZON.CancelIntent Exit
Comments