|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +# |
| 3 | +# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights |
| 4 | +# Reserved. |
| 5 | +# |
| 6 | +# Licensed under the Apache License, Version 2.0 (the "License"). |
| 7 | +# You may not use this file except in compliance with the License. |
| 8 | +# A copy of the License is located at |
| 9 | +# |
| 10 | +# http://aws.amazon.com/apache2.0/ |
| 11 | +# |
| 12 | +# or in the "license" file accompanying this file. This file is |
| 13 | +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS |
| 14 | +# OF ANY KIND, either express or implied. See the License for the |
| 15 | +# specific language governing permissions and limitations under the |
| 16 | +# License. |
| 17 | +# |
| 18 | +import typing |
| 19 | + |
| 20 | +from ask_sdk_model.intent_request import IntentRequest |
| 21 | +from ask_sdk_model.supported_interfaces import SupportedInterfaces |
| 22 | + |
| 23 | +if typing.TYPE_CHECKING: |
| 24 | + from ..handler_input import HandlerInput |
| 25 | + from typing import Optional, AnyStr |
| 26 | + from ask_sdk_model.slot import Slot |
| 27 | + from ask_sdk_model.dialog_state import DialogState |
| 28 | + |
| 29 | + |
| 30 | +def get_locale(handler_input): |
| 31 | + # type: (HandlerInput) -> AnyStr |
| 32 | + """Return locale value from input request. |
| 33 | +
|
| 34 | + The method returns the ``locale`` value present in the request. More |
| 35 | + information about the locale can be found here : |
| 36 | + https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#request-locale |
| 37 | +
|
| 38 | + :param handler_input: The handler input instance that is generally |
| 39 | + passed in the sdk's request and exception components |
| 40 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 41 | + :return: Locale value from the request |
| 42 | + :rtype: str |
| 43 | + """ |
| 44 | + return handler_input.request_envelope.request.locale |
| 45 | + |
| 46 | + |
| 47 | +def get_request_type(handler_input): |
| 48 | + # type: (HandlerInput) -> AnyStr |
| 49 | + """Return the type of the input request. |
| 50 | +
|
| 51 | + The method retrieves the request ``type`` of the input request. More |
| 52 | + information about the different request types are mentioned here : |
| 53 | + https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#request-body-parameters |
| 54 | +
|
| 55 | + :param handler_input: The handler input instance that is generally |
| 56 | + passed in the sdk's request and exception components |
| 57 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 58 | + :return: Type value of the input request |
| 59 | + :rtype: str |
| 60 | + """ |
| 61 | + return handler_input.request_envelope.request.object_type |
| 62 | + |
| 63 | + |
| 64 | +def get_intent_name(handler_input): |
| 65 | + # type: (HandlerInput) -> AnyStr |
| 66 | + """Return the name of the intent request. |
| 67 | +
|
| 68 | + The method retrieves the intent ``name`` from the input request, only if |
| 69 | + the input request is an |
| 70 | + :py:class:`ask_sdk_model.intent_request.IntentRequest`. If the input |
| 71 | + is not an IntentRequest, a :py:class:`TypeError` is raised. |
| 72 | +
|
| 73 | + :param handler_input: The handler input instance that is generally |
| 74 | + passed in the sdk's request and exception components |
| 75 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 76 | + :return: Name of the intent request |
| 77 | + :rtype: str |
| 78 | + :raises: TypeError |
| 79 | + """ |
| 80 | + request = handler_input.request_envelope.request |
| 81 | + if isinstance(request, IntentRequest): |
| 82 | + return request.intent.name |
| 83 | + |
| 84 | + raise TypeError("The provided request is not an IntentRequest") |
| 85 | + |
| 86 | + |
| 87 | +def get_account_linking_access_token(handler_input): |
| 88 | + # type: (HandlerInput) -> Optional[AnyStr] |
| 89 | + """Return the access token in the request. |
| 90 | +
|
| 91 | + The method retrieves the user's ``accessToken`` from the input request. |
| 92 | + Once a user successfully enables a skill and links their Alexa |
| 93 | + account to the skill, the input request will have the user's |
| 94 | + access token. A `None` value is returned if there is no access token |
| 95 | + in the input request. More information on this can be found here : |
| 96 | + https://developer.amazon.com/docs/account-linking/add-account-linking-logic-custom-skill.html |
| 97 | +
|
| 98 | + :param handler_input: The handler input instance that is generally |
| 99 | + passed in the sdk's request and exception components |
| 100 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 101 | + :return: User account linked access token if available. None if not |
| 102 | + available |
| 103 | + :rtype: Optional[str] |
| 104 | + """ |
| 105 | + return handler_input.request_envelope.context.system.user.access_token |
| 106 | + |
| 107 | + |
| 108 | +def get_api_access_token(handler_input): |
| 109 | + # type: (HandlerInput) -> AnyStr |
| 110 | + """Return the api access token in the request. |
| 111 | +
|
| 112 | + The method retrieves the ``apiAccessToken`` from the input request, |
| 113 | + which has the encapsulated information of permissions granted by the |
| 114 | + user. This token can be used to call Alexa-specific APIs. More information |
| 115 | + about this can be found here : |
| 116 | + https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#system-object |
| 117 | +
|
| 118 | + The SDK already includes this token in the API calls done through the |
| 119 | + `service_client_factory` in |
| 120 | + :py:class:`ask_sdk_core.handler_input.HandlerInput`. |
| 121 | +
|
| 122 | + :param handler_input: The handler input instance that is generally |
| 123 | + passed in the sdk's request and exception components |
| 124 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 125 | + :return: Api access token from the input request, which encapsulates any |
| 126 | + permissions consented by the user |
| 127 | + :rtype: str |
| 128 | + """ |
| 129 | + return handler_input.request_envelope.context.system.api_access_token |
| 130 | + |
| 131 | + |
| 132 | +def get_device_id(handler_input): |
| 133 | + # type: (HandlerInput) -> AnyStr |
| 134 | + """Return the device id from the input request. |
| 135 | +
|
| 136 | + The method retrieves the `deviceId` property from the input request. |
| 137 | + This value uniquely identifies the device and is generally used as |
| 138 | + input for some Alexa-specific API calls. More information about this |
| 139 | + can be found here : |
| 140 | + https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#system-object |
| 141 | +
|
| 142 | + :param handler_input: The handler input instance that is generally |
| 143 | + passed in the sdk's request and exception components |
| 144 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 145 | + :return: Unique device id of the device used to send the alexa request |
| 146 | + :rtype: str |
| 147 | + """ |
| 148 | + return handler_input.request_envelope.context.system.device.device_id |
| 149 | + |
| 150 | + |
| 151 | +def get_dialog_state(handler_input): |
| 152 | + # type: (HandlerInput) -> Optional[DialogState] |
| 153 | + """Return the dialog state enum from the intent request. |
| 154 | +
|
| 155 | + The method retrieves the `dialogState` from the intent request, if |
| 156 | + the skill's interaction model includes a dialog model. This can be |
| 157 | + used to determine the current status of user conversation and return |
| 158 | + the appropriate dialog directives if the conversation is not yet complete. |
| 159 | + More information on dialog management can be found here : |
| 160 | + https://developer.amazon.com/docs/custom-skills/define-the-dialog-to-collect-and-confirm-required-information.html |
| 161 | +
|
| 162 | + The method returns a ``None`` if there is no dialog model added or |
| 163 | + if the intent doesn't have dialog management. The method raises a |
| 164 | + :py:class:`TypeError` if the input is not an `IntentRequest`. |
| 165 | +
|
| 166 | + :param handler_input: The handler input instance that is generally |
| 167 | + passed in the sdk's request and exception components. |
| 168 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 169 | + :return: State of the dialog model from the intent request. |
| 170 | + :rtype: Optional[ask_sdk_model.dialog_state.DialogState] |
| 171 | + :raises: TypeError if the input is not an IntentRequest |
| 172 | + """ |
| 173 | + request = handler_input.request_envelope.request |
| 174 | + if isinstance(request, IntentRequest): |
| 175 | + return request.dialog_state |
| 176 | + |
| 177 | + raise TypeError("The provided request is not an IntentRequest") |
| 178 | + |
| 179 | + |
| 180 | +def get_slot(handler_input, slot_name): |
| 181 | + # type: (HandlerInput, AnyStr) -> Optional[Slot] |
| 182 | + """Return the slot information from intent request. |
| 183 | +
|
| 184 | + The method retrieves the slot information |
| 185 | + :py:class:`ask_sdk_model.slot.Slot` from the input intent request |
| 186 | + for the given ``slot_name``. More information on the slots can be |
| 187 | + found here : |
| 188 | + https://developer.amazon.com/docs/custom-skills/request-types-reference.html#slot-object |
| 189 | +
|
| 190 | + If there is no such slot, then a ``None`` |
| 191 | + is returned. If the input request is not an |
| 192 | + :py:class:`ask_sdk_model.intent_request.IntentRequest`, a |
| 193 | + :py:class:`TypeError` is raised. |
| 194 | +
|
| 195 | + :param handler_input: The handler input instance that is generally |
| 196 | + passed in the sdk's request and exception components |
| 197 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 198 | + :param slot_name: Name of the slot that needs to be retrieved |
| 199 | + :type slot_name: str |
| 200 | + :return: Slot information for the provided slot name if it exists, |
| 201 | + or a `None` value |
| 202 | + :rtype: Optional[ask_sdk_model.slot.Slot] |
| 203 | + :raises: TypeError if the input is not an IntentRequest |
| 204 | + """ |
| 205 | + request = handler_input.request_envelope.request |
| 206 | + if isinstance(request, IntentRequest): |
| 207 | + if request.intent.slots is not None: |
| 208 | + return request.intent.slots.get(slot_name, None) |
| 209 | + else: |
| 210 | + return None |
| 211 | + |
| 212 | + raise TypeError("The provided request is not an IntentRequest") |
| 213 | + |
| 214 | + |
| 215 | +def get_slot_value(handler_input, slot_name): |
| 216 | + # type: (HandlerInput, AnyStr) -> AnyStr |
| 217 | + """Return the slot value from intent request. |
| 218 | +
|
| 219 | + The method retrieves the slot value from the input intent request |
| 220 | + for the given ``slot_name``. More information on the slots can be |
| 221 | + found here : |
| 222 | + https://developer.amazon.com/docs/custom-skills/request-types-reference.html#slot-object |
| 223 | +
|
| 224 | + If there is no such slot, then a :py:class:`ValueError` is raised. |
| 225 | + If the input request is not an |
| 226 | + :py:class:`ask_sdk_model.intent_request.IntentRequest`, a |
| 227 | + :py:class:`TypeError` is raised. |
| 228 | +
|
| 229 | + :param handler_input: The handler input instance that is generally |
| 230 | + passed in the sdk's request and exception components |
| 231 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 232 | + :param slot_name: Name of the slot for which the value has to be retrieved |
| 233 | + :type slot_name: str |
| 234 | + :return: Slot value for the provided slot if it exists |
| 235 | + :rtype: str |
| 236 | + :raises: TypeError if the input is not an IntentRequest. ValueError is |
| 237 | + slot doesn't exist |
| 238 | + """ |
| 239 | + slot = get_slot(handler_input=handler_input, slot_name=slot_name) |
| 240 | + |
| 241 | + if slot is not None: |
| 242 | + return slot.value |
| 243 | + |
| 244 | + raise ValueError( |
| 245 | + "Provided slot {} doesn't exist in the input request".format( |
| 246 | + slot_name)) |
| 247 | + |
| 248 | + |
| 249 | +def get_supported_interfaces(handler_input): |
| 250 | + # type: (HandlerInput) -> SupportedInterfaces |
| 251 | + """Retrieves the supported interfaces from input request. |
| 252 | +
|
| 253 | + The method returns an |
| 254 | + :py:class:`ask_sdk_model.supported_interfaces.SupportedInterfaces` |
| 255 | + object instance listing each interface that the device |
| 256 | + supports. For example, if ``supported_interfaces`` includes |
| 257 | + ``audio_player``, then you know that the device supports streaming |
| 258 | + audio using the AudioPlayer interface. More information on |
| 259 | + `supportedInterfaces` can be found here : |
| 260 | + https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#system-object |
| 261 | +
|
| 262 | + :param handler_input: The handler input instance that is generally |
| 263 | + passed in the sdk's request and exception components |
| 264 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 265 | + :return: Instance of |
| 266 | + :py:class:`ask_sdk_model.supported_interfaces.SupportedInterfaces` |
| 267 | + mentioning which all interfaces the device supports |
| 268 | + :rtype: ask_sdk_model.supported_interfaces.SupportedInterfaces |
| 269 | + """ |
| 270 | + return ( |
| 271 | + handler_input.request_envelope.context.system.device. |
| 272 | + supported_interfaces) |
| 273 | + |
| 274 | + |
| 275 | +def is_new_session(handler_input): |
| 276 | + # type: (HandlerInput) -> bool |
| 277 | + """Return if the session is new for the input request. |
| 278 | +
|
| 279 | + The method retrieves the ``new`` value from the input request's |
| 280 | + session, which indicates if it's a new session or not. The |
| 281 | + :py:class:`ask_sdk_model.session.Session` is only included on all |
| 282 | + standard requests except ``AudioPlayer``, ``VideoApp`` and |
| 283 | + ``PlaybackController`` requests. More information can be found here : |
| 284 | + https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#session-object |
| 285 | +
|
| 286 | + A :py:class:`TypeError` is raised if the input request doesn't have |
| 287 | + the ``session`` information. |
| 288 | +
|
| 289 | + :param handler_input: The handler input instance that is generally |
| 290 | + passed in the sdk's request and exception components |
| 291 | + :type handler_input: ask_sdk_core.handler_input.HandlerInput |
| 292 | + :return: Boolean if the session is new for the input request |
| 293 | + :rtype: bool |
| 294 | + :raises: TypeError if the input request doesn't have a session |
| 295 | + """ |
| 296 | + session = handler_input.request_envelope.session |
| 297 | + |
| 298 | + if session is not None: |
| 299 | + return session.new |
| 300 | + |
| 301 | + raise TypeError("The provided request doesn't have a session") |
0 commit comments