如何使用Microsoft框架导出Skype机器人聊天日志至文本或数据库?
实现Skype机器人聊天日志导出到文本文件/数据库的指南
我来一步步教你基于现有代码添加日志导出功能,不管是存到文本文件还是数据库都很简单,直接嵌入到你的对话逻辑里就行。
一、导出到文本文件
文本文件的方式比较轻量,适合快速查看日志,我们可以每天生成一个独立的日志文件,避免文件过大。
步骤1:添加日志写入方法
在你的RootDialog类里添加一个静态方法,负责把聊天内容写入文本文件:
// 需要先添加命名空间:using System.IO; using System.Diagnostics; private static void WriteLogToTextFile(string userName, string userMessage, string botResponse, DateTime timestamp) { try { // 日志文件存放在项目根目录的Logs文件夹下,自动创建文件夹 string logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); if (!Directory.Exists(logDirectory)) { Directory.CreateDirectory(logDirectory); } // 按日期命名日志文件,比如ChatLog_20240520.txt string logFilePath = Path.Combine(logDirectory, $"ChatLog_{DateTime.Now:yyyyMMdd}.txt"); // 构建日志内容,包含时间、用户名、用户消息、机器人回复 string logContent = $"[{timestamp:yyyy-MM-dd HH:mm:ss}] 用户: {userName} | 消息: {userMessage} | 机器人回复: {botResponse}\n"; // 以追加模式写入文件 File.AppendAllText(logFilePath, logContent); } catch (Exception ex) { // 记录错误但不中断机器人流程 Trace.WriteLine($"写入文本日志失败: {ex.Message}"); } }
步骤2:在对话逻辑中调用日志方法
每次机器人回复用户后,调用上面的方法记录日志。比如在你的MessageReceivedAsync方法里修改:
// 示例:处理问候语的分支 else if (Usermessage.Contains("hello") || Usermessage.Contains("hi") || Usermessage.Contains("good day") || Usermessage.Contains("good morning")) { string botReply = $"Good day " + activity.From.Name.ToString() + ":)"; await context.PostAsync(botReply); // 调用日志方法记录这次交互 WriteLogToTextFile(activity.From.Name, activity.Text, botReply, DateTime.Now); }
按照这个方式,把所有回复分支都加上日志调用,就能完整记录所有聊天内容了。
二、导出到数据库
如果你需要长期存储和查询日志,数据库是更好的选择,你已经引用了SqlClient,我们以SQL Server为例实现:
步骤1:创建数据库表
先在你的SQL Server数据库里创建一个存储日志的表:
CREATE TABLE ChatLogs ( LogId INT IDENTITY(1,1) PRIMARY KEY, -- 自增主键 UserName NVARCHAR(100) NOT NULL, -- 用户名 UserMessage NVARCHAR(MAX) NOT NULL, -- 用户消息 BotResponse NVARCHAR(MAX), -- 机器人回复(允许为空) Timestamp DATETIME NOT NULL -- 交互时间 )
步骤2:添加数据库写入方法
在RootDialog类里添加异步方法,负责把日志插入数据库:
private async Task WriteLogToDatabase(string userName, string userMessage, string botResponse, DateTime timestamp) { try { // 替换成你的数据库连接字符串 string connectionString = "Data Source=你的服务器地址;Initial Catalog=你的数据库名;Integrated Security=True;"; using (SqlConnection connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); // 插入日志的SQL语句 string insertQuery = @"INSERT INTO ChatLogs (UserName, UserMessage, BotResponse, Timestamp) VALUES (@UserName, @UserMessage, @BotResponse, @Timestamp)"; using (SqlCommand command = new SqlCommand(insertQuery, connection)) { // 添加参数,避免SQL注入 command.Parameters.AddWithValue("@UserName", userName); command.Parameters.AddWithValue("@UserMessage", userMessage); // 处理回复为空的情况,用DBNull代替 command.Parameters.AddWithValue("@BotResponse", botResponse ?? DBNull.Value); command.Parameters.AddWithValue("@Timestamp", timestamp); await command.ExecuteNonQueryAsync(); } } } catch (Exception ex) { // 记录错误但不中断机器人流程 Trace.WriteLine($"写入数据库日志失败: {ex.Message}"); } }
步骤3:在对话逻辑中调用数据库方法
和文本日志一样,在每个回复后调用这个方法:
// 示例:处理问候语的分支 else if (Usermessage.Contains("hello") || Usermessage.Contains("hi") || Usermessage.Contains("good day") || Usermessage.Contains("good morning")) { string botReply = $"Good day " + activity.From.Name.ToString() + ":)"; await context.PostAsync(botReply); // 同时记录到数据库 await WriteLogToDatabase(activity.From.Name, activity.Text, botReply, DateTime.Now); }
三、完整修改后的代码示例
把上面的方法整合到你的dialog.cs里,完整代码如下:
using System; using System.Threading.Tasks; using Microsoft.Bot.Builder.Dialogs; using Microsoft.Bot.Connector; using System.Linq; using System.Data.SqlClient; using System.IO; using System.Diagnostics; namespace Angela.Dialogs { [Serializable] public class RootDialog : IDialog<object> { DateTime localDate = DateTime.Now; String DateToday = ""; public Task StartAsync(IDialogContext context) { context.Wait(MessageReceivedAsync); return Task.CompletedTask; } private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result) { var activity = await result as Activity; String Usermessage = activity.Text.ToString().ToLower(); if (Usermessage.Contains("hello") || Usermessage.Contains("hi") || Usermessage.Contains("good day") || Usermessage.Contains("good morning")) { string botReply = $"Good day " + activity.From.Name.ToString() + ":)"; await context.PostAsync(botReply); WriteLogToTextFile(activity.From.Name, activity.Text, botReply, DateTime.Now); await WriteLogToDatabase(activity.From.Name, activity.Text, botReply, DateTime.Now); } else if (Usermessage.Contains("good night") || Usermessage.Contains("night") || Usermessage.Contains("see you") || Usermessage.Contains("bye")) { string botReply = $"Good Night " + activity.From.Name.ToString() + ", Sleep well!"; await context.PostAsync(botReply); WriteLogToTextFile(activity.From.Name, activity.Text, botReply, DateTime.Now); await WriteLogToDatabase(activity.From.Name, activity.Text, botReply, DateTime.Now); } else if (Usermessage.Contains("who is angela") || Usermessage.Contains("who you") || Usermessage.Contains("kinsa ka") || Usermessage.Contains("who are you")) { string botReply = "I am Angela is a bot for Design4web! Nice meeting you " + activity.From.Name.ToString(); await context.PostAsync(botReply); WriteLogToTextFile(activity.From.Name, activity.Text, botReply, DateTime.Now); await WriteLogToDatabase(activity.From.Name, activity.Text, botReply, DateTime.Now); } else if (Usermessage.Contains("thank you")) { string botReply1 = "You're welcome " + activity.From.Name.ToString(); string botReply2 = "Hi " + activity.From.Name.ToString() + ", My name is ANGELA!, nice meeting you!"; await context.PostAsync(botReply1); await context.PostAsync(botReply2); // 这里可以把两次回复合并记录,或者分开记录,根据需求调整 WriteLogToTextFile(activity.From.Name, activity.Text, $"{botReply1}\n{botReply2}", DateTime.Now); await WriteLogToDatabase(activity.From.Name, activity.Text, $"{botReply1}\n{botReply2}", DateTime.Now); } // 如果没有匹配到任何指令,可以添加默认回复并记录 else { string botReply = "Sorry, I don't understand that message."; await context.PostAsync(botReply); WriteLogToTextFile(activity.From.Name, activity.Text, botReply, DateTime.Now); await WriteLogToDatabase(activity.From.Name, activity.Text, botReply, DateTime.Now); } context.Wait(MessageReceivedAsync); } private static void WriteLogToTextFile(string userName, string userMessage, string botResponse, DateTime timestamp) { try { string logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); if (!Directory.Exists(logDirectory)) { Directory.CreateDirectory(logDirectory); } string logFilePath = Path.Combine(logDirectory, $"ChatLog_{DateTime.Now:yyyyMMdd}.txt"); string logContent = $"[{timestamp:yyyy-MM-dd HH:mm:ss}] 用户: {userName} | 消息: {userMessage} | 机器人回复: {botResponse}\n"; File.AppendAllText(logFilePath, logContent); } catch (Exception ex) { Trace.WriteLine($"写入文本日志失败: {ex.Message}"); } } private async Task WriteLogToDatabase(string userName, string userMessage, string botResponse, DateTime timestamp) { try { // 替换为你的数据库连接字符串 string connectionString = "Data Source=YOUR_SERVER;Initial Catalog=YOUR_DATABASE;Integrated Security=True;"; using (SqlConnection connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); string insertQuery = @"INSERT INTO ChatLogs (UserName, UserMessage, BotResponse, Timestamp) VALUES (@UserName, @UserMessage, @BotResponse, @Timestamp)"; using (SqlCommand command = new SqlCommand(insertQuery, connection)) { command.Parameters.AddWithValue("@UserName", userName); command.Parameters.AddWithValue("@UserMessage", userMessage); command.Parameters.AddWithValue("@BotResponse", botResponse ?? DBNull.Value); command.Parameters.AddWithValue("@Timestamp", timestamp); await command.ExecuteNonQueryAsync(); } } } catch (Exception ex) { Trace.WriteLine($"写入数据库日志失败: {ex.Message}"); } } } }
注意:记得把数据库连接字符串里的YOUR_SERVER和YOUR_DATABASE替换成你实际的服务器地址和数据库名称。
内容的提问来源于stack exchange,提问作者Jovel Mark Diaz
相关产品推荐
相关产品推荐

