
Un Hilo de Conversación es una secuencia de respuestas a un mensaje con un tema común. Los mensajes dentro de la conversación pueden mostrarse de varias maneras, como en orden jerárquico o cronológico. Para mostrar un hilo de mensajes, las aplicaciones de correo electrónico identifican las respuestas a los mensajes. Los formatos de archivo de correo electrónico más populares ofrecen esta función.
Los hilos de conversación permiten a los lectores entender rápidamente la estructura general de una conversación, resaltar ciertos puntos de las conversaciones y analizar información importante.
En este artículo nos centraremos en usar las características PST/MAPI de Aspose.Email para encontrar y agrupar mensajes por conversación. Para ello, implementaremos un código de ejemplo que recorrerá los mensajes en una carpeta dada, los agrupará por conversación y luego guardará cada conversación en un directorio separado en el disco.
- Propiedades MAPI que se utilizan para soportar el Hilo de Conversación
- API C# .NET para Leer Archivos PST de Outlook
- Agrupar mensajes en PST por hilo de conversación
Propiedades MAPI que se utilizan para soportar el Hilo de Conversación
Dado que los mensajes en pst se almacenan como un conjunto de propiedades MAPI, necesitamos definir las propiedades MAPI que están asociadas con la recopilación de respuestas a los mensajes.
Esto se describe en la sección de Microsoft Docs.
Como se puede ver, la propiedad PidTagConversationIndex permite determinar con precisión si un mensaje está asociado con una conversación determinada o no. La propiedad también indica la posición relativa del mensaje dentro de un hilo de conversación. Visita la página para más información sobre la propiedad PidTagConversationIndex
. El encabezado son los primeros 22 bytes del valor de la propiedad PidTagConversationIndex
. Es una porción de datos para determinar si el mensaje pertenece a un cierto hilo de conversación.
API C# .NET para Leer Archivos PST de Outlook
Para leer archivos PST, utilizaremos Aspose.Email para .NET. Es una biblioteca impresionante para implementar aplicaciones de procesamiento de correo electrónico utilizando .NET. Usando la biblioteca, puedes manejar fácilmente muchos formatos diferentes de archivos de correo electrónico. Puedes instalar Aspose.Email para .NET a través de NuGet o descargar su DLL.
PM> Install-Package Aspose.Email
Agrupar mensajes en PST por hilo de conversación
Para agrupar los mensajes en PST por conversaciones, necesitamos lo siguiente:
- Primero, crear una clase
ConversationThread
. Es un contenedor para agrupar los mensajes dentro de una conversación. - Luego, crear un método para buscar y agrupar mensajes por la conversación.
- Finalmente, crear un método para guardar el hilo de conversación en un directorio separado.
Crear una clase ConversationThread
Tendrá las siguientes propiedades.
Id
: representación en cadena del encabezado del índice de conversación (22 bytes).Messages
: lista de IDs de mensajes que están en el hilo de conversación.
/// <summary> | |
/// Represents messages within a conversation thread. | |
/// </summary> | |
public class ConversationThread | |
{ | |
private string id; | |
private List<string> messages; | |
/// <summary> | |
/// Initializes a new instance of the <see cref="ConversationThread"/> class. | |
/// </summary> | |
/// <param name="id">The string representation of conversation index header.</param> | |
public MessageThread(string id) | |
{ | |
this.id = id; | |
this.messages = new List<string>(); | |
} | |
/// <summary> | |
/// Gets or sets the HEX string representation of conversation index header (22 bytes). | |
/// </summary> | |
public string Id { get => id; set => id = value; } | |
/// <summary> | |
/// Gets a list of message IDs that are within a conversation thread. | |
/// </summary> | |
public List<string> Messages { get => messages; } | |
} |
Crear un método para buscar y agrupar mensajes por conversación
Después de crear la clase ConversationThread
, podemos centrarnos en escribir un método que haga lo siguiente:
- Recorrer todos los mensajes en la carpeta. Por razones de rendimiento, solo leeremos el identificador del mensaje utilizando el método EnumerateMessagesEntryId.
- Para cada mensaje, extraeremos la propiedad
PidTagConversationIndex
utilizando el método ExtractProperty. - Los mensajes que tienen los mismos primeros 22 bytes del valor de la propiedad
PidTagConversationIndex
pertenecen a la misma conversación. Agregaremos el Id del mensaje a la lista representada por la propiedadMessages
de la instancia correspondiente de la claseConversationThread
. - Devolver la lista de instancias de
ConversationThread
.
using Aspose.Email.Mapi; | |
using Aspose.Email.Storage.Pst; | |
public List<ConversationThread> GroupMessagesByThread(PersonalStorage pst, FolderInfo folder) | |
{ | |
// Result | |
var list = new List<ConversationThread>(); | |
foreach (var entryId in folder.EnumerateMessagesEntryId()) | |
{ | |
// Extract PidTagConversationIndex property and its header value (22 bytes). | |
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(); | |
} |
Crear un método para guardar el hilo de conversación en un directorio separado
Finalmente, guardemos las conversaciones en los directorios.
Para cada instancia de ConversationThread
, haz lo siguiente:
- Crear un directorio separado con el nombre del tema del hilo.
- Enumerar los identificadores en la propiedad
ConversationThread.Messages
, para cada identificador extraer un mensaje utilizando el método ExtractMessage y guardar el mensaje en el directorio creado utilizando el método Save.
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; | |
} | |
} |
Obtener una Licencia API Gratuita
Puedes usar Aspose.Email para .NET sin limitaciones de evaluación utilizando una licencia temporal gratuita.
Conclusión
Este artículo muestra cómo usar Aspose.Email para buscar mensajes relacionados con la conversación en PST.
Al explorar más la documentación de PidTagConversationIndex, también puedes complicar la implementación agregando, por ejemplo, ordenamiento jerárquico de los mensajes de conversación. Puedes aprender más sobre Aspose.Email utilizando la documentación. En caso de que tengas alguna pregunta, puedes publicarla en nuestro foro.