I have to correct myself here. It’s possible to use the nabucasa url with the SSML audio tag.
So this will work:
<audio src='https://abcdefghijklmnupkxyz.ui.nabu.casa/local/audio/somefile.mp3'/>
And even more i was able to play this mp3 on my Echo with the new Triggering a Skill > https://github.com/custom-components/alexa_media_player/wiki#triggering-a-skill-versions--270 function for Alexa Media Player and an additional Alexa Custom Skill.
I created a new Custom and Alexa-Hosted (Phython) Skill and choose Fact Skill as a template for that.
The only thing i changed in that Skill was the lambda_function.py file. You find my code at the End.
I have no Idea what i am doing in Phython, so this was more a try and error process to change the sample code to the desired outcome.
I did some editing on the LaunchRequest Handler, here you put the URL:
# INSERT YOUR URL
# This is what Alexa says when the Skill is launched. For this purpose i only insert the SSML audio tag
# with the Link to the mp3 file but you can also put some text before or after
speech = "<audio src='https://abcdefghijklmnupkxyz.ui.nabu.casa/local/audio/somefile.mp3'/>"
If you have an Echo Show you can edit and display Text here:
handler_input.response_builder.speak(speech).set_card(
# INSERT YOUR TEXT
# This may be shown on an Echo Show, change "My Title" and "File is now played" to whatever you whant
SimpleCard(title="My Title", content="File is now played"))
You should now be able to invoke the Skill in an Automation:
(You can find the Skill ID here https://developer.amazon.com/alexa/console/ask under your Skill Name
View Skill ID)
action:
- service: media_player.play_media
data:
entity_id: <Your Echo Device>
media_content_id: <Skill ID>
media_content_type: skill
A good way to get familiar with creating a Custom Skill for this is to set up Alexa Actions from @keatontaylor https://github.com/keatontaylor/alexa-actions
Here is my Code in the lambda_function.py file:
# -*- coding: utf-8 -*-
"""Play Audio File on Skill Launch based on Simple fact sample app."""
import random
import logging
import json
import prompts
from ask_sdk_core.skill_builder import SkillBuilder
from ask_sdk_core.dispatch_components import (
AbstractRequestHandler, AbstractExceptionHandler,
AbstractRequestInterceptor, AbstractResponseInterceptor)
from ask_sdk_core.utils import is_request_type, is_intent_name
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model.ui import SimpleCard
from ask_sdk_model import Response
sb = SkillBuilder()
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# Built-in Intent Handlers
class PlayFileHandler(AbstractRequestHandler):
"""Handler for Skill Launch and GetNewFact Intent."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return (is_request_type("LaunchRequest")(handler_input))
def handle(self, handler_input):
# type: (HandlerInput) -> Response
logger.info("In PlayFileHandler")
# INSERT YOUR URL
# This is what Alexa says when the Skill is launched. For this purpose i only insert the SSML audio tag
# with the Link to the mp3 file but you can also put some text before or after
speech = "<audio src='https://abcdefghijklmnupkxyz.ui.nabu.casa/local/audio/somefile.mp3'/>"
handler_input.response_builder.speak(speech).set_card(
# INSERT YOUR TEXT
# This may be shown on an Echo Show, change "My Title" and "File is now played" to whatever you whant
SimpleCard(title="My Title", content="File is now played"))
return handler_input.response_builder.response
class HelpIntentHandler(AbstractRequestHandler):
"""Handler for Help Intent."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_intent_name("AMAZON.HelpIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
logger.info("In HelpIntentHandler")
# get localization data
data = handler_input.attributes_manager.request_attributes["_"]
speech = data[prompts.HELP_MESSAGE]
reprompt = data[prompts.HELP_REPROMPT]
handler_input.response_builder.speak(speech).ask(
reprompt).set_card(SimpleCard(
data[prompts.SKILL_NAME], speech))
return handler_input.response_builder.response
class CancelOrStopIntentHandler(AbstractRequestHandler):
"""Single handler for Cancel and Stop Intent."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return (is_intent_name("AMAZON.CancelIntent")(handler_input) or
is_intent_name("AMAZON.StopIntent")(handler_input))
def handle(self, handler_input):
# type: (HandlerInput) -> Response
logger.info("In CancelOrStopIntentHandler")
# get localization data
data = handler_input.attributes_manager.request_attributes["_"]
speech = data[prompts.STOP_MESSAGE]
handler_input.response_builder.speak(speech)
return handler_input.response_builder.response
class FallbackIntentHandler(AbstractRequestHandler):
"""Handler for Fallback Intent.
AMAZON.FallbackIntent is only available in en-US locale.
This handler will not be triggered except in that locale,
so it is safe to deploy on any locale.
"""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_intent_name("AMAZON.FallbackIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
logger.info("In FallbackIntentHandler")
# get localization data
data = handler_input.attributes_manager.request_attributes["_"]
speech = data[prompts.FALLBACK_MESSAGE]
reprompt = data[prompts.FALLBACK_REPROMPT]
handler_input.response_builder.speak(speech).ask(
reprompt)
return handler_input.response_builder.response
class LocalizationInterceptor(AbstractRequestInterceptor):
"""
Add function to request attributes, that can load locale specific data.
"""
def process(self, handler_input):
locale = handler_input.request_envelope.request.locale
logger.info("Locale is {}".format(locale))
# localized strings stored in language_strings.json
with open("language_strings.json") as language_prompts:
language_data = json.load(language_prompts)
# set default translation data to broader translation
if locale[:2] in language_data:
data = language_data[locale[:2]]
# if a more specialized translation exists, then select it instead
# example: "fr-CA" will pick "fr" translations first, but if "fr-CA" translation exists,
# then pick that instead
if locale in language_data:
data.update(language_data[locale])
else:
data = language_data[locale]
handler_input.attributes_manager.request_attributes["_"] = data
class SessionEndedRequestHandler(AbstractRequestHandler):
"""Handler for Session End."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_request_type("SessionEndedRequest")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
logger.info("In SessionEndedRequestHandler")
logger.info("Session ended reason: {}".format(
handler_input.request_envelope.request.reason))
return handler_input.response_builder.response
# Exception Handler
class CatchAllExceptionHandler(AbstractExceptionHandler):
"""Catch all exception handler, log exception and
respond with custom message.
"""
def can_handle(self, handler_input, exception):
# type: (HandlerInput, Exception) -> bool
return True
def handle(self, handler_input, exception):
# type: (HandlerInput, Exception) -> Response
logger.info("In CatchAllExceptionHandler")
logger.error(exception, exc_info=True)
handler_input.response_builder.speak(EXCEPTION_MESSAGE).ask(
HELP_REPROMPT)
return handler_input.response_builder.response
# Request and Response loggers
class RequestLogger(AbstractRequestInterceptor):
"""Log the alexa requests."""
def process(self, handler_input):
# type: (HandlerInput) -> None
logger.debug("Alexa Request: {}".format(
handler_input.request_envelope.request))
class ResponseLogger(AbstractResponseInterceptor):
"""Log the alexa responses."""
def process(self, handler_input, response):
# type: (HandlerInput, Response) -> None
logger.debug("Alexa Response: {}".format(response))
# Register intent handlers
sb.add_request_handler(PlayFileHandler())
sb.add_request_handler(HelpIntentHandler())
sb.add_request_handler(CancelOrStopIntentHandler())
sb.add_request_handler(FallbackIntentHandler())
sb.add_request_handler(SessionEndedRequestHandler())
# Register exception handlers
sb.add_exception_handler(CatchAllExceptionHandler())
# Register request and response interceptors
sb.add_global_request_interceptor(LocalizationInterceptor())
sb.add_global_request_interceptor(RequestLogger())
sb.add_global_response_interceptor(ResponseLogger())
# Handler name that is used on AWS lambda
lambda_handler = sb.lambda_handler()