Alexa-hostedスキルのデータ永続性にDynamoDBを使用する



Alexa-hostedスキルのデータ永続性にDynamoDBを使用する

Alexa-hostedスキルを作成すると、AlexaはコードとリソースをAWSに保存します。Alexa-hostedスキルの詳細については、Alexa-hostedスキルを使用してスキルをエンドツーエンドで作成するを参照してください。

Alexa-hostedスキルを作成すると、データを保持するためのAmazon DynamoDBテーブルにアクセスできます。Amazon DynamoDBの使用は無料利用枠内に制限されています:ストレージ25 GB、および1 GBのデータ転送送信(月あたり)。Alexa-hostedスキルは、表形式データにAWSでサポートされている暗号方式を使用します。

ASK SDK for Node.jsASK SDK for PythonにはそれぞれDynamoDBにデータを永続化するためのアダプターが含まれています。

Node.jsでデータを永続化する

  1. Node.jsでデータの永続性を使用するには、まずpackage.jsonファイルに次の依存関係を追加します。

    "ask-sdk": "^2.6.0"
    "aws-sdk": "2.637.0"
    "ask-sdk-dynamodb-persistence-adapter": "^2.9.0"
    
  2. 次に、index.jsファイルに以下のコードを追加します。ask persistence adapterの読み込み

    const AWS = require('aws-sdk');
    const ddbAdapter = require('ask-sdk-dynamodb-persistence-adapter');
    
  3. SessionEndedRequestHandlerリクエストハンドラーをSkillBuildersハンドラーに追加します。他のリクエストハンドラーは上書きしないでください。

    exports.handler = Alexa.SkillBuilders.custom()
        .addRequestHandlers(
            LaunchRequestHandler,
            //その他のリクエストハンドラー
            SessionEndedRequestHandler
        )
        .addErrorHandlers(ErrorHandler)
        .withPersistenceAdapter(
            new ddbAdapter.DynamoDbPersistenceAdapter({
                tableName: process.env.DYNAMODB_PERSISTENCE_TABLE_NAME,
                createTable: false,
                dynamoDBClient: new AWS.DynamoDB({apiVersion: 'latest', region: process.env.DYNAMODB_PERSISTENCE_REGION})
            })
        )
        .lambda();
    
  4. アトリビュートを保存するハンドラーの追加

    async handle(handlerInput)
    {
        const attributesManager = handlerInput.attributesManager;
        let attributes = {"counter":10};
    
        attributesManager.setPersistentAttributes(attributes);
        await attributesManager.savePersistentAttributes();
    
        let speechOutput = `こんにちは、ハローワールド! 保存したカウンターは${attributes.counter}です`;
    
        return handlerInput.responseBuilder
            .speak(speechOutput)
            .getResponse();
    }
    
  5. アトリビュートを取得するハンドラーを追加

    async handle(handlerInput){
    
        const attributesManager = handlerInput.attributesManager;
        const attributes = await attributesManager.getPersistentAttributes() || {};
        console.log('アトリビュート:', attributes);
    
        const counter = attributes.hasOwnProperty('counter')? attributes.counter : 0;
    
        let speechOutput = `こんにちは、ハローワールド! カウンターは${counter}です`;
    
        return handlerInput.responseBuilder
            .speak(speechOutput)
            .getResponse();
    }
    

Pythonでデータを永続化する

  1. Pythonでデータの永続性を使用するには、まずrequirements.txtファイルに次の依存関係を追加します。

    boto3==1.9.216
    ask-sdk-core==1.11.0
    ask-sdk-dynamodb-persistence-adapter==1.15.0
    
  2. 次に、lambda_function.pyファイルにコードを追加します。ask persistence adapterの読み込み

    import os
    import boto3
    
    from ask_sdk_core.skill_builder import CustomSkillBuilder
    from ask_sdk_dynamodb.adapter import DynamoDbAdapter
    
  3. 永続性アダプターを初期化します。

    ddb_region = os.environ.get('DYNAMODB_PERSISTENCE_REGION')
    ddb_table_name = os.environ.get('DYNAMODB_PERSISTENCE_TABLE_NAME')
    
    ddb_resource = boto3.resource('dynamodb', region_name=ddb_region)
    dynamodb_adapter = DynamoDbAdapter(table_name=ddb_table_name, create_table=False, dynamodb_resource=ddb_resource)
    
  4. SessionEndedRequestHandlerリクエストハンドラーをSkillBuildersハンドラーに追加します。他のリクエストハンドラーは上書きしないでください。

    sb = CustomSkillBuilder(persistence_adapter = dynamodb_adapter)
    
    sb.add_request_handler(LaunchRequestHandler())
    sb.add_request_handler(CancelOrStopIntentHandler())
    sb.add_request_handler(SessionEndedRequestHandler())
    #
    #その他のリクエストハンドラー
    #
    sb.add_exception_handler(CatchAllExceptionHandler())
    
    lambda_handler = sb.lambda_handler()
    
  5. アトリビュートを保存するハンドラーの追加

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
        attr = handler_input.attributes_manager.persistent_attributes
        if not attr:
            attr['counter'] = 0
            attr['state'] = 'ENDED'
    
        handler_input.attributes_manager.session_attributes = attr
    
        handler_input.attributes_manager.save_persistent_attributes()
        speak_output = ("おかえりなさい。保存されたカウンタは{}です.こんにちは、またはヘルプと言ってください".format(attr["counter"]))
        reprompt = “こんにちは、またはヘルプと言ってください。”
        return (
            handler_input.response_builder
                .speak(speak_output)
                .ask(reprompt)
                .response
        )
    
  6. アトリビュートを取得するハンドラーを追加

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
        session_attr = handler_input.attributes_manager.session_attributes
        session_attr['state'] = "STARTED"
        session_attr["counter"] += 1
        handler_input.attributes_manager.persistent_attributes = session_attr
        handler_input.attributes_manager.save_persistent_attributes()
    
        speak_output = ("ハローワールド! 保存されたカウンタは{}です。".format(session_attr["counter"]))
        return (
            handler_input.response_builder
                .speak(speak_output)
                # .ask('ユーザーが応答できるようセッションを開いたままにする場合は再プロンプトを追加してください')
                .response
        )
    
  7. アトリビュートを削除するハンドラーを追加(任意)

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
        session_attr = handler_input.attributes_manager.session_attributes
        session_attr['state'] = "ENDED"
    
        speak_output = ("さようなら。カウンタは{}です".format(session_attr[“counter”]))
    
        handler_input.attributes_manager.delete_persistent_attributes()
        return (
            handler_input.response_builder
                .speak(speak_output)
                .response
        )