Alexa Skills Kit SDK for Python¶
ASK SDK for Pythonを使うと、ボイラープレートコード(毎回書かなければならないお決まりのコード)を書く手間が不要になります。これにより空いた時間をさまざまな機能の実装に充てることができ、人気のスキルをより簡単に作成できるようになります。
SDKの使用に役立つ以下のガイドをご用意しました。今後もドキュメントやサンプルを増やしていく予定です。
ガイド¶
ASK SDKのセットアップ¶
はじめに¶
このガイドでは、Alexaスキルを開発する準備としてASK SDK for Pythonをインストールする方法を説明します。
前提条件¶
ASK SDK for PythonにはPython 2(2.7以上)またはPython 3(3.6以上)が必要です。続行する前に、サポートされているバージョンのPythonがインストールされていることを確認してください。バージョンを表示するには、コマンドプロンプトから以下のコマンドを実行します。
$ python --version
Python 3.6.5
Pythonの最新バージョンはここからダウンロードできます。
ASK SDK for Pythonをプロジェクトに追加する¶
ASK SDK for Pythonは、Python Package Index(PyPI)からコマンドラインツールpipを使用してダウンロードおよびインストールできます。Python 2バージョン2.7.9以降またはPython 3バージョン3.4以降を使用している場合、pipはPythonとともにデフォルトでインストールされています。
多くのPython開発者は仮想環境で作業をおこないます。隔離されたPython環境として使用でき、プロジェクトの依存関係やパッケージのバージョンの管理に便利であるためです。SDKを仮想環境にインストールするのが、最も簡単な開始方法です。SDKを仮想環境にセットアップするセクションを参照してください。
もうひとつの選択肢は、ASK SDK for Pythonを特定のフォルダーにインストールすることです。こうすることで、必要な依存関係を確実にインストールでき、完成したスキルに必要なファイルを簡単に見つけてデプロイできます。SDKを特定のフォルダーにセットアップするセクションを参照してください。
オプション1: SDKを仮想環境にセットアップする¶
以下のコマンドを使用して仮想環境を作成し、作成したフォルダーに移動します。
$ virtualenv skill
次に、仮想環境をアクティブ化します。MacOSまたはLinuxを使用している場合は、以下のコマンドを使用します。
$ source skill/bin/activate
Windowsユーザーの場合は、以下のコマンドを使用します。
$ skill\Scripts\activate
コマンドプロンプトのプレフィックスが、仮想環境内部で作業していることを示す(skill)になります。以下のコマンドを使用してASK SDK for Pythonをインストールします。
$ pip install ask-sdk
MacOSおよびLinuxでは、使用するPythonのバージョンによって、SDKがskill/lib/Python3.6/site-packagesフォルダーにインストールされます。Windowsでは、skillLibsite-packagesにインストールされます。site-packagesフォルダー内には次のようなディレクトリがあります。
ask_sdk
ask_sdk_core
ask_sdk_dynamodb
ask_sdk_model
boto3
…
オプション2: SDKを特定のフォルダーにセットアップする¶
最初に、コマンドプロンプトからAlexaスキル用の新規フォルダーを作成して、そのフォルダーに移動します。
$ mkdir skill
$ cd skill
次に、pipを使用してASK SDK for Pythonをインストールします。-tというオプションは、特定のフォルダーをインストールのターゲットにします。
$ pip install ask-sdk -t ask-sdk
このコマンドはスキルフォルダー内にask-sdkというフォルダーを作成してASK SDK for Pythonとその依存関係をインストールします。これで、スキルディレクトリにはフォルダーask-sdkが含まれ、その中には次のディレクトリが含まれているはずです。
ask_sdk
ask_sdk_core
ask_sdk_dynamodb
ask_sdk_model
boto3
…
注釈
Mac OS Xを使用しておりHomebrewを使用してPythonをインストールしている場合は、上記のコマンドは機能しません。次の内容のsetup.cfgファイルをask-sdkディレクトリに追加することで、この問題を簡単に回避できます。
[install]
prefix=
ask-sdkフォルダーに移動して、pip installコマンドを実行します。
$ cd ask-sdk
$ pip install ask-sdk -t .
詳細についてはhomebrewドキュメントで確認してください。
初めてのスキル開発¶
セットアップガイドでは、ASK SDK for Pythonを特定のディレクトリまたはvirtualenvを使用して仮想環境にインストールする方法を説明しました。このガイドでは、ASK SDK for Pythonを使ったスキル開発の手順を説明します。
前提条件¶
ASK SDK for Pythonのインストールに加えて、以下のものが必要です。
- Amazon開発者アカウント。Alexaスキルの作成と設定に必要です。
- アマゾンウェブサービス(AWS)アカウント。AWS Lambdaでスキルをホスティングするために必要です。
Hello Worldの作成¶
hello_world.pyというPythonファイルにHello Worldを作成します。先ほど作成したskillフォルダに、お好みのテキストエディターやIDEを使用してhello_world.pyという名前のファイルを作成してください。
Hello Worldの実装¶
リクエストハンドラー¶
Alexaサービスによって送信されたイベントに応答するには、カスタムスキルが必要です。たとえば、Alexaデバイス(Echo、Echo Dot、Echo Showなど)に「ハローワールドを開いて」と頼む場合、スキルがHello Worldスキルに送信されたLaunchRequestに応答する必要があります。ASK SDK for Pythonを使用すれば、リクエストハンドラーを作成するだけで済みます。リクエストハンドラーは受け取ったリクエストを処理して応答を返すコードです。このコードは受け取ったリクエストを正しいリクエストハンドラーを使用して処理し、応答を返します。ASK SDK for Pythonでは、次のいずれかの方法でリクエストハンドラーを作成することができます。
- ask_sdk_core.dispatch_componentsパッケージの下にAbstractRequestHandlerクラスを実装します。このクラスにはcan_handleおよびhandleメソッドの実装が含まれている必要があります。詳細についてはクラスを使用した実装セクションで説明しています。
- インスタンス化されたスキルビルダーオブジェクトのrequest_handlerデコレーターを使用して、異なる受信リクエストのハンドラーとして動作するように関数をタグ付けします。詳細についてはデコレーターを使用した実装セクションで説明しています。
Hello Worldスキルの実装を通じて、まずハンドラークラスの使用方法、次に同じスキルをデコレーターを使用して作成する方法を説明します。機能は同じです。どちらを使用してもかまいません。
例外ハンドラー¶
うまくいかないことが起こったときに、スキルコードで問題を正常に処理する方法が必要です。ASK SDK for Pythonは、リクエストの処理と似た方法で例外処理をサポートします。クラスまたはデコレーターを選んで使用できます。以下の実装セクションで、例外処理の実装方法を説明します。
ちなみに
スキルの記述には、クラスを使用した実装とデコレーターを使用した実装のどちらのオプションを使用してもかまいません。
警告
コード構造を良好に保つために、いずれかのオプションを選択し、スキル全体で常に使用することを強くお勧めします。
オプション1: ハンドラークラスを使用した実装¶
最初にスキルビルダーオブジェクトを作成します。スキルビルダーオブジェクトは、スキルで入力されたリクエストの処理とカスタム応答の生成を担当するコンポーネントを追加するのに便利です。
以下のコードを``hello_world.py``ファイルに入力するか貼り付けます。
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
ハンドラークラスを使用するには、``AbstractRequestHandler``クラスの2つのメソッド``can_handle``および``handle``を実装するクラスとして各リクエストハンドラーを作成する必要があります。
``can_handle``メソッドは、リクエストハンドラーがリクエストに対して適切な応答を作成できるかを示すブール値を返します。``can_handle``メソッドは、スキルが前回のリクエストに設定したり、前回のやり取りで保存した、リクエストタイプやそのほかのアトリビュートにアクセスできます。Hello Worldスキルで参照する必要があるのは、各ハンドラーが受け取ったリクエストに応答できるかどうかを判断するリクエスト情報のみです。
LaunchRequestハンドラー¶
以下は、スキルがLaunchRequestを受け取ったときに呼び出されるハンドラーを設定するコードのサンプルです。LaunchRequestイベントは、特定のインテントなしでスキルが呼び出された場合に発生します。
以下のコードを``hello_world.py``ファイルの、前述のコードの後に入力するか貼り付けます。
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.utils import is_request_type, is_intent_name
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model import Response
from ask_sdk_model.ui import SimpleCard
class LaunchRequestHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_request_type("LaunchRequest")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
speech_text = "ようこそ、アレクサスキルキットへ。こんにちは、と言ってみてください。"
handler_input.response_builder.speak(speech_text).set_card(
SimpleCard("ハローワールド", speech_text)).set_should_end_session(
False)
return handler_input.response_builder.response
受け取ったリクエストがLaunchRequestの場合、can_handle関数はTrueを返します。handle関数は、基本的なあいさつの応答を生成して返します。
HelloWorldIntentハンドラー¶
以下は、スキルがHelloWorldIntentという名前のインテントリクエストを受け取った時に呼び出されるハンドラーを設定するコードのサンプルです。以下のコードを``hello_world.py``ファイルの、前述のハンドラーの後に入力するか貼り付けます。
class HelloWorldIntentHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_intent_name("HelloWorldIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
speech_text = "こんにちは"
handler_input.response_builder.speak(speech_text).set_card(
SimpleCard("ハローワールド", speech_text)).set_should_end_session(
True)
return handler_input.response_builder.response
can_handle関数は受け取るリクエストがIntentRequestかどうかを検出し、インテント名がHelloWorldIntentの場合にTrueを返します。handle関数は、基本的な「こんにちは」という応答を生成して返します。
HelpIntentハンドラー¶
以下は、スキルがビルトインインテントAMAZON.HelpIntentを受け取ったときに呼び出されるハンドラーを設定するコードのサンプルです。以下のコードを``hello_world.py``ファイルの、前述のハンドラーの後に入力するか貼り付けます。
class HelpIntentHandler(AbstractRequestHandler):
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
speech_text = "こんにちは。と言ってみてください。"
handler_input.response_builder.speak(speech_text).ask(speech_text).set_card(
SimpleCard("ハローワールド", speech_text))
return handler_input.response_builder.response
先ほどのハンドラー同様、このハンドラーはIntentRequestを想定されるインテント名と照合します。基本的なヘルプ手順が返され、.ask(speech_text)によってユーザーのマイクがオンになりユーザーの応答を待ちます。
CancelAndStopIntentハンドラー¶
CancelAndStopIntentHandlerもビルトインインテントAMAZON.CancelIntentまたはAMAZON.StopIntentによって呼び出されるため、HelpIntentハンドラーに似ています。以下は、1つのハンドラーを使用して両方のインテントに応答する例です。以下のコードを``hello_world.py``ファイルの、前述のハンドラーの後に入力するか貼り付けます。
class CancelAndStopIntentHandler(AbstractRequestHandler):
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
speech_text = "さようなら"
handler_input.response_builder.speak(speech_text).set_card(
SimpleCard("ハローワールド", speech_text))
return handler_input.response_builder.response
両方のインテントに対する応答は同じであるため、1つのハンドラーにすることで重複するコードを減らせます。
SessionEndedRequestハンドラー¶
SessionEndedRequestを受け取った後は音声、カード、ディレクティブを使った応答を返すことはできませんが、クリーンアップロジックを追加するにはSessionEndedRequestHandlerが最適な場所です。以下のコードをhello_world.pyファイルの、前述のハンドラーの後に入力するか貼り付けます。
class SessionEndedRequestHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_request_type("SessionEndedRequest")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
# クリーンアップロジックをここに追加します
return handler_input.response_builder.response
例外ハンドラーの実装¶
以下は、catch all例外ハンドラーをスキルに追加して、すべての例外に対してスキルが意味のあるメッセージを返すようにする例です。以下のコードを``hello_world.py``ファイルの、前述のハンドラーの後に入力するか貼り付けます。
from ask_sdk_core.dispatch_components import AbstractExceptionHandler
class AllExceptionHandler(AbstractExceptionHandler):
def can_handle(self, handler_input, exception):
# type: (HandlerInput, Exception) -> bool
return True
def handle(self, handler_input, exception):
# type: (HandlerInput, Exception) -> Response
# CloudWatch Logsに例外を記録する
print(exception)
speech = "すみません、わかりませんでした。もう一度言ってください。"
handler_input.response_builder.speak(speech).ask(speech)
return handler_input.response_builder.response
Lambdaハンドラーの作成¶
注釈
カスタムスキルの場合、サービスは、AWS Lambdaでホスティングするか、独自のエンドポイントでウェブサービスとしてホスティングできます。
一般的に、AWS Lambdaでスキルコードをホスティングするのが最も簡単です。以下のセクションでは、その方法を説明します。
ただし、他のクラウドホスティングプロバイダーでホスティングする場合は、SDKにいくつか用意されているサポートパッケージ(ask-sdk-webservice-support
、flask-ask-sdk
、django-ask-sdk
)を使用してください。このコンフィギュレーションについて詳しくは、こちらを参照してください。
Lambdaハンドラーは、AWS Lambda関数のエントリポイントとなります。以下は、スキルが受信するすべてのリクエストのルーティングを行うLambdaハンドラー関数のコードサンプルです。Lambdaハンドラー関数は、作成したリクエストハンドラーを使用して設定されたSDKのスキルインスタンスを作成します。以下のコードを``hello_world.py``ファイルの、前述のハンドラーの後に入力するか貼り付けます。
sb.add_request_handler(LaunchRequestHandler())
sb.add_request_handler(HelloWorldIntentHandler())
sb.add_request_handler(HelpIntentHandler())
sb.add_request_handler(CancelAndStopIntentHandler())
sb.add_request_handler(SessionEndedRequestHandler())
sb.add_exception_handler(AllExceptionHandler())
handler = sb.lambda_handler()
オプション2: デコレーターを使用した実装¶
以下は、上記と同じ機能を実装するコードですが、関数デコレーターを使用しています。デコレーターは、上記の各ハンドラークラスに実装された``can_handle``メソッドに代わるものと考えてください。
最初にスキルビルダーオブジェクトを作成します。スキルビルダーオブジェクトは、スキルで入力されたリクエストの処理とカスタム応答の生成を担当するコンポーネントを追加するのに便利です。
以下のコードを``hello_world.py``ファイルに入力するか貼り付けます。
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
LaunchRequestハンドラー¶
以下は、スキルがLaunchRequestを受け取ったときに呼び出されるハンドラーを設定するコードのサンプルです。LaunchRequestイベントは、特定のインテントなしでスキルが呼び出された場合に発生します。
以下のコードを``hello_world.py``ファイルの、前述のコードの後に入力するか貼り付けます。
from ask_sdk_core.utils import is_request_type, is_intent_name
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model import Response
from ask_sdk_model.ui import SimpleCard
@sb.request_handler(can_handle_func=is_request_type("LaunchRequest"))
def launch_request_handler(handler_input):
# type: (HandlerInput) -> Response
speech_text = "ようこそ、アレクサスキルキットへ。こんにちは、と言ってみてください。"
handler_input.response_builder.speak(speech_text).set_card(
SimpleCard("ハローワールド", speech_text)).set_should_end_session(
False)
return handler_input.response_builder.response
クラスパターンのLaunchRequestHandlerの``can_handle``関数と同様に、デコレーターは受け取るリクエストがLaunchRequestの場合にTrueを返します。``handle``関数は、クラスパターンの``handle``関数と同じ方法で基本的なあいさつの応答を生成して返します。
HelloWorldIntentハンドラー¶
以下は、スキルがHelloWorldIntentという名前のインテントリクエストを受け取った時に呼び出されるハンドラーを設定するコードのサンプルです。以下のコードを``hello_world.py``ファイルの、前述のハンドラーの後に入力するか貼り付けます。
@sb.request_handler(can_handle_func=is_intent_name("HelloWorldIntent"))
def hello_world_intent_handler(handler_input):
# type: (HandlerInput) -> Response
speech_text = "こんにちは"
handler_input.response_builder.speak(speech_text).set_card(
SimpleCard("ハローワールド", speech_text)).set_should_end_session(
True)
return handler_input.response_builder.response
HelpIntentハンドラー¶
以下は、スキルがビルトインインテントAMAZON.HelpIntentを受け取ったときに呼び出されるハンドラーを設定するコードのサンプルです。以下のコードをhello_world.pyファイルの、前述のハンドラーの後に入力するか貼り付けます。
@sb.request_handler(can_handle_func=is_intent_name("AMAZON.HelpIntent"))
def help_intent_handler(handler_input):
# type: (HandlerInput) -> Response
speech_text = "こんにちは。と言ってみてください。"
handler_input.response_builder.speak(speech_text).ask(speech_text).set_card(
SimpleCard("ハローワールド", speech_text))
return handler_input.response_builder.response
先ほどのハンドラー同様、このハンドラーはIntentRequestを想定されるインテント名と照合します。基本的なヘルプ手順が返され、``.ask(speech_text)``によってユーザーのマイクがオンになりユーザーの応答を待ちます。
CancelAndStopIntentハンドラー¶
CancelAndStopIntentHandlerもビルトインインテントAMAZON.CancelIntentまたはAMAZON.StopIntentによって呼び出されるため、HelpIntentハンドラーに似ています。以下は、1つのハンドラーを使用して両方のインテントに応答する例です。以下のコードをhello_world.pyファイルの、前述のハンドラーの後に入力するか貼り付けます。
@sb.request_handler(
can_handle_func=lambda handler_input :
is_intent_name("AMAZON.CancelIntent")(handler_input) or
is_intent_name("AMAZON.StopIntent")(handler_input))
def cancel_and_stop_intent_handler(handler_input):
# type: (HandlerInput) -> Response
speech_text = "さようなら"
handler_input.response_builder.speak(speech_text).set_card(
SimpleCard("ハローワールド", speech_text))
return handler_input.response_builder.response
上記の例では、``can_handle``には渡す関数が必要です。``is_intent_name``は関数を返しますが、リクエストが*AMAZON.CancelIntent*なのか*AMAZON.StopIntent*なのかを確認する必要があります。これを行うには、Pythonの組み込み``lambda``関数を使用して、途中に無名関数を作成します。
両方のインテントに対する応答は同じであるため、1つのハンドラーにすることで重複するコードを減らせます。
SessionEndedRequestハンドラー¶
SessionEndedRequestを受け取った後は音声、カード、ディレクティブを使った応答を返すことはできませんが、クリーンアップロジックを追加するにはSessionEndedRequestHandlerが最適な場所です。以下のコードを``hello_world.py``ファイルの、前述のハンドラーの後に入力するか貼り付けます。
@sb.request_handler(can_handle_func=is_request_type("SessionEndedRequest"))
def session_ended_request_handler(handler_input):
# type: (HandlerInput) -> Response
# クリーンアップロジックをここに追加します
return handler_input.response_builder.response
例外ハンドラーの実装¶
以下は、catch all例外ハンドラーをスキルに追加して、すべての例外に対してスキルが意味のあるメッセージを返すようにする例です。以下のコードを``hello_world.py``ファイルの、前述のハンドラーの後に入力するか貼り付けます。
@sb.exception_handler(can_handle_func=lambda i, e: True)
def all_exception_handler(handler_input, exception):
# type: (HandlerInput, Exception) -> Response
# CloudWatch Logsに例外を記録する
print(exception)
speech = "すみません、わかりませんでした。もう一度言ってください。"
handler_input.response_builder.speak(speech).ask(speech)
return handler_input.response_builder.response
Lambdaハンドラーの作成¶
注釈
カスタムスキルの場合、サービスは、AWS Lambdaでホスティングするか、独自のエンドポイントでウェブサービスとしてホスティングできます。
一般的に、AWS Lambdaでスキルコードをホスティングするのが最も簡単です。以下のセクションでは、その方法を説明します。
ただし、他のクラウドホスティングプロバイダーでホスティングする場合は、SDKにいくつか用意されているサポートパッケージ(ask-sdk-webservice-support
、flask-ask-sdk
、django-ask-sdk
)を使用してください。このコンフィギュレーションについて詳しくは、こちらを参照してください。
Lambdaハンドラーは、AWS Lambda関数のエントリポイントとなります。以下は、スキルが受信するすべてのリクエストのルーティングを行うLambdaハンドラー関数のコードサンプルです。Lambdaハンドラー関数は、作成したリクエストハンドラーを使用して設定されたSDKのスキルインスタンスを作成します。
以下のコードを``hello_world.py``ファイルの、前述のハンドラーの後に入力するか貼り付けます。
handler = sb.lambda_handler()
デコレーターを使用する場合、リクエストハンドラーと例外ハンドラーはコードの最初にインスタンス化されたスキルビルダーオブジェクトによって自動的に識別されます。
AWS Lambda用にコードを準備する¶
コードが完成したので、Lambdaにアップロードするファイルを含む.zipファイルを作成する必要があります。
コードをAWS Lambdaにアップロードする際に、スキルコードとその依存関係をフラットファイル構造でzipファイル内に含める必要があります。こうすると、zipでの圧縮前にコードがASK SDK for Pythonと同じフォルダに配置されます。
仮想環境を使ってSDKをセットアップする場合、依存関係は 仮想環境のsite-packagesフォルダにインストールされます。 そのため、skill_envのsite-packagesフォルダに移動します。
注釈
Windowsの場合、site-packagesフォルダはskill_envLib フォルダ内にあります。
注釈
MacOS/Linuxの場合、site-packagesフォルダの場所は使用している Pythonのバージョンによって異なります。たとえば、Python 3.6ユーザーの場合、 skill_env/lib/Python3.6フォルダ内にsite-packagesが あります。
hello_world.pyファイルをsite-packagesフォルダにコピーし、 (そのフォルダ自体ではなく)そのフォルダのコンテンツの.zipファイルを作成します。 ファイルに「skill.zip」という名前を付けます。`デプロイパッケージ<https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html>`__ の作成の詳細については、 AWS Lambdaドキュメントを参照してください。
コードをAWS Lambdaにアップロードする前に、AWS Lambda関数を作成する必要があります。また、Alexa開発者ポータルでスキルを作成する必要があります。
AWS Lambda関数の作成¶
スキルに適切なロールでAWS Lambda関数を作成する手順については、カスタムスキルをAWS Lambda関数としてホスティングする を参照してください。関数作成時には、一から作成オプションを選択し、ランタイムとして``Python 2.7``または``Python 3.6``を選択します。
AWS Lambda関数が作成されたら、Alexaサービスでそれを呼び出すことができるようにします。これを行うには、Lambdaのコンフィギュレーションでトリガータブに移動して、Alexa Skills Kitをトリガータイプとして追加します。これが完了したら、前の手順で作成したskill.zipファイルをアップロードし、ハンドラー情報とmodule_name.handlerを入力します。この例ではhello_world.handlerです。
スキルの設定とテストを行う¶
スキルコードをAWS Lambdaにアップロードしたら、Alexaのスキルを設定できます。
以下の手順に従って新しいスキルを作成します。
- Alexa Skills Kit開発者コンソールにログインします。
- 右上のスキルの作成ボタンをクリックします。
- スキル名として「HelloWorld」と入力します。
- カスタムスキルを選択してからスキルを作成をクリックします。
次に、スキルの対話モデルを定義します。サイドバーの呼び出し名を選択し、スキルの呼び出し名に「ごあいさつ」を入力します。
次に、HelloWorldIntentというインテントを対話モデルに追加します。対話モデルのインテントセクションの下の追加ボタンをクリックします。「カスタムインテントを作成」を選択した状態で、インテント名として「HelloWorldIntent」を入力し、インテントを作成します。インテントの詳細ページで、ユーザーがこのインテントを呼び出すのに使用できるサンプル発話をいくつか追加します。この例では、以下のようなサンプル発話が適当ですが、これ以外に追加してもかまいません。
こんにちはと言って ハローワールドと言って こんにちは ハイと言って ハイワールドと言って ハイ ごきげんいかが
AMAZON.CancelIntent
、`AMAZON.HelpIntent
、``AMAZON.StopIntent``はAlexaのビルトインインテントのため、サンプル発話を追加する必要はありません。開発者コンソールでは、スキルモデル全体をJSON形式で編集できます。サイドバーでJSONエディターを選択します。この例では、以下のJSONスキーマを使用できます。
{ "interactionModel": { "languageModel": { "invocationName": "ごあいさつ", "intents": [ { "name": "AMAZON.CancelIntent", "samples": [] }, { "name": "AMAZON.HelpIntent", "samples": [] }, { "name": "AMAZON.StopIntent", "samples": [] }, { "name": "HelloWorldIntent", "slots": [], "samples": [ "ごきげんいかが", "ハイ", "ハイワールドと言って", "ハイと言って", "こんにちは", "ハローワールドと言って", "こんにちはと言って" ] } ], "types": [] } } }
- 対話モデルの編集が完了したら、モデルを保存してビルドします。
- 次に、スキルのエンドポイントを設定します。これを行うには次の手順に従います。
- スキルの中でエンドポイントタブをクリックし、AWS LambdaのARNを選択して、作成したスキルのスキルIDをコピーします。
- 新しいタブでAWS開発者コンソールを開きます。
- 前の手順で作成したAWS Lambda関数に移動します。
- Designerメニューから、Alexa Skills Kitトリガーメニューを追加し、スクロールダウンしてスキルID検証コンフィギュレーションにスキルIDを貼り付けます。完了したら追加、保存の順にクリックしてAWS Lambda関数を更新します。
- ページ右上隅のAWS Lambda関数ARNをコピーします。ARNは一意のリソース番号です。Alexaサービスはこれを使用して、スキルの呼び出し中に必要になるAWS Lambda関数を識別します。
- Alexa Skills Kit開発者コンソールに移動して、HelloWorldスキルをクリックします。
- スキルの中でエンドポイントタブをクリックし、AWS LambdaのARNを選択して、デフォルトの地域にARNを貼り付けます。
- 残りの設定は、デフォルト値のままでかまいません。エンドポイントを保存をクリックします。
- 呼び出し名タブをクリックして、モデルを保存およびビルドします。
- この時点で、スキルをテストできるようになります。上部メニューでテストをクリックします。このスキルでは、テストは有効になっていますオプションがONになっていることを確認します。テストページを使って、テキストや音声でリクエストをシミュレーションできます。
- 呼び出し名と、サンプル発話のうちの1つを使います。たとえば、「アレクサ、あいさつして」と言うと、スキルは「こんにちは」と音声で応え、ディスプレイ付きのデバイスでは「Hello World」カードが表示されるはずです。また、スマートフォンのAlexaアプリやhttps://alexa.amazon.comでスキルにスキルが表示されていることを確認できます。
- さまざまなインテントや、スキルコードに対応するリクエストハンドラーを試してみてください。ひととおりのテストが完了したら、スキルの認定を申請して世界中のユーザーに公開するプロセスに進むことができます。
サンプルスキル¶
このセクションでは、ASK SDK for Pythonを使って魅力的なAlexaスキルを開発する方法を説明するスキルサンプルを紹介します。
Hello World(クラス使用)¶
このコードサンプルでは、サンプルがトリガーされたときのAlexaの応答を聞くことができます。Alexa Skills KitやAWS Lambdaに慣れるための最小限のサンプルです。このサンプルでは、リクエストハンドラーのクラスを使用してスキルを作成する方法を説明します。詳細については、 リクエスト処理 を参照してください。
Hello World(デコレーター使用)¶
このコードサンプルでは、サンプルがトリガーされたときのAlexaの応答を聞くことができます。Alexa Skills KitやAWS Lambdaに慣れるための最小限のサンプルです。このサンプルでは、リクエストハンドラーのデコレーターを使用してスキルを作成する方法を説明します。詳細については、 リクエスト処理 を参照してください。
カラーピッカー¶
Hello Worldから機能を一歩進めて、ユーザーが好きな色を指定したら、Alexaが覚えてユーザーに知らせるようにします。ユーザーからの入力をキャプチャーできるようにします。スロットの使い方についても説明します。さらに、セッションアトリビュートと、リクエスト、応答のインターセプターの使い方も説明します。
ファクト¶
基本的な豆知識スキルのテンプレートです。トピックについての豆知識のリストを提供すると、ユーザーがスキルを呼び出したときに、Alexaがリストから豆知識をランダムに選んでユーザーに伝えます。スキルで複数のロケールを使用し国際化する方法を説明します。
クイズゲーム¶
基本的なクイズゲームスキルのテンプレートです。あらかじめ提供しておいた豆知識のリストの中から、Alexaがユーザーにクイズを出します。画面付きのAlexa搭載デバイスでの表示をサポートする、テンプレートレンダリングディレクティブの使い方について説明します。
デバイスのアドレス¶
ユーザーのデバイス設定で設定したアドレスをリクエストし、設定されたアドレスにアクセスするサンプルスキルです。SDKを使用したAlexa APIの使い方について説明します。詳細については、Alexaサービスクライアントを参照してください。
スキル内課金を使用した豆知識¶
スキル内課金 機能を使用した豆知識スキルのサンプルです。購入を促進するさまざまなパックや、パックを一括でロック解除するサブスクリプションを提供します。収益化Alexaサービスの呼び出し方とASK CLIを使ってスキル内課金を有効にする方法を説明します。
シティガイド¶
周辺地域のお勧め情報スキルのテンプレートです。Alexaはユーザーのリクエストに従って、開発者が提供したデータからお勧め情報をユーザーに知らせます。スキルから外部APIを呼び出す方法を説明します。
ペットマッチ¶
ユーザーとペットをマッチングするサンプルスキルです。Alexaは一致するペットを見つけるのに必要な情報をユーザーにたずねます。必要な情報をすべて収集できたら、スキルはデータを外部のウェブサービスに送信し、そこでデータが処理されてマッチングデータが返されます。ダイアログ管理と エンティティ解決 を使って、プロンプトを出してユーザーから複数の値を受け取り解析する方法を説明します。
ハイ&ローゲーム¶
基本的なハイ&ローゲームスキルのテンプレートです。ユーザーが数字を推測し、Alexaがその数字が正解より大きいか小さいかを答えます。SDKの永続アトリビュートと永続アダプターの使い方について説明します。
AudioPlayer SingleStreamおよびMultiStream¶
Alexaの AudioPlayerインターフェース と PlaybackControllerインターフェース を使ってAudioPlayerスキルを開発する方法を説明するスキルサンプルです。SingleStreamスキルサンプルでは、ローカリゼーションのサポート付きでライブラジオスキルを作成する方法を説明します。MultiStreamスキルサンプルでは、録音済みの複数のオーディオストリームを再生できる基本的なポッドキャストスキルを作成する方法を説明します。
Pager Karaoke¶
このサンプルでは、APLの3つの機能である Pagerコンポーネント 、 SpeakItemコマンド 、スキルコードの デバイスの特性 へのアクセスについて説明します。
ASK SDKのセットアップ¶
Pythonプロジェクトに依存関係としてSDKをインストールする方法を説明します。
SDKでサポートされているAlexaの機能¶
ASK SDKでサポートされているAlexaの機能の一覧です。
SDKの機能¶
リクエスト処理¶
このガイドでは、スキル開発用にSDKで使用できる次のリクエスト処理コンポーネントについて説明します。
ハンドラー入力¶
リクエストハンドラー、リクエストと応答のインターセプター、例外ハンドラーにはすべて、呼び出し時に共通の HandlerInput
オブジェクトが渡されます。このオブジェクトには、リクエスト処理に有効な各種エンティティが含まれます。以下はその例です。
- request_envelope :スキルに送信されるリクエスト本文全体を含みます。
- attributes_manager :リクエスト、セッション、永続アトリビュートへのアクセスを提供します。
- service_client_factory : Alexa APIの呼び出しが可能なサービスクライアントを構築します。
- response_builder : 応答を作成するヘルパー関数を含みます。
- context :ホストコンテナが渡すオプションのcontextオブジェクトを提供します。たとえば、AWS Lambdaで実行されるスキルの場合は、AWS Lambda関数のcontextオブジェクトになります。
リクエストハンドラー¶
リクエストハンドラーは、受信するさまざまなタイプのAlexaリクエストの処理を担当します。カスタムリクエストハンドラーを作成する方法は2つあります。
AbstractRequestHandler
クラスを実装する。- スキルビルダーの
request_handler
デコレーターを使用してカスタムハンドル関数をデコレートする。
インターフェース¶
AbstractRequestHandlerクラス¶
AbstractRequestHandler
クラスの使用を予定している場合は、次のメソッドを実装する必要があります。
- can_handle :
can_handle
は、SDKによって呼び出され、指定されたハンドラーが受け取ったリクエストを処理できるかどうかを判断します。この関数はハンドラー入力オブジェクトを受け付け、ブール型を返すように想定されています。メソッドがTrueを返せば、ハンドラーによってリクエストが正常に処理されたと考えられます。Falseを返す場合、ハンドラーが入力リクエストを処理できず、したがって実行されず完了もしなかったと考えられます。HandlerInput
オブジェクトにはさまざまなアトリビュートがあるため、リクエストを正常に処理できるかどうかをSDKが判別するための任意の条件を作成できます。 - handle :
handle
メソッドは、リクエストハンドラーを呼び出すときにSDKによって呼び出されます。この関数には、ハンドラーのリクエスト処理ロジックが含まており、ハンドラー入力を受け取り、応答オブジェクトを返します。
class AbstractRequestHandler(object):
@abstractmethod
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
pass
@abstractmethod
def handle(self, handler_input):
# type: (HandlerInput) -> Response
pass
以下は、HelloWorldIntent
を呼び出すことができるリクエストハンドラークラスの例です。
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_model.ui import SimpleCard
class HelloWorldIntentHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
return handler_input.request_envelope.request.type == "IntentRequest"
and handler_input.request_envelope.request.intent.name == "HelloWorldIntent"
def handle(self, handler_input):
speech_text = "Hello World";
return handler_input.response_builder.speak(speech_text).set_card(
SimpleCard("Hello World", speech_text)).response
can_handle
関数は受け取るリクエストが IntentRequest
かどうかを検出し、インテント名が HelloWorldIntent
の場合にtrueを返します。handle
関数は、基本的な「こんにちは」という応答を生成して返します。
SkillBuilderのrequest_handlerデコレーター¶
SkillBuilderクラスの request_handler
デコレーターは、AbstractRequestHandler
クラスに搭載されたカスタムラッパーであり、カスタムでデコレートされた任意の関数と同じ機能を提供します。ただし、デコレーターを使用するには考慮事項が2つあります。
- デコレーターは
can_handle_func
パラメーターを取ります。これはAbstractRequestHandler
のcan_handle
メソッドに似たものです。渡される値はハンドラー入力オブジェクトを受け付け、ブール型値を返す関数である必要があります。 - デコレートされた関数が受け付けるパラメーターはハンドラー入力1つのみであり、
Response
オブジェクトを返します。
class SkillBuilder(object):
....
def request_handler(self, can_handle_func):
def wrapper(handle_func):
# wrap the can_handle and handle into a class
# add the class into request handlers list
....
return wrapper
以下は、HelloWorldIntent
を処理できるリクエストハンドラー関数の例です。
from ask_sdk_core.utils import is_intent_name
from ask_sdk_model.ui import SimpleCard
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
@sb.request_handler(can_handle_func = is_intent_name("HelloWorldIntent"))
def hello_world_intent_handler(handler_input):
speech_text = "Hello World!"
return handler_input.response_builder.speak(speech_text).set_card(
SimpleCard("Hello World", speech_text)).response
is_intent_name
関数はstringパラメーターを受け取り無名関数を返します。この無名関数は、HandlerInput
を入力パラメーターとして受け取って、HandlerInput
の受信リクエストが IntentRequest
であるかを確認し、インテント名が string
に渡されているものであればそれを返します。この例では HelloWorldIntent
です。handle
関数は、基本的な「こんにちは」という応答を生成して返します。
リクエストハンドラーの登録と処理¶
SDKは、リクエストハンドラーで、スキルビルダーに指定された順序で can_handle
関数を呼び出します。
AbstractRequestHandler
クラスを使用する方法に従っている場合、次の方法でリクエストハンドラーを登録できます
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
# Implement FooHandler, BarHandler, BazHandler classes
sb.add_request_handler(FooHandler())
sb.add_request_handler(BarHandler())
sb.add_request_handler(BazHandler())
request_handler
デコレーターを使用する方法に従っている場合、ハンドラー関数を明示的に登録する必要はありません。スキルビルダーインスタンスを使用してすでにデコレートされています。
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
# decorate foo_handler, bar_handler, baz_handler functions
上記の例では、SDKが以下の順序でリクエストハンドラーを呼び出します。
FooHandler
クラス /foo_handler
関数BarHandler
クラス /bar_handler
関数BazHandle
rクラス /baz_handler
関数
SDKは、指定されたリクエストを処理できる最初のハンドラーを常に選択します。この例では、FooHandler
クラス / foo_handler
関数および BarHandler``クラス / ``bar_handler
関数のどちらも指定のリクエストを処理できる場合、FooHandler
クラス/foo_handler
関数が常に呼び出されます。リクエストハンドラーのデザインや登録を行う際には、この点を考慮に入れてください。
例外ハンドラー¶
例外ハンドラーはリクエストハンドラーに似ていますが、リクエストではなく1つまたは複数のタイプの例外を処理します。リクエストの処理中に未処理の例外がスローされると、SDKが例外ハンドラーを呼び出します。
ハンドラーはハンドラー入力オブジェクトに加えて、入力リクエストの処理中に発生した例外にもアクセスできます。そのため、ハンドラーが該当する例外の処理方法を判別しやすくなります。
リクエストハンドラーと同様に、カスタムリクエストインターセプターも2通りの方法で実装できます。
AbstractExceptionHandler
クラスを実装する。- スキルビルダーの
exception_handler
デコレーターを使用してカスタム例外ハンドル関数をデコレートする。
インターフェース¶
AbstractExceptionHandlerクラス¶
AbstractExceptionHandler
クラスの使用を予定している場合は、次のメソッドを実装する必要があります。
- can_handle :
can_handle
メソッドはSDKによって呼び出され、指定されたハンドラーが例外を処理できるかどうかを判断します。ハンドラーが例外を処理できる場合はTrue、できない場合はFalseを返します。catch-allハンドラーを作成する場合は常にTrue
を返します。 - handle :
handle
メソッドは例外ハンドラーを呼び出すときにSDKによって呼び出されます。この関数には、例外処理ロジックがすべて含まれ、応答オブジェクトを返します。
class AbstractExceptionHandler(object):
@abstractmethod
def can_handle(self, handler_input, exception):
# type: (HandlerInput, Exception) -> bool
pass
@abstractmethod
def handle(self, handler_input, exception):
# type: (HandlerInput, Exception) -> Response
pass
以下は、名前に「AskSdk」が含まれる例外をすべて処理する例外ハンドラーの例です。
class AskExceptionHandler(AbstractExceptionHandler):
def can_handle(self, handler_input, exception):
return 'AskSdk' in exception.__class__.__name__
def handle(self, handler_input, exception):
speech_text = "Sorry, I am unable to figure out what to do. Try again later!!";
return handler_input.response_builder.speak(speech_text).response
ハンドラーの can_handle
メソッドは、受け取る例外の名前が「AskSdk」で始まる場合にTrueを返します。handle
メソッドは、ユーザーに正常な例外応答を返します。
SkillBuilderのexception_handlerデコレーター¶
SkillBuilderクラスの exception_handler
デコレーターは、AbstractExceptionHandler
クラスに搭載されたカスタムラッパーであり、カスタムでデコレートされた任意の関数と同じ機能を提供します。ただし、デコレーターを使用するには以下の2点を考慮してください。
- デコレーターは
can_handle_func
パラメーターを取ります。これはAbstractExceptionHandler
のcan_handle
メソッドに似たものです。渡される値はハンドラー入力オブジェクトを例外インスタンスとして受け付け、ブール型値を返す関数である必要があります。 - デコレートされた関数が受け付けるパラメーターはハンドラー入力オブジェクトおよび例外オブジェクトの2つのみです。応答オブジェクトが返されます。
class SkillBuilder(object):
....
def exception_handler(self, can_handle_func):
def wrapper(handle_func):
# wrap the can_handle and handle into a class
# add the class into exception handlers list
....
return wrapper
以下は、名前に「AskSdk」が含まれる例外をすべて処理する例外ハンドラー関数の例です。
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
@sb.exception_handler(can_handle_func = lambda input, e: 'AskSdk' in e.__class__.__name__)
def ask_exception_intent_handler(handler_input, exception):
speech_text = "Sorry, I am unable to figure out what to do. Try again later!!";
return handler_input.response_builder.speak(speech_text).response
例外ハンドラーの登録と処理¶
AbstractExceptionHandler
クラスを使用する方法に従っている場合、次の方法でリクエストハンドラーを登録できます
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
# Implement FooExceptionHandler, BarExceptionHandler, BazExceptionHandler classes
sb.add_exception_handler(FooExceptionHandler())
sb.add_exception_handler(BarExceptionHandler())
sb.add_exception_handler(BazExceptionHandler())
exception_handler
デコレーターを使用する方法に従っている場合、ハンドラー関数を明示的に登録する必要はありません。スキルビルダーインスタンスを使用してすでにデコレートされています。
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
# decorate foo_exception_handler, bar_exception_handler, baz_exception_handler functions
リクエストハンドラーと同様に、例外ハンドラーはスキルで指定した順序で実行されます。
リクエストと応答のインターセプター¶
SDKは、一致する RequestHandler
の実行前と実行後に実行するリクエストと応答のグローバルインターセプターをサポートします。
リクエストインターセプター¶
グローバルリクエストインターセプターは、登録されたリクエストハンドラーの処理前に、ハンドラー入力オブジェクトを受け付けて処理します。リクエストハンドラーと同様に、カスタムリクエストインターセプターも2通りの方法で実装できます。
AbstractRequestInterceptor
クラスを実装する。- スキルビルダーの
global_request_interceptor
デコレーターを使用してカスタム処理関数をデコレートする。
インターフェース¶
AbstractRequestInterceptor
クラスを使用するには、処理メソッドを実装する必要があります。このメソッドはハンドラー入力インスタンスを取得し、何も返しません。
class AbstractRequestInterceptor(object):
@abstractmethod
def process(self, handler_input):
# type: (HandlerInput) -> None
pass
以下は、Alexaサービスが受け取ったリクエストを、処理の前にAWS CloudWatchログに書き込むリクエストインターセプタークラスの例です。
from ask_sdk_core.dispatch_components import AbstractRequestInterceptor
class LoggingRequestInterceptor(AbstractRequestInterceptor):
def process(self, handler_input):
print("Request received: {}".format(handler_input.request_envelope.request))
SkillBuilderクラスの global_request_interceptor
デコレーターは、AbstractRequestInterceptor
クラスに搭載されたカスタムラッパーであり、カスタムでデコレートされた任意の関数と同じ機能を提供します。ただし、デコレーターを使用するには以下の2点を考慮してください。
- デコレーターはスキルビルダーインスタンスを必要とするため、インターセプターを登録するには、関数名としてではなく関数として呼び出される必要があります。
- デコレートされた関数が受け付けるパラメーターはハンドラー入力オブジェクト1つのみであり、関数からの戻り値はキャプチャーされません。
class SkillBuilder(object):
....
def global_request_interceptor(self):
def wrapper(process_func):
# wrap the process_func into a class
# add the class into request interceptors list
....
return wrapper
以下は、リクエストインターセプターとして使用できるログ記録関数の例です。
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
@sb.global_request_interceptor()
def request_logger(handler_input):
print("Request received: {}".format(handler_input.request_envelope.request))
リクエストインターセプターの登録と処理¶
リクエストのインターセプターは、リクエストハンドラーが受け取ったリクエストを処理する直前に呼び出されます。ハンドラー入力のアトリビュートマネージャー内のリクエストアトリビュートは、リクエストインターセプターが他のリクエストインターセプターやリクエストハンドラーにデータやエンティティを渡す方法を提供します。
AbstractRequestInterceptor
クラスを使用する方法に従っている場合、次の方法でリクエストインターセプターを登録できます
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
# Implement FooInterceptor, BarInterceptor, BazInterceptor classes
sb.add_global_request_interceptor(FooInterceptor())
sb.add_global_request_interceptor(BarInterceptor())
sb.add_global_request_interceptor(BazInterceptor())
global_request_interceptor
デコレーターを使用する方法に従っている場合、インターセプター関数を明示的に登録する必要はありません。スキルビルダーインスタンスを使用してすでにデコレートされています。
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
# decorate foo_interceptor, bar_interceptor, baz_interceptor functions
上記の例では、SDKが以下の順序ですべてのリクエストインターセプターを実行します。
FooInterceptor
クラス /foo_interceptor
関数BarInterceptor
クラス /bar_interceptor
関数BazInterceptor
クラス /baz_interceptor
関数
応答インターセプター¶
グローバル応答インターセプターは、サポートされるリクエストハンドラーの処理後に、ハンドラー入力オブジェクト、つまり応答を受け付けて処理します。リクエストインターセプターと同様に、カスタム応答インターセプターも二通りの方法で実装できます。
AbstractResponseInterceptor
クラスを実装する。- スキルビルダーの
global_response_interceptor
デコレーターを使用してカスタム処理関数をデコレートする。
インターフェース¶
AbstractResponseInterceptor
クラスを使用するには、処理メソッドを実装する必要があります。このメソッドはハンドラー入力インスタンスの、先に実行されたリクエストハンドラーから返された応答オブジェクトを取ります。このメソッドから返されるものはありません。
class AbstractResponseInterceptor(object):
@abstractmethod
def process(self, handler_input, response):
# type: (HandlerInput, Response) -> None
pass
以下は、正常に処理されたリクエストから受け取った応答を、Alexaサービスにその応答が返される前にAWS CloudWatchログに書き込むレスポンスインターセプタークラスの例です。
from ask_sdk_core.dispatch_components import AbstractResponseInterceptor
class LoggingResponseInterceptor(AbstractResponseInterceptor):
def process(handler_input, response):
print("Response generated: {}".format(response))
SkillBuilderクラスの global_response_interceptor
デコレーターは、AbstractResponseInterceptor
クラスに搭載されたカスタムラッパーであり、カスタムでデコレートされた任意の関数と同じ機能を提供します。ただし、デコレーターを使用するには以下の2点を考慮してください。
- デコレーターはスキルビルダーインスタンスを必要とするため、インターセプターを登録するには、関数名としてではなく関数として呼び出される必要があります。
- デコレートされた関数は2つのパラメーターを受け付けます。それぞれハンドラー入力オブジェクトおよび応答オブジェクトです。この関数から返される値はキャプチャーされません。
class SkillBuilder(object):
....
def global_response_interceptor(self):
def wrapper(process_func):
# wrap the process_func into a class
# add the class into response interceptors list
....
return wrapper
以下は、応答インターセプターとして使用できるログ記録関数の例です。
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
@sb.global_response_interceptor()
def response_logger(handler_input, response):
print("Response generated: {}".format(response))
応答インターセプターの登録と処理¶
応答インターセプターは、受け取るリクエストのリクエストハンドラーが実行された直後に呼び出されます。
AbstractResponseInterceptor
クラスを使用する方法に従っている場合、次の方法で応答インターセプターを登録できます
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
# Implement FooInterceptor, BarInterceptor, BazInterceptor classes
sb.add_global_response_interceptor(FooInterceptor())
sb.add_global_response_interceptor(BarInterceptor())
sb.add_global_response_interceptor(BazInterceptor())
global_response_interceptor
デコレーターを使用する方法に従っている場合、インターセプター関数を明示的に登録する必要はありません。スキルビルダーインスタンスを使用してすでにデコレートされています。
from ask_sdk_core.skill_builder import SkillBuilder
sb = SkillBuilder()
# decorate foo_interceptor, bar_interceptor, baz_interceptor functions
リクエストインターセプターの処理と同様に、応答インターセプターはすべて、登録順に実行されます。
レスポンスビルディング¶
SDKには、 ResponseFactory
クラスが含まれています。このクラスにはヘルパー
応答を構築するための関数。Response
には複数の要素が含まれる場合があり、ヘルパー関数によって応答を生成しやすくなり、各応答の要素を初期化したり設定したりする時間を削減できます。
インターフェース¶
class ResponseFactory(object):
def __init__(self):
self.response = .... # Response object
def speak(self, speech):
# type: (str) -> 'ResponseFactory'
....
def ask(self, speech):
# type: (str) -> 'ResponseFactory'
....
def set_card(self, card):
# type: (Card) -> 'ResponseFactory'
....
def add_directive(self, directive):
# type: (Directive) -> 'ResponseFactory'
....
def set_should_end_session(self, end_session):
# type: (bool) -> 'ResponseFactory'
....
ResponseFactory
クラスのインスタンスである response_builder
は、
スキル開発者に
HandlerInput オブジェクトを返します。
スキルコンポーネントに渡される標準引数です。
以下は、ResponseFactory
ヘルパー関数を使用して応答を作成する方法の例です。
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_core.response_helper import get_plain_text_content
from ask_sdk_model.response import Response
from ask_sdk_model.interfaces.display import (
ImageInstance, Image, RenderTemplateDirective,
BackButtonBehavior, BodyTemplate2)
from ask_sdk_model import ui
class HelloIntentHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_intent_name("HelloIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
response_builder = handler_input.response_builder
speech = "This is a sample response"
response_builder.set_card(
ui.StandardCard(
title="Card Title",
text="Hey this is a sample card",
image=ui.Image(
small_image_url="<Small Image URL>",
large_image_url="<Large Image URL>"
)
)
)
if supports_display(handler_input):
img = Image(
sources=[ImageInstance(url="<Large Image URL>")])
title = "Template Title"
primary_text = get_plain_text_content(
primary_text="some text")
response_builder.add_directive(
RenderTemplateDirective(
BodyTemplate2(
back_button=BackButtonBehavior.VISIBLE,
image=img, title=title,
text_content=primary_text)))
return response_builder.speak(speech).response
テキストヘルパー¶
次のヘルパー関数がスキル開発者用に用意されており、テキストコンテンツの生成に役立ちます。
get_plain_text_content¶
def get_plain_text_content(primary_text, secondary_text, tertiary_text):
# type: (str, str, str) -> TextContent
# Create a text content object with text as PlainText type
....
get_rich_text_content¶
def get_rich_text_content(primary_text, secondary_text, tertiary_text):
# type: (str, str, str) -> TextContent
# Create a text content object with text as RichText type
....
get_text_content¶
def get_text_content(
primary_text, primary_text_type,
secondary_text, secondary_text_type,
tertiary_text, tertiary_text_type):
# type: (str, str, str, str, str, str) -> TextContent
# Create a text content object with text as corresponding passed-type
# Passed-in type is defaulted to PlainText
....
スキルのアトリビュート¶
このガイドでは、スキル開発に使用できるアトリビュートのさまざまなスコープと、スコープをスキルで使用する方法について説明します。
アトリビュート¶
SDKを使うと、さまざまなスコープでアトリビュートの保存と取得ができます。たとえば、アトリビュートを使用して後続のリクエストで取得するデータを保存できます。また、ハンドラーの can_handle
ロジックでアトリビュートを使用して、リクエストのルーティングに条件を追加することもできます。
アトリビュートは、キーと値で構成されます。キーは str
型限定、値は無制限の object
型です。セッションアトリビュートと永続アトリビュートの場合、値は保存して後で取得できるよう、シリアライズできるデータ型である必要があります。この制限はリクエストレベルのアトリビュートには適用されません。なぜならリクエストレベルのアトリビュートは、リクエスト処理のライフサイクルが終了すると、永続的に存在しないからです。
アトリビュートのスコープ¶
リクエストアトリビュート¶
リクエストアトリビュートは、1回のリクエスト処理ライフサイクルの間のみ存続します。リクエストを受信した時点では、リクエストアトリビュートは空です。また応答が生成されると破棄されます。
リクエストアトリビュートは、リクエストと応答のインターセプターと合わせて使うと便利です。たとえば、リクエストインターセプターを使って追加のデータとヘルパーメソッドをリクエストアトリビュートに挿入して、リクエストハンドラーが取得できるようにできます。
セッションアトリビュート¶
セッションアトリビュートは、現在のスキルセッションが継続している間存続します。セッションアトリビュートは、すべてのセッション内リクエストで使用できます。リクエスト処理のライフサイクル中に設定されたすべてのアトリビュートはAlexaサービスに返され、同じセッションの次のリクエストで提供されます。
セッションアトリビュートで、外部ストレージソリューションを使用する必要はありません。セッションアトリビュートはセッション外のリクエストの処理では使用できません。スキルセッションがクローズされると破棄されます。
永続アトリビュート¶
永続アトリビュートは、現在のセッションのライフサイクルが終了しても存続します。主要なスコープ(ユーザーID、デバイスID)、TTL、ストレージレイヤーを含む、これらのアトリビュートがどのように保存されるかはスキルのコンフィギュレーションによって異なります。
永続アトリビュートは、PersistenceAdapter
を使用してスキルのインスタンスを設定する場合にのみ使用できます。PersistenceAdapter
が設定されていない場合に、AttributesManager
を呼び出して永続アトリビュートの取得と保存を行おうとするとエラーが発生します。
PersistenceAdapter¶
AbstractPersistenceAdapter
は、永続レイヤー(データベースやローカルファイルシステムなど)でアトリビュートを保存したり取得したりする場合に AttributesManager
が使用します。ask-sdk-dynamodb-persistence-adapter
パッケージは、AWS DynamoDBを使用してAbstractPersistenceAdapterを実装します。
AbstractPersistenceAdapter
の実装はすべて、以下のインターフェースに従う必要があります。
インターフェース¶
class AbstractPersistenceAdapter(object):
def get_attributes(self, request_envelope):
# type: (RequestEnvelope) -> Dict[str, Any]
pass
def save_attributes(self, request_envelope, attributes):
# type: (RequestEnvelope, Dict[str, Any]) -> None
pass
AttributesManager¶
AttributesManagerには、ハンドラーで取得や更新を行えるアトリビュートがあります。AttributesManagerは、Handler Input オブジェクトからハンドラーで使用できます。AttributesManager
は、スキルで必要なアトリビュートと直接やり取りできるように、アトリビュートの取得と保存を行います。
インターフェース¶
class AttributesManager(object):
def __init__(self, request_envelope, persistence_adapter=None):
# type: (RequestEnvelope, AbstractPersistenceAdapter) -> None
....
@property
def request_attributes(self):
# type: () -> Dict[str, Any]
# Request Attributes getter
....
@request_attributes.setter
def request_attributes(self, attributes):
# type: (Dict[str, Any]) -> None
# Request Attributes setter
....
@property
def session_attributes(self):
# type: () -> Dict[str, Any]
# Session Attributes getter
....
@session_attributes.setter
def session_attributes(self, attributes):
# type: (Dict[str, Any]) -> None
# Session Attributes setter
....
@property
def persistent_attributes(self):
# type: () -> Dict[str, Any]
# Persistence Attributes getter
# Uses the Persistence adapter to get the attributes
....
@persistent_attributes.setter
def persistent_attributes(self, attributes):
# type: (Dict[str, Any]) -> None
# Persistent Attributes setter
....
def save_persistent_attributes(self):
# type: () -> None
# Persistence Attributes save
# Save the Persistence adapter to save the attributes
....
以下は、永続アトリビュートの取得と保存を行う方法のサンプルです。
class PersistenceAttributesHandler(AbstractRequestHandler):
def can_handle(handler_input):
persistence_attr = handler_input.attributes_manager.persistent_attributes
return persistence_attr['foo'] == 'bar'
def handle(handler_input):
persistence_attr = handler_input.attributes_manager.persistent_attributes
persistence_attr['foo'] = 'baz'
handler_input.attributes_manager.save_persistent_attributes()
return handler_input.response_builder.response
Alexaサービスクライアント¶
Alexa Skills Kitは複数のサービスAPIを提供しています。 あなたのスキル経験をパーソナライズする。 SDKには以下のサービスクライアントが含まれています。 スキルロジック内からAlexa APIを呼び出すために使用できます。
注釈
SDKは、セッション外のAlexa APIのサポートも提供します。 ( プロアクティブイベント<https://developer.amazon.com/docs/smapi/proactive-events-api.html> __、 スキルメッセージング<https://developer.amazon.com/docs/smapi/send-a-message-request-to-a-skill.html> __ 等。)。 SDKを介してこれらのサービスを呼び出す方法の詳細については、 チェックしてください セッション外のAlexaサービスクライアント<OUT_OF_SESSION_SERVICE_CLIENTS.html> __。
ServiceClientFactory¶
Handler Input <REQUEST_PROCESSING.html#handler-input> _の中に含まれる `` service_client_factory`` サポートされているすべてのAlexaサービスのクライアントインスタンスを取得できます。それ 個々のサービスクライアントを作成し、メタデータを設定します。 `` api_access_token``や `` api_endpoint``のように。
`` service_client_factory``を通して `` handler_input``で利用可能ですので 属性、サービスクライアントは任意のリクエストハンドラで使用できます、例外 ハンドラー、および要求、応答のインターセプター。
利用可能なサービスクライアント¶
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_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
注釈
`` service_client_factory``はあなたが利用できる場合にのみ利用可能です。 `スキルインスタンスを設定する<SKILL_BUILDERS.html#skill-builders>`_ ApiClientを使って
注釈
さまざまなサービスクライアント用のインターフェースおよびコードサンプルの詳細については、`こちらを参照してください。<https://alexa-skills-kit-python-sdk.readthedocs.io/en/latest/SERVICE_CLIENTS.html#alexa-service-clients>`__
Apiクライアント¶
`` ask_sdk_model.services.api_client.ApiClient``は AlexaサービスへのAPI呼び出しを行うときは `` service_client_factory``。 以下に準拠する任意のカスタマイズされた「ApiClient」を登録できます。 SDKとのインタフェース
インタフェース¶
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
CustomSkillBuilder <SKILL_BUILDERS.html#customskillbuilder-class> __ ApiClientを登録するためにコンストラクタを使用することができます。
from ask_sdk_core.skill_builder import CustomSkillBuilder
sb = CustomSkillBuilder(api_client = <YourClassInstance>)
DefaultApiClient¶
`` request``ライブラリに基づいた `` DefaultApiClient``は、以下で利用可能になります。 スキル開発者のための `` ask_sdk_core.api_client``モジュール
このクライアントはデフォルトで StandardSkillBuilder <SKILL_BUILDERS.html#standardskillbuilder-class> __に登録されています。 あるいは、スキル開発者はこのクライアントをに登録することができます。 CustomSkillBuilderです。
from ask_sdk_core.skill_builder import CustomSkillBuilder
from ask_sdk_core.api_client import DefaultApiClient
sb = CustomSkillBuilder(api_client=DefaultApiClient())
Alexaセッション外サービスクライアント¶
一部のAlexa Skills KitサービスAPIは、スキルのロジックの外で使用することもできます。たとえば、スキルメッセージAPIを使って、スキルにメッセージを送信できます。こうしたセッション外のサービスリクエストを通じて送信されるイベントを処理できるよう、スキルを設定してください。
この場合、サービスの呼び出しはユーザーのスキルコンテキストのセッション外で行われるため、スコープがサービスに依存するよう正しく設定されたアクセストークンを指定する必要があります。そのため、SDKを使わずにサービスを呼び出すには、以下の手順を実行します。
- 開発者コンソールでスキル>アクセス権限タブからクライアントIDとクライアントシークレットを取得し、正しいスコープを指定してAlexaエンドポイントを呼び出し、Alexaから必要なアクセストークンを取得します。
- 適切な入力パラメーターと認可済みのアクセストークンを指定して、サービスAPIを呼び出します。
SDKには、この両方の手順が1回のサービス呼び出しで行われるサービスクライアントが用意されています。クライアントは、クライアントIDとクライアントシークレットを受け取り、サービスに関する必要なスコープを設定してアクセストークンを取得し、そのトークンを使ってAlexaサービスを呼び出して、目的の応答オブジェクトを提供します。これによって、サービスを呼び出すためだけにボイラープレートコード(毎回書かなければならないお決まりのコード)を設定する手間をが省略できます。
重要
開発者コンソールでは、適切な権限が設定されているスキルにのみ、クライアントIDとクライアントシークレットの値が表示されます。これらの値は、開発者コンソールのスキル>アクセス権限タブから取得できます。
注釈
このようなサービスクライアントはスキルセッションのコンテキスト外であるため、handler_inputオブジェクトの``service_client_factory``では使用できません。スキルセッションのコンテキストで呼び出せるサービスの詳細については、 In-Session Service Clients(英語) を参照してください。
利用可能なサービスクライアント¶
- プロアクティブイベント:
ask_sdk_model.services.proactive_events.proactive_events_service_client.ProactiveEventsServiceClient
- スキルメッセージ:
ask_sdk_model.services.skill_messaging.skill_messaging_service_client.SkillMessagingServiceClient
サービスクライアントのコンストラクターには ask_sdk_model.services.api_configuration.ApiConfiguration
と ask_sdk_model.services.authentication_configuration.AuthenticationConfiguration
のインスタンスが必要です。
AuthenticationConfiguration¶
ask_sdk_model.services.authentication_configuration.AuthenticationConfiguration
はコンフィギュレーションクラスであり、Alexaからアクセストークンを取得するためにクライアントIDとクライアントシークレットを受け取ります。
ApiConfiguration¶
ask_sdk_model.services.api_configuration.ApiConfiguration
は、api_client(サービスを呼び出すために使用)、serializer(リクエスト/応答オブジェクトのシリアル化/逆シリアル化に使用)、api_endpoint(呼び出し先)の設定に必要です。
注釈
セッション外の呼び出しには、ApiConfigurationクラスのauthorization_valueは不要です。
注釈
カスタマイズされたAPIクライアントは、ask_sdk_model.services.api_client.ApiClient
インターフェースに従っていれば指定できます。この方法で使用する場合、SDKのask_sdk_core.api_client.DefaultApiClient
を利用できます。
注釈
カスタマイズされたシリアライザーは、ask_sdk_model.services.serializer.Serializer
インターフェースに従っていれば指定できます。この方法で使用する場合、SDKの ask_sdk_core.serialize.DefaultSerializer
実装を利用できます。
ProactiveEventsServiceClient¶
プロアクティブイベントAPI を使用すると、Alexaスキル開発者はAlexaにイベントを送信できます。イベントとは、ユーザーが興味を持つと考えられる事実に基づくデータのことです。イベントを受信すると、Alexaは、これらのイベントを受け取るようサブスクリプションを行ったユーザーに、プロアクティブに情報を配信します。
現在、このAPIは、Alexa通知というプロアクティブチャネルを1つサポートしています。将来的にプロアクティブチャネルが追加されると、開発者は新しいAPIを統合しなくても、追加のチャネルを利用できるようになります。
インターフェース¶
class ask_sdk_model.services.proactive_events.ProactiveEventsServiceClient:
def __init__(self, api_configuration, authentication_configuration):
# type: (ApiConfiguration, AuthenticationConfiguration) -> None
def create_proactive_event(self, create_proactive_event_request, stage):
# type: (CreateProactiveEventRequest, SkillStage) -> Union[Error]
class ask_sdk_model.services.proactive_events.CreateProactiveEventRequest:
def __init__(self, timestamp=None, reference_id=None, expiry_time=None, event=None, localized_attributes=None, relevant_audience=None):
# type: (Optional[datetime], Optional[str], Optional[datetime], Optional[Event], Optional[List[object]], Optional[RelevantAudience]) -> None
class ask_sdk_model.services.proactive_events.SkillStage(Enum):
DEVELOPMENT = "DEVELOPMENT"
LIVE = "LIVE"
class ask_sdk_model.services.proactive_events.Event:
def __init__(self, name=None, payload=None):
# type: (Optional[str], Optional[object]) -> None
class ask_sdk_model.services.proactive_events.RelevantAudience:
def __init__(self, object_type=None, payload=None):
# type: (Optional[RelevantAudienceType], Optional[object]) -> None
class ask_sdk_model.services.proactive_events.RelevantAudienceType(Enum):
Unicast = "Unicast"
Multicast = "Multicast"
モデルの詳細については こちら を参照してください。
サンプルコード¶
以下の例で、天気のプロアクティブイベントをAlexaに送信する方法を示します。Alexaは受信したイベントを、スキルに登録されているすべてのユーザーにマルチキャストします。
from datetime import datetime, timedelta
from ask_sdk_model.services.proactive_events import (
ProactiveEventsServiceClient, CreateProactiveEventRequest,
RelevantAudienceType, RelevantAudience, SkillStage, Event)
from ask_sdk_model.services import (
ApiConfiguration, AuthenticationConfiguration)
from ask_sdk_core.serialize import DefaultSerializer
from ask_sdk_core.api_client import DefaultApiClient
def create_notification():
client_id = "XXXX"
client_secret = "XXXX"
user_id = "XXXX"
proactive_client = ProactiveEventsServiceClient(
api_configuration=ApiConfiguration(
serializer=DefaultSerializer(),
api_client=DefaultApiClient(),
api_endpoint="https://api.amazonalexa.com"),
authentication_configuration=AuthenticationConfiguration(
client_id=client_id,
client_secret=client_secret))
weather_event = Event(
name="AMAZON.WeatherAlert.Activated",
payload={
"weatherAlert": {
"alertType": "SNOW_STORM",
"source": "localizedattribute:source"
}
}
)
create_event = CreateProactiveEventRequest(
timestamp=datetime.utcnow(),
reference_id="1234",
expiry_time=datetime.utcnow() + timedelta(hours=1),
event=weather_event,
localized_attributes=[{"locale": "en-US", "source": "Foo"}],
relevant_audience=RelevantAudience(
object_type=RelevantAudienceType.Multicast,
payload={}
)
)
proactive_client.create_proactive_event(
create_proactive_event_request=create_event,
stage=SkillStage.DEVELOPMENT)
SkillMessagingServiceClient¶
指定されたユーザーのスキルにメッセージリクエストを送信するには スキルメッセージAPI を使います。
インターフェース¶
class ask_sdk_model.services.skill_messaging.SkillMessagingServiceClient:
def __init__(self, api_configuration, authentication_configuration):
# type: (ApiConfiguration, AuthenticationConfiguration) -> None
def send_skill_message(self, user_id, send_skill_messaging_request):
# type: (str, SendSkillMessagingRequest) -> Union[Error]
class ask_sdk_model.services.skill_messaging.SkillMessagingRequest:
def __init__(self, data=None, expires_after_seconds=None):
# type: (Optional[object], Optional[int]) -> None
モデルの詳細については、 こちら を参照してください。
サンプルコード¶
以下に、スキルメッセージをスキルに送信する例を示します。スキルは、``Messaging.MessageReceived``型のリクエストを処理できるハンドラーにより、リマインダーを処理します。
from ask_sdk_core.api_client import DefaultApiClient
from ask_sdk_model.services import (
ApiConfiguration, AuthenticationConfiguration)
from ask_sdk_core.serialize import DefaultSerializer
from ask_sdk_model.services.skill_messaging import (
SkillMessagingServiceClient, SendSkillMessagingRequest)
def send_skill_messaging():
reminder_id = "XXXX"
client_id = "XXXX"
client_secret = "XXXX"
user_id = "XXXX"
skill_messaging_client = SkillMessagingServiceClient(
api_configuration=ApiConfiguration(
serializer=DefaultSerializer(),
api_client=DefaultApiClient(),
api_endpoint="https://api.amazonalexa.com"),
authentication_configuration=AuthenticationConfiguration(
client_id=client_id,
client_secret=client_secret)
)
message = SendSkillMessagingRequest(
data={"reminder_id": reminder_id})
skill_messaging_client.send_skill_message(
user_id=user_id, send_skill_messaging_request=message)
LwaClient¶
``LwaClient``は、他のセッション外サービスクライアントが、サービスに固有の必要なスコープを設定してAlexaからアクセストークンを取得するために使用します。ただし、特定のスコープを指定すれば、スキル開発者がアクセストークンを取得するためにネイティブに使用することもできます。
インターフェース¶
class ask_sdk_model.services.lwa.LwaClient:
def __init__(self, api_configuration, authentication_configuration):
# type: (ApiConfiguration, AuthenticationConfiguration) -> None
def get_access_token_for_scope(self, scope):
# type: (str) -> str
モデルの詳細については、 こちら を参照してください。
サンプルコード¶
以下に、``alexa:abc``スコープのアクセストークンを取得する方法の例を示します。
from ask_sdk_core.api_client import DefaultApiClient
from ask_sdk_model.services import (
ApiConfiguration, AuthenticationConfiguration)
from ask_sdk_core.serialize import DefaultSerializer
from ask_sdk_model.services.lwa import LwaClient
def out_of_session_reminder_update():
client_id = "XXXX"
client_secret = "XXXX"
scope = "alexa:abc"
api_configuration = ApiConfiguration(
serializer=DefaultSerializer(),
api_client=DefaultApiClient(),
api_endpoint="https://api.amazonalexa.com")
lwa_client = LwaClient(
api_configuration=api_configuration,
authentication_configuration=AuthenticationConfiguration(
client_id=client_id,
client_secret=client_secret))
access_token = lwa_client.get_access_token_for_scope(scope=scope)
スキルビルダー¶
SDKには、Skill
インスタンスを作成する SkillBuilder
が含まれています。構造は次のとおりです。
class SkillBuilder(object):
def __init__(self):
# Initialize empty collections for request components,
# exception handlers, interceptors.
def add_request_handler(self, handler):
# type: (AbstractRequestHandler) -> None
....
def add_exception_handler(self, handler):
# type: (AbstractExceptionHandler) -> None
....
def add_global_request_interceptor(self, interceptor):
# type: (AbstractRequestInterceptor) -> None
....
def add_global_response_interceptor(self, interceptor):
# type: (AbstractResponseInterceptor) -> None
....
@property
def skill_configuration(self):
# type: () -> SkillConfiguration
# Build configuration object using the registered components
....
def create(self):
# type: () -> Skill
# Create the skill using the skill configuration
....
def lambda_handler(self):
# type: () -> LambdaHandler
# Create a lambda handler function that can be tagged to
# AWS Lambda handler.
# Processes the alexa request before invoking the skill,
# processes the alexa response before providing to the service
....
def request_handler(self, can_handle_func):
# type: (Callable[[HandlerInput], bool]) -> None
# Request Handler decorator
def exception_handler(self, can_handle_func):
# type: (Callable[[HandlerInput, Exception], bool]) -> None
# Exception Handler decorator
def global_request_interceptor(self):
# type: () -> None
# Global Request Interceptor decorator
def global_response_interceptor(self):
# type: () -> None
# Global Response Interceptor decorator
SkillBuilder
クラスには2つの拡張機能 CustomSkillBuilder
および StandardSkillBuilder
があります。
CustomSkillBuilderクラス¶
CustomSkillBuilder
は、ask-sdk-core
と ask-sdk
パッケージの両方で使用できます。上の共通のヘルパー関数に加えて、CustomSkillBuilder
にも AbstractPersistentAdapter
と ask_sdk_model.services.ApiClient
クラスのカスタム実装を登録できる関数があります。
class CustomSkillBuilder(SkillBuilder):
def __init__(self, persistence_adapter=None, api_client=None):
# type: (AbstractPersistenceAdapter, ApiClient) -> None
....
@property
def skill_configuration(self):
# Create skill configuration from skill builder along with
# registered persistence adapter and api client
....
StandardSkillBuilderクラス¶
StandardSkillBuilder
は ask-sdk
パッケージでのみ使用できます。これはpersistence_adapterを ask_sdk_dynamo.adapter.DynamoDbPersistenceAdapter
として、api_clientを ask_sdk_core.api_client.DefaultApiClient
として使用し、持続性機能およびサービスクライアント機能を提供する CustomSKillBuilder
のラッパーです。また、Dynamo DBテーブルオプションを設定するオプションのパラメーターも提供します。
class StandardSkillBuilder(SkillBuilder):
def __init__(self,
table_name=None, auto_create_table=None,
partition_keygen=None, dynamodb_client=None):
# type: (str, bool, Callable[[RequestEnvelope], str], ServiceResource) -> None)
....
@property
def skill_configuration(self):
# Create skill configuration from skill builder along with
# default api client and dynamodb persistence adapter with
# the passed in table configuration options.
....
カスタムスキルをウェブサービスとしてホスティングする¶
ウェブサービスを実装してAlexa用のカスタムスキルを開発できます。このウェブサービスは、クラウド内のAlexaサービスからリクエストを受け付けて応答を返します。
Alexaから送信されたリクエストを処理するには、特定の要件を満たす必要があり、また、Alexa Skills Kitインターフェース規格に準拠する必要があります。詳細については、Alexa Skills Kit技術資料の「カスタムスキルをウェブサービスとしてホスティングする<https://developer.amazon.com/ja/docs/custom-skills/host-a-custom-skill-as-a-web-service.html>」__ を参照してください。
注釈
現在、これらの機能はベータ版です。ソースコードは、 GitHubの Ask Python Sdk リポジトリで確認できます。正式版のリリース時に、インターフェースが変更される可能性が あります。
ASD SDKウェブサービスサポート¶
Alexa Skills Kit SDK(ASK SDK)for Pythonでは、リクエストとタイムスタンプの検証用のボイラープレートコードが「ask-sdk-webservice-support <https://pypi.org/project/ask-sdk-webservice-support/>」__パッケージで提供されます。これは`Skill Builder <SKILL_BUILDERS.html>`__ オブジェクトと統合されます。このパッケージでは検証コンポーネントと、スキルを呼び出すためのベースハンドラーのみが提供され、ウェブアプリケーション開発の基本フレームワークからは独立しています。
インストール¶
「pip」を使用して``ask-sdk-webservice-support``パッケージをインストールします。
重要
このパッケージは、リクエスト検証用の`cryptography <https://cryptography.io/en/latest/>`__に依存しています。また、「cryptography」パッケージは、オペレーティングシステムに応じて追加条件がある場合があります。詳細については、`cryptography」ドキュメントの「インストールガイド<https://cryptography.io/en/latest/installation/>`__ を参照してください。
ウェブサービスジェネリックハンドラー¶
``WebserviceSkillHandler``クラスでは、``SkillBuilder``オブジェクトからスキルインスタンスを登録し、``verify_request_and_dispatch``メソッドを提供します。このメソッドは、スキルハンドラーを呼び出す前に入力リクエストを検証します。
``WebserviceSkillHandler``インスタンスのboolean型パラメーター``verify_signature``および``verify_timestamp``を設定し、テスト目的として、リクエストまたはタイムスタンプの検証を有効または無効にできます。また、スキルを呼び出す前に入力リクエストに適用する必要がある、追加のカスタムベリファイア(verifier)も提供されます。
``verify_request_and_dispatch``メソッドにより、ウェブサービスから``http_headers``と``http_body``が取り出され、スキルの呼び出しに成功すると、文字列形式で``response``が返されます。入力と出力をウェブサービス固有のリクエスト/応答の構造に変換する必要があります。
使用形態¶
from ask_sdk_core.skill_builder import SkillBuilder
from ask_sdk_webservice_support.webservice_handler import WebserviceSkillHandler
skill_builder = SkillBuilder()
# リクエストハンドラー、例外ハンドラーなどを実装します。
# ハンドラーをスキルビルダーインスタンスに登録します。
webservice_handler = WebserviceSkillHandler(
skill=skill_builder.create())
# HTTPリクエストヘッダーと本文をそれぞれネイティブ形式の
# dictとstrに変換し、dispatchメソッドを呼び出します。
response = webservice_handler.verify_request_and_dispatch(
headers, body)
# 応答strをウェブサービスの形式に変換して返します。
フレームワーク固有のアダプター¶
Pythonには、FlaskとDjangoという2つのウェブサービスフレームワークがあり、ウェブサービスを開発するときによく活用されています。 ASK SDKでは、フレームワーク別に``ask-sdk-webservice-support``パッケージの拡張機能が提供され、FlaskとDjangoの両方に対応しています。 これにより、リクエスト/応答の変換処理が内部で行われます。さらに、既に開発しているSDKスキルを簡単に統合して、ウェブサービスで動作させることができます。
flask-ask-sdk拡張パッケージ¶
``flask-ask-sdk``パッケージは、Flaskの拡張機能を提供します。これにより、カスタムスキルと一緒に``Flask``アプリケーションを登録できます。helperメソッドも提供され、スキルの呼び出しを、URLエンドポイントとしてFlaskアプリケーションに登録できます。
``flask-ask-sdk``パッケージは、`Flask拡張機能の構造<http://flask.pocoo.org/docs/1.0/extensiondev/#flask-extension-development>`__ に従っています。 「SkillAdapter」クラスのコンストラクターで、以下を取り出します。
-「スキル」インスタンス -「skill id」(拡張ディレクトリにスキルインスタンスを登録する) -「Flask」アプリケーション(オプション。アプリケーションに拡張機能を登録する)
また、``init_app``メソッドも提供され、後でFlaskアプリインスタンスに渡され、拡張機能のインスタンスを作成し構成します。
リクエストとタイムスタンプの検証はデフォルトで有効になっています。アプリコンフィギュレーション``VERIFY_SIGNATURE_APP_CONFIG``と``VERIFY_TIMESTAMP_APP_CONFIG``を使用して、それぞれのboolean値を設定し、検証の有効/無効を設定できます。
SkillAdapterの``dispatch_request``メソッドを使用して、スキルをエンドポイントURLルールとして登録できます。リクエスト/応答の変換処理、リクエストとタイムスタンプの検証、スキルの呼び出しを処理します。
インストール¶
「pip」を使用して``flask-ask-sdk``パッケージをインストールできます。
重要
また、cryptography パッケージが、リクエスト検証の依存関係として含まれています。また、「cryptography」パッケージは、オペレーティングシステムに応じて追加条件がある場合があります。詳細については、「cryptography」ドキュメントの「インストールガイド<https://cryptography.io/en/latest/installation/>」__を参照してください。
使用形態¶
from flask import Flask
from ask_sdk_core.skill_builder import SkillBuilder
from flask_ask_sdk.skill_adapter import SkillAdapter
app = Flask(__name__)
skill_builder = SkillBuilder()
# インテントハンドラーをskill_builderオブジェクトに登録します。
skill_adapter = SkillAdapter(
skill=skill_builder.create(), skill_id=<SKILL_ID>, app=app)
@app.route("/"):
def invoke_skill:
return skill_adapter.dispatch_request()
注釈
「ASK_SDK_SKILL_ADAPTER」キーを使用して、拡張機能のインスタンスが アプリケーション拡張機能マッピングに追加されます。同じアプリケーション内の 異なるルートに複数のスキルが構成されるので、 複数の拡張機能インスタンスを介して、それぞれの拡張機能が スキルIDマッピングとして、アプリ拡張機能の「ASK_SDK_SKILL_ADAPTER」ディクショナリに 追加されます。
django-ask-sdk拡張パッケージ¶
``django-ask-sdk``拡張パッケージにより、Djangoの拡張機能が提供され、エンドポイントとして、カスタムスキルをDjangoアプリケーションに登録できます。
拡張機能では``SkillAdapter``ビュークラスが提供されます。カスタムスキルインスタンスでビュークラスをインスタンス化し、ASK SDK Skill Builderオブジェクトでビルドし、Djangoアプリの``urls.py``ファイルに登録します。これにより、対応するエンドポイントでスキルが呼び出されます。
リクエストとタイムスタンプの検証はデフォルトで有効になっています。コンストラクター引数``verify_request``と``verify_timestamp``を使用して、それぞれのboolean値を設定することで、各検証を有効または無効にできます。
インストール¶
「pip」を使用して``django-ask-sdk``拡張機能をインストールできます。
重要
また、cryptography パッケージが、リクエスト検証の依存関係として含まれています。また、「cryptography」パッケージは、オペレーティングシステムに応じて追加条件が ある場合があります。詳細については、「cryptography」ドキュメントの`インストールガイド<https://cryptography.io/en/latest/installation/>`__ を参照してください。
注釈
Django 2.0はPython 3のみをサポートしているため、これに依存する ``django-ask-sdk``パッケージは、Python3.0以降と互換性があります。
スキルのアトリビュート¶
スキルのアトリビュートを使ったスキルデータの保存と取得の方法を説明します。
Alexaサービスクライアント¶
サービスクライアントを使ってスキルからAlexa APIにアクセスする方法を説明します。
Alexaセッション外サービスクライアント¶
スキルのセッションコンテキスト外で機能するAlexa APIを呼び出す方法(通常のスキルフローの外でのスキルユーザーへの通知の送信など)を説明します。
フィードバック¶
コミュニティ¶
- Amazon開発者フォーラム: ぜひ会話に参加してください。
- Hackster.io - 他の人がAlexaでどんなものをビルドしているか見てみましょう。