Things used in this project

Hardware components:
Echo
Amazon Alexa Amazon Echo
Any Alexa enabled device will work.
×1
Software apps and online services:
Screen%20shot%202015 07 20%20at%206.10.26%20pm
Amazon Web Services AWS Lambda
Dp image kit 02
Amazon Alexa Alexa Skills Kit

Schematics

VUI Diagram
This demonstrates the basic interaction flow of a countdown skill. If the stream is open it means Alexa is waiting for a response from the user. If it is closed it means any further response will not be passed to the skill until it is reopened.
Vui 2vqthwjx2j

Code

Lambda Function for Destiny 2 CountdownPython
This is the production Lambda code for the Destiny 2 Countdown Skill
from datetime import datetime
import math
# --------------- 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 beta():
    session_attributes = {}
    card_title = "Countdown"
    now = datetime.today()
    target = datetime.strptime('Jul 18 2017  4:00AM', '%b %d %Y %I:%M%p')
    difference = target - now
    days = difference.days
    hours = math.floor(difference.seconds / 3600) % 24
    seconds = difference.seconds % 60
    minutes = math.floor(difference.seconds / 60) % 60
    totalDays = difference.days
    speech_output = "There are " + str(days) + " days, " + str(hours) + " hours, " + str(minutes) + " minutes, and " + str(seconds) + " seconds left until the Early Access Beta will be available on Playstation. 24 Hours later it will be avaiable on Xbox and 48 hours later after Xbox the beta will be open on both consoles. The PC beta date is still unknown."
    reprompt_text = "There are about " + str(totalDays) + " days left.Just ask if you want to know anything more."
    should_end_session = False
    return build_response(session_attributes, build_speechlet_response(
        card_title, speech_output, reprompt_text, should_end_session))
        
def release_countdown():
    session_attributes = {}
    card_title = "Countdown"
    now = datetime.today()
    target = datetime.strptime('Sep 6 2017  4:00AM', '%b %d %Y %I:%M%p')
    difference = target - now
    days = difference.days
    hours = math.floor(difference.seconds / 3600) % 24
    seconds = difference.seconds % 60
    minutes = math.floor(difference.seconds / 60) % 60
    totalDays = difference.days
    speech_output = "There are " + str(days) + " days, " + str(hours) + " hours, " + str(minutes) + " minutes, and " + str(seconds) + " seconds left until Destiny 2 will be released on console. PC will come out 48 days afterwards."
    reprompt_text = "There are about " + str(totalDays) + " days left. Just ask if you want to know anything more."
    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 = "Thanks for using this skill."
    speech_output = "Thanks for using this skill. For news on new Destiny skills follow @randomrumblegen on Twitter."
    should_end_session = True
    return build_response({}, build_speechlet_response(
        card_title, speech_output, None, should_end_session))

def help():
    card_title = "Help"
    speech_output = "This skill provides a countdown until important Destiny 2 events. You can ask how long is left until the release or the beta."
    should_end_session = False
    return build_response({}, build_speechlet_response(
        card_title, speech_output, speech_output, should_end_session))
        



# --------------- Events ------------------

def on_session_started():
    session_attributes = {}

def on_launch(launch_request, session):
    print(release_countdown())
    return release_countdown()

def on_intent(intent_request, session):
    intent = intent_request['request']['intent']
    intent_name = intent_request['request']['intent']['name']

    if intent_name == "ReleaseCountdownIntent":
        return release_countdown()
    elif intent_name == "BetaCountdownIntent":
        return beta()
    elif intent_name == "AMAZON.HelpIntent":
        return help()
    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):
    return  handle_session_end_request()
    print("on_session_ended requestId=" + session_ended_request['requestId'] +
          ", sessionId=" + session['sessionId'])


# --------------- Main handler ------------------

def lambda_handler(event, context):
    if event['request']['type'] == "IntentRequest":
        return on_intent(event, event['session'])
    elif event['request']['type'] == "SessionEndedRequest":
        return on_session_ended(event['request'], event['session'])
    else:
        return release_countdown()
Skill Builder Code for Destiny 2 Countdown SkillJSON
This code is pasted into the new skill builder portal under the code section.
{
  "intents": [
    {
      "name": "AMAZON.CancelIntent",
      "samples": []
    },
    {
      "name": "AMAZON.HelpIntent",
      "samples": [
        "What can you do",
        "Help me",
        "What are your commands",
        "What functions do you have",
        "What can you tell me"
      ]
    },
    {
      "name": "AMAZON.StopIntent",
      "samples": [
        "Don't do that",
        "That's wrong"
      ]
    },
    {
      "name": "BetaCountdownIntent",
      "samples": [
        "How long until the beta",
        "how long until the destiny two beta",
        "when is the beta",
        "time until the beta",
        "how long is left on the beta",
        "beta",
        "How many days until the beta"
      ],
      "slots": []
    },
    {
      "name": "ReleaseCountdownIntent",
      "samples": [
        "How long is left",
        "How long",
        "Time left",
        "Countdown",
        "How long until Destiny two",
        "Destiny two countdown",
        "Destiny two",
        "Destiny two release",
        "Countdown for Destiny two release",
        "Time until release",
        "Release countdown"
      ],
      "slots": []
    }
  ]
}
Lambda TemplatePython
Edit this template to make the Lambda function for your own skill.
from datetime import datetime
import math
# --------------- 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 ------------------

#when adding more secondary events just copy this function and change the name to have the next letter each time. Make sure to also change the date so that it isn't counting down to the same thing!

def secondary_a():
    session_attributes = {}
    card_title = "Countdown"
    now = datetime.today()
    
    #Change the date below
    target = datetime.strptime('Jul 18 2017  4:00AM', '%b %d %Y %I:%M%p')
    
    difference = target - now
    days = difference.days
    hours = math.floor(difference.seconds / 3600) % 24
    seconds = difference.seconds % 60
    minutes = math.floor(difference.seconds / 60) % 60
    totalDays = difference.days
    speech_output = "There are " + str(days) + " days, " + str(hours) + " hours, " + str(minutes) + " minutes, and " + str(seconds) + " seconds left until the event."
    reprompt_text = "There are about " + str(totalDays) + " days left. Just ask if you want to know about any of the other dates."
    should_end_session = False
    return build_response(session_attributes, build_speechlet_response(
        card_title, speech_output, reprompt_text, should_end_session))
        
def primary():
    session_attributes = {}
    card_title = "Countdown"
    now = datetime.today()
    
    #change the date in the line below
    target = datetime.strptime('Sep 6 2017  4:00AM', '%b %d %Y %I:%M%p')
    
    difference = target - now
    days = difference.days
    hours = math.floor(difference.seconds / 3600) % 24
    seconds = difference.seconds % 60
    minutes = math.floor(difference.seconds / 60) % 60
    totalDays = difference.days
    speech_output = "There are " + str(days) + " days, " + str(hours) + " hours, " + str(minutes) + " minutes, and " + str(seconds) + " seconds left until the event."
    reprompt_text = "There are about " + str(totalDays) + " days left. Just ask if you want to know about any of the other dates."
    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 = "Thanks for using this skill."
    
    #Fill in the fields that are in ALL CAPS
    speech_output = "Thanks for using this skill. Follow " + "YOURUSERNAME on PLATFORM" + "for updates"
    
    should_end_session = True
    return build_response({}, build_speechlet_response(
        card_title, speech_output, None, should_end_session))

def help():
    card_title = "Help"
    speech_output = "This skill provides a countdown until important events. You can ask how long is left."
    repromt_text = "Try asking how long is left."
    should_end_session = False
    return build_response({}, build_speechlet_response(
        card_title, speech_output, repromt_text, should_end_session))
        



# --------------- Events ------------------

def on_session_started():
    session_attributes = {}

def on_launch(launch_request, session):
    return primary()

def on_intent(intent_request, session):
    intent = intent_request['request']['intent']
    intent_name = intent_request['request']['intent']['name']

    if intent_name == "PrimaryIntent":
        return primary()
    elif intent_name == "SecondaryAIntent":
        return secondary_a()
        
    #If adding another secondary just copy the two lines above, changing A to B and so on each time you copy. Make sure to also copy the function code up higher in the file as instructed
    
    elif intent_name == "AMAZON.HelpIntent":
        return help()
    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):

    return  handle_session_end_request()
    print("on_session_ended requestId=" + session_ended_request['requestId'] +
          ", sessionId=" + session['sessionId'])


# --------------- Main handler ------------------

def lambda_handler(event, context):
    if event['request']['type'] == "IntentRequest":
        return on_intent(event, event['session'])
    elif event['request']['type'] == "SessionEndedRequest":
        return on_session_ended(event['request'], event['session'])
    else:
        return primary()
Skill Builder TemplateJSON
Edit and then paste into the skill builder code field. Copy the SecondaryAIntent as needed to add more secondary intents changing the letter and phrases each time. Change it where it says "EVENT" to match your event name.
{
  "intents": [
    {
      "name": "AMAZON.CancelIntent",
      "samples": []
    },
    {
      "name": "AMAZON.HelpIntent",
      "samples": [
        "What can you do",
        "Help me",
        "What are your commands",
        "What functions do you have",
        "What can you tell me"
      ]
    },
    {
      "name": "AMAZON.StopIntent",
      "samples": [
        "Don't do that",
        "That's wrong"
      ]
    },
    {
      "name": "SecondaryAIntent",
      "samples": [
        "How long until the EVENT",
        "when is the EVENT",
        "time until the EVENT",
        "how long is left on the EVENT",
        "EVENT",
        "How many days until the EVENT"
      ],
      "slots": []
    },
    {
      "name": "ReleaseCountdownIntent",
      "samples": [
        "How long is left",
        "How long",
        "Time left",
        "Countdown",
        "How long until EVENT",
        "EVENT countdown",
        "EVENT",
        "EVENT start",
        "Countdown for EVENT release",
        "Time until start",
        "Start countdown"
      ],
      "slots": []
    }
  ]
}

Credits

Big engram isns8txm7l
Elvis Wolcott

Self-taught app developer and hardware developer, currently working on making the Random Rumble Generator and other voice based solutions

Contact

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Cryptocurrency Price Checker!
Easy
  • 161
  • 2

Full instructions

With the recent rise in cryptocurrencies, this Price Checker will keep you up to date with the most recent market fluctuations!

Trademark Master
Easy
  • 321
  • 10

Work in progress

Trademark Master tells you if any string has already been registered.

Opening Bell
Easy
  • 1,542
  • 23

Full instructions

A simple Alexa voice skill to retrieve the current performance of a publicly traded stock (NASDAQ, NYSE) using the company name.

Brick Bot
Easy
  • 705
  • 14

Protip

A one-stop-skill for your LEGO® needs! Alexa can tell you available sets, themes, and sub-themes and give you details based on set numbers.

Funny Quoter
Easy
  • 326
  • 8

Full instructions

This has some of the weirdest quotes up her sleeve! If you're feeling blue, and need something to cheer you up, just call on Funny Quoter.

Voice Control RGB LED
Easy
  • 7,686
  • 41

Full instructions

Control your rgb kitchen lighting with Alexa and Photon.

Add projectSign up / Login