ASK SDKのセットアップ

このガイドでは、プロジェクトでASK SDK v2 for Node.jsを使用する方法を説明します。

前提条件

  • NPMプロジェクト。
  • 適切なNode.js開発環境。ASK SDK v2 for Node.jsには、Node 4.3.2以上が必要です。

ASK SDKをプロジェクトに追加する

プロジェクトでASK SDK v2 for Node.jsを使うには、NPMモジュールとしてSDKをインストールする必要があります。標準SDK配布パッケージ、SDKのコアモジュールといずれかのアドオンパッケージを選択してインストールします。すぐにセットアップして実行するには、標準SDK配布パッケージを選ぶのがもっとも簡単です。標準SDK配布パッケージには、SDKのコアモジュール、モデルパッケージ、DynamoDBにスキルのアトリビュートを格納できるようにするAmazon DynamoDB永続アダプターが含まれます。

標準ASK SDK配布パッケージをインストールする

NPMプロジェクトから、以下のコマンドを実行して標準ASK SDK v2 for Node.js配布パッケージをインストールします。

npm install --save ask-sdk

コアSDKモジュールのみをインストールする

ask-sdkモジュールすべてを使う必要がない場合、コアモジュールのみをインストールし、後からアドオンパッケージを個別に追加できます。NPMプロジェクトから、以下のコマンドを実行してコアASK SDK v2 for Node.js配布パッケージをインストールします。

モデル(ask-sdk-coreのpeer依存関係として必要)

npm install --save ask-sdk-model

コアSDK

npm install --save ask-sdk-core

アドオンのASK SDKモジュールのインストール

アドオンパッケージをインストールすると、PersistenceAdapterなどのSDK機能が実装されます。スキルの機能を拡張するには、必要に応じてモジュールを選んでコアSDKモジュールに追加インストールできます。

Amazon DynamoDB永続アダプター

npm install --save ask-sdk-dynamodb-persistence-adapter

Amazon S3永続アダプター

npm install --save ask-sdk-s3-persistence-adapter

次のステップ

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

初めてのスキル開発

このガイドでは、ASK SDK v2 for Node.jsを使ったスキル開発の手順を説明します。

前提条件

  • Amazon開発者アカウント。Alexaスキルの作成と設定に必要です。
  • アマゾンウェブサービス(AWS)アカウント。このガイドで、AWS Lambdaでスキルをホスティングする手順を確認できます。
  • インストールされたSDKに対応したNPM プロジェクト。標準ASK SDKモジュールのインストールについては ASK SDK v2 for Node.jsのセットアップを参照してください。このサンプルスキルには、標準SDK配布パッケージが必要です。依存関係をカスタマイズしている場合は、コアSDKのサポートモジュールをインストールする必要があります。

スキルコードの記述

以下のセクションでは、ハンドラーごとのスキルコードの記述について説明します。

注釈

ASK SDK v2 for Node.jsには、TypeScriptプロジェクトで使用するためのTypeScript定義ファイルがバンドルされています。このガイドでは、ネイティブのJavaScriptを使用したAlexaスキルの作成について説明し、それに対応したTypeScriptコードのスニペットもリファレンスとして提供します。TypeScriptプロジェクトの開始に関する情報については、こちらのリンクを参照してください。

依存関係の読み込み

index.js(以下のセクションでTypeScript.Sameを使用する場合は、index.ts)というファイルを作成し、以下のコードを貼り付けます。

const Alexa = require('ask-sdk-core');
import {
  ErrorHandler,
  HandlerInput,
  RequestHandler,
  SkillBuilders,
} from 'ask-sdk-core';
import {
  Response,
  SessionEndedRequest,
} from 'ask-sdk-model';

リクエストハンドラーの追加

まず、スキルで受信するさまざまなタイプのリクエストを処理するのに必要なリクエストハンドラーを作成します。.

LaunchRequestハンドラー

以下は、スキルがLaunchRequestを受信した時に呼び出されるハンドラーを設定するコードのサンプルです。特定のインテントなしでスキルが呼び出された場合、LaunchRequestイベントが発生します。

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    const speechText = 'Welcome to the Alexa Skills Kit, you can say hello!';

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  }
};
const LaunchRequestHandler : RequestHandler = {
  canHandle(handlerInput : HandlerInput) : boolean {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput : HandlerInput) : Response {
    const speechText = 'Welcome to the Alexa Skills Kit, you can say hello!';

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  },
};

受信したリクエストがLaunchRequestの場合、canHandle関数はtrueを返します。handle関数は、基本的なあいさつの応答を生成して返します。

HelloWorldIntentハンドラー

以下は、スキルがHelloWorldIntentを受信した時に呼び出されるハンドラーを設定するコードのサンプルです。

以下のコードをindex.jsファイルの、前述のハンドラーの後に貼り付けます。

const HelloWorldIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'HelloWorldIntent';
  },
  handle(handlerInput) {
    const speechText = 'Hello World!';

    return handlerInput.responseBuilder
      .speak(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  }
};
const HelloWorldIntentHandler : RequestHandler = {
  canHandle(handlerInput : HandlerInput) : boolean {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'HelloWorldIntent';
  },
  handle(handlerInput : HandlerInput) : Response {
    const speechText = 'Hello World!';

    return handlerInput.responseBuilder
      .speak(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  },
};

canHandle関数は受信するリクエストがIntentRequestかどうかを検出し、インテント名がHelloWorldIntentの場合にtrueを返します。handle関数は、基本的な「こんにちは」という応答を生成して返します。

HelpIntentハンドラー

以下は、スキルがビルトインインテントAMAZON.HelpIntentを受信した時に呼び出されるハンドラーを設定するコードのサンプルです。

以下のコードをindex.jsファイルの、前述のハンドラーの後に貼り付けます。

const HelpIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput) {
    const speechText = 'You can say hello to me!';

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  }
};
const HelpIntentHandler : RequestHandler = {
  canHandle(handlerInput : HandlerInput) : boolean {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
  },
  handle(handlerInput : HandlerInput) : Response {
    const speechText = 'You can say hello to me!';

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  },
};

さきほどのハンドラー同様、このハンドラーはIntentRequestを想定されるインテント名と照合します。基本のヘルプ手順が返されます。

CancelAndStopIntentハンドラー

CancelAndStopIntentハンドラーもビルトインインテントによって呼び出されるため、HelpIntentハンドラーに似ています。以下は、1つのハンドラーを使ってAmazon.CancelIntentAmazon.StopIntentという2つのインテントに応答している例です。

以下のコードをindex.jsファイルの、前述のハンドラーの後に貼り付けます。

const CancelAndStopIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && (handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent'
        || handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput) {
    const speechText = 'Goodbye!';

    return handlerInput.responseBuilder
      .speak(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  }
};
const CancelAndStopIntentHandler : RequestHandler = {
  canHandle(handlerInput : HandlerInput) : boolean {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && (handlerInput.requestEnvelope.request.intent.name === 'AMAZON.CancelIntent'
        || handlerInput.requestEnvelope.request.intent.name === 'AMAZON.StopIntent');
  },
  handle(handlerInput : HandlerInput) : Response {
    const speechText = 'Goodbye!';

    return handlerInput.responseBuilder
      .speak(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  },
};

両方のインテントに対する応答は同じであるため、1つのハンドラーにすることで重複するコードを減らせます。

SessionEndedRequestハンドラー

SessionEndedRequestを受信した後は音声、カード、ディレクティブを使った応答を返すことはできませんが、クリーンアップロジックを追加するにはSessionEndedRequestハンドラーが最適な場所です

以下のコードをindex.jsファイルの、前述のハンドラーの後に貼り付けます。

const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
  },
  handle(handlerInput) {
    //any cleanup logic goes here
    return handlerInput.responseBuilder.getResponse();
  }
};
const SessionEndedRequestHandler : RequestHandler = {
  canHandle(handlerInput : HandlerInput) : boolean {
    return handlerInput.requestEnvelope.request.type === 'SessionEndedRequest';
  },
  handle(handlerInput : HandlerInput) : Response {
    console.log(`Session ended with reason: ${(handlerInput.requestEnvelope.request as SessionEndedRequest).reason}`);

    return handlerInput.responseBuilder.getResponse();
  },
};

エラーハンドラーの追加

ASK SDK v2 for Node.jsはエラー処理が簡単で、スムーズなユーザーエクスペリエンスを実現するスキルが作成しやすくなります。エラーハンドラーは、未処理のリクエストやAPIサービスのタイムアウトなどのエラー処理ロジックを組み込むのに最適です。以下の例では、catch allエラーハンドラーをスキルに追加して、すべてのエラーに対してスキルが意味のあるメッセージを返すようにしています。

以下のコードをindex.jsファイルの、前述のハンドラーの後に貼り付けます。

const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, I can\'t understand the command. Please say again.')
      .reprompt('Sorry, I can\'t understand the command. Please say again.')
      .getResponse();
  },
};
const ErrorHandler : ErrorHandler = {
  canHandle(handlerInput : HandlerInput, error : Error ) : boolean {
    return true;
  },
  handle(handlerInput : HandlerInput, error : Error) : Response {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, I can\'t understand the command. Please say again.')
      .reprompt('Sorry, I can\'t understand the command. Please say again.')
      .getResponse();
  },
};

Lambdaハンドラーを作成する

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

以下のコードをindex.jsファイルの、前述のセクションの後に貼り付けます。

let skill;

exports.handler = async function (event, context) {
  console.log(`REQUEST++++${JSON.stringify(event)}`);
  if (!skill) {
    skill = Alexa.SkillBuilders.custom()
      .addRequestHandlers(
        LaunchRequestHandler,
        HelloWorldIntentHandler,
        HelpIntentHandler,
        CancelAndStopIntentHandler,
        SessionEndedRequestHandler,
      )
      .addErrorHandlers(ErrorHandler)
      .create();
  }

  const response = await skill.invoke(event, context);
  console.log(`RESPONSE++++${JSON.stringify(response)}`);

  return response;
};
let skill;

exports.handler = async (event, context) => {
  console.log(`REQUEST++++${JSON.stringify(event)}`);
  if (!skill) {
    skill = SkillBuilders.custom()
      .addRequestHandlers(
        LaunchRequestHandler,
        HelloWorldIntentHandler,
        HelpIntentHandler,
        CancelAndStopIntentHandler,
        SessionEndedRequestHandler,
      )
      .addErrorHandlers(ErrorHandler)
      .create();
  }

  const response = await skill.invoke(event, context);
  console.log(`RESPONSE++++${JSON.stringify(response)}`);

  return response;
};

関数は、SkillBuilders.customビルダーを使用してSDKインスタンスを作成します。addRequestHandlersビルダー関数はリクエストハンドラーを登録します。関数は、Lambdaハンドラー関数としてエクスポートされます。

また、ASK SDK v2 for Node.jsで提供されるlambdaビルダー関数を使って、Skillのインスタンスを呼び出して応答を返すLambdaハンドラー関数を簡単に作成することもできます。以下の例を参照してください。

exports.handler = Alexa.SkillBuilders.custom()
  .addRequestHandlers(
    LaunchRequestHandler,
    HelloWorldIntentHandler,
    HelpIntentHandler,
    CancelAndStopIntentHandler,
    SessionEndedRequestHandler)
  .addErrorHandlers(ErrorHandler)
  .lambda();
exports.handler = SkillBuilders.custom()
  .addRequestHandlers(
    LaunchRequestHandler,
    HelloWorldIntentHandler,
    HelpIntentHandler,
    CancelAndStopIntentHandler,
    SessionEndedRequestHandler,
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

スキルパッケージを作成する

スキルのコードが完成したら、スキルパッケージを作成できます。スキルをAWS Lambdaにアップロードするには、スキルファイルとnode_modulesフォルダーを含むzipファイルを作成します。すべてのプロジェクトファイルは、プロジェクトフォルダーではなく、ファイルを直接圧縮するようにしてください。

スキルをAWS Lambdaにアップロードする

スキルに適切なロールでAWS Lambda関数を作成する手順については、カスタムスキルをAWS Lambda関数としてホスティングするを参照してください。関数作成時には、一から作成オプションを選択し、ランタイムとしてNode.js 8.10を選択します。

AWS Lambda関数を作成しトリガーとして「Alexa Skills Kit」を設定したら、前のステップで作成した.zipファイルをアップロードします。ハンドラーはデフォルトのindex.handlerのままにします。最後に、AWS Lambda関数のARNをコピーします。このARNはAmazon開発者コンソールでスキルを設定する際に必要となります。

スキルの設定とテストを行う

スキルコードをAWS Lambdaにアップロードしたら、Alexaのスキルを設定できます。新しいスキルを作成するには、

  1. Alexa Skills Kit開発者コンソールに移動してログインします。
  2. 右上のスキルの作成ボタンをクリックします。
  3. スキル名として「HelloWorld」と入力します。
  4. カスタムスキルを選択してからスキルを作成をクリックします。

次に、スキルの対話モデルを定義します。サイドバーの呼び出し名を選択し、スキルの呼び出し名に「ごあいさつ」を入力します。

次に、HelloWorldIntentというインテントを対話モデルに追加します。対話モデルのインテントセクションの下の追加ボタンをクリックします。カスタムインテントを作成を選択した状態で、インテント名として「HelloWorldIntent」を入力し、インテントを作成します。インテントの詳細ページで、ユーザーがこのインテントを呼び出すのに使用できるサンプル発話をいくつか追加します。この例では、以下のサンプル発話を追加しましたが、これ以外でもかまいません。

こんにちはと言って
ハローワールドと言って
こんにちは
ハイと言って
ハイワールドと言って
ハイ
ごきげんいかが

AMAZON.CancelIntentAMAZON.HelpIntentAMAZON.StopIntentはAlexaのビルトインインテントのため、サンプル発話を追加する必要はありません。

開発者コンソールでは、スキルモデル全体をJSON形式で編集することもできます。サイドバーでJSONエディターを選択します。この例では、以下のJSONスキーマを使用できます。

{
  "interactionModel": {
    "languageModel": {
      "invocationName": "greeter",
      "intents": [
        {
          "name": "AMAZON.CancelIntent",
          "samples": []
        },
        {
          "name": "AMAZON.HelpIntent",
          "samples": []
        },
        {
          "name": "AMAZON.StopIntent",
          "samples": []
        },
        {
          "name": "HelloWorldIntent",
          "slots": [],
          "samples": [
            "ごきげんいかが",
            "ハイ",
            "ハイワールドと言って",
            "ハイと言って",
            "こんにちは",
            "ハローワールドと言って",
            "こんにちはと言って"
          ]
        }
      ],
      "types": []
    }
  }
}

対話モデルの編集が完了したら、モデルを保存してビルドします。

次に、スキルのエンドポイントを設定します。エンドポイントAWS LambdaのARNを選択し、さきほど作成した関数のARNを貼り付けます。残りの設定は、デフォルト値のままでかまいません。エンドポイントを保存をクリックします。

この時点で、スキルをテストできるようになります。上部にあるメニューでテストをクリックし、テストページに移動します。このスキルでは、テストは有効になっていますオプションがONになっていることを確認します。テストページを使って、テキストや音声でリクエストをシミュレーションできます。

呼び出し名と、さきほど設定したサンプル発話のうち1つを使います。たとえば、「アレクサ、ごあいさつを開いてこんにちはと言って」と言うと、スキルは「こんにちは」と答えるはずです。また、(スマートフォンやhttps://alexa.amazon.comで)Alexaアプリを開くと、スキル一覧が表示されます。ここから、Alexaが使えるデバイスでテストできるように、アカウントでスキルを有効にすることができます。

この時点で、さまざまなインテントや、スキルコードに対応するリクエストハンドラーを試してみてください。一通りのテストが完了したら、スキルの認定を申請してAlexaユーザーに公開するプロセスに進むことができます。

ASK SDK移行ガイド

このガイドでは、ASK SDK v2 for Node.jsとASK SDK v1アダプターを使ってASK SDK v1 for Node.js(alexa-sdk)で開発した既存のスキルをv2 SDK(ask-sdk)に移行する手順を詳しく説明します。

後方互換性

ASK SDK v1アダプターにはASK SDK v1インターフェースとの後方互換性があるため、v1のAlexaスキルを簡単にSDK v2に移行できます。v1アダプターを使うと、v1とv2の形式でコーディングされたリクエストハンドラーを共存させることができます。これにより、既存のAlexaスキルをv2形式のリクエストハンドラーで拡張でき、同時に既存のハンドラーを都合の良いタイミングでアップデートできます。新規のスキルの場合、v2の機能を活用するために最初からASK SDK v2 for Node.jsで開発するようにしてください。

前提条件

  • インストールされた標準ASK SDKモジュールとの依存関係を持つNPM プロジェクト。標準ASK SDKモジュールのインストールについてはASK SDK v2 for Node.jsのセットアップセクションを参照してください。ASK SDK v1アダプターには、標準ASK SDK v2 for Node.js配布パッケージ(ask-sdk)とのpeer依存関係があります。
  • 適切なNode.js開発環境。ASK SDK v2 for Node.jsには、Node.jsのバージョン4.3.2以上が必要です。

移行の手順

ASK SDK v1アダプターをプロジェクトに追加する

NPMプロジェクトから、以下のコマンドを実行してASK SDK v1アダプターモジュールをインストールします。

npm install --save ask-sdk-v1adapter

import文をアップデートする

ASK SDK v1 for Node.jsを使用するスキルコードを移植するには、alexa-sdkパッケージではなくask-sdk-v1adapterパッケージからインポートする必要があります。アダプターは内部のロジック解釈を処理してASK SDK v2 for Node.jsを使用する Skillインスタンスを作成します。

コードの以下の部分を変更します。

const Alexa = require('alexa-sdk');

変更後は以下のようになります。

const Alexa = require('ask-sdk-v1adapter');

スキルコードのこれ以外の部分は変更しません。

exports.handler = function(event, context, callback) {
    const alexa = Alexa.handler(event, context, callback);
    alexa.appId = APP_ID // APP_IDは、スキルを作成したAmazon開発者コンソールで割り当てられたスキルIDのことです。
    alexa.registerHandlers(...)
    alexa.execute();
};

v2リクエストハンドラーを追加する

ASK SDK v1アダプターを使用することで、v1とv2のリクエストハンドラーを共存させることができます。ただし、Alexaスキルを拡張している場合は、ASK SDK v2 for Node.jsの機能をフルに活用できるv2のリクエストハンドラーを使用することをお勧めします。

リクエストを処理できるv1ハンドラーがない場合のみ、v1のリクエストハンドラーの後にv2のリクエストハンドラーにアクセスします。そのため、v1ハンドラーをv2ハンドラーで置き換えた場合、v1ハンドラーのコードを必ず削除してください。

以下のコードサンプルでは、 AMAZON.HelpIntentを処理できるv2リクエストハンドラーを既存の hello worldサンプルスキル に追加しています。この例では、元のv1のAMAZON.HelpIntent ハンドラーがhandlers定数から削除されています。

'use strict';
const Alexa = require('ask-sdk-v1adapter');

exports.handler = function(event, context, callback) {
    const alexa = Alexa.handler(event, context);
    alexa.registerHandlers(handlers);
    alexa.registerV2Handlers(HelpIntentHandler); // v2リクエストハンドラー
    alexa.execute();を登録するための新しいAPI関数
};

const handlers = {
    'LaunchRequest': function () {
        this.emit('こんにちは、と言ってください。');
    },
    'HelloWorldIntent': function () {
        this.emit('こんにちは');
    },
    'SayHello': function () {
        this.response.speak('こんにちは!');
        this.emit(':responseReady');
    },
    'AMAZON.CancelIntent': function () {
        this.response.speak('さようなら');
        this.emit(':responseReady');
    },
    'AMAZON.StopIntent': function () {
        this.response.speak('またね');
        this.emit(':responseReady');
    }
};

// HelpIntentHandlerは次のv2リクエストハンドラーインターフェースを再書き込みします
const HelpIntentHandler = {
    canHandle : function({requestEnvelope}) {
        return requestEnvelope.request.type === 'IntentRequest'
        && requestEvelope.request.intent.name === 'AMAZON.HelpIntent';
    },
    handle : function({responseBuilder}){
        const speechOutput = 'これはご挨拶をするサンプルスキルです。';
        const reprompt = 'こんにちは、と言ってみてください。';
        return responseBuilder.speak(speechOutput)
                              .reprompt(reprompt)
                              .getResponse();
    },
};

リクエスト処理

標準のリクエスト

作成したスキルサービスとAlexaとの通信は、SSL/TLSを利用してHTTPを使用するリクエスト-応答メカニズムで行います。ユーザーがAlexaスキルと対話するとき、作成したサービスは、JSON本文を含むPOSTリクエストを受け取ります。このリクエスト本文には、サービスがロジックを実行してJSON形式の応答を生成するために必要なパラメーターが含まれています。Node.jsはネイティブにJSONを処理できるため、ASK SDK v2 for Node.jsではJSONのシリアル化と逆シリアル化が必要ありません。リクエスト本文のJSON構造についてのドキュメントは、こちらを参照してください。

ハンドラー入力

リクエストハンドラー、リクエストと応答のインターセプター、エラーハンドラーにはすべて、呼び出し時にHandlerInputオブジェクトが渡されます。このオブジェクトには、リクエスト処理に有効な各種エンティティが含まれます。以下はその例です。

  • RequestEnvelope:スキルの送信されるリクエスト本文全体を含みます。
  • AttributesManager:リクエスト、セッション、永続アトリビュートへのアクセスを提供します。
  • ServiceClientFactory:Alexa APIの呼び出しが可能なサービスクライアントを構築します。
  • ResponseBuilder:応答を作成するヘルパー関数を含みます。
  • Context:ホストコンテナが渡すオプションのcontextオブジェクトを提供します。たとえば、AWS Lambdaで実行されるスキルの場合は、AWS Lambda関数のcontextオブジェクトになります。

リクエストハンドラー

リクエストハンドラーは、受け取った1つ以上のタイプのリクエストを処理します。リクエストハンドラーの作成には、以下のRequestHandlerインターフェースを使います。このインターフェースは2つの関数で構成されます。

  • canHandleは、SDKによって呼び出され、指定されたハンドラーが受け取ったリクエストを処理できるかどうかを判断します。この関数は、HandlerInputオブジェクトを受け取り、リクエストを処理できる場合はtrue、処理できない場合はfalseを返します。受信するリクエストのタイプやパラメーター、スキルのアトリビュートなど、この判断を行うための条件を選択できます。
  • handleは、リクエストハンドラーを呼び出すときにSDKによって呼び出されます。この関数には、ハンドラーのリクエスト処理ロジックが含まれます。また、HandlerInputを受け取り、ResponsePromise<Response>のいずれかを返します。

インターフェース

interface RequestHandler {
    canHandle(handlerInput: HandlerInput): Promise<boolean> | boolean;
    handle(handlerInput: HandlerInput): Promise<Response> | Response;
}

サンプルコード

以下は、HelloWorldIntentを呼び出すことができるリクエストハンドラーの例です。

const HelloWorldIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'HelloWorldIntent';
  },
  handle(handlerInput) {
    const speechText = 'こんにちは';

    return handlerInput.responseBuilder
      .speak(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  }
};
import {
    HandlerInput,
    RequestHandler,
} from 'ask-sdk-core';
import { Response } from 'ask-sdk-model';

const HelloWorldIntentHandler : RequestHandler = {
  canHandle(handlerInput : HandlerInput) : boolean {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'HelloWorldIntent';
  },
  handle(handlerInput : HandlerInput) : Response {
    const speechText = 'こんにちは';

    return handlerInput.responseBuilder
      .speak(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  },
};

canHandleメソッドは、受け取るリクエストがIntentRequestかどうかを検出し、インテント名がHelloWorldIntentの場合にtrueを返します。handleメソッドは、基本的な「こんにちは」という応答を生成して返します。

以下の例は、SDKを使ってリクエストハンドラーを登録する方法を示しています。

const Alexa = require('ask-sdk-core');

const skill = Alexa.SkillBuilders.custom()
  .addRequestHandlers(
    FooHandler,
    BarHandler,
    BazHandler)
  .create();
import { SkillBuilders } from 'ask-sdk-core';

const skill = SkillBuilders.custom()
  .addRequestHandlers(
    FooHandler,
    BarHandler,
    BazHandler)
   .create();

注釈

SDKは、登録された順序に従いリクエストハンドラーでcanHandleメソッドを呼び出します。上記の例では、SDKが以下の順序でリクエストハンドラーを呼び出します。

  1. FooHandler
  2. BarHandler
  3. BazHandler

SDKは、指定されたリクエストを処理できる最初のハンドラーを常に選択します。この例では、FooHandlerBarHandlerの両方が特定のリクエストを処理できる場合、常にFooHandlerが呼び出されます。リクエストハンドラーのデザインや登録を行う際には、この点を考慮に入れてください。

リクエストと応答のインターセプター

SDKは、RequestHandlerの実行前と実行後に実行するリクエストと応答のインターセプターをサポートします。インターセプターは、RequestInterceptorインターフェースかResponseInterceptorインターフェースを使用して実装できます。

どちらのインターセプターインターフェースも、戻り値の型がvoidであるprocessメソッドを1つ実行します。リクエストのインターセプターはHandlerInputオブジェクトにアクセスでき、応答のインターセプターはHandlerInputと、RequestHandlerによって生成されるオプションのResponseにアクセスできます。

インターフェース

interface RequestInterceptor {
    process(handlerInput: HandlerInput): Promise<void> | void;
}

interface ResponseInterceptor {
    process(handlerInput: HandlerInput, response?: Response): Promise<void> | void;
}

リクエストのインターセプターは、受け取るリクエストのリクエストハンドラーが実行される直前に呼び出されます。リクエストアトリビュートは、リクエストのインターセプターがリクエストハンドラーにデータやエンティティを渡す方法を提供します。

応答のインターセプターは、リクエストハンドラーが実行された直後に呼び出されます。応答のインターセプターはリクエストハンドラーを実行して生成される出力結果にアクセスできるため、応答のサニタイズや検証といったタスクに適しています。

サンプルコード

以下は、応答がAlexaに送信される前に永続アトリビュートのデータベースへの保存を処理する応答のインターセプターの例です。

const PersistenceSavingResponseInterceptor = {
  process(handlerInput) {
    return new Promise((resolve, reject) => {
      handlerInput.attributesManager.savePersistentAttributes()
        .then(() => {
          resolve();
        })
        .catch((error) => {
          reject(error);
        });
    });
  }
};
import {
  HandlerInput,
  ResponseInterceptor,
} from 'ask-sdk-core';

const PersistenceSavingResponseInterceptor : ResponseInterceptor = {
  process(handlerInput : HandlerInput) : Promise<void> {
    return handlerInput.attributesManager.savePersistentAttributes();
  },
};

以下の例は、SDKを使ってインターセプターを登録する方法を示しています。

const Alexa = require('ask-sdk-core');

const skill = Alexa.SkillBuilders.custom()
  .addRequestHandlers(
    FooHandler,
    BarHandler,
    BazHandler)
  .addRequestInterceptors(
    FooRequestInterceptor,
    BarRequestInterceptor)
  .addResponseInterceptors(
    FooResponseInterceptor,
    BarResponseInterceptor)
  .create();
import { SkillBuilders } from 'ask-sdk-core';

const skill = SkillBuilders.custom()
  .addRequestHandlers(
    FooHandler,
    BarHandler,
    BazHandler)
  .addRequestInterceptors(
    FooRequestInterceptor,
    BarRequestInterceptor)
  .addResponseInterceptors(
    FooResponseInterceptor,
    BarResponseInterceptor)
  .create();

注釈

SDKは、登録された順序に従いリクエストと応答のインターセプターを実行します。上記の例では、SDKが以下の順序でインターセプターを実行します。

  1. FooRequestInterceptor
  2. BarRequestInterceptor
  3. <Request handler picked for the request>
  4. FooResponseInterceptor
  5. BarResponseInterceptor

エラーハンドラー

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

すべてのエラーハンドラーは、ErrorHandlerインターフェースを使用する必要があります。このインターフェースは以下の2つのメソッドで構成されています。

  • canHandleは、SDKによって呼び出され、指定されたハンドラーがエラーを処理できるかどうかを判断します。ハンドラーがエラーを処理できる場合はtrue、処理できない場合はfalseを返します。catch-allハンドラーを作成する場合は常にtrueを返します。
  • handleは、エラーハンドラーを呼び出すときにSDKによって呼び出されます。このメソッドにはエラー処理ロジックがすべて含まれ、ResponseまたはPromise<Response>を返します。

インターフェース

interface ErrorHandler {
    canHandle(handlerInput: HandlerInput, error: Error): Promise<boolean> | boolean;
    handle(handlerInput: HandlerInput, error: Error): Promise<Response> | Response;
}

サンプルコード

以下は、名前が「AskSdk」で始まるエラーをすべて処理するエラーハンドラーの例です。

const myErrorHandler = {
  canHandle(handlerInput, error) {
    return error.name.startsWith('AskSdk');
  },
  handle(handlerInput, error) {
    return handlerInput.responseBuilder
      .speak('An error was encountered while handling your request. Try again later')
      .getResponse();
  }
};
import { HandlerInput } from 'ask-sdk-core';
import { Response } from 'ask-sdk-model';

const myErrorHandler = {
  canHandle(handlerInput : HandlerInput, error : Error) : boolean {
    return error.name.startsWith('AskSdk');
  },
  handle(handlerInput : HandlerInput, error : Error) : Response {
    return handlerInput.responseBuilder
      .speak('An error was encountered while handling your request. Try again later')
      .getResponse();
  },
};

ハンドラーのcanHandleメソッドは、受け取るエラーの名前が「AskSdk」で始まる場合にtrueを返します。handleメソッドは、ユーザーに正常なエラー応答を返します。

以下の例は、SDKを使ってエラーハンドラーを登録する方法を示しています。

const Alexa = require('ask-sdk-core');

const skill = Alexa.SkillBuilders.custom()
  .addRequestHandlers(
    FooHandler,
    BarHandler,
    BazHandler)
  .addRequestInterceptors(
    FooRequestInterceptor,
    BarRequestInterceptor)
  .addResponseInterceptors(
    FooResponseInterceptor,
    BarResponseInterceptor)
  .addErrorHandlers(
    FooErrorHandler,
    BarErrorHandler)
  .create();
import { SkillBuilders } from 'ask-sdk-core';

const skill = SkillBuilders.custom()
  .addRequestHandlers(
    FooHandler,
    BarHandler,
    BazHandler)
  .addRequestInterceptors(
    FooRequestInterceptor,
    BarRequestInterceptor)
  .addResponseInterceptors(
    FooResponseInterceptor,
    BarResponseInterceptor)
  .addErrorHandlers(
    FooErrorHandler,
    BarErrorHandler)
  .create();

注釈

リクエストハンドラーと同様に、エラーハンドラーは登録された順序に従い実行されます。上記の例では、SDKが以下の順序でエラーハンドラーを呼び出します。

  1. FooErrorHandler
  2. BarErrorHandler

応答のビルド

標準的な応答

Lambdaをスキルのエンドポイントに使用している場合は、Alexaがユーザーリクエストに応答するための応答本文を提供するだけで済みます。応答本文のJSON構造についてのドキュメントは、 こちら を参照してください。

応答本文には、次のプロパティが含まれる場合があります:

  • version
  • sessionAttributes
  • response

ASK SDK v2 for Node.jsを使用すると、versionとsessionAttributesを入力してくれるので、ボイラープレートコード(毎回書かなければならないお決まりのコード)を書く手間が省けるので、その分応答の作成に集中できます。

ResponseBuilder

ResponseBuilder には応答を作成するためのヘルパーメソッドが含まれています。 Response には複数の要素が含まれる場合があり、ヘルパーメソッドによって、各応答の要素を初期化したり設定したりする必要がなくなり、応答を生成しやすくなります。 ResponseBuilder は、 HandlerInput コンテナオブジェクトからハンドラーで使用できます。 ResponseBuilder の詳細については、 TypeDoc を参照してください。

利用可能なメソッド

speak(speechOutput: string): this;
reprompt(repromptSpeechOutput: string): this;
withSimpleCard(cardTitle: string, cardContent: string): this;
withStandardCard(cardTitle: string, cardContent: string, smallImageUrl?: string, largeImageUrl?: string): this;
withLinkAccountCard(): this;
withAskForPermissionsConsentCard(permissionArray: string[]): this;
withCanFulfillIntent(canFulfillIntent : CanFulfillIntent) : this;
addDelegateDirective(updatedIntent?: Intent): this;
addElicitSlotDirective(slotToElicit: string, updatedIntent?: Intent): this;
addConfirmSlotDirective(slotToConfirm: string, updatedIntent?: Intent): this;
addConfirmIntentDirective(updatedIntent?: Intent): this;
addAudioPlayerPlayDirective(playBehavior: interfaces.audioplayer.PlayBehavior, url: string, token: string, offsetInMilliseconds: number, expectedPreviousToken?: string, audioItemMetadata? : AudioItemMetadata): this;
addAudioPlayerStopDirective(): this;
addAudioPlayerClearQueueDirective(clearBehavior: interfaces.audioplayer.ClearBehavior): this;
addRenderTemplateDirective(template: interfaces.display.Template): this;
addHintDirective(text: string): this;
addVideoAppLaunchDirective(source: string, title?: string, subtitle?: string): this;
withShouldEndSession(val: boolean): this;
addDirective(directive: Directive): this;
getResponse(): Response;

以下の例は、 ResponseBuilder ヘルパーメソッドを使用して応答を作成する方法を示しています。

const response = handlerInput.responseBuilder
  .speak('foo')
  .reprompt('bar')
  .withSimpleCard('title', 'cardText')
  .getResponse();
const response = handlerInput.responseBuilder
  .speak('foo')
  .reprompt('bar')
  .withSimpleCard('title', 'cardText')
  .getResponse();

注釈

speakとreprompt値のコンテンツはSSMLタグで囲みます。つまり、値に含まれるXMLの特殊文字はエスケープ処理をする必要があります。たとえば、 handlerInput.responseBuilder.speak("I like M&M's") では、このままでは失敗します。文字 &&amp と記述する必要があります。他にも処理が必要な文字は、 < -> &lt;、および > -> &gt; などがあります。

画像とテキストのヘルパー

ASK SDK v2 for Node.jsは以下のヘルパークラスを提供しています。これらは、Echo Showと互換性のあるスキルで広く使用されるテキストや画像の要素の作成に便利です。

ImageHelper

const Alexa = require('ask-sdk-core');

const myImage = new Alexa.ImageHelper()
  .withDescription('FooDescription')
  .addImageInstance('http://BarImageSource')
  .getImage();
import { ImageHelper } from 'ask-sdk-core';
import { interfaces } from 'ask-sdk-model';
import Image = interfaces.display.Image;

const myImage : Image = new ImageHelper()
  .withDescription('FooDescription')
  .addImageInstance('http://BarImageSource')
  .getImage();

PlainTextContentHelper

const Alexa = require('ask-sdk-core');

const myTextContent = new Alexa.PlainTextContentHelper()
  .withPrimaryText('Foo')
  .withSecondaryText('Bar')
  .withTertiaryText('Baz')
  .getTextContent();
import { PlainTextContentHelper } from 'ask-sdk-core';
import { interfaces } from 'ask-sdk-model';
import TextContent = interfaces.display.TextContent;

const myTextContent : TextContent = new PlainTextContentHelper()
  .withPrimaryText('Foo')
  .withSecondaryText('Bar')
  .withTertiaryText('Baz')
  .getTextContent();

RichTextContentHelper

const Alexa = require('ask-sdk-core');

const myTextContent = new Alexa.RichTextContentHelper()
  .withPrimaryText('Foo')
  .withSecondaryText('Bar')
  .withTertiaryText('Baz')
  .getTextContent();
import { RichTextContentHelper } from 'ask-sdk-core';
import { interfaces } from 'ask-sdk-model';
import TextContent = interfaces.display.TextContent;

const myTextContent : TextContent = new RichTextContentHelper()
  .withPrimaryText('Foo')
  .withSecondaryText('Bar')
  .withTertiaryText('Baz')
  .getTextContent();

アトリビュートの管理

SDKを使うと、さまざまなスコープでアトリビュートの保存と取得が可能になります。たとえば、アトリビュートを使って後続のリクエストで取得するデータを保存できます。また、ハンドラーの canHandle ロジックでアトリビュートを使うことで、リクエストのルーティングに影響を与えることも可能です。

アトリビュートは、キーと値で構成されます。キーは String 型で強制型、値は無制限の Object 型です。セッションアトリビュートと永続アトリビュートの場合、値は保存して後で取得できるよう、シリアライズできるデータ型である必要があります。この制限はリクエストレベルのアトリビュートには適用されません。なぜならリクエストレベルのアトリビュートは、リクエスト処理のライフサイクルが終了すると、永続的に存在しないからです。

アトリビュートのスコープ

リクエストアトリビュート

リクエストアトリビュートは、1回のリクエスト処理ライフサイクルの間のみ存続します。リクエストを受信した時点では、リクエストアトリビュートは空です。また応答が生成されると破棄されます。

リクエストアトリビュートは、リクエストと応答のインターセプターと合わせて使うと便利です。たとえば、リクエストインターセプターを使って追加のデータとヘルパークラスをリクエストアトリビュートに挿入して、リクエストハンドラーから取得できるようにすることが可能です。

セッションアトリビュート

セッションアトリビュートは、現在のスキルセッションが継続している間存続します。セッションアトリビュートは、すべてのセッション内リクエストで使用できます。リクエスト処理のライフサイクル中に設定されたすべてのアトリビュートはAlexaサービスに返され、同じセッションの次のリクエストで提供されます。

セッションアトリビュートで、外部ストレージソリューションを使用する必要はありません。セッションアトリビュートはセッション外のリクエストの処理では使用できません。スキルセッションがクローズされると破棄されます。

永続アトリビュート

永続アトリビュートは、現在のセッションのライフサイクルが終了しても存続します。主要なスコープ(ユーザーID、デバイスID)、TTL、ストレージレイヤーを含む、これらのアトリビュートがどのように保存されるかは PersistenceAdapter のコンフィギュレーションによって異なります。

注釈

永続アトリビュートは、PersistenceAdapterを使用して スキルのインスタンスを設定 する場合にのみ使用できます。PersistenceAdapterが設定されていない場合に、AttributesManagerを呼び出して永続アトリビュートの取得と保存を行おうとするとエラーが発生します。

AttributesManager

AttributesManager には、ハンドラーで取得や更新を行えるアトリビュートがあります。AttributesManager は、HandlerInput コンテナオブジェクトからハンドラーで使用できます。AttributesManager は、スキルで必要なアトリビュートと直接やり取りできるように、アトリビュートの取得と保存を行います。AttributesManager の詳細については、TypeDoc を参照してください。

利用可能なメソッド

getRequestAttributes() : {[key : string] : any};
getSessionAttributes() : {[key : string] : any};
getPersistentAttributes() : Promise<{[key : string] : any}>;
setRequestAttributes(requestAttributes : {[key : string] : any}) : void;
setSessionAttributes(sessionAttributes : {[key : string] : any}) : void;
setPersistentAttributes(persistentAttributes : {[key : string] : any}) : void;
savePersistentAttributes() : Promise<void>;

以下は、永続アトリビュートの取得と保存を行う方法のサンプルです

const PersistentAttributesHandler = {
  canHandle(handlerInput) {
    return new Promise((resolve, reject) => {
      handlerInput.attributesManager.getPersistentAttributes()
        .then((attributes) => {
          resolve(attributes.foo === 'bar');
        })
        .catch((error) => {
          reject(error);
        })
    });
  },
  handle(handlerInput) {
    return new Promise((resolve, reject) => {
      handlerInput.attributesManager.getPersistentAttributes()
        .then((attributes) => {
          attributes.foo = 'bar';
          handlerInput.attributesManager.setPersistentAttributes(attributes);

          return handlerInput.attributesManager.savePersistentAttributes();
        })
        .then(() => {
          resolve(handlerInput.responseBuilder
            .speak('Persistent attributes updated!')
            .getResponse());
        })
        .catch((error) => {
          reject(error);
        });
    });
  },
};
import {
  HandlerInput,
  RequestHandler,
} from 'ask-sdk-core';
import { Response } from 'ask-sdk-model';

const PersistentAttributesHandler : RequestHandler = {
  async canHandle(handlerInput : HandlerInput) : Promise<boolean> {
    const persistentAttributes = await  handlerInput.attributesManager.getPersistentAttributes();

    return persistentAttributes.foo === 'bar';

  },
  async handle(handlerInput : HandlerInput) : Promise<Response> {
    const persistentAttributes = await handlerInput.attributesManager.getPersistentAttributes();
    persistentAttributes.foo = 'bar';
    handlerInput.attributesManager.setPersistentAttributes(persistentAttributes);

    await handlerInput.attributesManager.savePersistentAttributes();

    return handlerInput.responseBuilder
      .speak('Persistent attributes updated!')
      .getResponse();
  },
};

注釈

スキルのパフォーマンスを高めるため、 AttributesManager は永続アトリビュートをローカルにキャッシュします。 setPersistentAttributes() は、ローカルにキャッシュされた永続アトリビュートのみを更新します。永続アトリビュートを永続レイヤーに保存するには、 savePersistentAttributes() を呼び出す必要があります。

PersistenceAdapter

PersistenceAdapter は、永続レイヤー(データベースやローカルファイルシステムなど)でアトリビュートを保存したり取得したりする場合に AttributesManager が使用します。SDKを使用して、次のインターフェースに準拠する任意のカスタマイズ済み PersistenceAdapter を登録できます。

インターフェース

interface PersistenceAdapter {
  getAttributes(requestEnvelope : RequestEnvelope) : Promise<{[key : string] : any}>;
  saveAttributes(requestEnvelope : RequestEnvelope, attributes : {[key : string] : any}) : Promise<void>;
}

DynamoDbPersistenceAdapter

ask-sdk-dynamodb-persistence-adapter パッケージは、AWS DynamoDB を使って PersistenceAdapter を実装した DynamoDbPersistenceAdapter を提供します

コンストラクターの詳細

new DynamoDbPersistenceAdapter(config = {}) => Object

DynamoDbPersistenceAdapter オブジェクトを構築します。このオブジェクトは、アトリビュートオブジェクトを取得してDynamoDBテーブルに保存するために AttributesManager によって使用されます。このテーブルには2つの列があります。1つはパーティションキー、1つはアトリビュートに使用されます。 createTable コンフィギュレーションが true に設定されている場合に DynamoDbPersistenceAdapter がインスタンス化されると、SDKは指定された tableName で新しいDynamoDBテーブルを作成しようとします。

const { DynamoDbPersistenceAdapter } = require('ask-sdk-dynamodb-persistence-adapter');

const dynamoDbPersistenceAdapter = new DynamoDbPersistenceAdapter({ tableName : 'FooTable' })
import { PersistenceAdapter } from 'ask-sdk-core';
import { DynamoDbPersistenceAdapter } from 'ask-sdk-dynamodb-persistence-adapter';

const dynamoDbPersistenceAdapter : PersistenceAdapter = new DynamoDbPersistenceAdapter({ tableName : 'FooTable' });
コンフィギュレーションオプション
  • tableName (文字列) - 使用するDynamoDBテーブルの名前です。
  • partitionKeyName (文字列) - 任意です。パーティションキー列の名前です。指定されない場合、デフォルトの "id" になります。
  • attributesName (文字列) - 任意です。アトリビュート列の名前です。指定されない場合、デフォルトの "attributes" になります。
  • createTable (ブール値) - 任意です。true に設定すると、テーブルが存在しない場合に DynamoDbPersistenceAdapter によって自動的に作成されます。指定されない場合、デフォルトの false になります。
  • partitionKeyGenerator (関数) - 任意です。 RequestEnvelope を使ってパーティションキーを生成するときに使用される関数です。デフォルトでは、 userId を使ってパーティションキーを生成します。
  • dynamoDBClient (AWS.DynamoDB ) - 任意です。AWS DynamoDBテーブルのクエリーに使用する DynamoDBClient です。ここにカスタムコンフィギュレーションを使った DynamoDBClient を挿入できます。デフォルトでは、 new AWS.DynamoDB({apiVersion : 'latest'}) が使用されます。

メソッドの詳細

getAttributes(requestEnvelope : RequestEnvelope) : Promise<{[key : string] : any}>

getAttributes 操作により、DynamoDBテーブルからアトリビュートが取得されます。 RequestEnvelope オブジェクトを取り込んで PartitionKeyGenerator に渡し、パーティションキーが生成されます。その後、 attributesName に関連したキーを持つDynamoDBから返されたアトリビュートを取得します。対応するパーティションキーが見つからない場合、 getAttributes は空のオブジェクトを返します。

saveAttributes(requestEnvelope : RequestEnvelope, attributes : {[key : string] : any}) : Promise<void>

saveAttributes 操作では、 RequestEnvelope から生成されたパーティションキーを使用してDynamoDBテーブルにアトリビュートを保存します。 convertEmptyValuestrue に設定した DynamoDBDocumentClient を使用します。これは、アトリビュートオブジェクト内のすべての ""nullundefined の値が変換されるようにするためです。

S3PersistenceAdapter

ask-sdk-s3-persistence-adapter パッケージは、AWS S3 を使って PersistenceAdapter を実装した S3PersistenceAdapter を提供します。

注釈

Amazon S3では既存オブジェクトへの更新に対して 結果整合性 を提供するため、スキルで書き込み後の読み込み整合性が必要とする場合は永続アトリビュートに DynamoDbPersistenceAdapter を使用することをおすすめします。

コンストラクターの詳細

new S3PersistenceAdapter(config = {}) => Object

S3PersistenceAdapter オブジェクトを構築します。このオブジェクトは、アトリビュートオブジェクトを取得してS3バケットに保存するために AttributesManager によって使用されます。アトリビュートオブジェクトは、オブジェクトキーのファイル名を持つ個別のファイルとして表わされます。

const { S3PersistenceAdapter } = require('ask-sdk-s3-persistence-adapter');

const S3PersistenceAdapter = new S3PersistenceAdapter({ bucketName : 'FooBucket' })
import { PersistenceAdapter } from 'ask-sdk-core';
import { S3PersistenceAdapter } from 'ask-sdk-dynamodb-persistence-adapter';

const S3PersistenceAdapter : PersistenceAdapter = new S3PersistenceAdapter({ bucketName : 'FooBucket' });
コンフィギュレーションオプション
  • bucketName (文字列) - 使用するS3バケットの名前です。
  • objectKeyGenerator (関数) - 任意です。 RequestEnvelope を使ってオブジェクトキーを生成するために使用される関数です。デフォルトでは、 userId を使ってオブジェクトキーを生成します。
  • s3Client (AWS.S3) - 任意です。AWS S3バケットのクエリーに使用される S3Client です。ここにカスタムコンフィギュレーションを使った S3Client を挿入できます。デフォルトでは、 new AWS.S3({apiVersion : 'latest'}) が使用されます。
  • pathPrefix (文字列) - 生成されたオブジェクトキーに追加されるプレフィックスの値です。s3でファイルシステム構造を模倣するために使用されます。デフォルトは空の文字列です。

メソッドの詳細

getAttributes(requestEnvelope : RequestEnvelope) : Promise<{[key : string] : any}>

getAttributes 操作により、S3バケットからアトリビュートが取得されます。 RequestEnvelope オブジェクトを取り込んで ObjectKeyGenerator に渡し、オブジェクトキーが生成されます。その後、S3バケットから返されたアトリビュートを取得します。対応するオブジェクトキーが見つからない場合、またはオブジェクトにbodyデータがない場合、getAttributes は空のオブジェクトを返します。

saveAttributes(requestEnvelope : RequestEnvelope, attributes : {[key : string] : any}) : Promise<void>

saveAttributes 操作では、RequestEnvelope から生成されたオブジェクトキーを使用してS3バケットにアトリビュートを保存します。

AlexaサービスAPIの呼び出し

Alexa Skills Kitには、スキルエクスペリエンスをパーソナライズできる複数のサービスAPIが用意されています。SDKには、スキルのロジックからAlexa APIを簡単に呼び出すことができるサービスクライアントが含まれています。

ServiceClientFactory

ServiceClientFactory は、 HandlerInput コンテナオブジェクトからハンドラーで使用できます。個別のサービスクライアントの作成と ApiAccessToken および ApiEndpoint の設定を行います。

利用可能なメソッド

getDeviceAddressServiceClient() : deviceAddress.DeviceAddressServiceClient;
getDirectiveServiceClient() : directive.DirectiveServiceClient;
getListManagementServiceClient() : listManagement.ListManagementServiceClient;
getMonetizationServiceClient() : monetization.MonetizationServiceClient;
getUpsServiceClient() : ups.UpsServiceClient;

注釈

ServiceClientFactory は、ApiClient を使用して スキルのインスタンスを設定 する場合にのみ使用できます。

ApiClient

ApiClient は、Alexaサービスに対してAPIコールを行うときに ServiceClientFactory によって使用されます。SDKを使用して、次のインターフェースに準拠する任意のカスタマイズ済み ApiClient を登録できます。

インターフェース

interface ApiClient {
  invoke(request: ApiClientRequest): Promise<ApiClientResponse>;
}

interface ApiClientMessage {
  headers: Array<{key: string; value: string;}>;
  body?: string;
}

interface ApiClientRequest extends ApiClientMessage {
  url: string;
  method: string;
}

interface ApiClientResponse extends ApiClientMessage {
  statusCode: number;
}

DefaultApiClient

ask-sdk-core パッケージは、 DefaultApiClient を提供します。これは、Node.jsのネイティブ https クライアントを使用したApiClientの実装です。

コンストラクターの詳細

new DefaultApiClient() => object

DefaultApiClient オブジェクトを構築します。このオブジェクトは、 ServiceClient が個別のAlexaサービスにAPTクラスを作成するために使用します。

DeviceAddressServiceClient

DeviceAddressServiceClient は、デバイスアドレスAPI に対してユーザーのAlexaデバイスに関連付けられた所在地データを照会するために使用できます。この所在地データを使用して、スキルの主要機能を提供したり、ユーザーエクスペリエンスを向上させることができます。たとえば、スキルはこの所在地情報を使って、近くの店舗の所在地一覧を提供したり、おすすめのレストランを紹介したりすることができます。

タイプ定義

class DeviceAddressServiceClient {
  getCountryAndPostalCode(deviceId: string): Promise<services.deviceAddress.ShortAddress>;
  getFullAddress(deviceId: string): Promise<services.deviceAddress.Address>;
};

interface ShortAddress {
  countryCode?: string;
  postalCode?: string;
}

interface Address {
  addressLine1?: string;
  addressLine2?: string;
  addressLine3?: string;
  countryCode?: string;
  stateOrRegion?: string;
  city?: string;
  districtOrCounty?: string;
  postalCode?: string;
}

サンプルコード

以下は、DeviceAddressServiceClient のインスタンスを作成し、ユーザーの住所を取得するリクエストハンドラーの例です。

const GetAddressIntent = {
  canHandle(handlerInput) {
    const { request } = handlerInput.requestEnvelope;

    return request.type === 'IntentRequest' && request.intent.name === 'GetAddressIntent';
  },
  async handle(handlerInput) {
    const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
    const consentToken = requestEnvelope.context.System.user.permissions
        && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
      return responseBuilder
        .speak('Please enable Location permissions in the Amazon Alexa app.')
        .withAskForPermissionsConsentCard(['read::alexa:device:all:address'])
        .getResponse();
    }

    try {
      const { deviceId } = requestEnvelope.context.System.device;
      const deviceAddressServiceClient = serviceClientFactory.getDeviceAddressServiceClient();
      const address = await deviceAddressServiceClient.getFullAddress(deviceId);

      console.log('Address successfully retrieved, now responding to user.');

      let response;
      if (address.addressLine1 === null && address.stateOrRegion === null) {
        response = responseBuilder
          .speak(`It looks like you don't have an address set. You can set your address from the companion app.`)
          .getResponse();
      } else {
        const ADDRESS_MESSAGE = `Here is your full address: ${address.addressLine1}, ${address.stateOrRegion}, ${address.postalCode}`;
        response = responseBuilder
          .speak(ADDRESS_MESSAGE)
          .getResponse();
      }
      return response;
    } catch (error) {
      if (error.name !== 'ServiceError') {
        const response = responseBuilder
          .speak('Uh Oh. Looks like something went wrong.')
          .getResponse();

        return response;
      }
      throw error;
    }
  },
};
import {
  HandlerInput,
  RequestHandler,
} from 'ask-sdk-core';
import {
  Response,
  services,
} from 'ask-sdk-model';
import Address = services.deviceAddress.Address;

const GetAddressIntent : RequestHandler = {
  canHandle(handlerInput : HandlerInput) : boolean {
    const { request } = handlerInput.requestEnvelope;

    return request.type === 'IntentRequest' && request.intent.name === 'GetAddressIntent';
  },
  async handle(handlerInput : HandlerInput) : Promise<Response> {
    const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;

    const consentToken = requestEnvelope.context.System.user.permissions
                         && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
      return responseBuilder
        .speak('Please enable Location permissions in the Amazon Alexa app.')
        .withAskForPermissionsConsentCard(['read::alexa:device:all:address'])
        .getResponse();
    }
    try {
      const { deviceId } = requestEnvelope.context.System.device;
      const deviceAddressServiceClient = serviceClientFactory.getDeviceAddressServiceClient();
      const address : Address = await deviceAddressServiceClient.getFullAddress(deviceId);

      console.log('Address successfully retrieved, now responding to user.');

      let response;
      if (address.addressLine1 === null && address.stateOrRegion === null) {
        response = responseBuilder
          .speak(`It looks like you don't have an address set. You can set your address from the companion app.`)
          .getResponse();
      } else {
        const ADDRESS_MESSAGE = `Here is your full address: ${address.addressLine1}, ${address.stateOrRegion}, ${address.postalCode}`;
        response = responseBuilder
          .speak(ADDRESS_MESSAGE)
          .getResponse();
      }

      return response;
    } catch (error) {
      if (error.name !== 'ServiceError') {
        const response = responseBuilder
          .speak('Uh Oh. Looks like something went wrong.')
          .getResponse();

        return response;
      }
      throw error;
    }
  },
};

DirectiveServiceClient

DirectiveServiceClient は、 プログレッシブ応答API にディレクティブを送信するために使用できます。プログレッシブ応答を使用すると、スキルがユーザーのリクエストへの完全な応答を準備している間もユーザーの関心を引き続けることができます。

タイプ定義

class DirectiveServiceClient {
  enqueue(sendDirectiveRequest: services.directive.SendDirectiveRequest): Promise<void>;
}

interface SendDirectiveRequest {
  header: services.directive.Header;
  directive: services.directive.Directive;
}

interface Header {
  requestId: string;
}

type Directive = services.directive.SpeakDirective;

interface SpeakDirective {
  type: 'VoicePlayer.Speak';
  speech?: string;
}

サンプルコード

以下は、 DirectiveServiceClient のインスタンスを作成してプログレッシブ応答を送信する関数の例です。

function callDirectiveService(handlerInput, date) {
  const requestEnvelope = handlerInput.requestEnvelope;
  const directiveServiceClient = handlerInput.serviceClientFactory.getDirectiveServiceClient();

  const requestId = requestEnvelope.request.requestId;
  const directive = {
    header: {
      requestId,
    },
    directive: {
      type: 'VoicePlayer.Speak',
      speech: `$Please wait while I look up information about ${date}...`,
    },
  };

  return directiveServiceClient.enqueue(directive);
}
import { HandlerInput } from 'ask-sdk-core';
import { services } from 'ask-sdk-model';
import SendDirectiveRequest = services.directive.SendDirectiveRequest;

function callDirectiveService(handlerInput : HandlerInput, date : string) : Promise<void> {
  const requestEnvelope = handlerInput.requestEnvelope;
  const directiveServiceClient = handlerInput.serviceClientFactory.getDirectiveServiceClient();

  const requestId = requestEnvelope.request.requestId;

  const directive : SendDirectiveRequest = {
      header: {
          requestId,
      },
      directive: {
          type: 'VoicePlayer.Speak',
          speech: `$Please wait while I look up information about ${date}...`,
      },
  };

  return directiveServiceClient.enqueue(directive);
}

ListManagementServiceClient

ListManagementServiceClient を使用して、Alexaのデフォルトリストやユーザーが保持しているカスタムリストの読み取りや変更を行うために リスト管理API にアクセスできます。

タイプ定義

class ListManagementServiceClient {
  getListsMetadata(): Promise<services.listManagement.AlexaListsMetadata>;
  getList(listId: string, status: string): Promise<services.listManagement.AlexaList>;
  getListItem(listId: string, itemId: string): Promise<services.listManagement.AlexaListItem>;
  createList(createListRequest: services.listManagement.CreateListRequest): Promise<services.listManagement.AlexaListMetadata>;
  createListItem(listId: string, createListItemRequest: services.listManagement.CreateListItemRequest): Promise<services.listManagement.AlexaListItem>;
  updateList(listId: string, updateListRequest: services.listManagement.UpdateListRequest): Promise<services.listManagement.AlexaListMetadata>;
  updateListItem(listId: string, itemId: string, updateListItemRequest: services.listManagement.UpdateListItemRequest): Promise<services.listManagement.AlexaListItem>;
  deleteList(listId: string): Promise<void>;
  deleteListItem(listId: string, itemId: string): Promise<void>;
}

MonetizationServiceClient

スキル内課金サービス

ASK SDK for Node.jsには、 inSkillPurchase API を呼び出す MonetizationServiceClient が用意されています。このAPIでは、現在のスキルに関連付けられているすべてのスキル内商品を取得し、各商品が課金可能かまたは現在のユーザーがすでに課金済みかを確認できます。次のメソッドがあります。

getInSkillProducts(locale : string, purchasable? : string, entitled? : string, productType? : string, nextToken? : string, maxResults? : number) : Promise<services.monetization.InSkillProductsResponse>
getInSkillProduct(locale : string, productId : string) : Promise<services.monetization.InSkillProduct>
  • locale は、 handlerInput.requestEnvelope.request.locale のリクエストから取得できます。
  • purchasable には、すべてのスキル内商品を取得する場合は null 、課金可能かどうかに関する応答をフィルターする場合は PURCHASABLE または NOT_PURCHASABLE を指定できます。
  • productType には、すべてのタイプのスキル内商品を取得する場合は null 、商品タイプでフィルターする場合は ENTITLEMENTCONSUMABLE 、または SUBSCRIPTION を指定できます。
  • entitled には、すべてのスキル内商品を取得する場合は null 、非消費型アイテムのステータスに関する応答をフィルターする場合は ENTITLED または NOT_ENTITLED を指定できます。
  • nextToken は複数ページのクエリーの場合は必須です。 maxResults ではスキルでAPI呼び出しごとに取得されるレコードの数を制御できます。デフォルトのページサイズは100レコードです。
  • productId には取得するスキル内商品を指定します。

getInSkillProducts

getInSkillProducts メソッドは、現在のスキルに関連付けられているすべてのスキル内商品を取得し、現在のスキルとユーザーについて各スキル内商品の課金可能性と非消費型アイテムのステータスを示します。

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    console.log("In LaunchRequest");

    const locale = handlerInput.requestEnvelope.request.locale;
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProducts(locale).then(function(result) {
      // Code to handle result.inSkillProducts goes here
       const totalProducts = result.inSkillProducts.length;
       const purchasableProducts = result.inSkillProducts.filter(record => record.purchasable == 'PURCHASABLE');
       const entitledProducts = result.inSkillProducts.filter(record => record.entitled == 'ENTITLED');

       return handlerInput.responseBuilder
        .speak('Found total ' + result.inSkillProducts.length + ' products of which ' + purchasableProducts.length + ' are purchasable and ' + entitledProducts.length + ' are entitled.');
        .getResponse();
    });
  },
}

API応答にはスキル内商品レコードの配列が含まれます。

{
   "inSkillProducts":[
     {
       "productId": "amzn1.adg.product....",
       "referenceName": "<Product Reference Name as defined by the developer>",
       "type": "SUBSCRIPTION",               // Or ENTITLEMENT
       "name": "<locale specific product name as defined by the developer>",
       "summary": "<locale specific product summary, as provided by the developer>",
       "entitled": "ENTITLED",              // Or NOT_ENTITLED
       "purchasable": "PURCHASABLE",        // Or NOT_PURCHASABLE
       "purchaseMode": "TEST"               // Or LIVE
       "activeEntitlementCount": 1
     }
   ],
   "isTruncated": true,
   "nextToken": "string"
 }

getInSkillProduct

getInSkillProduct APIは指定されたproductIdで識別される単一のスキル内商品の商品レコードを取得します。

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    console.log("In LaunchRequest");

    const locale = handlerInput.requestEnvelope.request.locale;
    const productId = 'amzn1.adg.product.<GUID>';
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProduct(locale, productId).then(function(result) {
       // Code to handle result.inSkillProduct goes here
    });
  },
}

API応答には単一のスキル内商品レコードが含まれます。

{
    "productId": "amzn1.adg.product....",
    "referenceName": "<Product Reference Name as defined by the developer>",
    "type": "SUBSCRIPTION",               // Or ENTITLEMENT
    "name": "<locale specific product name as defined by the developer>",
    "summary": "<locale specific product summary, as provided by the developer>",
    "entitled": "ENTITLED",              // Or NOT_ENTITLED
    "purchasable": "PURCHASABLE",        // Or NOT_PURCHASABLE
    "purchaseMode": "TEST"               // Or LIVE
    "activeEntitlementCount": 1
}

スキル実装でのこれらのAPIとその使い方の詳細については、こちらを参照してください。 カスタムスキルへのスキル内課金の追加

スキル内課金のインターフェース(日本未対応)

ASK SDK for Node.jsには、スキルでAlexaからスキル内課金とキャンセルのリクエストを開始するための addDirective() メソッドが用意されています。Amazonシステムはユーザーとの音声による対話を管理し、課金取引を処理して、ステータス応答をリクエスト元のスキルに返します。このインターフェースを使用して、 UpsellBuyCancel の3つのアクションがサポートされます。

これらのアクションと推奨されるユースケースの詳細については、こちらを参照してください。 カスタムスキルへのスキル内課金の追加

Upsell

スキルは、ユーザーが明示的にコンテキストをリクエストしなかった場合にスキルのコンテキストを提供するためにUpsellアクションを開始する必要があります。たとえば、無料のコンテンツが提供されている間または後です。Upsellアクションを開始するには、製品IDとアップセルメッセージが必要です。アップセルメッセージを使って、開発者はAlexaで価格を提示する前にユーザーにスキル内商品を提示する方法を指定できます。

// スキルフローでは、ユーザーから明示的な依頼なしで
// スキル内製品を提供するために意思決定がなされた場合

return handlerInput.responseBuilder
  .addDirective({
    'type': 'Connections.SendRequest',
    'name': 'Upsell',
    'payload': {
      'InSkillProduct': {
          'productId': '<productId for the ISP which you wish to upsell>'
      },
      'upsellMessage': '<introductory upsell description for the in-skill product>'
    },
    'token': 'correlationToken'
  })
  .getResponse();

Buy

スキルは、ユーザーが特定のスキル内商品の課金をリクエストしたときにBuyアクションを開始します。Buyアクションを開始するには、製品IDが必要です。

// スキル内製品を購入するためにユーザーのインテントをキャプチャするカスタムインテント
// (buyProductIntent below)を実装し、次にAlexaに対してBuyリクエストを開始します。
// 例:'アレクサ、<product name>を買って'

const buyProductIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'buyProductIntent';
  },
  handle(handlerInput) {
    // Obtain the corresponding productId for the requested in-skill product by invoking inSkillProducts API.
    // Below, the slot variable productName is only for demonstration.

    const locale = handlerInput.requestEnvelope.request.locale;
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProducts(locale).then(function(res) {
      const slots = handlerInput.requestEnvelope.request.intent.slots;
      const productReferenceName = slots['productName'].value;
      const product_record = res.inSkillProducts.filter(record => record.referenceName == productRef);
      if (product_record.length > 0)  {
        return handlerInput.responseBuilder
          .addDirective({
            'type': 'Connections.SendRequest',
            'name': 'Buy',
            'payload': {
              'InSkillProduct': {
                'productId': product_record[0].productId
              }
            },
           'token': 'correlationToken'
          })
          .getResponse();
      }
      else {
        return handlerInput.responseBuilder
          .speak('I am sorry. That product is not available for purchase')
          .getResponse();
      }
    });
  }
};

Cancel

スキルは、ユーザーがサポートされているスキル内商品の既存の非消費型アイテムまたはサブスクリプションのキャンセルをリクエストしたときにCancelアクションを開始します。Cancelアクションを開始するには、製品IDが必要です。

const cancelIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'cancelProductIntent';
  },
  handle(handlerInput) {
    // Obtain the corresponding productId for the requested in-skill product by invoking inSkillProducts API.
    // Below, the slot variable productName is only for demonstration.

    const locale = handlerInput.requestEnvelope.request.locale;
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProducts(locale).then(function(res) {
      const slots = handlerInput.requestEnvelope.request.intent.slots;
      const productReferenceName = slots['productName'].value;
      const product_record = res.inSkillProducts.filter(record => record.referenceName == productReferenceName);

      if (product_record.length > 0)  {
        return handlerInput.responseBuilder
          .addDirective({
            'type': 'Connections.SendRequest',
            'name': 'Cancel',
            'payload': {
              'InSkillProduct': {
                'productId': product_record[0].productId
              }
            },
            'token': 'correlationToken'
          })
          .getResponse();
      }
      else  {
        return handlerInput.responseBuilder
          .speak('I am sorry. I don\'t know that one.');
          .getResponse();
      }
    });
  }
};

UpsServiceClient

UpsServiceClient を使用して、 AlexaユーザープロフィールAPI に対してユーザーの連絡先情報を照会したり、Alexaユーザー設定API に対してユーザーのタイムゾーン設定、長さの単位、および温度の単位を照会できます。

タイプ定義

class UpsServiceClient {
  getProfileEmail(): Promise<string>;
  getProfileGivenName(): Promise<string>;
  getProfileMobileNumber(): Promise<services.ups.PhoneNumber>;
  getProfileName(): Promise<string>;
  getSystemDistanceUnits(deviceId: string): Promise<services.ups.DistanceUnits>;
  getSystemTemperatureUnit(deviceId: string): Promise<services.ups.TemperatureUnit>;
  getSystemTimeZone(deviceId: string): Promise<string>;
}

ReminderManagementServiceClient

ReminderManagementServiceClient を使用して、スキルからリマインダーを作成、管理するために Alexa Reminders API をクエリーすることができます。

タイプ定義

class ReminderManagementServiceClient extends BaseServiceClient {
  deleteReminder(alertToken: string): Promise<void>;
  getReminder(alertToken: string): Promise<services.reminderManagement.GetReminderResponse>;
  updateReminder(alertToken: string, reminderRequest: services.reminderManagement.ReminderRequest): Promise<services.reminderManagement.ReminderResponse>;
  deleteReminders(): Promise<void>;
  getReminders(): Promise<services.reminderManagement.GetRemindersResponse>;
  createReminder(reminderRequest: services.reminderManagement.ReminderRequest): Promise<services.reminderManagement.ReminderResponse>;
}

スキルインスタンスのコンフィギュレーション

Skill - スキル

Skillオブジェクトは、すべてのスキルロジックを統合したものです。このオブジェクトは、AttributesManagerServiceClientFactoryなどのSDKユーティリティを初期化し、処理のリクエストを開始します。

利用可能なメソッド

invoke(requestEnvelope : RequestEnvelope, context? : any) : Promise<ResponseEnvelope>;

スキルビルダー

SkillBuilderはスキルの作成、ユーザーエージェントのカスタマイズ、Lambda統合ハンドラーの作成に役立つ関数を提供します。ASK SDK v2 for Node.jsを使用することで、カスタマイズ可能なSkillBuilderをさまざまな方法で実装できます(SkillBuilderSkillBuildersオブジェクトから使用できます)。

以下は、SkillBuildersプロバイダーを使用してスキルビルダーを作成する方法のサンプルです。

const Alexa = require('ask-sdk');

const customSkillBuilder = Alexa.SkillBuilders.custom();
const standardSkillBuilder = Alexa.SkillBuilders.standard();
import { SkillBuilders } from 'ask-sdk';

const customSkillBuilder = SkillBuilders.custom();
const standardSkillBuilder = SkillBuilders.standard()

BaseSkillBuilder

BaseSkillBuilderには、スキルの設定にもっとも重要なメソッドが含まれています。これが、SkillBuilderをカスタマイズするための基礎となります。

利用可能なメソッド

addRequestHandler(matcher : ((handlerInput : HandlerInput) => Promise<boolean> | boolean) | string, executor : (handlerInput : HandlerInput) => Promise<Response> | Response) : this;
addRequestHandlers(...requestHandlers : RequestHandler[]) : this;
addRequestInterceptors(...executors : Array<RequestInterceptor | ((handlerInput : HandlerInput) => Promise<void> | void)>) : this;
addResponseInterceptors(...executors : Array<ResponseInterceptor | ((handlerInput : HandlerInput, response? : Response) => Promise<void> | void)>) : this;
addErrorHandler(matcher : (handlerInput : HandlerInput, error : Error) => Promise<boolean> | boolean, executor : (handlerInput : HandlerInput, error : Error) => Promise<Response> | Response) : this;
addErrorHandlers(...errorHandlers : ErrorHandler[]) : this;
withCustomUserAgent(customUserAgent : string) : this;
withSkillId(skillId : string) : this;
getSkillConfiguration() : SkillConfiguration;
create() : Skill;
lambda() : LambdaHandler;

CustomSkillBuilder

CustomSkillBuilderask-sdk-coreask-sdkのパッケージで使用でき、これにはBaseSkillBuilderで使用できるすべてのメソッドが含まれています。また、CustomSkillBuilderにもカスタムのPersistentAdapterApiClientを登録できる関数があります。

利用可能なメソッド

withPersistenceAdapter(persistenceAdapter : PersistenceAdapter) : this;
withApiClient(apiClient : ApiClient) : this;

StandardSkillBuilder

StandardSkillBuilderask-sdkのパッケージでのみ使用でき、これにはBaseSkillBuilderで使用できるすべてのメソッドが含まれます。これはデフォルトでDynamoDbPersistenceAdapterDefaultApiClientを使用し、DynamoDbPersistenceAdapterの設定に役立つ便利なメソッドを提供します。

利用可能なメソッド

withTableName(tableName : string) : this;
withAutoCreateTable(autoCreateTable : boolean) : this;
withPartitionKeyGenerator(partitionKeyGenerator : PartitionKeyGenerator) : this;
withDynamoDbClient(customDynamoDBClient : DynamoDB) : this;

ユーティリティ

The SDK provides mutiple utility functions that aims to reduce boilerplate code so that you can focus on skill business logic.

RequestEnvelopeUtils

The RequestEnvelopeUtils provides functions for getting frequently used attributes from the RequestEnvelope with error checking logic.

Available Methods

getLocale(requestEnvelope: RequestEnvelope): string;
getRequestType(requestEnvelope: RequestEnvelope): string;
getIntentName(requestEnvelope: RequestEnvelope): string;
getAccountLinkingAccessToken(requestEnvelope: RequestEnvelope): string;
getApiAccessToken(requestEnvelope: RequestEnvelope): string;
getDeviceId(requestEnvelope: RequestEnvelope): string;
getDialogState(requestEnvelope: RequestEnvelope): string;
getSlot(requestEnvelope: RequestEnvelope, slotName: string): Slot;
getSlotValue(requestEnvelope: RequestEnvelope, slotName: string): string;
getSupportedInterfaces(requestEnvelope: RequestEnvelope): SupportedInterfaces;
isNewSession(requestEnvelope: RequestEnvelope): boolean;

SsmlUtils

The SsmlUtils provides a function for escaping invalid SSML characters in a speech string.

Available Methods

escapeXmlCharacters(input: string): string

ViewportUtils

The ViewportUtils provides functions for checking the viewport profile and other device characteristics such as display size or dpi in the RequestEnvelope.

Available Methods

getViewportOrientation(width: number, height: number): ViewportOrientation;
getViewportSizeGroup(size: number): ViewportSizeGroup;
getViewportDpiGroup(dpi: number): ViewportDpiGroup;
getViewportProfile(requestEnvelope: RequestEnvelope): ViewportProfile;

ASK SDK for Node.js

ASK SDK v2 for Node.jsを使うと、ボイラープレートコード(毎回書かなければならないお決まりのコード)を書く手間が省けます。これにより空いた時間をさまざまな機能の実装に充てることができ、人気のスキルをより簡単に作成できるようになります。

SDKでサポートされているAlexaの機能

このセクションでは、現在SDKでサポートされているAlexaのすべての機能を紹介します。

プレビュー機能

注釈

以下の機能は、公開プレビュー版としてリリースされます。インターフェースは今後のリリースで変更される可能性があります。

ガイド

SDKを使って開発を始めるには、以下のリソースを参照してください。

ASK SDKのセットアップ

NPMプロジェクトに依存関係としてSDKをインストールする方法を説明します。

初めてのスキル開発

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

ASK SDK移行ガイド

SDK v1からSDK v2にAlexaスキルを移行する手順を説明します。

技術文書

リクエスト処理

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

応答のビルド

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

アトリビュートの管理

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

AlexaサービスAPIの呼び出し

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

スキルビルダー

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

ユーティリティ

ユーティリティ関数の使い方を説明します。

フィードバック

Alexaの機能に関するリクエストや投票は、こちらをご覧ください。