Pobieranie i listowanie e‑maili z serwera IMAP

Pobieranie i listowanie wiadomości

Jak uzyskać informacje identyfikacyjne wiadomości w skrzynce pocztowej

Podczas pobierania i przetwarzania wiadomości e‑mail można uzyskać szczegółowe informacje identyfikacyjne, takie jak numery kolejnych i unikalne identyfikatory, korzystając z poniższych funkcji udostępnionych w najnowszej wersji Aspose.Email dla .NET:

Aspose.Email.ImapMessageInfo klasa: Reprezentuje informacje identyfikacyjne o wiadomości w skrzynce IMAP.

ImapMessageInfo.SequenceNumber właściwość: Pobiera numer kolejny wiadomości.

ImapMessageInfo.UniqueId właściwość: Pobiera unikalny identyfikator wiadomości.

Aspose.Email.MailMessage.ItemId właściwość: Reprezentuje dodatkowe informacje identyfikacyjne wiadomości w skrzynce pocztowej.

Poniższy fragment kodu demonstruje, jak uzyskać informacje identyfikacyjne wiadomości w skrzynce IMAP:

  1. Utwórz instancję ImapClient klasa, podając niezbędne parametry, takie jak host serwera IMAP, port, adres e‑mail, hasło oraz opcje zabezpieczeń.
  2. Użyj ListMessages metoda do pobrania listy wiadomości z folderu "INBOX". Ogranicz listę do pierwszych pięciu wiadomości za pomocą metody Take(5).
  3. Wyodrębnij numery kolejnych wymienionych wiadomości, używając SequenceNumber właściwość każdej wiadomości.
  4. Użyj FetchMessages metoda do pobrania pełnych szczegółów wiadomości z serwera, przy użyciu numerów kolejnych uzyskanych w poprzednim kroku.
  5. Przejdź przez pobrane wiadomości i dla każdej z nich pobierz oraz wyświetl następujące informacje:
  • Numer kolejny wiadomości.
  • Właściwość ItemId.SequenceNumber.
  • Temat wiadomości.
using (var client = new ImapClient(imapHost, port, emailAddress, password, securityOption))
{
    // List the first 5 messages from the inbox
    var msgs = client.ListMessages("INBOX").Take(5);
    
    // Get sequence numbers of the messages
    var seqIds = msgs.Select(t => t.SequenceNumber);
    
    // Fetch messages based on sequence numbers
    var msgsViaFetch = client.FetchMessages(seqIds);
    
    for (var i = 0; i < 5; i++)
    {
        var thisMsg = msgsViaFetch[i];
        Console.WriteLine($"Message ID: {seqIds.ElementAt(i)} SequenceNumber: {thisMsg.ItemId.SequenceNumber} Subject: {thisMsg.Subject}");
    }
}

Lista identyfikatorów wiadomości MIME z serwera

ImapMessageInfo udostępnia MIME MessageId do identyfikacji wiadomości bez wyciągania całej wiadomości. Poniższy fragment kodu pokazuje, jak wyświetlić MIME messageId.

ImapClient client = new ImapClient();
client.Host = "domain.com";
client.Username = "username";
client.Password = "password";
    
try
{
    ImapMessageInfoCollection messageInfoCol = client.ListMessages("Inbox");
    foreach (ImapMessageInfo info in messageInfoCol)
    {
        // Display MIME Message ID
        Console.WriteLine("Message Id = " + info.MessageId);
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

Lista wiadomości z serwera

Aspose.Email udostępnia dwuelementową przeciążoną wersję ListMessages() aby pobrać określoną liczbę wiadomości na podstawie zapytania. Poniższy fragment kodu pokazuje, jak wyświetlić listę wiadomości.


imapClient.SelectFolder("Inbox");
ImapQueryBuilder builder = new ImapQueryBuilder();
MailQuery query =
	builder.Or(
	builder.Or(
	builder.Or(
	builder.Or(
	builder.Subject.Contains(" (1) "),
	builder.Subject.Contains(" (2) ")),
	builder.Subject.Contains(" (3) ")),
	builder.Subject.Contains(" (4) ")),
	builder.Subject.Contains(" (5) "));
ImapMessageInfoCollection messageInfoCol4 = imapClient.ListMessages(query, 4);
Console.WriteLine((messageInfoCol4.Count == 4) ? "Success" : "Failure");

Rekurencyjne wymienianie wiadomości

Protokół IMAP obsługuje rekurencyjne listowanie wiadomości z folderu skrzynki. Dzięki temu można również wyświetlać wiadomości z podfolderów. Poniższy fragment kodu pokazuje, jak listować wiadomości rekurencyjnie.

// Create an imapclient with host, user and password
ImapClient client = new ImapClient();
client.Host = "domain.com";
client.Username = "username";
client.Password = "password";
client.SelectFolder("InBox");
ImapMessageInfoCollection msgsColl = client.ListMessages(true);
Console.WriteLine("Total Messages: " + msgsColl.Count);

Wymień wiadomości z użyciem MultiConnection

ImapClient zapewnia UseMultiConnection właściwość, której można używać do tworzenia wielu połączeń przy intensywnych operacjach. Możesz także ustawić liczbę połączeń używanych w trybie wielokrotnego połączenia, używając ImapClient.ConnectionsQuantity. Poniższy fragment kodu demonstruje użycie trybu wielokrotnego połączenia do listowania wiadomości i porównuje jego wydajność z trybem jednego połączenia.

ImapClient imapClient = new ImapClient();
imapClient.Host = "<HOST>";
imapClient.Port = 993;
imapClient.Username = "<USERNAME>";
imapClient.Password = "<PASSWORD>";
imapClient.SupportedEncryption = EncryptionProtocols.Tls;
imapClient.SecurityOptions = SecurityOptions.SSLImplicit;

imapClient.SelectFolder("Inbox");
imapClient.ConnectionsQuantity = 5;
imapClient.UseMultiConnection = MultiConnectionMode.Enable;
DateTime multiConnectionModeStartTime = DateTime.Now;
ImapMessageInfoCollection messageInfoCol1 = imapClient.ListMessages(true);
TimeSpan multiConnectionModeTimeSpan = DateTime.Now - multiConnectionModeStartTime;

imapClient.UseMultiConnection = MultiConnectionMode.Disable;
DateTime singleConnectionModeStartTime = DateTime.Now;
ImapMessageInfoCollection messageInfoCol2 = imapClient.ListMessages(true);
TimeSpan singleConnectionModeTimeSpan = DateTime.Now - singleConnectionModeStartTime;
            
double performanceRelation = singleConnectionModeTimeSpan.TotalMilliseconds / multiConnectionModeTimeSpan.TotalMilliseconds;
Console.WriteLine("Performance Relation: " + performanceRelation);

Wymienianie wiadomości ze wsparciem stronicowania

W scenariuszach, w których serwer e‑mail zawiera dużą liczbę wiadomości w skrzynce, często pożądane jest wyświetlanie lub pobieranie wiadomości z obsługą stronicowania. API Aspose.Email ImapClient pozwala pobrać wiadomości z serwera z obsługą stronicowania.

///<summary>
/// This example shows the paging support of ImapClient for listing messages from the server
/// Available in Aspose.Email for .NET 6.4.0 and onwards
///</summary>
using (ImapClient client = new ImapClient("host.domain.com", 993, "username", "password"))
{
    try
    {
        int messagesNum = 12;
        int itemsPerPage = 5;
        MailMessage message = null;
        // Create some test messages and append these to server's inbox
        for (int i = 0; i < messagesNum; i++)
        {
            message = new MailMessage(
                "from@domain.com",
                "to@domain.com",
                "EMAILNET-35157 - " + Guid.NewGuid(),
                "EMAILNET-35157 Move paging parameters to separate class");
            client.AppendMessage(ImapFolderInfo.InBox, message);
        }

        // List messages from inbox
        client.SelectFolder(ImapFolderInfo.InBox);
        ImapMessageInfoCollection totalMessageInfoCol = client.ListMessages();
        // Verify the number of messages added
        Console.WriteLine(totalMessageInfoCol.Count);

        ////////////////// RETREIVE THE MESSAGES USING PAGING SUPPORT////////////////////////////////////

        List<ImapPageInfo> pages = new List<ImapPageInfo>();
        PageSettings pageSettings = new PageSettings();
        ImapPageInfo pageInfo = client.ListMessagesByPage(itemsPerPage, 0, pageSettings);
        Console.WriteLine(pageInfo.TotalCount);
        pages.Add(pageInfo);
        while (!pageInfo.LastPage)
        {
            pageInfo = client.ListMessagesByPage(itemsPerPage, pageInfo.NextPage.PageOffset, pageSettings);
            pages.Add(pageInfo);
        }
        int retrievedItems = 0;
        foreach (ImapPageInfo folderCol in pages)
            retrievedItems += folderCol.Items.Count;
        Console.WriteLine(retrievedItems);
    }
    finally
    {
    }
}

Lista załączników wiadomości

Aby uzyskać informacje o załącznikach, takie jak nazwa czy rozmiar, bez pobierania danych załącznika, wypróbuj następujące API:

  • Aspose.Email.Clients.Imap.ImapAttachmentInfo – Reprezentuje informacje o załączniku.
  • Aspose.Email.Clients.Imap.ImapAttachmentInfoCollection – Reprezentuje kolekcję ImapAttachmentInfo klasa.
  • Aspose.Email.Clients.Imap.ListAttachments(int sequenceNumber) – Pobiera informacje o każdym załączniku w wiadomości.

Przykładowy kod wraz z poniższymi krokami pokaże, jak używać API:

  1. Wywołaj ListMessages() metoda na obiekcie imapClient. Ta metoda zwróci ImapMessageInfoCollection zawierającą informacje o wiadomościach w skrzynce pocztowej.
  2. Iteruj po każdej wiadomości w kolekcji messageInfoCollection używając pętli foreach.
  3. Wywołaj ListAttachments() metoda na obiekcie imapClient, przekazująca właściwość SequenceNumber obiektu wiadomości jako parametr. Ta metoda zwróci ImapAttachmentInfoCollection zawierającą informacje o załącznikach w wiadomości.
  4. Iteruj po każdym załączniku w kolekcji attachmentInfoCollection używając pętli foreach.
  5. W wewnętrznej pętli możesz uzyskać dostęp do informacji o każdym załączniku, używając właściwości obiektu attachmentInfo.
var messageInfoCollection = imapClient.ListMessages();
    
foreach (var message in messageInfoCollection)
{
    var attachmentInfoCollection = imapClient.ListAttachments(message.SequenceNumber);

    foreach (var attachmentInfo in attachmentInfoCollection)
    {
        Console.WriteLine("Attachment: {0} (size: {1})", attachmentInfo.Name, attachmentInfo.Size);
    }
}

Pobieranie i zapisywanie wiadomości

Pobierz wiadomości z serwera

Ten ImapClient klasa może pobierać wiadomości z serwera IMAP i zapisywać je w formacie EML na lokalnym dysku. Następujące kroki są wymagane, aby zapisać wiadomości na dysku:

  1. Utwórz instancję ImapClient klasa.
  2. Określ nazwę hosta, port, nazwę użytkownika i hasło w ImapClient constructor.
  3. Wybierz folder używając SelectFolder() metoda.
  4. Wywołaj ListMessages metodę, aby uzyskać ImapMessageInfoCollection obiekt.
  5. Iteruj przez ImapMessageInfoCollection kolekcję, wywołaj SaveMessage() metodę i podać ścieżkę wyjściową oraz nazwę pliku.

Poniższy fragment kodu pokazuje, jak pobrać wiadomości e-mail z serwera i je zapisać.

// Select the inbox folder and Get the message info collection
client.SelectFolder(ImapFolderInfo.InBox);
ImapMessageInfoCollection list = client.ListMessages();

// Download each message
for (int i = 0; i < list.Count; i++)
{
    // Save the EML file locally
    client.SaveMessage(list[i].UniqueId, dataDir + list[i].UniqueId + ".eml");
}

Pobierz wiadomości w kolejności malejącej

Aspose.Email udostępnia ImapClient.ListMessagesByPage metoda, która wymienia wiadomości z obsługą stronicowania. Niektóre przeciążenia ImapClient.ListMessagesByPage przyjmuje PageSettings jako parametr. PageSettings zapewnia AscendingSorting właściwość, która ustawiona na false, zwraca e‑maile w kolejności malejącej.

Poniższy kod przykładu demonstruje użycie AscendingSorting właściwość PageSettings klasa do zmiany kolejności e-maili.

ImapClient imapClient = new ImapClient();
imapClient.Host = "<HOST>";
imapClient.Port = 993;
imapClient.Username = "<USERNAME>";
imapClient.Password = "<PASSWORD>";
imapClient.SupportedEncryption = EncryptionProtocols.Tls;
imapClient.SecurityOptions = SecurityOptions.SSLImplicit;

PageSettings pageSettings = new PageSettings { AscendingSorting = false };
ImapPageInfo pageInfo = imapClient.ListMessagesByPage(5, pageSettings);
ImapMessageInfoCollection messages = pageInfo.Items;

foreach (ImapMessageInfo message in messages)
{
    Console.WriteLine(message.Subject + " -> " + message.Date.ToString());
}

Zapisz wiadomości w formacie MSG

Aby zapisać e‑maile w formacie MSG, ImapClient.FetchMessage() metodę należy wywołać. Zwraca wiadomość jako instancję MailMessage klasa. Ta MailMessage.Save() metodę można następnie wywołać, aby zapisać wiadomość w formacie MSG. Poniższy fragment kodu pokazuje, jak zapisać wiadomości w formacie MSG.

// The path to the file directory.
string dataDir = RunExamples.GetDataDir_IMAP();

// Create an imapclient with host, user and password
ImapClient client = new ImapClient("localhost", "user", "password");

// Select the inbox folder and Get the message info collection
client.SelectFolder(ImapFolderInfo.InBox);
ImapMessageInfoCollection list = client.ListMessages();

// Download each message
for (int i = 0; i < list.Count; i++)
{
    // Save the message in MSG format
    MailMessage message = client.FetchMessage(list[i].UniqueId);
    message.Save(dataDir + list[i].UniqueId + "_out.msg", SaveOptions.DefaultMsgUnicode);
}

Grupowanie pobranych wiadomości

ImapClient zapewnia FetchMessages metoda, która przyjmuje iterowalny zestaw numerów sekwencyjnych lub unikalnych ID i zwraca listę MailMessage. Poniższy fragment kodu demonstruje użycie FetchMessages metoda pobierająca wiadomości według numerów sekwencyjnych i unikalnego ID.

ImapClient imapClient = new ImapClient();
imapClient.Host = "<HOST>";
imapClient.Port = 993;
imapClient.Username = "<USERNAME>";
imapClient.Password = "<PASSWORD>";
imapClient.SupportedEncryption = EncryptionProtocols.Tls;
imapClient.SecurityOptions = SecurityOptions.SSLImplicit;

ImapMessageInfoCollection messageInfoCol = imapClient.ListMessages();
Console.WriteLine("ListMessages Count: " + messageInfoCol.Count);
int[] sequenceNumberAr = messageInfoCol.Select((ImapMessageInfo mi) => mi.SequenceNumber).ToArray();
string[] uniqueIdAr = messageInfoCol.Select((ImapMessageInfo mi) => mi.UniqueId).ToArray();

IList<MailMessage> fetchedMessagesBySNumMC = imapClient.FetchMessages(sequenceNumberAr);
Console.WriteLine("FetchMessages-sequenceNumberAr Count: " + fetchedMessagesBySNumMC.Count);

IList<MailMessage> fetchedMessagesByUidMC = imapClient.FetchMessages(uniqueIdAr);
Console.WriteLine("FetchMessages-uniqueIdAr Count: " + fetchedMessagesByUidMC.Count);

Pobierz foldery i odczytaj wiadomości rekurencyjnie

W tym artykule, większość ImapClient funkcje są używane do stworzenia aplikacji, która rekurencyjnie wyświetla wszystkie foldery i podfoldery z serwera IMAP. Zapisuje również wiadomości w każdym folderze i podfolderze w formacie MSG na lokalnym dysku. Na dysku foldery i wiadomości są tworzone i zapisywane w takiej samej strukturze hierarchicznej jak na serwerze IMAP. Poniższy fragment kodu pokazuje, jak uzyskać wiadomości oraz informacje o podfolderach w sposób rekurencyjny.

public static void Run()
{
    // Create an instance of the ImapClient class
    ImapClient client = new ImapClient();

    // Specify host, username, password, Port and SecurityOptions for your client
    client.Host = "imap.gmail.com";
    client.Username = "your.username@gmail.com";
    client.Password = "your.password";
    client.Port = 993;
    client.SecurityOptions = SecurityOptions.Auto;
    try
    {
        // The root folder (which will be created on disk) consists of host and username
        string rootFolder = client.Host + "-" + client.Username;

        // Create the root folder and List all the folders from IMAP server
        Directory.CreateDirectory(rootFolder);
        ImapFolderInfoCollection folderInfoCollection = client.ListFolders();
        foreach (ImapFolderInfo folderInfo in folderInfoCollection)
        {
            // Call the recursive method to read messages and get sub-folders
            ListMessagesInFolder(folderInfo, rootFolder, client);
        }
        // Disconnect to the remote IMAP server
        client.Dispose();
    }
    catch (Exception ex)
    {
        Console.Write(Environment.NewLine + ex);
    }

    Console.WriteLine(Environment.NewLine + "Downloaded messages recursively from IMAP server.");
}

/// Recursive method to get messages from folders and sub-folders
private static void ListMessagesInFolder(ImapFolderInfo folderInfo, string rootFolder, ImapClient client)
{
    // Create the folder in disk (same name as on IMAP server)
    string currentFolder = RunExamples.GetDataDir_IMAP();
    Directory.CreateDirectory(currentFolder);

    // Read the messages from the current folder, if it is selectable
    if (folderInfo.Selectable)
    {
        // Send status command to get folder info
        ImapFolderInfo folderInfoStatus = client.GetFolderInfo(folderInfo.Name);
        Console.WriteLine(folderInfoStatus.Name + " folder selected. New messages: " + folderInfoStatus.NewMessageCount + ", Total messages: " + folderInfoStatus.TotalMessageCount);

        // Select the current folder and List messages
        client.SelectFolder(folderInfo.Name);
        ImapMessageInfoCollection msgInfoColl = client.ListMessages();
        Console.WriteLine("Listing messages....");
        foreach (ImapMessageInfo msgInfo in msgInfoColl)
        {
            // Get subject and other properties of the message
            Console.WriteLine("Subject: " + msgInfo.Subject);
            Console.WriteLine("Read: " + msgInfo.IsRead + ", Recent: " + msgInfo.Recent + ", Answered: " + msgInfo.Answered);

            // Get rid of characters like ? and :, which should not be included in a file name and Save the message in MSG format
            string fileName = msgInfo.Subject.Replace(":", " ").Replace("?", " ");
            MailMessage msg = client.FetchMessage(msgInfo.SequenceNumber);
            msg.Save(currentFolder + "\\" + fileName + "-" + msgInfo.SequenceNumber + ".msg", SaveOptions.DefaultMsgUnicode);
        }
        Console.WriteLine("============================\n");
    }
    else
    {
        Console.WriteLine(folderInfo.Name + " is not selectable.");
    }

    try
    {
        // If this folder has sub-folders, call this method recursively to get messages
        ImapFolderInfoCollection folderInfoCollection = client.ListFolders(folderInfo.Name);
        foreach (ImapFolderInfo subfolderInfo in folderInfoCollection)
        {
            ListMessagesInFolder(subfolderInfo, rootFolder, client);
        }
    }
    catch (Exception) { }            
}

Obsługa specjalnych informacji wiadomości

Pobierz dodatkowe parametry jako informacje podsumowujące

using (ImapClient client = new ImapClient("host.domain.com", "username", "password"))
{
    MailMessage message = new MailMessage("from@domain.com", "to@doman.com", "EMAILNET-38466 - " + Guid.NewGuid().ToString(), "EMAILNET-38466 Add extra parameters for UID FETCH command");

    // append the message to the server
    string uid = client.AppendMessage(message);

    // wait for the message to be appended
    Thread.Sleep(5000);

    // Define properties to be fetched from server along with the message
    string[] messageExtraFields = new string[] { "X-GM-MSGID", "X-GM-THRID" };

    // retreive the message summary information using it's UID
    ImapMessageInfo messageInfoUID = client.ListMessage(uid, messageExtraFields);

    // retreive the message summary information using it's sequence number
    ImapMessageInfo messageInfoSeqNum = client.ListMessage(1, messageExtraFields);

    // List messages in general from the server based on the defined properties
    ImapMessageInfoCollection messageInfoCol = client.ListMessages(messageExtraFields);

    ImapMessageInfo messageInfoFromList = messageInfoCol[0];

    // verify that the parameters are fetched in the summary information
    foreach (string paramName in messageExtraFields)
    {
        Console.WriteLine(messageInfoFromList.ExtraParameters.ContainsKey(paramName));
        Console.WriteLine(messageInfoUID.ExtraParameters.ContainsKey(paramName));
        Console.WriteLine(messageInfoSeqNum.ExtraParameters.ContainsKey(paramName));
    }
}

Pobierz informacje z nagłówka List-Unsubscribe

Nagłówek List-Unsubscribe zawiera adres URL umożliwiający wypisanie się z list mailingowych, np. reklam, biuletynów itp. Aby uzyskać nagłówek List-Unsubscribe, użyj ListUnsubscribe właściwość ImapMessageInfo klasa. Poniższy przykład pokazuje użycie ListUnsubscribe właściwość umożliwiająca pobranie nagłówka List-Unsubscribe.

ImapClient imapClient = new ImapClient();
imapClient.Host = "<HOST>";
imapClient.Port = 993;
imapClient.Username = "<USERNAME>";
imapClient.Password = "<PASSWORD>";
imapClient.SupportedEncryption = EncryptionProtocols.Tls;
imapClient.SecurityOptions = SecurityOptions.SSLImplicit;

ImapMessageInfoCollection messageInfoCol = imapClient.ListMessages();
foreach (ImapMessageInfo imapMessageInfo in messageInfoCol)
{
    Console.WriteLine("ListUnsubscribe Header: " + imapMessageInfo.ListUnsubscribe);
}