BEACHSIDE BLOG

MicrosoftとかC#を好むレンジャーの個人的メモ

チャットボットの会話のログを Table Storage に出力( Bot Framework )

今回は Azure の Table Storage に、チャットボットの会話のやり取りをロギングする方法を整理します。

前回は、ログ出力の重要な要素、IActivityLogger インターフェースについて概要を整理しました。それを応用して…と言いたいところですが、Nuget で用意されているライブラリを使うだけで簡単に実現できます。

https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/

Overview

Environment

  • Visual Studio 2017
  • .NET Framework 4.6
  • (NuGet) Microsoft.Bot.Builder v3.9

  • Azure のアカウントは必要です。そしてなんらかのリソースを作ると課金がかかる場合があるので、ご注意ください。

Table Storage の作成

リソースグループの作成

Azure のリソースグループについてざっくり説明しておきます。Azureでは、さまざまなサービスがありますのでたくさん作るとごっちゃごちゃになり、どれがどれに依存しているとかどのプロジェクトでどれを使っているかわからなくなりがちです。それを何らかの単位でグルーピングするための機能がリソースグループです。

私は、だいたいプロジェクト単位で作ります。あとで一括で削除しやすくするのが目的です。

前置きが長くなりましたが、Azure ポータル(portal.azure.com)にログインし、リソースグループのアイコンをクリックして作っていきましょう。今回は、「botbuilder-azure」という名前にしました。

f:id:beachside:20170828142226p:plain


そのリソースグループの中に、Storage を作ります。ここら辺は細かく操作方法は書きませんが、追加する際、検索で「blob」と入力するといい感じに Storage が検索できます。(tableだと検索出てこなかった…)

f:id:beachside:20170828142422p:plain


あとは適当のポチポチ作ればOKです。ちなみに、後でQueueとかも使う予定なので、Storage を作る際の項目「アカウントの種類」は、「汎用」を選択しました。

f:id:beachside:20170828142538p:plain

ちなみに今回の Storage のカウント名は「bot2azurestorage」にしています。

Bot.Builder.Azureを使ったアプリの作成

プロジェクトの作成

Bot のアプリケーションを作成するだけなので手順省略。 (前回のここらへんにあります)

Nuget パッケージの追加と更新

検索で「bot.builder.azure」と入力し、「Microsoft.Bot.Builder.Azure」をインストールしましょう。今回だと、バージョンは、3.2.3 になります。

f:id:beachside:20170828142920p:plain


そのほかのパッケージを最新にしておきましょう。恒例の「パッケージマネージャーコンソールから update-package です(詳しくは前回)。

Table Storage へのログ出力

Bot.Builder 内の IActivityLogger インターフェースを実装しているクラスは、ユーザーからボットがメッセージを受け取ったとき、ボットがユーザーにメッセージを送信したタイミングで保存されます。

つまり今回やることは2つ。IActivityLogger を実装したクラスを作ってでログを出力処理を実装と、DIコンテナーへの登録です。

IActivityLogger を実装したクラスの作成

Microsoft.Bot.Builder.Azure の中に TableLogger クラスが用意されていますのでこれを使います。

DIコンテナーに登録

TableLogger を使うには、TableStorageの接続の文字列から CloudStorageAccount を作り、それから CloudTableClient をつくって TableReference を作って…というお決まりの処理が必要ですが、 TableLoggerModule が用意されていて、すべてやってくれます。

BotBuilder-Azure/TableLogger.cs at bff9593f75c7b12e5a43cc03d4f75a56929e7604 · Microsoft/BotBuilder-Azure · GitHub

このモジュールを、いつも通りに Global.asax.cs に登録するだけです。

まずは RegisterDependencies() メソッド(19行目)を簡単に解説します。

  • (21行目)Azure の Storage アカウントの文字列を取得
  • (22行目)StorageAccontのインスタンスを作成
  • (24行目~)"MessageLog" というテーブル名を指定してDIコンテナーに登録で完了。

21行目の接続文字列の取得ですが、接続文字列は、Azure Portal のStorage アカウントの アクセス キー を開くと、接続文字列がありますので取ってきましょう。

f:id:beachside:20170828143522p:plain

(キーが見えかけてますが、すぐリソースグループごと削除するので気にしません。)


その接続文字列を、Web.config の configuration > connectionStrings 内に、以下のように設定して取得できるようにしています。

<configuration>
  <connectionStrings>
    <add name="StorageConnectionString"
         connectionString="接続文字列!をAzure Portal から取ってきて張り付ける!"/>
  </connectionStrings>

最後に Application_Startメソッドで、RegisterDependencies() を呼び出します(14行目)。

動作確認

デバッグ実行

デバッグエミュレーターからボットに問いかけてみます。

f:id:beachside:20170828143723p:plain


Azure Storage Explorer を使って Table の中身の確認。

f:id:beachside:20170828143804p:plain

MessageLog というテーブルが作られ、2件のログが出力(ユーザー→ボットと、ボット→ユーザーへのメッセージ)されていて、想定通り動いていますね。

出力内容の確認

BotBuilder-Azure の TableLogger がどうなっているか理解しておかないと意味がないですね。 内部実装をみるとすぐわかりますが、IActivity の内容を出力しているだけです。ざっくりメモしておきます。

項目 IActivityのどの値を使っているか
PartitionKey channelId と conversationId をくっつけたもの
RowKey Timestamp の Ticks
Timestamp Timestamp
Version 3で固定
From From
Recipient Recipient
Activity0 IActivity 全体をシリアル化して、圧縮した値

Activity0 を Azure Storage Explorer で見るとこんな感じです。

f:id:beachside:20170828143848p:plain

圧縮は、内部の実装を見ての通りですので、展開は適当にやればできます。
今回検証したときは、setterで展開して文字列のプロパティ(Activity)にセットする以下のクラスを作りました。

Table Storage からデータ読み込み時に、こいつに値をぶっこんでいけばとりあえず中身が見れます。
(以下はコンソールアプリでデータを出力してみました。)

f:id:beachside:20170828143900p:plain


参考

github.com