Visual StudioでAlexaスキル開発。C#で。複数インテントに応答する。


はじめに

Visual StudioでAlexaスキルのコーディングを行ってAWS Lambdaにデプロイし、それを実際に動かすところまではこちらの記事に書きました。
そこではLaunchRequestかそうでないか(IntentRequestか)でAlexaの応答を変更するだけの至極単純なスキルにしていました。

今回はもう少し作り込んで、IntentRequestだった場合にそれが何のインテントなのかによって更に応答を変化させるようにしてみましょう。

対話モデルにインテントを追加

まずはAlexa開発者コンソールに移動し、前回作った「 MyFirstCSharpSkill」の対話モデルにインテントを追加します。
Alexaに「挨拶して」と話しかけたら「こんにちは」と挨拶を返してくれるようにしてみましょう。
「挨拶して」に対して発行されるインテントを「GreetingIntent」として追加します。

名前をつけてカスタムインテントを作成します。

そして、以下のように申し訳程度のサンプル発話を登録します。
ユーザーからこれらの発話があった場合にGreetingIntentが発行されます。

対話モデルに変更を加えたので、ビルドします。
これで、「サンプル呼び出しで挨拶して」と言うとGreetingIntentがAWS Lambdaに送られます。

AWS Lambda側の処理を変更

Visual Studioで前回作ったMyFirstCSharpSkill_Lambdaプロジェクトを開きます。

コードが泥臭いのはとりあえず目をつむってください。
より良い書き方はいずれ。

さて、以下が変更を加えたFunctionHandlerメソッドです。
どこが変更、というか追加されたかというと中盤あたりの「インテント名で場合分け」というコメントのあたりからです。
IntentRequestオブジェクトを取得して、そこからインテント名を取得し、それに従って処理を場合分けしています。

:FunctionHandlerメソッド

        /// <summary>
        /// A simple function that takes a string and does a ToUpper
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public SkillResponse FunctionHandler(SkillRequest input, ILambdaContext context)
        {
            //ResponseプロパティにAlexaに喋らせる内容などを突っ込んでいく
            var skillResponse = new SkillResponse
            {
                Version = "1.0",//お約束
                Response = new ResponseBody()//お約束
            };


            //リクエストタイプが「LaunchRequest」かそれ以外の「IntentRequest」か判別する
            //今回はスキル起動時に送られる「LaunchRequest」のときとそれ以外のときで異なるレスポンスを返すようにした。
            if (input.Request.Type == nameof(Alexa.NET.Request.Type.LaunchRequest))
            {
                skillResponse.Response.OutputSpeech = new PlainTextOutputSpeech
                {
                    Text = "スキルを起動しましたよ。"
                };
            }
            else
            {
                //LaunchRequest以外はこちら
                //つまりIntentRequestもこちら

                //IntentRequestの場合
                //SampleIntentとGreetingIntentの2種類+ビルトインインテント数種類がある
                //今回は自分で登録したSmapleIntentとGreetingIntentだけを扱う。

                //RequestをIntentRequestにキャスト
                var intentRequest = (IntentRequest) input.Request;
                //インテント名はこのIntentRequestオブジェクトが持っている
                var intentName = intentRequest.Intent.Name;

                //インテント名で場合分け
                if (intentName == "SampleIntent")
                {
                    skillResponse.Response.OutputSpeech = new PlainTextOutputSpeech
                    {
                        Text = "サンプルインテントでした。"
                    };
                }
                else if (intentName == "GreetingIntent")
                {
                    skillResponse.Response.OutputSpeech = new PlainTextOutputSpeech
                    {
                        Text = "こんにちは。グリーティングインテントでした。"
                    };
                }
                else
                {
                    skillResponse.Response.OutputSpeech = new PlainTextOutputSpeech
                    {
                        Text = "どれでもありませんでした。"
                    };
                }
            }


            //セッション終了させる。
            skillResponse.Response.ShouldEndSession = true;

            return skillResponse;
        }

テスト

試してみましょう。
SampleIntentGreetingIntentをそれぞれ呼び出してみると、以下のように対応した応答が帰ってくるのがわかります。

おわりに

これで、より複雑な対話をアレクサと楽しむことができるようになりました。