前置き
技術書典7 で本を出します!
Azure && (C# || ノンコーディング) でクロスプラットフォームなスマートスピーカースキル開発する本です。
いままで試してきたことをまとめたいなぁと思って書いていたのですが、書いているといろいろ気づくこととか新たに知ることも多かったりします。
そこで、技術書典までにちょこちょこそういった小ネタを少しずつブログのほうにも載せていこうと思います。
C# で Alexa開発
今回は Alexaスキルの開発の話です。
普段 Alexa.NET という NuGetパッケージを使ってC#+Azure Functions でスキル開発しています。
で、このSDKなんですが、よくよく見てみると便利な機能がありました。
今回紹介するのは、そのひとつ ResponseBuilder
です。
ResponseBuilder とは
Alexa に返すレスポンスオブジェクトを簡単に作れる便利クラスです。
代表的な機能は Tell
と Ask
の2つです。
このメソッドの戻り値をそのままHTTPレスポンスで返してしまえばOKという、非常にシンプルで使い勝手のいい機能です。
Alexa のレスポンス
Alexa のレスポンスは shouldEndSession
を true
にするか false
にするかで対話を継続するかどうかを切り替えることができます。
shouldEndSession
を false
にして返すと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