aws-lambdaalexa-skills-kit

How to use Alexa SkillBuilder into AWS Lambda into a Container


I successfully launched an Alexa Smart Home Skill within an AWS Python Lambda in a container. https://github.com/MelleD/haaska-tailscale

A json response was always returned in the evenHandler method. This works so far.

def event_handler(event, context):
...
ha = HomeAssistant(config)

return ha.post('alexa/smart_home', event, wait=True)

See entry point and docker file https://github.com/MelleD/haaska-tailscale/blob/main/Dockerfile#L32 https://github.com/MelleD/haaska-tailscale/blob/main/haaska/haaska.py#L113

Now I'm trying the same thing with the Skill Builder as in the instructions here: I found an example for Python here. https://developer.amazon.com/en-US/docs/alexa/custom-skills/handle-requests-sent-by-alexa.html#do-skill-id-verification-in-code

Here is the SkillBuilder: https://github.com/keatontaylor/alexa-actions/blob/master/lambda/lambda_function.py#L646

However, I don't understand how I should design the even handler method now?

I tried:

def event_handler(event, context):
    """
    The SkillBuilder object acts as the entry point for your skill, routing all request and response
    payloads to the handlers above. Make sure any new handlers or interceptors you've
    defined are included below.
    The order matters - they're processed top to bottom.
    """
    sb = SkillBuilder()
    logger.info("Add SkillBuilder to the lambda handler.")
    # register request / intent handlers
    sb.add_request_handler(LaunchRequestHandler())
    sb.add_request_handler(YesIntentHandler())
    sb.add_request_handler(NoIntentHandler())
    sb.add_request_handler(StringIntentHandler())
    sb.add_request_handler(SelectIntentHandler())
    sb.add_request_handler(NumericIntentHandler())
    sb.add_request_handler(DurationIntentHandler())
    sb.add_request_handler(DateTimeIntentHandler())
    sb.add_request_handler(CancelOrStopIntentHandler())
    sb.add_request_handler(SessionEndedRequestHandler())
    sb.add_request_handler(IntentReflectorHandler())

    # register exception handlers
    sb.add_exception_handler(CatchAllExceptionHandler())

    # register response interceptors
    sb.add_global_request_interceptor(LocalizationInterceptor())

    lambda_handler = sb.lambda_handler()
    logger.info("End SkillBuilder to the lambda handler.")
    return lambda_handler

Error is:

2024-04-24T20:54:17.255+02:00
LAMBDA_WARNING: Unhandled exception. The most likely cause is an issue in the function code. However, in rare cases, a Lambda runtime update can cause unexpected function behavior. For functions using managed runtimes, runtime updates can be triggered by a function change, or can be applied automatically. To determine if the runtime has been updated, check the runtime version in the INIT_START log entry. If this error correlates with a change in the runtime version, you may be able to mitigate this error by temporarily rolling back to the previous runtime version. For more information, see https://docs.aws.amazon.com/lambda/latest/dg/runtimes-update.html
[ERROR] Runtime.MarshalError: Unable to marshal response: Object of type function is not JSON serializable
Traceback (most recent call last):

Is this still needed or do I not need an evenHandler function or what does the entry point look like in Docker and what is the response?

EntryPoint is here: https://github.com/MelleD/alexa-actions-tailscale/blob/main/Dockerfile#L39

Since I'm not a expert with AWS Lambda with Alexa Skills, maybe someone can tell me what I did wrong with the handler. I guess I need a different return value.

EDIT:

Also tried to add just a lambda_function.py with directly the SkillBuilder like in the example but then

[ERROR] Runtime.MalformedHandlerName: Bad handler 'lambda_function': not enough values to unpack (expected 2, got 1)
Traceback (most recent call last):

Solution

  • See here the solution

    Put the skill to top level and change the entry point