とある技術の開発日記

Diary of irregular phrase programmer

ASP.NET Core RC2 WebAPIでSwaggerを利用する

2016年6月7日~9日にかけてdotnetConf2016というイベントがありました。

www.dotnetconf.net

セッション内容はChannel9で公開されているので気になる方は見てみましょう。

今回は最近のAPI開発周りでよく耳にするSwaggerを利用してみたいと思います。

従来のASP.NETでもSwaggerを利用する事はできましたが、基本的な流れは変わりません。Swaggerの説明はみそ先生のブログが参考になるでしょう。

miso-soup3.hateblo.jp

手順

  1. NugetパッケージマネージャーでSwashbuckleをインストールする
  2. Startup.csにSwaggerを利用する設定を追記
  3. /swagger/uiにアクセスするとSwaggerUIが表示される

1.NugetでSwashbuckleをインストール

Install-Package Swashbuckle -Pre

.NET Core版はまだbetaなので-Preオプションを付けましょう

f:id:airish9:20160614004225p:plain

2. Startup.csにSwaggerを利用する設定を追記

サービスの設定でSwaggerGenServiceCollectionExtensions.AddSwaggerGenを呼び出して。
アプリケーションの設定でSwaggerGenBuilderExtensions.UseSwaggerGenSwaggerUiBuilderExtensions.UseSwaggerUiを呼び出せばOKです。

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddSwaggerGen();  // Add
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.UseMvc();

    app.UseSwaggerGen(); // Add
    app.UseSwaggerUi();  // Add
}

3. /swagger/uiにアクセスするとSwaggerUIが表示される

f:id:airish9:20160614010001p:plain

コンフィグの方法がCoreでよく利用するDIになっている以外は基本的に従来と同じで簡単ですね。

Web API: The Good Parts

Web API: The Good Parts

Build 2016で発表された、Micorosft Bot Frameworkが楽しそうだったので少し動かしてみた

日本時間の昨夜からBuild 2016が開催されました。

Keynoteの様子や全体のまとめはぶちざっきを見ると良いかと思います。

//build/ 2016 Day 1 Keynote | ブチザッキ

//build/ 2016 Day 1 で発表されたリンクあれこれ | ブチザッキ

色々な発表があったのですが、この中で私が注目したのは「Microsoft Bot Framework

ChatOpsという言葉もありますが、最近はSkypeやSlackなどチャットツールの利用頻度が圧倒的に高くなっていますし、Hubotを利用してSlackのBotを作成している方も少なからず居ると思います。

今回発表されたMicrosoft Bot FrameworkではC#やNode.jsを利用して簡単にBotを作成する事ができます。かつ、作成したBotは登録する事で他のWebサービスと簡単に連携する事ができます。

サンプルを少し触ってみたのでご紹介します。詳細な説明は他の方がやってくれることでしょう・・・。

docs.botframework.com

GitHubにサンプルコードもあるので眺めてみるとBot周りのASP.NET WebAPIクラスが増えているのが確認できます。

github.com

ソリューション構成

ASP.NET WebAPIで開発したことある方ならお馴染みのソリューション構成です。 f:id:airish9:20160331094057p:plain

コントローラーの中身はこんな感じ。

using System;
using System.Linq;
using System.Threading.Tasks;
using System.Web.Http;

using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Connector.Utilities;

namespace Microsoft.Bot.Sample.EchoBot
{
    [BotAuthentication]
    public class MessagesController : ApiController
    {
        /// <summary>
        /// POST: api/Messages
        /// receive a message from a user and reply to it
        /// </summary>
        public async Task<Message> Post([FromBody]Message message)
        {
            return await Conversation.SendAsync(message, () => new EchoDialog());
        }
    }
}

Microsoft.Botの名前空間にBot周りのクラスが定義されています。 BotAuthentication属性やMessageクラス、Microsoft.Bot.Builder.Dialogs.IDialogを実装しているクラス(ここではEchoDialog

Botの主な動作はMicrosoft.Bot.Builder.Dialogs.IDialogStartAsyncを実装してIDialogContext.Wait(ResumeAfter<Message> resume)を呼び出すことで動作します。

ResumeAfterはジェネリクスで指定されている型の引数とIDialogContextのデリゲートです。

public delegate Task ResumeAfter<in T>(IDialogContext context, IAwaitable<T> result);

サンプルソースを参考にして実装するとこんな感じです

        public async Task StartAsync(IDialogContext context)
        {
            context.Wait(MessageReceivedAsync);
        }

        public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<Message> argument)
        {
            var message = await argument;

            // << ここで入力された内容を処理する >>

            // メッセージを返却する
            await context.PostAsync(string.Format("入力したメッセージは {0} ねっ?", message.Text));

            // 入力待ち状態で入力を受け付ける
            context.Wait(MessageReceivedAsync);

        }

デバック方法

BotのEmulatorツールが公開されています。

docs.botframework.com

作成したWeb APIをビルド&デバック状態にしてEmulatorからBotと会話する事が出来ます。(単純に指定したエンドポイントにPOSTリクエストを投げているだけっぽい?)

f:id:airish9:20160331101641p:plain

公開&連携

今回は以下のページを参考にしてAzure WebAppで作ったAPIをホストして、Bot FrameworkのページからBotの登録を行いました。

docs.botframework.com

登録するとAPIIDとKeyが発行されるのでWeb.configを書き換えましょう。

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301879
  -->
<configuration>
  <appSettings>
    <!-- update these with your appid and one of your appsecret keys-->
    <add key="AppId" value="hanayobot" />
    <add key="AppSecret" value="YourAppSecret" />
  </appSettings>

後は管理画面右側の連携したいサービスからADDすれば追加できます。Web Hook対応のサービスからなら登録できるはずなのでBotライフを楽しみましょう

f:id:airish9:20160331104915p:plain

うまくできなかった事

  • 管理画面の「Test connection to your bot」で会話できるはずなのですが、sendボタンを押しても無反応だった・・・
  • Web Chatで作成されたタグを仕込んでもbotが無反応だった。

認証系っぽい…。

TwilioとASP.NET MVCで簡単なアンケートプログラムの作り方

f:id:airish9:20150701163541p:plain

しばらく間が空きましたがTwilioネタの3回目になります。当初の目的であったアンケートシステムを作るうえで必要な、キー入力をTwilioで処理する方法をご紹介します。

前回の記事はコチラになります。

blog.hamamotsu.jp

前回は電話をかけるとTwilioで自動音声を再生して電話を切るだけでしたが、今回は相手からの操作を受け取って処理してみましょう。

Gatherタグを使用してユーザーからの入力を処理する

Twilioからのリクエストには様々なパラメータがありますが、今回はFromとToパラメータを使用して電話をかけてきた発信先と発信元を判断できるようにしました。 相手からの入力を処理する場合はBeginGatherを使用して処理を行います。numDigitsパラメータで入力する桁数を指定して、finishOnKeyパラメータで入力の終わりを検出します。actionとmethodで入力した内容を処理するURIを指定する事で入力後の処理へ引き継ぎます。

public ActionResult Sample(string From, string To, string CallSid)
{
    var response = new TwilioResponse();
    if (!string.IsNullOrEmpty(From))
    {
        var msg = "From is ";
        msg = (From == "+819012345678") ? msg += "TwilioUser" : msg += From;

        response.Say(msg);
    }
    response.BeginGather(new { numDigits = 2, action = "http://mytwiliowebsite.azurewebsites.net/TwilioSample/Call", method = "POST", finishOnKey = "#" })
        .Say("Hello")
        .Play("http://mytwiliostorage.blob.core.windows.net/music/friend.mp3")
        .Pause(30)
        .EndGather();

    response.Say("Goodbye");
    return TwiML(response);
}

返却されるXML(TwlML)は次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<Response>
  <Gather numDigits="2" action="http://mytwiliowebsite.azurewebsites.net/TwilioSample/Call" method="POST" finishOnKey="#">
    <Say>Hello</Say>
    <Play>http://mytwiliostorage.blob.core.windows.net/music/friend.mp3</Play>
    <Pause length="30" />
  </Gather>
  <Say>Good bay</Say>
</Response>

ブラウザから実行するとFromパラメータが存在しないため電話番号を通知するSayタグは存在しません。 番号入力を受け取った後の処理の例は以下の様になります。

入力後の処理を作成する

Gatherタグから呼び出されるURLはDigitsパラメータを使用して作成するのがポイントです。

public ActionResult Call(string From, string To, string CallSid, string Digits)
{
    var response = new TwilioResponse();
    response.Say("Thank you call");

    switch (Digits)
    {
        case "1":
            response.Say("Digits is one.");
            break;

        case "2":
            response.Say("Digits is two.");
            response.Record(new { maxLength = 10, action = "http://mytwiliostorage.azurewebsites.net/TwilioSample/Recorded" });
            break;

        case "10":
            response.Say("Digits is ten.");
            break;
        default:
            break;
    }

    response.Say("Goodbye Twiliouser");
    return TwiML(response);
}

Digitsパラメータで入力されたキーを判定します。今回の例では'2'が入力された時は10秒間の音声を録音を行っていますが。入力されたキーごとに集計すればアンケートシステムとなります。

まとめ

  1. ユーザーからの入力待ちにはGatherタグを使用する
  2. Gatherタグで指定したURLにはDigitsパラメータが送信されるので、Digitsパラメータを元に処理を分岐する。

このようにアンケートアプリ程度なら簡単に作成する事ができます。