Chatbotの会話ログを保存しよう

Chatbotの会話ログを保存しよう
Chatbotとの会話のやりとりは、チャットとして文字を送受信することです。ログとして会話を保存することで、ユーザーの思考分析やマーケット戦略などに再利用することが可能です。Bot Frameworkでは簡単にログを保存できる機能「IActivityLoggerインターフェース」があらかじめ用意されています。今回はこちらを利用して、Chatbotにログの保存機能を追加していきましょう。
今回の記事で使用するファイル一式は、以下のリンクからダウンロード可能です。
クラスファイルの作成
これまでと同様に「ChatBot201707」にログ取得機能を追加します。Visual Studioからログを取得するための仕込みとして、新しいクラスファイル「ChatbotLogger.cs」を追加します。
リスト1:ChatbotLogger.cs(初期状態)
using Microsoft.Bot.Connector;
using System.Threading.Tasks;
namespace Chatbot201707
{
public class ChatbotLogger : IActivityLogger
{
public async Task LogAsync(IActivity activity)
{
}
}
}
ログ取得のために最低限必要な記述は、上記のようになります。着目すべき点をおさえておきましょう。
参照設定
Bot FrameworkのMicrosoft.Bot.Connectorと、C#でお約束のSystem.Threading.Tasksを参照しています。
IactivityLogger
インターフェースとして「IActivityLogger」を実装します。
LogAsync
メソッドとして「LogAsync」を追加します。メソッド名はこの名前が必須です。ユーザーとChatbotがチャットするごとにこのメソッドが呼び出されて、ログ取得の処理を行います。「activity」の中に会話の様々な情報が格納されています。
実際にログ処理のコードを追加していきましょう。
リスト2:ChatbotLogger.csに処理コードを追加
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.History;
using Microsoft.Bot.Connector;
using System;
using System.Text;
using System.IO;
using System.Web;
namespace Chatbot201707
{
public class ChatbotLogger : IActivityLogger
{
public async Task LogAsync(IActivity activity)
{
DateTime timeStamp = activity.Timestamp.Value;
string localTimeStamp = (timeStamp + new TimeSpan(9, 00, 00)).ToString();
string log = $"{localTimeStamp} {activity.From.Name} > {activity.Recipient.Name} : {activity.AsMessageActivity().Text}";
Debug.WriteLine(log);
var rootPath = HttpContext.Current.Server.MapPath("~");
Encoding enc = Encoding.GetEncoding("utf-8");
using (StreamWriter sw = new StreamWriter($"{rootPath}\\ChatLog.txt", true, enc))
{
sw.WriteLine(log);
}
}
}
}
処理内容は「ログを作成してファイルに保存する」といった簡単な処理です。ポイントとなる箇所を見ていきましょぅ。
DateTime timeStamp = activity.Timestamp.Value
まずは日付時刻の取得です。activity.TimestampでDateTime型のタイムスタンプ情報が取得できます。
(timeStamp + new TimeSpan(9, 00, 00)).ToString()
日本時間に合わせるために、9時間プラスしています。
string log = $"{localTimeStamp} {activity.From.Name} > {activity.Recipient.Name} : {activity.AsMessageActivity().Text}"
タイムスタンプと、会話の送信者「activity.From.Name」、会話の受信者「activity.Recipient.Name」、そして会話の内容「activity.AsMessageActivity().Text」を組み合わせたものをログとして作成しています。
Debug.WriteLine(log)
Visual Studioで確認のためにデバッグログとして表示します。
続いてログを保存します。
var rootPath = HttpContext.Current.Server.MapPath("~")
Chatbotの本体はWebアプリケーションなので、ログファイルの保存場所としてHttpContext.Current.Server.MapPathでChatbotのローカルパスを取得しています。デバッグ環境では「C:\ ChatBot201707」のようなファイルパスでもログファイルを保存することは可能ですが、Chatbotを利用する場合はAzureのApp Serviceにデプロイする必要がありますので、ファイルパスでは保存場所の指定が出来ません。AzureのApp ServiceでもServer.MapPathは利用できるので、こちらに保存します。
Encoding enc = Encoding.GetEncoding("utf-8")
UTF-8でエンコードしたものを、テキストファイルとして保存します。
using (StreamWriter sw = new StreamWriter($"{rootPath}\\ChatLog.txt", true, enc))
Chabotのルートフォルダに「ChatLog.txt」として保存します。
sw.WriteLine(log)
テキストファイルにチャットのログとして、会話ごとに一行ずつ追加されます。
Global.asaxの修正
作成したChatbotLoggerクラスをChatbotで利用できるようにするために、Global.asaxを修正します。Bot FrameworkではDIコンテナとしてAutofacを利用することでログ収集を可能としています。Global.asaxで「ログ収集にはChatbotLoggerクラスを使います」ということを定義します。
リスト3:Global.asax.csファイルを修正
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Routing;
using Microsoft.Bot.Builder.Dialogs;
using Autofac;
namespace Chatbot201707
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
Conversation.UpdateContainer(containerBuilder =>
{
containerBuilder.RegisterType<ChatbotLogger>().AsImplementedInterfaces().InstancePerDependency();
});
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
Visual StudioからGlobal.asax.csを開きます。注目すべきポイントをいくつか見ていきましょう。
参照設定
Microsoft.Bot.Builder.DialogsとAutofacを参照設定に追加します。
Conversation.UpdateContainer(containerBuilder =>
ContainerBuilderを定義します。
containerBuilder.RegisterType<ChatbotLogger>().AsImplementedInterfaces().InstancePerDependency()
ContainerBuilderに作成したクラスChatbotLoggerを登録します。
以上で、Chatbotで会話が発生するごとに、ChatbotLoggerクラスが呼び出され、ログの処理が可能となります。


