チュートリアル: ASK SDK for Node.jsでAlexaスキル開発を始める
このチュートリアルでは、 Alexa Skills Kit(ASK)Software Development Kit(SDK)v2 for Node.jsを使ったスキル開発の手順を説明します。以下は、サンプルスキルのフローです。
ユーザー: アレクサ、天気を教えて
Alexa: 天気は晴れです
まず、空のスキルプロジェクトを使ってリクエストハンドラーを追加してから、スキルパッケージを作成します。次に、AWSマネジメントコンソールで対応するAmazon Web Services(AWS)Lambda関数を作成し、ASK開発者コンソールを使ってスキルの設定を行います。設定したら、開発者コンソールのシミュレーターかAlexa搭載デバイスを使ってスキルを実行します。
- 前提条件
- ASK SDK for Node.jsを使ったスキル作成手順
- ステップ1: 空のスキルプロジェクトを作成
- ステップ2: 依存関係を読み込む
- ステップ3: リクエストハンドラーを追加
- ステップ4: スキルパッケージを作成
- ステップ5: AWS Lambda関数を作成
- ステップ6: スキルの作成と設定
- ステップ7: スキルのテスト
- 関連トピック
前提条件
このチュートリアルを開始するには、次のアカウントとツールを準備する必要があります。
- Amazon開発者アカウント – Alexaスキルを作成して設定するにはAmazon開発者アカウントが必要です。アカウントを作成する方法の詳細については、Amazon開発者アカウントの作成を参照してください。(注:日本のAlexaスキル開発者はAmazon.co.jpでアカウントを作成してから、同じアカウントで開発者ポータルにログインしてください)
- AWSアカウント – AWS LambdaでスキルコードをホストするにはAWSアカウントが必要です。AWSアカウントを作成するには、AWS無料利用枠を参照してください。
- Node Package Manager(NPM) – NPMのインストール方法については、NPMドキュメントのGetting started(英語)を参照してください。
- ASK SDK v2 for Node.js – SDKのインストール方法については、ASK SDKのセットアップを参照してください。このチュートリアルを開始するには、以下のいずれかをインストールする必要があります。
- 標準SDK配布パッケージ
- コアSDKのサポートモジュール(依存関係をカスタマイズする場合)
ASK SDK for Node.jsを使ったスキル作成手順
以下の手順でスキルを作成します。
ステップ1: 空のスキルプロジェクトを作成
以下の手順に従い、NPMを使って空のスキルを作成します。
空のスキルプロジェクトを作成する
- コンピューターにスキル用のフォルダを作成します。
- コマンドプロンプトを開き、スキルフォルダに移動します。
- コマンドプロンプトに、
npm init
と入力します。 - すべてのプロンプトに対してEnterキーを押します。
スキルコードフォルダに、package.json
というファイルが作成されました。 - スキルコードフォルダで、
npm install --save ask-sdk
と入力します。
このコマンドを実行すると、node_modules
フォルダが作成されます。 - スキルフォルダに、
index.js
という空のファイルを作成します。
ステップ2: 依存関係を読み込む
コードがASK SDK for Node.jsに依存するよう指定するには、依存関係としてSDKを読み込む必要があります。
依存関係を読み込む
- 以下のコードを
index.js
ファイルに貼り付けます。
const Alexa = require('ask-sdk-core');
import {
ErrorHandler,
HandlerInput,
RequestHandler,
SkillBuilders,
} from 'ask-sdk-core';
import {
Response,
SessionEndedRequest,
} from 'ask-sdk-model';
ステップ3: リクエストハンドラーを追加
リクエストハンドラーは、スキルで受信するさまざまなタイプのリクエストを処理します。以下のセクションは、リクエストハンドラーのサンプルコードです。スキルコードに貼り付けて使用できます。
- LaunchRequestハンドラー
- AskWeatherIntentハンドラー
- HelpIntentハンドラー
- CancelAndStopIntentハンドラー
- SessionEndedRequestハンドラー
- Errorハンドラー
- Lambdaハンドラー
LaunchRequestハンドラー
ユーザーが特定のインテントなしでスキルを呼び出すと、AlexaはスキルにLaunchRequest
を送信します。以下のコードでは、スキルがLaunchRequest
を受信したときにAlexaが呼び出すハンドラーを設定しています。
LaunchRequestハンドラーを追加する
- 以下のコードを、
index.js
ファイルの前回追加したrequire
行の後に貼り付けます。
const LaunchRequestHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
},
handle(handlerInput) {
const speechText = '開発キットの天気ボットにようこそ。天気のことは私に聞いてください。';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('開発キットの天気ボットにようこそ。天気のことは私に聞いてください。', speechText)
.getResponse();
}
};
const LaunchRequestHandler : RequestHandler = {
canHandle(handlerInput : HandlerInput) : boolean {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest';
},
handle(handlerInput : HandlerInput) : Response {
const speechText = '開発キットの天気ボットにようこそ。天気のことは私に聞いてください。';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('開発キットの天気ボットにようこそ。天気のことは私に聞いてください。', speechText)
.getResponse();
},
};
コードでは、受信したリクエストがLaunchRequest
の場合、canHandle()
関数はtrue
を返します。handle()
関数は、Alexaへの応答を生成して返します。
AskWeatherIntentハンドラー
以下のコードでは、ユーザーが天気をたずねたときにAlexaが呼び出すハンドラーを設定しています。
AskWeatherIntentハンドラーを追加する
- 以下のコードを、
index.js
ファイルの前回のハンドラーの後に貼り付けます。
const AskWeatherIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'AskWeatherIntent';
},
handle(handlerInput) {
const speechText = '今日の天気は晴れです。';
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('今日の天気は晴れです。', speechText)
.getResponse();
}
};
const AskWeatherIntentHandler : RequestHandler = {
canHandle(handlerInput : HandlerInput) : boolean {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'AskWeatherIntent';
},
handle(handlerInput : HandlerInput) : Response {
const speechText = '今日の天気は晴れです。';
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('今日の天気は晴れです。', speechText)
.getResponse();
},
};
コードでは、canHandle()
関数が受信するリクエストがIntentRequest
かどうかを検出し、インテント名がAskWeatherIntent
の場合にtrue
を返します。handle()
関数は、応答と天気を読み上げるAlexa音声を返します。
HelpIntentハンドラー
以下のコードは、スキルがビルトインインテントAMAZON.HelpIntent
を受信したときにAlexaが呼び出すハンドラーを設定します。ユーザーがビルトインインテントをトリガーする方法については、標準ビルトインインテントを参照してください。
HelpIntentハンドラーを追加する
- 以下のコードを、
index.js
ファイルの前回のハンドラーの後に貼り付けます。
const HelpIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
const speechText = '天気のことは私に聞いてください。';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('天気のことは私に聞いてください。', speechText)
.getResponse();
}
};
const HelpIntentHandler : RequestHandler = {
canHandle(handlerInput : HandlerInput) : boolean {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'AMAZON.HelpIntent';
},
handle(handlerInput : HandlerInput) : Response {
const speechText = '天気のことは私に聞いてください。';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('天気のことは私に聞いてください。', speechText)
.getResponse();
},
};
先ほどのハンドラー同様、HelpIntent
ハンドラーはIntentRequest
を想定されるインテント名と照合します。ハンドラーは、指定された提案をAlexaが読み上げる応答を返します。
CancelAndStopIntentハンドラー
1つのハンドラーで2つの異なるインテントに応答することができます。以下は、1つのハンドラーを使ってAMAZON.CancelIntent
とAMAZON.StopIntent
という2つのビルトインインテントに応答している例です。両方のインテントに対する応答は同じであるため、1つのハンドラーを使うことで重複するコードを減らせます。
CancelAndStopIntentハンドラーを追加する
- 以下のコードを、
index.js
ファイルの前回のハンドラーの後に貼り付けます。
const CancelAndStopIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& (Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.CancelIntent'
|| Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.StopIntent');
},
handle(handlerInput) {
const speechText = 'さようなら。';
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('さようなら。', speechText)
.withShouldEndSession(true)
.getResponse();
}
};
const CancelAndStopIntentHandler : RequestHandler = {
canHandle(handlerInput : HandlerInput) : boolean {
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'AMAZON.CancelIntent'
|| request.intent.name === 'AMAZON.StopIntent');
},
handle(handlerInput : HandlerInput) : Response {
const speechText = 'さようなら。';
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('さようなら。', speechText)
.withShouldEndSession(true)
.getResponse();
},
};
SessionEndedRequestハンドラー
スキルはSessionEndedRequest
を受け取った後に応答を返すことはできませんが、クリーンアップロジックを含むハンドラーを提供することはできます。以下は、SessionEndedRequest
のハンドラーを作成する方法の例です。
SessionEndedRequestハンドラーを追加する
- 以下のコードを、
index.js
ファイルの前回のハンドラーの後に貼り付けます。
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'SessionEndedRequest';
},
handle(handlerInput) {
// クリーンアップロジックをここに追加します。
return handlerInput.responseBuilder.getResponse();
}
};
const SessionEndedRequestHandler : RequestHandler = {
canHandle(handlerInput : HandlerInput) : boolean {
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionEndedRequest';
},
handle(handlerInput : HandlerInput) : Response {
console.log(`セッションが終了しました。理由:${(handlerInput.requestEnvelope.request as SessionEndedRequest).reason}`);
return handlerInput.responseBuilder.getResponse();
},
};
Errorハンドラー
エラー処理ロジックをエラーハンドラーに追加できます。たとえば、未処理のリクエストやAPIサービスのタイムアウトなどを処理するロジックを追加できます。以下のコードでは、スキルがすべてのエラーに対して意味のあるメッセージを返すよう、スキルにエラーハンドラーを追加しています。
エラーハンドラーを追加する
- 以下のコードを、
index.js
ファイルの前回のハンドラーの後に貼り付けます。
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
console.log(`処理されたエラー: ${error.message}`);
return handlerInput.responseBuilder
.speak('すみません。コマンドを理解できませんでした。もう一度言ってください。')
.reprompt('すみません。コマンドを理解できませんでした。もう一度言ってください。')
.getResponse();
}
};
const ErrorHandler : ErrorHandler = {
canHandle(handlerInput : HandlerInput, error : Error ) : boolean {
return true;
},
handle(handlerInput : HandlerInput, error : Error) : Response {
console.log(`処理されたエラー:${error.message}`);
return handlerInput.responseBuilder
.speak('すみません。コマンドを理解できませんでした。もう一度言ってください。')
.reprompt('すみません。コマンドを理解できませんでした。もう一度言ってください。')
.getResponse();
}
};
Lambdaハンドラー
Lambdaハンドラーは、AWS Lambda関数のエントリーポイントとなります。以下は、スキルが受信するすべてのリクエストのルーティングを行うLambdaハンドラー関数のコードです。
Lambdaハンドラーを追加する
- 以下のコードを、
index.js
ファイルの前回のハンドラーの後に貼り付けます。
let skill;
exports.handler = async function (event, context) {
console.log(`REQUEST++++${JSON.stringify(event)}`);
if (!skill) {
skill = Alexa.SkillBuilders.custom()
.addRequestHandlers(
LaunchRequestHandler,
AskWeatherIntentHandler,
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,
AskWeatherIntentHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
)
.addErrorHandlers(ErrorHandler)
.create();
}
const response = await skill.invoke(event, context);
console.log(`RESPONSE++++${JSON.stringify(response)}`);
return response;
};
Lambdaハンドラー関数は、SkillBuilders.custom()
ビルダー関数を使ってSDKのSkill
インスタンスを作成します。addRequestHandlers()
ビルダー関数は、先ほどのステップで作成したリクエストハンドラーを登録します。コードは、関数をLambdaハンドラー関数としてエクスポートします。
また、ASK SDK v2 for Node.jsで提供されるlambda
ビルダー関数を使い、Skill
のインスタンスを呼び出して応答を返すLambdaハンドラー関数を作成することもできます。以下は、lambda
ビルダー関数を使用する方法の例です。
exports.handler = Alexa.SkillBuilders.custom()
.addRequestHandlers(
LaunchRequestHandler,
AskWeatherIntentHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler)
.addErrorHandlers(ErrorHandler)
.lambda();
exports.handler = SkillBuilders.custom()
.addRequestHandlers(
LaunchRequestHandler,
AskWeatherIntentHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
)
.addErrorHandlers(ErrorHandler)
.lambda();
ステップ4: スキルパッケージを作成
スキルコードが完成したら、後続のステップでAWS Lambdaにアップロードするスキルパッケージを作成します。
スキルパッケージを作成する
-
スキルコードフォルダのコンテンツを含むzipファイルを作成します。
zipファイルには、index.js
、package.json
、node_modules
フォルダが含まれます。重要: スキルコードフォルダ自体ではなく、スキルコードフォルダのコンテンツのみを圧縮するようにしてください。
ステップ5: AWS Lambda関数を作成
先ほどのステップで、Lambda関数のコードを作成しました。AWSコンソールで、対応するLambda関数も作成する必要があります。作成したら、スキルコードをLambda関数にアップロードします。
AWS Lambda関数を作成する
- AWS Lambdaコンソールにサインインします。
- コンソールの右上隅にあるリージョンのドロップダウンリストをクリックし、米国東部(バージニア北部)などAlexaスキルで利用可能なAWSリージョンを1つ選択します。
Alexaスキルで利用可能なリージョンの一覧については、AWS Lambda関数に最適なリージョンを選択するを参照してください。 - まだLambda関数がない場合は、今すぐ始めるをクリックします。
- 1つ以上のLambda関数がある場合は、関数の作成をクリックします。
- 一から作成を選択します。
- 関数名に、Lambda関数の名前を入力します。
- ランタイムで、Node.js 10.xを選択します。
- アクセス権限で、デフォルトの実行ロールの変更を展開し、AWSポリシーテンプレートから新しいロールを作成を選択します。
- ロール名に、ロールの名前を入力します。
- ポリシーテンプレートリストで、シンプルなマイクロサービスのアクセス権限を選択します。
- ページ下部にある関数の作成をクリックします。
- 関数の概要をクリックし、トリガーを追加をクリックします。
- トリガーの設定で、Alexa Skills Kitを選択します。
- スキルID検証で無効を選択します。
- 追加をクリックします。
- ページの中ほどにあるコードタブをクリックします。
- 右側のアップロード元をクリックし、.zipファイルを選択します。
- ステップ4: スキルパッケージを作成で作成したzipファイルをアップロードします。
- Lambda関数ページの右上にあるARNをコピーをクリックし、後でアクセスできる場所にARNを貼り付けます。
ARNは、次のステップでASK開発者コンソールからスキルを設定するときに必要です。
ステップ6: スキルの作成と設定
スキルコードをAWS Lambdaに追加したら、ASK開発者コンソールでスキルを作成し、設定します。
Alexaスキルを作成して設定する
- ASK開発者コンソールにサインインします。
- スキルの作成をクリックします。
- スキル名を入力します。
- スキルに追加するモデルを選択でカスタムを選択します。
- スキルのバックエンドリソースをホスティングする方法を選択で、ユーザー定義のプロビジョニングを選択します。
- スキルを作成をクリックします。
- スキルに追加するテンプレートを選択で、スクラッチで作成を選択します。
- 右上にある選択をクリックします。
- 左側の呼び出しをクリックします。
- スキルの呼び出し名に
開発キットの天気ボット
と入力し、モデルを保存をクリックします。
スキルを起動するには、「アレクサ、開発キットの天気ボットを開いて」と呼びかけます。 - 左側で対話モデルを展開し、インテントをクリックしてインテントを追加をクリックします。
- カスタムインテントを作成で
AskWeatherIntent
と入力し、カスタムインテントを作成をクリックします。 - サンプル発話で、ユーザーが天気をたずねるときに言う可能性のあるサンプル発話をいくつか追加します。エントリーごとにプラス記号(+)をクリックするか、Enterを押します。
次のようなサンプル発話を追加できますが、これ以外に追加してもかまいません。どんな天気 天気を教えて 外の天気はどう 外の天気を教えて
注:AMAZON.CancelIntent
、AMAZON.HelpIntent
、AMAZON.StopIntent
はAlexaのビルトインインテントのため、サンプル発話を追加する必要はありません。 - 画面上部のモデルを保存をクリックします。
- 画面上部のモデルをビルドをクリックします。
- 左側でアセットを展開し、エンドポイントをクリックします。
- デフォルトの地域をステップ5: AWS Lambda関数を作成でコピーしたAWS Lambda ARNで置き換えます。
- 画面上部のエンドポイントを保存をクリックします。
ステップ7: スキルをテストする
スキルのテストには、開発者コンソールのAlexaシミュレーターを使うこともできますし、EchoデバイスなどのAlexa搭載デバイスを使うこともできます。スキルのテストの詳細については、スキルのテストとデバッグを参照してください。
開発者コンソールでスキルをテストする
- 開発者コンソールの上部で、テストタブをクリックします。
- 左上にあるこのスキルでは、テストは無効になっていますで、開発中を選択します。
- Alexaシミュレーターの入力またはマイクを長押しで発話フィールドをクリックし、
開発キットの天気ボットを開いて
と入力してEnterを押します。 - 「天気を教えて」と入力するか、マイクのアイコンを押しながら話しかけます。
Alexaは「天気は晴れです」と答えるはずです。
EchoデバイスなどのAlexa搭載デバイスを使ってスキルをテストすることもできます。使用するデバイスは、スキルを作成したものと同じAmazonアカウントに登録する必要があります。
Alexa搭載デバイスを使ってスキルをテストする
- Alexa搭載デバイスに「アレクサ、開発キットの天気ボットを開いて」と話しかけます。
- Alexaがスキルを起動したら、「天気を教えて」とたずねます。
Alexaがスキルを見つけられない場合、Alexa搭載デバイスがスキルの作成に使用したものと同じAmazonアカウントに登録されていることを確認してください。
関連トピック
最終更新日: 2023 年 05 月 16 日