Step by Step

  1. Navigate to the AWS Lambda service in the console.

  2. Click Create function and specify the following:

    • Function name: orderLambda-team#Click to copy

    • Runtime: Python 3.8 – This is the language we’ll be writing our business logic in

    • Execution role: Use an existing role: LambdaOrdersRole – This provides our Lambda function programmatic access to our machine learning model and IoT drones for delivery

  3. Select Create function.

  4. We can now specify our business logic in the form of Python code! Copy and paste the below code into the Function code:

    import boto3
    import json
    import os
    ##############################
    # Look up users name in DynamoDB to retrieve UserID and Mobile Number
    ##############################
    def ddb_get_user_data(name):
    
        dynamodb = boto3.resource('dynamodb')
        table = dynamodb.Table('user')
    
        response = table.get_item(Key={'name': name})
    
        item = response['Item']
        return item
    
    ##############################
    # IoT call to drones with product colour and mobile number
    ##############################
    def iot_Publish(iot_Payload):
        iot_client = boto3.client('iot-data')
    
        iot_response = iot_client.publish(
            topic='OMIn',
            payload = json.dumps(iot_Payload)
        )
        return iot_response
    
    
    ##############################
    # Builders
    ##############################
    
    def build_PlainSpeech(body):
        speech = {}
        speech['type'] = 'PlainText'
        speech['text'] = body
        return speech
    
    def build_response(message, session_attributes={}):
        response = {}
        response['version'] = '1.0'
        response['sessionAttributes'] = session_attributes
        response['response'] = message
        return response
    
    def build_SimpleCard(title, body):
        card = {}
        card['type'] = 'Simple'
        card['title'] = title
        card['content'] = body
        return card
    
    ##############################
    # Responses
    ##############################
    
    def statement(title, body):
        speechlet = {}
        speechlet['outputSpeech'] = build_PlainSpeech(body)
        speechlet['card'] = build_SimpleCard(title, body)
        speechlet['shouldEndSession'] = False
        return build_response(speechlet)
    
    def endStatement(title, body):
        speechlet = {}
        speechlet['outputSpeech'] = build_PlainSpeech(body)
        speechlet['card'] = build_SimpleCard(title, body)
        speechlet['shouldEndSession'] = True
        return build_response(speechlet)
    
    def continue_dialog():
        message = {}
        message['shouldEndSession'] = False
        message['directives'] = [{'type': 'Dialog.Delegate'}]
        return build_response(message)
    
    ##############################
    # Custom Intents
    ##############################
    
    def surprise_me_intent(event, context):
        print(event)
        dialog_state = event['request']['dialogState']
    
        if dialog_state in ("STARTED", "IN_PROGRESS"):
            return continue_dialog()
    
        elif dialog_state == "COMPLETED":
    
            #Step 1: Extract First Name from Alexa slot
            first_Name = (event['request']['intent']['slots']['name']['value']).lower()
            print(first_Name)
    
            #Step 2: Use the First Name to get the users Mobile number and UserID from DynamoDB
            get_ddb_info = ddb_get_user_data(first_Name)
            ddb_user_id = get_ddb_info['userid']
            print(ddb_user_id)
            mobile = get_ddb_info['mobile']
    
            #Step 3: Call the Personalize API. 
    
            #Offer Option1: Most Ordered
            offer = ['24852','44632','5077','9076','25890','31506','27156','8021']
    
            personalizeRt = boto3.client('personalize-runtime')
            aws_account_id = context.invoked_function_arn.split(":")[4]
            aws_region = context.invoked_function_arn.split(":")[3]
            personalize_arn = "arn:aws:personalize:" + aws_region + ":" + aws_account_id + ":campaign/B4E"
            response = personalizeRt.get_personalized_ranking(
                campaignArn = personalize_arn,
                userId = ddb_user_id,
                inputList = offer) #banana, strawberries, organic milk
            topProduct = response['personalizedRanking'][0]['itemId']
            print(response)
    
    
            #Step 4: Convert Product into Colour for Drones LED
            droneColours = ["blue","red","green","yellow","purple","white","orange","aqua"]
            products = ["Bananas", "Sparkling Water Grapefruit","100% Whole Wheat Bread","Blueberries","Boneless Skinless Chicken Breast","Extra Virgin Olive Oil","Organic Black Beans","100% Recycled Paper Towels"]
            moduloProduct = int(offer.index(topProduct))
            print(moduloProduct)
            productColour = droneColours[moduloProduct]
            print(productColour)
            product = products[moduloProduct]
    
            if (moduloProduct==0):
                productid="banana"
            if (moduloProduct==1):
                productid="water"
            if (moduloProduct==2):
                productid="bread"
            if (moduloProduct==3):
                productid="blueberries"
            if (moduloProduct==4):
                productid="chicken"
            if (moduloProduct==5):
                productid="olive"
            if (moduloProduct==6):
                productid="bean"
            if (moduloProduct==7):
                productid="papertowel"
    
            #Step 5: Publish IoT message to the topic the Drones are subscribed to
            #iot_Payload = recommendation[][][] #analyse response...
            iot_Payload = {
                    "product": productid,
                    "mobile": mobile
            }
            iot_Publish(iot_Payload)
    
            #Step 5: Return a message back to Alexa
            return_statement = "Thanks " + first_Name + "! According to your purchase history, we think you would really like " + product + ". We're sending it to you now."
    
            return endStatement("surprise_me_intent", return_statement)
    
        else:
            return statement("surprise_me_intent", "No dialog")
    
    ##############################
    # Required Intents
    ##############################
    
    def cancel_intent():
        return statement("CancelIntent", "You want to cancel")  #don't use CancelIntent as title it causes code reference error during certification 
    
    def help_intent():
        return statement("CancelIntent", "You want help")       #same here don't use CancelIntent
    
    def stop_intent():
        return statement("StopIntent", "You want to stop")      #here also don't use StopIntent
    
    ##############################
    # On Launch
    ##############################
    
    def on_launch(event, context):
        return statement("title", "Welcome to Daily Deal, you can ask me to surprise you")
    
    ##############################
    # Routing
    ##############################
    
    def intent_router(event, context):
        intent = event['request']['intent']['name']
    
        # Custom Intents
    
        if intent == "SurpriseMeIntent":
            return surprise_me_intent(event, context)
    
        # Required Intents
    
        if intent == "AMAZON.CancelIntent":
            return cancel_intent()
    
        if intent == "AMAZON.HelpIntent":
            return help_intent()
    
        if intent == "AMAZON.StopIntent":
            return stop_intent()
    
    ##############################
    # Program Entry
    ##############################
    
    def lambda_handler(event, context):
        if event['request']['type'] == "LaunchRequest":
            return on_launch(event, context)
    
        elif event['request']['type'] == "IntentRequest":
            return intent_router(event, context)
    

    There’s a fair bit of code here, that’s doing the following:

    • Collecting the user’s name from Alexa and finding their mobile number in our database

    • Sending their name as well as our top 8 products to our machine learning model, to determine which of the 8 products they would be most interested in

    • Sending that information to the drones for delivery of the recommended product to the customer

    Expand for an Added Challenge!
  5. The final thing left to do is ensure the Alexa skill invokes the Lambda function once it’s collected the user’s details. To do this, expand the Designer window, click Add trigger, the select Alexa Skills Kit. Select Disable for the Skill ID verification and select Add. Click Save. Copy the ARN which is a resource identifier for the Lambda function in the top right hand corner.

  6. Go back to your Alexa developer console and select Endpoint, then choose AWS Lambda ARN, and paste the ARN copied in the previous step, in Default Region. Click Save Endpoints. Select the Invocation tab, then select Build Model.