【スプラトゥーン2】ブキのスペシャルを教えてくれるAlexaスキルを作った

#はじめに
私は週末スプラトゥーンプレイヤーですが、辛いところが一つあります。
それはアップデートで次々とブキが増えていくため、どのブキがどのスペシャルか、覚えきれんのです。
ガチヤグラではハイパープレッサーの有無で戦略が大きく変わるように、有利に立ち回るためにはスペシャルを事前に把握することが大切ですが、試合が始まるとコントローラー操作で手が塞がってしまうため、調べる術がないのです。

今回Amazonプライムセールでecho dotがお財布に優しい値段でしたので、手が使えないなら口を使えばいいじゃない…という発想で作ってみました。

#使い方
私「アレクサ、スプラでスプラシューターのスペシャルは？」
↓
アレクサちゃん「スーパーチャクチ」

「アレクサ」は、ウェイクワードといって、アレクサを立ち上げるための必須ワードです。
一応「エコー」とか「アマゾン」とかにも変えられるみたいですが、アレクサが一番しっくりくる気がします。

「スプラで」はカスタムスキルを呼び出すために必要なワード（呼び出し名）です。
本当はこれ無しで応答してもらえると楽なんですが、制約上仕方ないですね。

#構成
Amazon Echo Dot →　Alexa →　AWS Lambda

Amazon Echo Dotで音声の聞き取りを行い、Alexaで音声処理をして、AWS Lambdaに値を渡します。
AWS Lambdaで値を処理して、逆経路でデータを返していきます。


#必要となるアカウント
■Alexaコンソールのアカウント
→こちらは普段使っているAmazon.co.jpのアカウントでログイン可能です。
UI的に分かりづらく、「Amazon Developer アカウントを作成」というボタンからアカウントをつくってしまうと、Amazon.com用のアカウントが作成されてしまうようで、後々に影響がでますので要注意です。

■AWS(Lambda)のアカウント
→こちらはAmazon.co.jpのアカウントとは別に用意する必要があります。
無料枠の中で利用する分にはお金はかかりませんが、クレジットカードの登録や電話番号での認証などが必要です。

#設定とソースコード
Alexaのコンソール画面に表示がありますが、大きく分けて以下4ステップがあり、これらをすべて設定します。
![alexaconsole.png](https://qiita-image-store.s3.amazonaws.com/0/104983/cbea404c-58ba-e2a3-94cb-c2c2b0899f1e.png)

なお設定については、[Amazon様公式のチュートリアル](https://developer.amazon.com/ja/blogs/alexa/post/6e716e5c-55b0-445b-b936-9cfac4712e7b/training-1)が分かりやすいと思いますので、そちらを推奨します。

今回のスキルでは、ブキ名が変数（スロット）となりますので、以下のようにインテントを設定します。
![intent.png](https://qiita-image-store.s3.amazonaws.com/0/104983/ae88da1c-3314-0c28-7092-aaa7c1b1cc2d.png)

スロットタイプはカスタムを選択し、ここにすべてのブキ名を記述します。
![weaponslot.png](https://qiita-image-store.s3.amazonaws.com/0/104983/c2bfa7bd-206a-58d0-4aba-e85c6b7fb876.png)

あとはAWS Lambda側で、処理を記述します。

```javascript
'use strict';
const Alexa = require('alexa-sdk');

const APP_ID = undefined;
const SKILL_NAME = 'スプラ2スペシャル';
const HELP_MESSAGE = 'ブキのスペシャルを聞いてください';
const HELP_REPROMPT = 'どうしますか';
const STOP_MESSAGE = 'バイバイ';

const weapon_special = {
    'スプラシューター':'スーパーチャクチ',
    'スプラシューターコラボ':'ジェットパック',
    'わかばシューター':'インクアーマー',
    ～省略～
    'キャンピングシェルターソレーラ':'ボムピッチャー(カーリングボム)',
    'スパイガジェット':'スーパーチャクチ',
    'スパイガジェットソレーラ':'イカスフィア'
};

const handlers = {
    'LaunchRequest': function () {
        this.emit(':responseReady');
    },
    'GetWeaponSpecial': function () {
        let speechOutput;
        if(this.event.request.intent.slots.query.resolutions.resolutionsPerAuthority[0].status.code === "ER_SUCCESS_MATCH"){
            speechOutput = weapon_special[this.event.request.intent.slots.query.resolutions.resolutionsPerAuthority[0].values[0].value.name];
        }else{
            speechOutput = weapon_special[this.event.request.intent.slots.query.value];
        }
        this.response.cardRenderer(SKILL_NAME, speechOutput);
        this.response.speak(speechOutput);
        this.emit(':responseReady');
    },
    'AMAZON.HelpIntent': function () {
        const speechOutput = HELP_MESSAGE;
        const reprompt = HELP_REPROMPT;

        this.response.speak(speechOutput).listen(reprompt);
        this.emit(':responseReady');
    },
    'AMAZON.CancelIntent': function () {
        this.response.speak(STOP_MESSAGE);
        this.emit(':responseReady');
    },
    'AMAZON.StopIntent': function () {
        this.response.speak(STOP_MESSAGE);
        this.emit(':responseReady');
    },
};

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

```

#問題
1:ブキ名を解読できない
ブキ名が造語なためか、アレクサちゃんが認識してくれない場合が多いです。

例えば、
バケットスロッシャー→bucketts ロシア
…ワールドカップはもう終わった

スプラスコープ→splus コープ
…生協やない

など。

スロットタイプの設定で、シノニム（同義語）に誤認識されやすい単語を入れとくことである程度対応できますが、本来は同じ意味をもつ別の単語を入れるための機能ですので、正攻法ではないですね。

2:勝手に漢字に変換される
例えば、
ホクサイ→北斎
ヒッセン→筆洗
など。

こちらはシノニムに漢字の単語を入れておくことで対応可能です。
スロット値に合わす形でカタカナで値を渡してくれれば助かるんですが…

#今後やりたいこと
- スキルの公開
著作権関連が厳しいらしく、任天堂の許可を取らないとだめっぽいので、ちょっとハードルが高いかも。
モンハン関係のスキルを開発される方がいらしゃって、その方はカプコンから許可をとったようです。
[Amazon Alexaスキル作成時に気をつけること　その１ - Qiita](https://qiita.com/second113/items/161eb3d30598e78f63d6)

- 聞き取り精度の向上
力技でシノニムに単語を追加していく。

#おわりに
ベストプラクティスがあれば教えていただけると幸いです。