2. Amazon Alexaで音声から引数を受け取る

# 連載記事
前後関係があるため順番に読んでもらえると分かりやすくなっています。

[1. Amazon AlexaとFire TVでHello Worldを試してみる \- Qiita](https://qiita.com/tochi/items/4da38b02b424926d1095)
[2. Amazon Alexaで音声から引数を受け取る \- Qiita](https://qiita.com/tochi/items/f96ca5979ec2ea6387d8)
[3. Amazon AlexaのCustom Slot Typesを設定する \- Qiita](https://qiita.com/tochi/items/a0342f0882b2c642d40c)
[4. Amazon AlexaからHerokuのRailsにつなぐ \- Qiita](https://qiita.com/tochi/items/183658fabd1416028065)
[5. Amazon Alexaで会話を続ける（セッションを引き継ぐ） \- Qiita](https://qiita.com/tochi/items/ec613355e4f5913a8755)
[6. Amazon Alexa のスキルを日本語化する \- Qiita](https://qiita.com/tochi/items/682adf708bb7fd0f1ca9)
[7. 自作した日本語のAlexa SkillをEcho dotで動かす \- Qiita](https://qiita.com/tochi/items/db9542e191bbdb7f77c2)

#　はじめに
前回はFire TV > Alexa > Lambda でHello Worldを作りました。

[Amazon AlexaとFire TVでHello Worldを試してみる \- Qiita](http://qiita.com/tochi/items/4da38b02b424926d1095)

前回のHello Worldは決められた音声に対して決められた回答を返すだけのシンプルなものでした。
今回は少し発展させて話しかけた音声内の言葉を引数として受け取り、その受け取った引数によって動的に話す言葉を変えてみます。

入力音声の中に引数を設定する
----

入力音声の定義は、Amazon開発者ポータルのAlexaからUtterancesを設定します。

[Amazon開発者ポータル](https://developer.amazon.com/ja/)

``` SampleUtterances
HelloWorldIntent hello my name is {firstName}
HelloWorldIntent say hello my name is {firstName}
HelloWorldIntent say hello world my name is {firstName}
```

`{firstName}`の所が引数の設定です。
例えば「Hello my name is Bob」と話しかけると`HelloWorldIntent`が呼び出され、その際に`firstName`という引数名で「Bob」という単語が受け渡されます。

Intent Schemaを定義する
----

次にLambdaにデータを渡すためのschemaを定義します。

``` IntentSchema
{
  "intents": [
    {
      "intent": "HelloWorldIntent",
      "slots": [
        {
          "name": "firstName",
          "type": "AMAZON.US_FIRST_NAME"
        }
      ]
    }
  ]
}
```

`slots`の中身が引数の定義です。
`name`は引数名で今回は`firstName`です。
`type`とはAmazon側で定義されている引数の型の様なものです。
型には他にも多くのものが存在しており随時追加されているようです。

[Slot Type Reference \- Amazon Apps & Services Developer Portal](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/built-in-intent-ref/slot-type-reference)

Slot typeの何が便利かというと、例えば`AMAZON.DATE`の型で定義すると「today」という音声入力にたいして`2017-09-09`の様に今日の日付でAlexaがリクエストを投げてくれます。
色々な音声入力のパターンをAlexaが吸収して統一した形式に変換してくれるので、数多ある音声入力のパターンをシンプルにすることができそうです。

今回は`AMAZON.US_FIRST_NAME`という型にしています。これはUSでよく使われている名前を網羅していて「steve」とか「john」とかを受け取れます。
もちろん、このSlot typeは自分で独自の型を定義することも可能です。

Alexaの設定
----

上記のUtterancesとIntent Schemaの設定を行ったAlexaの設定は下記のようになります。

![スクリーンショット_2017-09-09_16_20_53.png](https://qiita-image-store.s3.amazonaws.com/0/4529/650a3957-87a9-b87e-076c-253c52e8721e.png "スクリーンショット_2017-09-09_16_20_53.png")

これでAlexaの設定は完了です。
次にLambdaのプログラムを修正します。

Lambdaでfirst nameを受け取って喋らせる
----

プログラムは前回のHello worldを流用します。

[Amazon AlexaとFire TVでHello Worldを試してみる \- Qiita](http://qiita.com/tochi/items/4da38b02b424926d1095)

``` index.js
'use strict';
var Alexa = require("alexa-sdk");

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.registerHandlers(handlers);
    alexa.execute();
};

var handlers = {
    'LaunchRequest': function () {
        this.emit('SayHello');
    },
    'HelloWorldIntent': function () {
        this.emit('SayHello')
    },
    'SayHello': function () {
        this.emit(':tell', 'Hello World!' + this.event.request.intent.slots.firstName.value);
    }
};

```

今回変更したのは最後の方にある`this.emit(':tell', 'Hello World!' + this.event.request.intent.slots.firstName.value);`だけです。
`this.event.request.intent.slots.firstName.value`でAlexaから渡ってきた`firstName`のテキストを受け取り、「Hello world!」につなげて名前を喋らせています。

結果
----

僕「Tell hello world hello my name is Bob.」
Alexa「Hello world! Bob」

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Amazon Alexaで音声から引数を受け取る <a href="https://t.co/lgBEACc6sR">https://t.co/lgBEACc6sR</a> <a href="https://twitter.com/YouTube">@YouTube</a>さんから</p>&mdash; tochi (@aguuu) <a href="https://twitter.com/aguuu/status/907046628976029696">2017年9月11日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

Let's enjoy Alexa.


参考
----
http://dev.classmethod.jp/cloud/introduction-of-alexa-skill-kit/