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ドキュメントで確認してください。​

次のステップ

プロジェクトにSDKを追加したので、スキルの開発を開始できます。次の初めてのスキル開発セクションに進み、基本のスキル開発の手順をご覧ください。

初めてのスキル開発

セットアップガイドでは、ASK SDK for Pythonを特定のディレクトリまたはvirtualenvを使用して仮想環境にインストールする方法を説明しました。このガイドでは、ASK SDK for Pythonを使ったスキル開発の手順を説明します。

前提条件

ASK SDK for Pythonのインストールに加えて、以下のものが必要です。

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では、次のいずれかの方法でリクエストハンドラーを作成することができます。

  1. ask_sdk_core.dispatch_componentsパッケージの下にAbstractRequestHandlerクラスを実装します。このクラスにはcan_handleおよびhandleメソッドの実装が含まれている必要があります。詳細についてはクラスを使用した実装セクションで説明しています。
  2. インスタンス化されたスキルビルダーオブジェクトの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-supportflask-ask-sdkdjango-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-supportflask-ask-sdkdjango-ask-sdk)を使用してください。このコンフィギュレーションについて詳しくは、こちらを参照してください。

Lambdaハンドラーは、AWS Lambda関数のエントリポイントとなります。以下は、スキルが受信するすべてのリクエストのルーティングを行うLambdaハンドラー関数のコードサンプルです。Lambdaハンドラー関数は、作成したリクエストハンドラーを使用して設定されたSDKのスキルインスタンスを作成します。

以下のコードを``hello_world.py``ファイルの、前述のハンドラーの後に入力するか貼り付けます。

handler = sb.lambda_handler()

デコレーターを使用する場合、リクエストハンドラーと例外ハンドラーはコードの最初にインスタンス化されたスキルビルダーオブジェクトによって自動的に識別されます。

ソースコード全文

hello_world.pyのソースコード全文はこちらにあります。

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ドキュメントを参照してください。

SDKを特定のフォルダにセットアップする場合、依存関係は その特定のフォルダにインストールされます。セットアップガイドの手順に従った場合、 そのフォルダはskill_envです。 hello_world.pyファイルをskill_envフォルダにコピーし、 (そのフォルダ自体ではなく)そのフォルダのコンテンツの.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のスキルを設定できます。

  • 以下の手順に従って新しいスキルを作成します。

    1. Alexa Skills Kit開発者コンソールにログインします。
    2. 右上のスキルの作成ボタンをクリックします。
    3. スキル名として「HelloWorld」と入力します。
    4. カスタムスキルを選択してからスキルを作成をクリックします。
  • 次に、スキルの対話モデルを定義します。サイドバーの呼び出し名を選択し、スキルの呼び出し名に「ごあいさつ」を入力します。

  • 次に、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": []
    }
  }
}
  • 対話モデルの編集が完了したら、モデルを保存してビルドします。
  • 次に、スキルのエンドポイントを設定します。これを行うには次の手順に従います。
    1. スキルの中でエンドポイントタブをクリックし、AWS LambdaのARNを選択して、作成したスキルのスキルIDをコピーします。
    2. 新しいタブでAWS開発者コンソールを開きます。
    3. 前の手順で作成したAWS Lambda関数に移動します。
    4. Designerメニューから、Alexa Skills Kitトリガーメニューを追加し、スクロールダウンしてスキルID検証コンフィギュレーションにスキルIDを貼り付けます。完了したら追加、保存の順にクリックしてAWS Lambda関数を更新します。
    5. ページ右上隅のAWS Lambda関数ARNをコピーします。ARNは一意のリソース番号です。Alexaサービスはこれを使用して、スキルの呼び出し中に必要になるAWS Lambda関数を識別します。
    6. Alexa Skills Kit開発者コンソールに移動して、HelloWorldスキルをクリックします。
    7. スキルの中でエンドポイントタブをクリックし、AWS LambdaのARNを選択して、デフォルトの地域にARNを貼り付けます。
    8. 残りの設定は、デフォルト値のままでかまいません。エンドポイントを保存をクリックします。
    9. 呼び出し名タブをクリックして、モデルを保存およびビルドします。
  • この時点で、スキルをテストできるようになります。上部メニューでテストをクリックします。このスキルでは、テストは有効になっていますオプションが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をインストールする方法を説明します。

初めてのスキル開発

Hello Worldサンプルをビルドする手順を詳しく説明します。

サンプルスキル

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_handlecan_handle は、SDKによって呼び出され、指定されたハンドラーが受け取ったリクエストを処理できるかどうかを判断します。この関数はハンドラー入力オブジェクトを受け付け、ブール型を返すように想定されています。メソッドがTrueを返せば、ハンドラーによってリクエストが正常に処理されたと考えられます。Falseを返す場合、ハンドラーが入力リクエストを処理できず、したがって実行されず完了もしなかったと考えられます。HandlerInput オブジェクトにはさまざまなアトリビュートがあるため、リクエストを正常に処理できるかどうかをSDKが判別するための任意の条件を作成できます。
  • handlehandle メソッドは、リクエストハンドラーを呼び出すときに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 パラメーターを取ります。これは AbstractRequestHandlercan_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が以下の順序でリクエストハンドラーを呼び出します。

  1. FooHandler クラス / foo_handler 関数
  2. BarHandler クラス / bar_handler 関数
  3. BazHandle rクラス / baz_handler 関数

SDKは、指定されたリクエストを処理できる最初のハンドラーを常に選択します。この例では、FooHandler クラス / foo_handler 関数および BarHandler``クラス ``bar_handler 関数のどちらも指定のリクエストを処理できる場合、FooHandler クラス/foo_handler 関数が常に呼び出されます。リクエストハンドラーのデザインや登録を行う際には、この点を考慮に入れてください。

例外ハンドラー

例外ハンドラーはリクエストハンドラーに似ていますが、リクエストではなく1つまたは複数のタイプの例外を処理します。リクエストの処理中に未処理の例外がスローされると、SDKが例外ハンドラーを呼び出します。

ハンドラーはハンドラー入力オブジェクトに加えて、入力リクエストの処理中に発生した例外にもアクセスできます。そのため、ハンドラーが該当する例外の処理方法を判別しやすくなります。

リクエストハンドラーと同様に、カスタムリクエストインターセプターも2通りの方法で実装できます。

  • AbstractExceptionHandler クラスを実装する。
  • スキルビルダーexception_handler デコレーターを使用してカスタム例外ハンドル関数をデコレートする。
インターフェース
AbstractExceptionHandlerクラス

AbstractExceptionHandler クラスの使用を予定している場合は、次のメソッドを実装する必要があります。

  • can_handlecan_handle メソッドはSDKによって呼び出され、指定されたハンドラーが例外を処理できるかどうかを判断します。ハンドラーが例外を処理できる場合はTrue、できない場合はFalseを返します。catch-allハンドラーを作成する場合は常に True を返します。
  • handlehandle メソッドは例外ハンドラーを呼び出すときに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 パラメーターを取ります。これは AbstractExceptionHandlercan_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クラス

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デコレーター

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が以下の順序ですべてのリクエストインターセプターを実行します。

  1. FooInterceptor クラス / foo_interceptor 関数
  2. BarInterceptor クラス / bar_interceptor 関数
  3. BazInterceptor クラス / baz_interceptor 関数
応答インターセプター

グローバル応答インターセプターは、サポートされるリクエストハンドラーの処理後に、ハンドラー入力オブジェクト、つまり応答を受け付けて処理します。リクエストインターセプターと同様に、カスタム応答インターセプターも二通りの方法で実装できます。

  • AbstractResponseInterceptor クラスを実装する。
  • スキルビルダーglobal_response_interceptor デコレーターを使用してカスタム処理関数をデコレートする。
インターフェース
AbstractResponseInterceptorクラス

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デコレーター

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 オブジェクトを返します。 スキルコンポーネントに渡される標準引数です。

注釈

  • 異なるディレクティブを使用して追加するには、directive モデル定義。
  • カードを使用して設定するには、Card モデル定義。

以下は、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.ApiConfigurationask_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-coreask-sdk パッケージの両方で使用できます。上の共通のヘルパー関数に加えて、CustomSkillBuilder にも AbstractPersistentAdapterask_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クラス

StandardSkillBuilderask-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以降と互換性があります。

使用形態

``SkillBuilder``インスタンスを使用してスキルを開発する場合は、 ``example.urls.py``で以下を使用すると、 ``example``というDjangoアプリで、エンドポイントとしてスキルを登録できます。

import skill
from django_ask_sdk.skill_response import SkillAdapter

view = SkillAdapter.as_view(skill=skill.sb.create())

urlpatterns = [
    path("/myskill", view, name='index')
]

リクエスト処理

リクエストハンドラー、例外ハンドラー、リクエストと応答のインターセプターをビルドする方法を説明します。

応答のビルド

ResponseBuilderを使って、テキスト、カード、オーディオといった複数の要素を使用して1つの応答を構成する方法を説明します。

スキルのアトリビュート

スキルのアトリビュートを使ったスキルデータの保存と取得の方法を説明します。

スキルビルダー

スキルインスタンスの構成と作成の方法を説明します。

Alexaサービスクライアント

サービスクライアントを使ってスキルからAlexa APIにアクセスする方法を説明します。

Alexaセッション外サービスクライアント

スキルのセッションコンテキスト外で機能するAlexa APIを呼び出す方法(通常のスキルフローの外でのスキルユーザーへの通知の送信など)を説明します。

スキルをウェブサービスとしてホスティングする

スキルをウェブサービスとしてホスティングする方法を説明します。

フィードバック

  • バグ、機能のリクエスト、ご質問、簡単なフィードバックがあればぜひお聞かせください。新しく問題を提起する前に既存の問題を検索してください。また、問題やプルリクエストはテンプレートに従って作成してください。プルリクエストの場合は投稿のガイドラインに従ってください。
  • Alexaの機能に関するリクエストや投票は、こちらをご覧ください。

そのほかのリソース

コミュニティ

チュートリアルとガイド

  • 音声デザインガイド ー 会話型スキルや音声ユーザーインターフェースのデザインを学ぶことができる優れたリソースです。