Alexa Service Clients


Alexa Skills Kit provides multiple service APIs that you can use to personalize your skill experience. The SDK includes service clients that you can use to call Alexa APIs from within your skill logic.

ServiceClientFactory

The service_client_factory contained inside the Handler Input allows you to retrieve client instances for every supported Alexa service. It takes care of creating individual service clients and configuring the metadata like api_access_token and api_endpoint.

Since it is available in handler_input through service_client_factory attribute, service clients can be used in any request handler, exception handler, and request, response interceptors.

Available service clients

def get_device_address_service(self):
    # type: () -> ask_sdk_model.services.device_address.DeviceAddressServiceClient

def get_directive_service(self):
    # type: () -> ask_sdk_model.services.directive.DirectiveServiceClient

def get_endpoint_enumeration_service(self):
   # type: () -> EndpointEnumerationServiceClient   

def get_list_management_service(self):
    # type: () -> ask_sdk_model.services.list_management.ListManagementServiceClient

def get_monetization_service(self):
    # type: () -> ask_sdk_model.services.monetization.MonetizationServiceClient

def get_ups_service(self):
    # type: () -> ask_sdk_model.services.ups.UpsServiceClient

def get_reminder_management_service(self):
    # type: () -> ask_sdk_model.services.reminder_management.ReminderManagementServiceClient

ApiClient

The ask_sdk_model.services.api_client.ApiClient is used by the service_client_factory when making API calls to Alexa services. You can register any customized ApiClient that conforms to the following interface with the SDK.

Interface

class ask_sdk_model.services.api_client.ApiClient:
    def invoke(self, request):
        # type: (ApiClientRequest) -> ApiClientResponse

class ask_sdk_model.services.api_client_request.ApiClientRequest(ApiClientMessage):
    def __init__(self, headers=None, body=None, url=None, method=None):
        # type: (List[Tuple[str, str]], str, str, str) -> None

class ask_sdk_model.services.api_client_request.ApiClientResponse(ApiClientMessage):
    def __init__(self, headers=None, body=None, status_code=None):
        # type: (List[Tuple[str, str]], str, int) -> None

class ask_sdk_model.services.api_client_message.ApiClientMessage(object):
    def __init__(self, headers=None, body=None):
        # type: (List[Tuple[str, str]], str) -> None

The CustomSkillBuilder constructor can be used to register the ApiClient.

from ask_sdk_core.skill_builder import CustomSkillBuilder

sb = CustomSkillBuilder(api_client=<YourClassInstance>)

DefaultApiClient

A DefaultApiClient based on the requests library, is made available in the ask_sdk_core.api_client module for skill developers.

This client is registered by default in the StandardSkillBuilder. Alternatively, skill developers can register this client to the CustomSkillBuilder.

from ask_sdk_core.skill_builder import CustomSkillBuilder
from ask_sdk_core.api_client import DefaultApiClient

sb = CustomSkillBuilder(api_client=DefaultApiClient())

DeviceAddressServiceClient

DeviceAddressServiceClient can be used to query Device Address API for address data associated with the customer's Alexa device. You can then use this address data to provide key functionality for the skill, or to enhance the customer experience. For example, your skill could provide a list of nearby store locations or provide restaurant recommendations using this address information.

Interface

class ask_sdk_model.services.device_address.DeviceAddressServiceClient:
    def get_country_and_postal_code(device_id):
        # type: (str) -> Union[ShortAddress, Error]

    def get_full_address(self, device_id):
        # type: (str) -> Union[Address, Error]

class ask_sdk_model.services.device_address.ShortAddress:
    def __init__(self, country_code=None, postal_code=None):
        # type: (Optional[str], Optional[str]) -> None

class ask_sdk_model.services.device_address.Address:
    def __init__(
        self, address_line1=None, address_line2=None, address_line3=None,
        country_code=None, state_or_region=None, city=None,
        district_or_county=None, postal_code=None):
        # type: (Optional[str], Optional[str], Optional[str], Optional[str], Optional[str], Optional[str], Optional[str], Optional[str]) -> None

More information on the models can be found here.

Code Sample

The following example shows how a request handler retrieves customer's full address.

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import is_intent_name
from ask_sdk_model.response import Response
from ask_sdk_model.ui import AskForPermissionsConsentCard
from ask_sdk_model.services import ServiceException

NOTIFY_MISSING_PERMISSIONS = ("Please enable Location permissions in "
                              "the Amazon Alexa app.")
NO_ADDRESS = ("It looks like you don't have an address set. "
              "You can set your address from the companion app.")
ADDRESS_AVAILABLE = "Here is your full address: {}, {}, {}"
ERROR = "Uh Oh. Looks like something went wrong."
LOCATION_FAILURE = ("There was an error with the Device Address API. "
                    "Please try again.")

permissions = ["read::alexa:device:all:address"]

class GetAddressIntentHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return is_intent_name("GetAddressIntent")(handler_input)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
        req_envelope = handler_input.request_envelope
        service_client_fact = handler_input.service_client_factory
        response_builder = handler_input.response_builder

        if not (req_envelope.context.system.user.permissions and
                req_envelope.context.system.user.permissions.consent_token):
            response_builder.speak(NOTIFY_MISSING_PERMISSIONS)
            response_builder.set_card(
                AskForPermissionsConsentCard(permissions=permissions))
            return response_builder.response

        try:
            device_id = req_envelope.context.system.device.device_id
            device_addr_client = service_client_fact.get_device_address_service()
            addr = device_addr_client.get_full_address(device_id)

            if addr.address_line1 is None and addr.state_or_region is None:
                response_builder.speak(NO_ADDRESS)
            else:
                response_builder.speak(ADDRESS_AVAILABLE.format(
                    addr.address_line1, addr.state_or_region, addr.postal_code))
            return response_builder.response
        except ServiceException:
            response_builder.speak(ERROR)
            return response_builder.response
        except Exception as e:
            raise e

DirectiveServiceClient

DirectiveServiceClient can be used to send directives to Progressive Response API. Progressive responses can be used to keep the user engaged while your skill prepares a full response to the user's request.

Interface

class ask_sdk_model.services.directive.DirectiveServiceClient:
    def enqueue(self, send_directive_request):
        # type: (SendDirectiveRequest) -> Union[Error]

class ask_sdk_model.services.directive.SendDirectiveRequest:
    def __init__(self, header=None, directive=None):
        # type: (Optional[Header], Optional[SpeakDirective]) -> None

class ask_sdk_model.services.directive.SpeakDirective:
    def __init__(self, speech=None):
        # type: (Optional[str]) -> None

More information on the models can be found here.

Code Sample

The following example shows a function that can be used in a handle method for sending a progressive response.

from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model.services.directive import (
    SendDirectiveRequest, Header, SpeakDirective)
import time

def get_progressive_response(handler_input):
    # type: (HandlerInput) -> None
    request_id_holder = handler_input.request_envelope.request.request_id
    directive_header = Header(request_id=request_id_holder)
    speech = SpeakDirective(speech="Ok, give me a minute")
    directive_request = SendDirectiveRequest(
        header=directive_header, directive=speech)

    directive_service_client = handler_input.service_client_factory.get_directive_service()
    directive_service_client.enqueue(directive_request)
    time.sleep(5)
    return

EndpointEnumerationServiceClient

Skills can use EndpointEnumerationServiceClient to retrieve the user's connected endpoints that the skill can interact with.

Interface

def init(self, api_configuration):
   # type: (ApiConfiguration) → None
def get_endpoints(self, kwargs):
    # type: (Any) -> Union[EndpointEnumerationResponse, Error]

Code Sample

The following example shows a function that gets the connected endpoints.

from ask_sdk_core.skill_builder import CustomSkillBuilder
from ask_sdk_core.api_client import DefaultApiClient
....
skill_builder = CustomSkillBuilder(api_client=DefaultApiClient())
....
def get_connected_endpoints(handler_input: HandlerInput):
    return handler_input.service_client_factory.get_endpoint_enumeration_service().get_endpoints().endpoints

ListManagementServiceClient

ListManagementServiceClient can be used to access the List Management API in order to read or modify both the Alexa default lists and any custom lists customer may have.

Interface

class ask_sdk_model.services.list_management.ListManagementServiceClient:
    def get_lists_metadata(self):
        # type: () -> Union[ForbiddenError, Error, AlexaListsMetadata]

    def get_list(self, list_id, status):
        # type: (str, str) -> Union[AlexaList, Error]

    def get_list_item(self, list_id, item_id):
        # type: (str, str) -> Union[AlexaListItem, Error]

    def create_list(self, create_list_request):
        # type: (CreateListRequest) -> Union[Error, AlexaListMetadata]

    def create_list_item(self, list_id, create_list_item_request):
        # type: (str, CreateListItemRequest) -> Union[AlexaListItem, Error]

    def update_list(self, list_id, update_list_request):
        # type: (str, UpdateListRequest) -> Union[Error, AlexaListMetadata]

    def update_list_item(self, list_id, item_id, update_list_item_request):
        # type: (str, str, UpdateListItemRequest) -> Union[AlexaListItem, Error]

    def delete_list(self, list_id):
        # type: (str) -> Union[Error]

    def delete_list_item(self, list_id, item_id):
        # type: (str, str) -> Union[Error]

More information on the models can be found here.

MonetizationServiceClient

The MonetizationServiceClient invokes the In-Skill Purchase Service API to retrieve information about in-skill products associated with the current skill or information about paid skills. The response indicates if the product or skill is purchasable and/or already purchased by the current customer. For details about in-skill purchases, see Understand In-Skill Purchasing. For details about paid skills, see Understand Paid Skills.

In-Skill Purchase Service

The in-skill product service includes the following methods for in-skill products and paid skills.

Interface

class ask_sdk_model.services.monetization.MonetizationServiceClient:
    def get_in_skill_products(
        self, accept_language, purchasable=None, entitled=None,
        product_type=None, next_token=None, max_results=None):
        # type: (str, Optional[PurchasableState], Optional[EntitledState], Optional[ProductType], Optional[str], Optional[float]) -> Union[Error, InSkillProductsResponse]

    def get_in_skill_product(self, accept_language, product_id):
        # type: (str, str) -> Union[Error, InSkillProduct]

    def get_in_skill_products_transactions(
        self, accept_language, product_id=None, status=None,
        from_last_modified_time=None, to_last_modified_time=None,
        next_token=None, max_results=None):
        # type: (str, Optional[str], Optional[Status], Optional[datetime], Optional[datetime], Optional[str], Optional[float]) -> Union[Error, InSkillProductTransactionsResponse]
 
    def get_voice_purchase_setting(self):
        # type: () -> Union[Error, bool] 

class ask_sdk_model.services.monetization.InSkillProductsResponse:
    def __init__(self, in_skill_products=None, is_truncated=None, next_token=None):
        # type: (Optional[List[InSkillProduct]], Optional[bool], Optional[str]) -> None

class ask_sdk_model.services.monetization.InSkillProduct:
self, product_id=None, reference_name=None, name=None, object_type=None, summary=None, purchasable=None, entitled=None, active_entitlement_count=None, purchase_mode=None
    def __init__(
        self, product_id=None, reference_name=None, name=None,
        object_type=None, summary=None, purchasable=None, entitled=None,
        active_entitlement_count=None, purchase_mode=None):
        # type: (Optional[str], Optional[str], Optional[str], Optional[ProductType], Optional[str], Optional[PurchasableState], Optional[EntitledState], Optional[int], Optional[PurchaseMode]) -> None

class ask_sdk_model.services.monetization.ProductType(Enum):
    SUBSCRIPTION = "SUBSCRIPTION"
    ENTITLEMENT = "ENTITLEMENT"
    CONSUMABLE = "CONSUMABLE"

class ask_sdk_model.services.monetization.PurchasableState(Enum):
    PURCHASABLE = "PURCHASABLE"
    NOT_PURCHASABLE = "NOT_PURCHASABLE"

class ask_sdk_model.services.monetization.EntitledState(Enum):
    ENTITLED = "ENTITLED"
    NOT_ENTITLED = "NOT_ENTITLED"

class ask_sdk_model.services.monetization.PurchaseMode(Enum):
    TEST = "TEST"
    LIVE = "LIVE"

For more details about the models, see ASK Python Monetization.

get_in_skill_products

The get_in_skill_products method retrieves all associated in-skill products for the current skill along with purchasability and entitlement indications for each in-skill product for the current skill and customer.

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import is_request_type
from ask_sdk_model.response import Response
from ask_sdk_model.services.monetization import (
    EntitledState, PurchasableState, InSkillProductsResponse)

class LaunchRequestHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        return is_request_type("LaunchRequest")(handler_input)

    def handle(self, handler_input):
        locale = handler_input.request_envelope.request.locale
        ms = handler_input.service_client_factory.get_monetization_service()
        product_response = ms.get_in_skill_products(locale)

        if isinstance(product_response, InSkillProductsResponse):
            total_products = len(product_response.in_skill_products)
            entitled_products = len([l for l in product_response.in_skill_products
                                 if l.entitled == EntitledState.ENTITLED])
            purchasable_products = len([l for l in product_response.in_skill_products
                                    if l.purchasable == PurchasableState.PURCHASABLE])

            speech = (
                "Found total {} products of which {} are purchasable and {} "
                "are entitled".format(
                    total_products, purchasable_products, entitled_products))
        else:
            speech = "Something went wrong in loading your purchase history."

        return handler_input.response_builder.speak(speech).response

The API response contains an array of in-skill product records.

get_in_skill_product

The get_in_skill_product API retrieves the product record for a single in-skill product or a single paid skill identified by a given productId. For a paid skill, set productId to the skill ID.

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import is_request_type
from ask_sdk_model.response import Response
from ask_sdk_model.services.monetization import InSkillProduct

class LaunchRequestHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        return is_request_type("LaunchRequest")(handler_input)

    def handle(self, handler_input):
        locale = handler_input.request_envelope.request.locale
        ms = handler_input.service_client_factory.get_monetization_service()
        product_id = "amzn1.adg.product.<GUID>"
        product_response = ms.get_in_skill_product(locale)

        if isinstance(product_response, InSkillProduct):
            # code to handle InSkillProduct goes here
            speech = ""
            pass
        else:
            speech = "Something went wrong in loading your product."

        return handler_input.response_builder.speak(speech).response

The API response contains a single in-skill product record or paid skill record.

For more details, see Add In-Skill Purchases to a Custom Skill and Steps to Implement Paid Skills.

get_in_skill_products_transactions

The get_in_skill_products_transactions method provides information about in-skill product transactions, such as if a previous purchase request was denied. You can query transactions by transaction status or date. This API only returns recent results for transactions in kid skills.

    from ask_sdk_core.dispatch_components import AbstractRequestHandler
    from ask_sdk_core.handler_input import HandlerInput
    from ask_sdk_core.utils import is_request_type
    from ask_sdk_model.response import Response
    from ask_sdk_model.services.monetization import (Status, InSkillProductTransactionsResponse)
 
    class LaunchRequestHandler(AbstractRequestHandler):
        def can_handle(self, handler_input):
            return is_request_type("LaunchRequest")(handler_input)
 
        def handle(self, handler_input):
            locale = handler_input.request_envelope.request.locale
            ms = handler_input.service_client_factory.get_monetization_service()
            transaction_response = ms.get_in_skill_products_transactions(locale)
 
            if isinstance(transaction_response, InSkillProductTransactionsResponse):
                total_transaction = len(transaction_response.results)
                pending_transactions = len([l for l in transaction_response.results
                                           if l.status == Status.PENDING_APPROVAL_BY_PARENT])
                approved_transactions = len([l for l in transaction_response.results
                                            if l.status == Status.APPROVED_BY_PARENT])
                denied_transactions = len([l for l in transaction_response.results
                                          if l.status == Status.DENIED_BY_PARENT])
 
                speech = (
                    "Found total {} transaction of which {} are pending, {} "
                    "are approved and {} are denied".format(
                        total_transaction, pending_transactions, approved_transactions, denied_transactions))
            else:
                speech = "Something went wrong in loading your transaction history."
 
            return handler_input.response_builder.speak(speech).response
 

A successful response contains a list of transactions sorted by lastModifiedTime. The latest transaction is at index 0. By default, the list truncates to 50 transactions.

    {
        "results": [
            {
                "status": "PENDING_APPROVAL_BY_PARENT",
                "productId": "amzn1.adg.product.unique-id-4",
                "createdTime": "2018-11-23T12:23:10.52Z",
                "lastModifiedTime": "2018-11-23T12:23:10.52Z"
            },
            {
                "status": "PENDING_APPROVAL_BY_PARENT",
                "productId": "amzn1.adg.product.unique-id-3",
                "createdTime": "2018-11-23T11:21:10.52Z",
                "lastModifiedTime": "2018-11-23T11:21:10.52Z"
            },
            {
                "status": "EXPIRED_NO_ACTION_BY_PARENT",
                "productId": "amzn1.adg.product.unique-id-3",
                "createdTime": "2018-11-20T12:23:10.52Z",
                "lastModifiedTime": "2018-11-21T12:23:10.52Z"
            },
            {
                "status": "DENIED_BY_PARENT",
                "productId": "amzn1.adg.product.unique-id-2",
                "createdTime": "2018-11-15T11:03:07.52Z",
                "lastModifiedTime": "2018-11-15T11:03:08.52Z"
            },
            {
                "status": "APPROVED_BY_PARENT",
                "productId": "amzn1.adg.product.unique-id-1",
                "createdTime": "2018-11-14T22:21:00.52Z",
                "lastModifiedTime": "2018-11-14T22:22:00.52Z"
            }
        ],
        "metadata": {
            "resultSet": {
                "nextToken": "EXAMPLE123456789ABCDEFGHI"
            }
        }
    }

For more information about this API, see Build Premium Experiences for Kid Skills in the US.

get_voice_purchase_setting

The get_voice_purchase_setting method gets the purchase control setting that the account holder chose in the Alexa app.

    from ask_sdk_core.dispatch_components import AbstractRequestHandler
    from ask_sdk_core.handler_input import HandlerInput
    from ask_sdk_core.utils import is_request_type
    from ask_sdk_model.response import Response
 
    class LaunchRequestHandler(AbstractRequestHandler):
        def can_handle(self, handler_input):
            return is_request_type("LaunchRequest")(handler_input)
 
        def handle(self, handler_input):
            ms = handler_input.service_client_factory.get_monetization_service()
            purchase_preference_response = ms.get_voice_purchase_setting()
 
            if isinstance(purchase_preference_response, bool):
                speech = "Customer's purchase preference value is {}".format(purchase_preference_response)
            else:
                speech = "Something went wrong in loading customer's purchase preference settings."
 
            return handler_input.response_builder.speak(speech).response

The API response contains a Boolean value. The value is true if the account holder has enabled voice purchasing in the Alexa app.

For more information about this API, see Build Premium Experiences for Kid Skills in the US.

In-Skill Purchase Interface

The add_directive() method initiates purchase and cancellation flows for in-skill purchases and paid skills. Alexa manages the voice interaction with customers, handles the purchase transaction, and returns a status response to the requesting skill. The add_directive() method supports the following actions:

  • Upsell
  • Buy
  • Cancel

For details about these actions and recommended use cases, see Add In-Skill Purchases to a Custom Skill and Steps to Implement Paid Skills.

Upsell

Your skill can invoke the Upsell action to present an in-skill product contextually when the user didn't explicitly ask for it, such as, during or after your skill serves free content. The Upsell action requires a productId and upsell message. The upsell message allows developers to specify how Alexa can present the in-skill product to the user before beginning the purchase offer.

from ask_sdk_model.interfaces.connections import SendRequestDirective

# In the skill flow, once a decision is made to offer an in-skill product to a
# customer without an explicit ask from the customer


return handler_input.response_builder.add_directive(
        SendRequestDirective(
            name="Upsell",
            payload={
                "InSkillProduct": {
                    "productId": "<product_id>",
                },
                "upsellMessage": "<introductory upsell description for the in-skill product>",
            },
            token="correlationToken")
    ).response

Buy

Your skill should invoke the Buy action when a customer asks to buy a specific product or paid skill. This action requires a productId for in-skill purchases. For a paid skill, set productId to the skill ID.

The following example shows a Buy action for an in-skill purchase.

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import is_intent_name
from ask_sdk_model.response import Response
from ask_sdk_model.interfaces.connections import SendRequestDirective

# Skills would implement a custom intent (BuyProductIntent below) that captures
# user's intent to buy an in-skill product and then trigger the Buy request for it.
# For e.g. 'Alexa, buy <product name>'

class BuyProductIntentHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return is_intent_name("BuyProductIntent")(handler_input)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response

        # Obtain the corresponding product_id for the requested in-skill
        # product by invoking InSkillProducts API.
        # The slot variable product_name used below is only for demonstration.

        locale = handler_input.request_envelope.request.locale
        ms = handler_input.service_client_factory.get_monetization_service()

        product_response = ms.get_in_skill_products(locale)
        slots = handler_input.request_envelope.request.intent.slots
        product_ref_name = slots.get("product_name").value
        product_record = [l for l in product_response.in_skill_products
                          if l.reference_name == product_ref_name]

        if product_record:
            return handler_input.response_builder.add_directive(
                SendRequestDirective(
                    name="Buy",
                    payload={
                        "InSkillProduct": {
                            "productId": product_record[0].product_id
                        }
                    },
                    token="correlationToken")
            ).response
        else:
            return handler_input.response_builder.speak(
                "I am sorry. That product is not available for purchase"
                ).response

Cancel

Your skill should invoke the Cancel action when a customer asks to cancel an existing entitlement or subscription for an in-skill product or paid skill. This action requires a productId for in-skill purchases. For a paid skill, set productId to the skill ID.

The following example shows a Cancel action for an in-skill purchase.

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import is_intent_name
from ask_sdk_model.response import Response
from ask_sdk_model.interfaces.connections import SendRequestDirective

# Skills would implement a custom intent (CancelProductIntent below) that captures
# user's intent to cancel an in-skill product and then trigger the Cancel request for it.
# For e.g. 'Alexa, cancel <product name>'

class CancelProductIntentHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return is_intent_name("CancelProductIntent")(handler_input)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response

        # Obtain the corresponding product_id for the requested in-skill
        # product by invoking InSkillProducts API.
        # The slot variable product_name used below is only for demonstration.

        locale = handler_input.request_envelope.request.locale
        ms = handler_input.service_client_factory.get_monetization_service()

        product_response = ms.get_in_skill_products(locale)
        slots = handler_input.request_envelope.request.intent.slots
        product_ref_name = slots.get("product_name").value
        product_record = [l for l in product_response.in_skill_products
                          if l.reference_name == product_ref_name]

        if product_record:
            return handler_input.response_builder.add_directive(
                SendRequestDirective(
                    name="Cancel",
                    payload={
                        "InSkillProduct": {
                            "productId": product_record[0].product_id
                        }
                    },
                    token="correlationToken")
            ).response
        else:
            return handler_input.response_builder.speak(
                "I am sorry. I don't know that one").response

UpsServiceClient

UpsServiceClient can be used to query Alexa Customer Profile API for customer contact information and Alexa Customer Settings API for retrieving customer preferences for the time zone, distance measuring unit and temperature measurement unit.

Interface

class ask_sdk_model.services.ups.UpsServiceClient:
    def get_profile_email(self):
        # type: () -> Union[str, Error]

    def get_profile_given_name(self):
        # type: () -> Union[str, Error]

    def get_profile_mobile_number(self):
        # type: () -> Union[PhoneNumber, Error]

    def get_profile_name(self):
        # type: () -> Union[str, Error]

    def get_system_distance_units(self, device_id):
        # type: (str) -> Union[Error, DistanceUnits]

    def get_system_temperature_unit(self, device_id):
        # type: (str) -> Union[TemperatureUnit, Error]

    def get_system_time_zone(self, device_id):
        # type: (str) -> Union[str, Error]

class ask_sdk_model.services.ups.PhoneNumber:
    def __init__(self, country_code=None, phone_number=None):
        # type: (Optional[str], Optional[str]) -> None

class ask_sdk_model.services.DistanceUnits(Enum):
    METRIC = "METRIC"
    IMPERIAL = "IMPERIAL"

class ask_sdk_model.services.TemparatureUnit(Enum):
    CELSIUS = "CELSIUS"
    FAHRENHEIT = "FAHRENHEIT"

Code Sample

Alexa Customer Settings API

The Alexa Customer Settings API provides access to three pieces of information: preferred distance units, preferred temperature units and the device's current configured time zone. When using the UpsServiceClient, get_system_distance_units and get_system_temperature_unit will return enum objects whose values must be accessed by using the .value attribute. By comparison, get_system_time_zone will simply return a string.

device_id = req_envelope.context.system.device.device_id
user_preferences_client = handler_input.service_client_factory.get_ups_service()

# Fetch Preferred Distance Units From Alexa Settings API
preferred_distance_units = user_preferences_client.get_system_distance_units(device_id).value
print (preferred_distance_units) # String of either "IMPERIAL" or "METRIC"

# Fetch Preferred Temperature Units From Alexa Settings API
preferred_temperature_units = user_preferences_client.get_system_temperature_unit(device_id).value
print (preferred_temperature_units) # String of either "FAHRENHEIT" or "CELSIUS"

# Fetch Device's Current Configured Time Zone From Alexa Settings API
time_zone = user_preferences_client.get_system_time_zone(device_id)
print (time_zone) # String representing a time zone for example "America/Los_Angeles"

More information on the models can be found here.

ReminderManagementServiceClient

ReminderManagementServiceClient can be used to create and manage Reminders for your customers.

Interface

class ask_sdk_model.services.reminder_management.ReminderManagementServiceClient:
    def create_reminder(self, reminder_request):
        # type: (ReminderRequest) -> Union[ReminderResponse, Error]

    def update_reminder(self, alert_token, reminder_request):
        # type: (str, ReminderRequest) -> Union[ReminderResponse, Error]

    def delete_reminder(self, alert_token):
        # type: (str) -> Union[Error]

    def get_reminder(self, alert_token):
        # type: (str) -> Union[GetReminderResponse, Error]

    def get_reminders(self):
        # type: () -> Union[GetRemindersResponse, Error]

Code Sample

The following example shows a request handler that creates an instance of the ReminderManagementServiceClient and creates a new reminder.

import logging
import typing

from datetime import datetime
from ask_sdk_core.skill_builder import CustomSkillBuilder
from ask_sdk_model.ui import SimpleCard
from ask_sdk_core.utils import is_intent_name
from ask_sdk_core.api_client import DefaultApiClient
from ask_sdk_model.services.reminder_management import (
    ReminderRequest, Trigger, TriggerType, AlertInfo, PushNotification,
    PushNotificationStatus, ReminderResponse, SpokenInfo, SpokenText)
from ask_sdk_model.services import ServiceException
from ask_sdk_model.ui import AskForPermissionsConsentCard

if typing.TYPE_CHECKING:
    from ask_sdk_core.handler_input import HandlerInput
    from ask_sdk_model import Response

permissions = ["alexa::alerts:reminders:skill:readwrite"]
NOTIFY_MISSING_PERMISSIONS = ("Please enable Reminders permissions in "
                              "the Amazon Alexa app.")


sb = CustomSkillBuilder(api_client=DefaultApiClient())
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)


@sb.request_handler(can_handle_func=is_intent_name("CreateReminder"))
def create_reminder_intent_handler(handler_input):
    # type: (HandlerInput) -> Response
    req_envelope = handler_input.request_envelope
    response_builder = handler_input.response_builder

    # Check if user gave permissions to create reminders.
    # If not, request to provide permissions to the skill.
    if not (req_envelope.context.system.user.permissions and
            req_envelope.context.system.user.permissions.consent_token):
        response_builder.speak(NOTIFY_MISSING_PERMISSIONS)
        response_builder.set_card(
            AskForPermissionsConsentCard(permissions=permissions))
        return response_builder.response

    reminder_client = handler_input.service_client_factory.get_reminder_management_service()

    try:
        reminder_response = reminder_client.create_reminder(
            reminder_request=ReminderRequest(
                request_time=datetime.utcnow(),
                trigger=Trigger(
                    object_type=TriggerType.SCHEDULED_RELATIVE,
                    offset_in_seconds=60),
                alert_info=AlertInfo(
                    spoken_info=SpokenInfo(
                        content=[SpokenText(locale="en-US", text="Test reminder")])),
                push_notification=PushNotification(
                    status=PushNotificationStatus.ENABLED))) # type: ReminderResponse
        speech_text = "Great! I've scheduled a reminder for you."

        logger.info("Created reminder : {}".format(reminder_response))
        return handler_input.response_builder.speak(speech_text).set_card(
            SimpleCard(
                "Reminder created with id", reminder_response.alert_token)).response

    except ServiceException as e:
        logger.info("Exception encountered : {}".format(e.body))
        speech_text = "Uh Oh. Looks like something went wrong."
        return handler_input.response_builder.speak(speech_text).set_card(
            SimpleCard(
                "Reminder not created",str(e.body))).response

More information on the models can be found here.


Was this page helpful?

Last updated: Nov 28, 2023