
今回は、Amazon Echoの特長であるスキルを開発してみます。開発というと何か難しそうな印象を受ける単語ですが、結構簡単に作成できる内容なので、皆さんも挑戦して見られることをオススメします。
必要なもの
- Amazon Echo
もちろん有った方が楽しいですが、無くてもシミュレータでテストすることは可能です。 - AWSアカウント
Alexa Skills Kitを使って、音声ユーザインタフェイス(VUI)を作成するために、AmazonWebServiceのLambdaを使うために必要です。 - Amazon開発者アカウント
開発者ポータルで簡単に作成可能です。Lambdaで作成した音声ユーザインタフェイスのコードをスキルとして登録する際に必要です。
開発者コンソールでAlexaスキルを開発する
Amazon開発者コンソールを使って、Alexaスキル開発の元になる部分を作成します。
1. Amazon開発者コンソールにサインインします。

2. [ALEXA]タブをクリックして、表示された[Alexaで開発を始める]の一覧から[Alexa Skill Kit]の[始める]ボタンをクリックします。
3. [Alexa Skill Kitを使用してAlexaスキルを開発する]画面で[新しいスキルを追加する]ボタンをクリックします。

4. [Alexaスキルを作成]画面で[スキルの種類:カスタム対話モデル]、[言語:Japanese]、[スキル名:(都道府県クイズ)]、[呼び出し名:(トドウフケンクイズ)]を入力して[保存]ボタンをクリックします。

5. 保存された[Alexaスキルの作成]画面の[次へ]ボタンをクリックします。
6. 表示された[対話モデル]画面で[スキルビルダーを起動する(ベータ)]ボタンをクリックします。

7. [Skill Builder]画面が表示されます。

8. [ADD+]をクリックして、[Create a custom intent]オプションを選択して”QuizIntent”を追加します。

9. 追加された[QuizIntent]編集画面を表示します。

10. 画面右側の[Intent Slots]部分に新しいスロット[Answer]を追加します。([Create a new slot]に”Answer”と入力して[Add]ボタンをクリックします)

11. 追加された[Answer]部分の[Choose a slot type…▼]を選択して、オプションを選択して、Alexaが音声を認識するための型を定義します。

例えば。AMAZON.Numberを選べば、「ゴ」を「5」だと認識してくれます。AMAZON.Regionであれば、「アイチ」が「愛知県」と認識されます。
12. 同様に、[ADD+]をクリックして[Use an existing intent from the built-in library]オプションを選択して[AMAZON.StartOverIntent]と[AMAZON.RepeatIntent]を選択して[Add Intents]ボタンをクリックします。
13. 追加されたリストから[AMAZON.StartOverIntent]を選択します。
14. [AMAZON.StartOverIntent]設定画面で[Sample Utterances]に”クイズスタート”と入力して[+]をクリックします。

15. [Save Model][Build Model]ボタンをクリックして設定をビルドします。
16. ビルド正常終了が通知されたら[Configuration]ボタンをクリックします。
Alexa Skills Kitで編集する
AWSアカウントでサインインしてスキルの元になるコードを追加していきます。
1. AWSアカウントでサインイン後、[AWSサービス]を選択する画面で[Lambda]をクリックします。 
2. 表示された[AWS Lambda]画面で[関数の作成]ボタンをクリックします。

3. 関数の作成]画面で[設計図]を選択して、表示された設計図一覧から[alexa-skill-kit-sdk-factskill]を選択して[設定]ボタンをクリックします。

4. 基本的な情報]画面で、作成する関数の[名前:(AlexaPrefQuiz)][ロール名:(SampleRole)]を入力していきます。

5. 関数の作成]ボタンをクリックします。
6. 作成された関数の画面が表示されます。

7. 画面をスクロールして表示されたコード[index.js]を編集します。

"use strict";
const Alexa = require('alexa-sdk');
// ステートの定義
const states = {
QUIZ: '_QUIZMODE',
START: "_STARTMODE"
};
// クイズ内容の定義
const questions = [
{'q':'日本一の湖がある都道府県は?', 'a':'滋賀県'},
{'q':'日本一大きな面積の都道府県は?', 'a':'北海道'},
{'q':'日本で一番人口が多い都道府県は?', 'a':'東京都'},
];
var languageString = {
"ja-JP": {
translation: {
"WELCOME_MESSAGE": "都道府県クイズへようこそ。 ",
"HELP_MESSAGE": "正解だと思う都道府県を答えてください。",
"START_MESSAGE": "クイズを始める場合は「クイズスタート」と話してください。 ",
"ANSWER_OK_MESSAGE": "正解です。 ",
"ANSWER_NG_MESSAGE": "残念、不正解です。 ",
"GAME_OVER_MESSAGE": "全ての問題が終わりました。",
"UNHANDLED_MESSAGE": "すみません、聞きとれませんでした。"
}
}
};
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.resources = languageString;
alexa.registerHandlers(handlers, startStateHandlers, quizHandlers);
alexa.execute();
};
var handlers = {
'LaunchRequest': function () {
this.handler.state = states.START;
this.emitWithState("QuizStart");
},
"AMAZON.StartOverIntent": function() {
this.handler.state = states.START;
this.emitWithState("QuizStart");
},
'AMAZON.HelpIntent': function () {
this.emit(':ask', this.t("HELP_MESSAGE") + this.t("START_MESSAGE"));
},
'Unhandled': function () {
var speechOutput = this.t("UNHANDLED_MESSAGE") + this.t("START_MESSAGE");
this.emit(":ask", speechOutput, speechOutput);
}
};
var startStateHandlers = Alexa.CreateStateHandler(states.START, {
"QuizStart": function () {
this.handler.state = states.QUIZ;
this.attributes['next'] = 1;
this.attributes['current'] = 0;
var message = this.t("WELCOME_MESSAGE") + this.t("HELP_MESSAGE") + questions[0].q;
var reprompt = questions[0].q;
this.emit(':ask', message, reprompt);
console.log(message);
}
});
var quizHandlers = Alexa.CreateStateHandler(states.QUIZ, {
'QuizIntent': function() {
var usersAnswer = this.event.request.intent.slots.Answer.value;
if(!usersAnswer){
this.emitWithState("Unhandled");
}
var resultMessage;
if(questions[this.attributes['advance']-1].a == usersAnswer){
resultMessage = this.t("ANSWER_OK_MESSAGE");
this.attributes['current'] ++;
}else{
resultMessage = this.t("ANSWER_NG_MESSAGE");
}
if(this.attributes['next'] < questions.length){
var nextMessage = questions[this.attributes['next']].q;
this.attributes['next'] ++;
this.emit(':ask', resultMessage+nextMessage, nextMessage);
}else{
var endMessage = this.t("GAME_OVER_MESSAGE", this.attributes['current']);
this.handler.state = '';
this.attributes['STATE'] = undefined;
this.attributes['next'] = 0;
this.emit(':tell', resultMessage + endMessage, endMessage);
}
},
"AMAZON.RepeatIntent": function() {
var nextMessage = questions[this.attributes['next']-1].q;
this.emit(':ask', nextMessage, nextMessage);
},
'Unhandled': function() {
var reprompt = this.t("UNHANDLED_MESSAGE") + this.t("HELP_MESSAGE");
this.emit(':ask', reprompt, reprompt);
}
});
8. 画面上部にスクロールして、[トリガーの追加]部分から[Alexa Skill Kit]を選択します。

9. [トリガーの設定]で[追加]ボタンをクリックします。
10. [保存]ボタンをクリックします。
11. 画面に表示されている[ARN]部分の文字列をコピーします。

- AWS側での作業は以上です。
再度Amazon開発コンソール
1. コンソールの[スキル|設定]画面の[サービスエンドポイントのタイプ]で[AWS LambdaのARN]を選択します。
2. 表示された[デフォルト]部分にコピーした[ARN]を貼り付けます。

3. [次へ]ボタンをクリックします。
4. [テスト]画面が表示されます。
-
サービスシミュレーターでテスト
テスト画面まで表示されたら、実機が無くてもテストができます。[サービスシミュレーター]画面の[発話を入力してください]に[クイズスタート]([AMAZON.StartOverIntent]インテントに入力したキーワードです)と入力します。

サービスから応答が戻ってきたら成功です。応答が戻らない場合や「すいません」が戻るようであれば、AWS:Lambda側のコードを確認します。
実機でテスト
[サービスシミュレーター]でテストができたら、いよいよ実機でテストができるようになります。長くなってきたので実機でのテストは別で投稿します。
スポンサーリンク
最後までご覧いただき、ありがとうございます。

こんにちは!
Amazon echoゲットしたのでスキル作ってみたいと思い検索していたところ此方の記事を見つけ、参考にしながらスキルを作らせてもらってます。
「開発者コンソールでAlexaスキルを開発する」の9.が分からないです‥。
”例えば。AMAZON.Numberを選べば、「ゴ」を「5」だと認識してくれます。”とありますがAMAZON.Numberを選択した後はどのように操作・入力する必要があるのでしょうか?
実機でテスト楽しみにしてます!
コメントありがとうございます。
確かに分かりにくかったですね。ごめんなさい。
手順8.くらいから、画像付きで手順を修正しました。参考になればと思います。