Alexaスキルの定義されているスロット値以外も受け取る問題



# Alexaスキルが生成するeventデータ
Alxaスキルは、呼び出す先のAWS Lambdaのファンクション(または、独自のエンドポイントでも良い）へ、Amazon Echoから呼び出された情報を渡します。

その際、渡されるデータのトップレベルの項目は大きく分けると以下の4カテゴリ。

- version
    - alexa skill kitのバージョン？
- session
    - 現在のセッションの新規/継続、ID、アプリケーションのID、ユーザのIDなど。
- context
    - （sessionにも含まれますが）アプリケーションのIDやユーザのID。
    - デバイスのIDやAPIのアクセストークン
- request
    - インテントの呼び出しタイプ、タイムスタンプ、インテント名やスロットで拾えた値。

[こちらでも書いたが、](https://qiita.com/second113/items/161eb3d30598e78f63d6)このでrequestに含まれるスロットで拾える値は、事前に定義して**いない**値も取れてしまう。これは、カスタムスロットとして定義した場合も、Amazon提供のビルトイン・スロット（Amazon.Actorなど）を利用した場合にも発生する。例えば、スロットの値として「新垣結衣」しか設定していなかったとしても、「ナチス」などがあるインテントのスロット値として認識される。

# 問題
問題は、受け取った値がスロット値に定義されていたかどうかrequestから判断できるかどうか？である。例えば女優や俳優、アーティストなど（つまり、人）に対してのみ処理したい場合に、全く別のものが値として渡されてきたとして、それが判断できなければ、適切に処理を分岐できない。

ビルトイン・スロットのAmazon.ActorとAmazon.Artistを利用している場合のrequestのデータ（抜粋）を見てみる。　※それ以外の項目には、判断するためのデータが明らかに無し・・！


- スロットに定義されている（はずの）値の場合：新垣結衣

```json
   "request": {
        "type": "IntentRequest",
        "requestId": "amzn1.echo-api.request.c8563394-0efa-4568-8a22-a69343549ff8",
        "timestamp": "2018-07-03T11:01:32Z",
        "locale": "ja-JP",
        "intent": {
            "name": "ActorIntent",
            "confirmationStatus": "NONE",
            "slots": {
                "Answer": {
                    "name": "Answer",
                    "confirmationStatus": "NONE"
                },
                "AnswerArtist": {
                    "name": "AnswerArtist",
                    "value": "新垣結衣",
                    "confirmationStatus": "NONE"
                }
            }
        }
```


- スロットに定義されていない（はずの）値の場合：ナチス

```json
    "request": {
        "type": "IntentRequest",
        "requestId": "amzn1.echo-api.request.7ac73a18-2357-4a42-8280-e500db1e9996",
        "timestamp": "2018-07-03T10:35:19Z",
        "locale": "ja-JP",
        "intent": {
            "name": "ActorIntent",
            "confirmationStatus": "NONE",
            "slots": {
                "Answer": {
                    "name": "Answer",
                    "confirmationStatus": "NONE"
                },
                "AnswerArtist": {
                    "name": "AnswerArtist",
                    "value": "ナチス",
                    "confirmationStatus": "NONE"
                }
            }
        }
    }
```

お分かりいただけただろうか。

＃スロット名が微妙なのは、あとからAmaozon.Artistスロットを追加することを想定せずに設計しちゃったためなので、置いておいて・・・

Amazon.Artist用のスロット”AmazonArtist”に「ナチス」が入ってしまっています。その他の項目では、**見分けが付きそうにない・・・**。

[芸能人サーチ](https://www.amazon.co.jp/dp/B07DNWVWFY/ref=sr_1_1?s=digital-skills&ie=UTF8&qid=1528798094&sr=1-1&keywords=%E8%8A%B8%E8%83%BD%E4%BA%BA)では、受け取った値を元に処理しているが、これではナチスを調べにいってしまう。（情報のソースはWikipediaなので見つかってしまう）




# 解決策？

「芸能人の情報を検索できるよ」という趣旨の説明文を書いて申請すると、以下のようにリジェクトされちゃいます。

```text
スキル詳細に提示されている情報は、スキルのコアファンクションを正確に反映していません。スキルの長い詳細および短い詳細が、ユーザーがこのスキルを使用した際のコアファンクションを正確に説明する必要があります。 現在提示されております、スキルの詳細では「日本の俳優、女優、アーティスト」のみの情報を伝える機能と捉えられますが、その他一部の情報も対応しているようです。スキル詳細、またはスキルのコアファンクションの変更をお願いいたします。 
```
では、ご指摘＆提案いただいた「説明通りに動作するようスキルを修正する」 or 「説明を書き換える」について考えて見る。


## 説明通りに動作するようスキルを修正する
結論としては、難しい。

### カスタムスロットを利用している場合
（[芸能人サーチ](https://www.amazon.co.jp/dp/B07DNWVWFY/ref=sr_1_1?s=digital-skills&ie=UTF8&qid=1528798094&sr=1-1&keywords=%E8%8A%B8%E8%83%BD%E4%BA%BA)では、ビルトイン・スロットしか利用していないため、該当しないので検討のみ。）

最悪、定義している内容はAlexa Skill Kit上でJSONデータとして見れるため、AWS Lambdaなどのバックエンド側で同じリストを持っておき、入力値のチェックを行うことができるだろう。

しかしながら、普通の感覚では「Alexa側でやってくれ（判断可能な値を含んでをバックエンドに投げてくれ）」と思いませんか？なんのためのスロット定義なのか。シノニム設定やID設定くらいしか価値が無いことになる。

###ビルトイン・スロットを利用している場合
現在、Amazon.Actorなどのビルトイン・スロットは開発者プレビュー段階ではあるものの、何がスロットのリストに含まれているか公開されていない。そのため、カスタムスロットのようにバックエンド側で処理を分岐するために入力チェックを行うことは困難である。



## 説明を書き換える
「○○を対象にできる」という書きっぷりではなく、「○○などを対象にできる」というように変更すればリジェクトされないのではないか、と推測する。

＃正直、これしか無いのでは。まだ再申請していないので確証はない。