Đọc tệp MS Outlook PST trong C# .NET

Chuỗi hội thoại là một chuỗi các câu trả lời cho một tin nhắn có chủ đề chung. Tin nhắn trong cuộc trò chuyện có thể được hiển thị theo nhiều cách khác nhau, chẳng hạn như theo thứ tự thứ bậc hoặc thứ tự thời gian. Để hiển thị một chuỗi tin nhắn, các ứng dụng email xác định các phản hồi tin nhắn. Các định dạng tệp e-mail phổ biến nhất cung cấp tính năng này. Chủ đề hội thoại cho phép người đọc hiểu nhanh cấu trúc tổng thể của một cuộc hội thoại, nêu bật một số điểm nhất định của cuộc hội thoại và phân tích thông tin quan trọng. Trong bài viết này, chúng tôi sẽ tập trung vào việc sử dụng các tính năng PST / MAPI của Aspose.Email để tìm và nhóm các tin nhắn theo cuộc trò chuyện. Để làm điều này, chúng tôi sẽ triển khai một mã mẫu sẽ duyệt qua các thư trong một thư mục nhất định, nhóm chúng theo cuộc hội thoại và sau đó lưu từng cuộc hội thoại vào một thư mục đĩa riêng biệt.

Thuộc tính MAPI được sử dụng để hỗ trợ chuỗi hội thoại

Vì các thông báo trong pst được lưu trữ dưới dạng một tập các thuộc tính MAPI, chúng ta cần xác định các thuộc tính MAPI được liên kết với việc thu thập các phản hồi thông báo. Điều này được mô tả trong phần Microsoft Documents. Như có thể thấy, thuộc tính PidTagConversationIndex cho phép xác định chính xác liệu một tin nhắn có được liên kết với một cuộc hội thoại nhất định hay không. Thuộc tính cũng cho biết vị trí thư tương đối trong chuỗi hội thoại. Truy cập trang để biết thêm thông tin về thuộc tính PidTagConversationIndex. Tiêu đề là 22 byte đầu tiên của giá trị thuộc tính PidTagConversationIndex. Nó là một phần dữ liệu để xác định xem tin nhắn có thuộc một chuỗi hội thoại nhất định hay không.

C# .NET API để đọc tệp Outlook PST

Để đọc tệp PST, chúng tôi sẽ sử dụng Aspose.Email for .NET. Đây là một thư viện tuyệt vời để triển khai các ứng dụng xử lý email bằng .NET. Sử dụng thư viện, bạn có thể dễ dàng xử lý nhiều định dạng tệp email khác nhau. Bạn có thể cài đặt Aspose.Email for .NET qua NuGet hoặc tải xuống DLL của nó.

PM> Install-Package Aspose.Email

Nhóm các tin nhắn trong PST theo chuỗi hội thoại

Để nhóm các tin nhắn trong PST theo các cuộc hội thoại, chúng ta cần những điều sau:

  • Đầu tiên, tạo một lớp ConversationThread. Nó là một vùng chứa để nhóm các tin nhắn trong một cuộc trò chuyện.
  • Sau đó, tạo một phương pháp để tìm kiếm và nhóm các thư theo cuộc trò chuyện.
  • Cuối cùng, tạo một phương thức để lưu chuỗi hội thoại vào một thư mục riêng.

Tạo lớp ConversationThread

Nó sẽ có các thuộc tính sau.

  • Id: biểu diễn chuỗi của tiêu đề chỉ mục hội thoại (22 byte).
  • Tin nhắn: danh sách các ID tin nhắn có trong chuỗi hội thoại.
///<summary>
/// Đại diện cho các tin nhắn trong một chuỗi hội thoại.
///</summary>
public class ConversationThread
{
    private string id;
    private List<string> messages;
    
    ///<summary>
    /// Khởi tạo một phiên bản mới của<see cref="ConversationThread"/> lớp.
    ///</summary>
    ///<param name="id"> Biểu diễn chuỗi của tiêu đề chỉ mục hội thoại.</param>
    public MessageThread(string id)
    {
        this.id = id;
        this.messages = new List<string>();
    }
    
    ///<summary>
    /// Lấy hoặc đặt biểu diễn chuỗi HEX của tiêu đề chỉ mục hội thoại (22 byte).
    ///</summary>
    public string Id { get => id; set => id = value; }
    
    ///<summary>
    /// Nhận danh sách ID tin nhắn trong chuỗi hội thoại.
    ///</summary>
    public List<string> Messages { get => messages; }
}

Tạo phương pháp tìm kiếm và nhóm các tin nhắn theo cuộc trò chuyện

Sau khi tạo lớp ConversationThread, chúng ta có thể tập trung vào việc viết một phương thức thực hiện như sau:

  • Xem qua tất cả các thư trong thư mục. Vì lý do hiệu suất, chúng tôi sẽ chỉ đọc mã nhận dạng thông báo bằng phương thức EnumerateMessagesEntryId.
  • Đối với mỗi thông báo, chúng tôi sẽ trích xuất thuộc tính PidTagConversationIndex bằng phương thức ExtractProperty.
  • Các thư có cùng 22 byte đầu tiên của giá trị thuộc tính PidTagConversationIndex thuộc cùng một cuộc hội thoại. Chúng tôi sẽ thêm Id thông báo vào danh sách được đại diện bởi thuộc tính Messages của cá thể lớp ConversationThread tương ứng.
  • Trả lại danh sách các trường hợp ConversationThread.
using Aspose.Email.Mapi;
using Aspose.Email.Storage.Pst;

public List<ConversationThread> GroupMessagesByThread(PersonalStorage pst, FolderInfo folder)
{
    // Kết quả
    var list = new List<ConversationThread>();
        
    foreach (var entryId in folder.EnumerateMessagesEntryId())
    {
        // Trích xuất thuộc tính PidTagConversationIndex và giá trị tiêu đề của nó (22 byte).
        var convIndexTag = KnownPropertyList.ConversationIndex.Tag;
        var convIndexProperty = pst.ExtractProperty(Convert.FromBase64String(entryId), convIndexTag);
        var convIndexHeader = (convIndexProperty != null && convIndexProperty.Data != null) ? convIndexProperty.Data.Take(22).ToArray() : null;
        var convIndexHeaderString = convIndexHeader != null ? 
			      BitConverter.ToString(convIndexHeader).Replace('-', '') : null;
        
        if (convIndexHeaderString != null)
        {
            var convThread = list.Find(x => x.Id == convIndexHeaderString);
            
            if (convThread == null)
            {
                convThread = new ConversationThread(convIndexHeaderString);
                convThread.Messages.Add(entryId);
                list.Add(convThread);
            }
            else
            {
                convThread.Messages.Add(entryId);
            }
        }
    }
        
    return list.Where(x => x.Messages.Count > 1).ToList();
}

Tạo một phương pháp để lưu chuỗi hội thoại vào một thư mục riêng

Cuối cùng, hãy lưu các cuộc hội thoại trong các thư mục.

Đối với mỗi phiên bản ConversationThread, hãy làm như sau:

  • Tạo một thư mục riêng với tên của chủ đề chủ đề.
  • Liệt kê các số nhận dạng trong thuộc tính ConversationThread.Messages, đối với mỗi số nhận dạng, trích xuất một thông báo bằng phương thức ExtractMessage và lưu thông báo trong thư mục đã tạo bằng phương thức Lưu.
public void SaveThreads(List<ConversationThread> list, string outDirectory)
{
    var invalidChars = Path.GetInvalidFileNameChars();
    
    foreach (var item in list)
    {
        string? threadDirectory = null;
        var i = item.Messages.Count - 1;
        
        foreach (var entryId in item.Messages)
        {
            var msg = pst.ExtractMessage(entryId);
            
            if (threadDirectory == null)
            {
                var threadName = new string(msg.ConversationTopic.Where(x => !invalidChars.Contains(x)).ToArray()).Trim();
                threadDirectory = Path.Combine(outDirectory, threadName);
                Directory.CreateDirectory(threadDirectory);
            }
            
            msg.Save(Path.Combine(threadDirectory, $"{i--}.msg"));
        }
        
        threadDirectory = null;
    }
}

Nhận giấy phép API miễn phí

Bạn có thể sử dụng Aspose.Email for .NET mà không có giới hạn đánh giá bằng cách sử dụng giấy phép tạm thời miễn phí.

Sự kết luận

Bài viết này hướng dẫn cách sử dụng Aspose.Email để tìm kiếm các tin nhắn liên quan đến cuộc trò chuyện trong PST. Bằng cách khám phá thêm tài liệu PidTagConversationIndex, bạn cũng có thể làm phức tạp việc triển khai bằng cách thêm, ví dụ: sắp xếp thứ bậc các tin nhắn hội thoại. Bạn có thể tìm hiểu thêm về Aspose.Email bằng tài liệu. Trong trường hợp bạn có bất kỳ câu hỏi nào, bạn có thể đăng lên diễn đàn của chúng tôi.

Xem thêm