himanago

Azure・C#などのMS系技術やLINE関連技術など、好きな技術について書くブログ

Alexa.NET を使うなら ResponseBuilder がおすすめ

前置き

技術書典7 で本を出します!
Azure && (C# || ノンコーディング) でクロスプラットフォームスマートスピーカースキル開発する本です。

techbookfest.org

いままで試してきたことをまとめたいなぁと思って書いていたのですが、書いているといろいろ気づくこととか新たに知ることも多かったりします。

そこで、技術書典までにちょこちょこそういった小ネタを少しずつブログのほうにも載せていこうと思います。

C# で Alexa開発

今回は Alexaスキルの開発の話です。
普段 Alexa.NET という NuGetパッケージを使ってC#+Azure Functions でスキル開発しています。

www.nuget.org

で、このSDKなんですが、よくよく見てみると便利な機能がありました。

今回紹介するのは、そのひとつ ResponseBuilder です。

ResponseBuilder とは

Alexa に返すレスポンスオブジェクトを簡単に作れる便利クラスです。

代表的な機能は TellAsk の2つです。

このメソッドの戻り値をそのままHTTPレスポンスで返してしまえばOKという、非常にシンプルで使い勝手のいい機能です。

Alexa のレスポンス

Alexa のレスポンスは shouldEndSessiontrue にするか false にするかで対話を継続するかどうかを切り替えることができます。

shouldEndSessionfalse にして返すとAlexa がしゃべったあとユーザーの返答を待つためにリスニング状態でスキルのセッションが維持されます。

ResponseBuilder.Tell

Tell メソッドは、単純なテキストのメッセージの読み上げをセッションを継続せずに行います(shouldEndSession: trueでレスポンスを作ってくれる)。

Tell は「伝える」という意味であり、質問ではありません。なのでユーザーの返答が不要なときに使うことになります。

ResponseBuilder.Ask

対して Ask メソッドは、単純なテキストのメッセージの読み上げをセッションを継続して行います(shouldEndSession: falseでレスポンスを作ってくれる)。

Ask は「尋ねる」という意味で、質問です。だからユーザーの返答が必要。わかりやすい!

中学生でも知っているような明確な単語で動きをシンプルに定義していてとてもよいです。こういうSDKの作り方、見習いたい。

サンプルコード

Azure Functions でのコードです(なんてことない「はい」「いいえ」だけの会話)。

いちいち response.ShouldEndSession = false; とか書かなくていいのですっきりです。

あと地味にビルトインインテントを定数で用意してくれてるのもポイント高い。

using Alexa.NET;
using Alexa.NET.Request;
using Alexa.NET.Request.Type;
using Alexa.NET.Response;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Threading.Tasks;

namespace Sample
{
    public static class AlexaEndpoint
    {
        [FunctionName(nameof(AlexaEndpoint))]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            var request = JsonConvert.DeserializeObject<SkillRequest>(await req.ReadAsStringAsync());

            // レスポンス用の変数を宣言
            SkillResponse response = null;

            switch (request.Request)
            {
                case LaunchRequest lr:
                    response = ResponseBuilder.Ask(
                        "こんにちは。お元気ですか?", new Reprompt("元気ですか?"));
                    break;

                case IntentRequest ir:
                    switch (ir.Intent.Name)
                    {
                        case BuiltInIntent.Yes:    // 「はい」と答えたとき
                            response = ResponseBuilder.Ask(
                                "それはよかったです。まだお話ししますか?", new Reprompt("まだお話しますか?"));
                            break;

                        case BuiltInIntent.No:     // 「いいえ」と答えたとき
                            response = ResponseBuilder.Tell("そうですか。それではまた元気なときにお話ししましょう。");
                            break;

                        default:
                            response = ResponseBuilder.Tell("またお話ししましょう。");
                            break;
                    }
                    break;
            }

            return new OkObjectResult(response);
        }
    }
}

C# 8.0 の正式リリースが来たら、switch式でもっとすっきりしそうな可能性を秘めてる気がする。

おわりに

ということで、あまり記事として紹介されていない話かなと思ったので紹介してみました(GitHubのREADMEにはちゃんと書いてある)。

技術書典で頒布する本にはこういった話もたくさん入れつつ体系的にまとめようとしています(まだできてないw)。

『AzureでつくるクロスプラットフォームAIアシスタントスキル』、興味のある方はぜひm(_ _)m

サークルチェックもお願いします! techbookfest.org