بازیابی و فهرست کردن ایمیل‌ها از سرور IMAP

بازیابی و فهرست‌کردن پیام‌ها

چگونگی به‌دست آوردن اطلاعات شناسایی پیام‌ها در یک صندوق‌پست

هنگام بازیابی و پردازش پیام‌های ایمیل، می‌توانید اطلاعات شناسایی دقیق مانند شماره توالی و شناسه‌های یکتا را با استفاده از ویژگی‌های زیر که در جدیدترین نسخه Aspose.Email برای .NET موجود است، به‌دست آورید:

Aspose.Email.ImapMessageInfo کلاس: اطلاعات شناسایی یک پیام در صندوق‌پست IMAP را نشان می‌دهد.

ImapMessageInfo.SequenceNumber ویژگی: شماره توالی پیام را بازیابی می‌کند.

ImapMessageInfo.UniqueId ویژگی: شناسه یکتای پیام را بازیابی می‌کند.

Aspose.Email.MailMessage.ItemId ویژگی: نمایانگر اطلاعات شناسایی اضافی درباره پیام درون صندوق‌پست است.

قطعه کد زیر نشان می‌دهد چگونه اطلاعات شناسایی پیام‌ها در یک صندوق‌پست IMAP به‌دست آید:

  1. یک نمونه از ImapClient کلاس با ارائه پارامترهای لازم مانند میزبان سرور IMAP، پورت، آدرس ایمیل، رمز عبور و گزینه‌های امنیتی.
  2. از ListMessages متد برای بازیابی فهرست پیام‌ها از پوشه "INBOX". فهرست را با استفاده از متد Take(5) به اولین پنج پیام محدود کنید.
  3. با استفاده از … شماره‌های توالی پیام‌های فهرست‌شده را استخراج کنید. SequenceNumber ویژگی هر پیام.
  4. از FetchMessages متد برای دریافت جزئیات کامل پیام‌ها از سرور، با استفاده از شماره‌های توالی به‌دست آمده در مرحله قبل.
  5. در پیام‌های بازیابی‌شده حلقه بزنید و برای هر پیام، اطلاعات زیر را بازیابی و نمایش دهید:
  • شماره توالی پیام.
  • ویژگی ItemId.SequenceNumber.
  • موضوع پیام.
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}");
    }
}

فهرست شناسه‌های پیام MIME از سرور

ImapMessageInfo MIME را فراهم می‌کند MessageId برای شناسایی پیام بدون استخراج کامل پیام. کد زیر نشان می‌دهد چگونه شناسهٔ پیام MIME را لیست کنیم.

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);
}

لیست پیام‌ها از سرور

Aspose.Email یک نسخهٔ overload شدهٔ ۲ عضوی از ListMessages() برای بازیابی تعداد مشخصی از پیام‌ها بر پایه یک پرس‌و‌جو. قطعه کد زیر نشان می‌دهد چگونه پیام‌ها را فهرست کنید.


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");

فهرست پیام‌ها به‌صورت بازگشتی

پروتکل IMAP از لیست کردن پیام‌ها به صورت بازگشتی از یک پوشهٔ صندوق پست پشتیبانی می‌کند. این امکان فهرست کردن پیام‌ها از زیرپوشه‌های یک پوشه را نیز فراهم می‌سازد. کد زیر نشان می‌دهد چگونه پیام‌ها را به صورت بازگشتی لیست کنیم.

// 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);

فهرست پیام‌ها با چنداتصال

ImapClient ارائه می‌دهد یک UseMultiConnection ویژگی که می‌تواند برای ایجاد چندین اتصال برای عملیات سنگین استفاده شود. همچنین می‌توانید با استفاده از ImapClient.ConnectionsQuantity. کد زیر استفاده از حالت چند‑اتصال برای لیست کردن پیام‌ها را نشان می‌دهد و عملکرد آن را با حالت اتصال تک مقایسه می‌کند.

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);

فهرست پیام‌ها با پشتیبانی از صفحه‌بندی

در موقعیت‌هایی که سرور ایمیل حاوی تعداد زیادی پیام در صندوق‌پست است، معمولاً خواستار لیست یا بازیابی پیام‌ها با پشتیبانی از صفحه‌بندی می‌شود. API‌های Aspose.Email ImapClient به شما امکان می‌دهد پیام‌ها را از سرور با پشتیبانی از صفحه‌بندی بازیابی کنید.

///<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
    {
    }
}

لیست پیوست‌های پیام

برای دریافت اطلاعات درباره پیوست‌ها مانند نام و اندازه بدون دریافت داده‌های پیوست، API‌های زیر را امتحان کنید:

  • Aspose.Email.Clients.Imap.ImapAttachmentInfo - نمایانگر اطلاعات یک پیوست.
  • Aspose.Email.Clients.Imap.ImapAttachmentInfoCollection - نمایانگر یک مجموعه از ImapAttachmentInfo کلاس.
  • Aspose.Email.Clients.Imap.ListAttachments(int sequenceNumber) - اطلاعاتی برای هر پیوست در یک پیام دریافت می‌کند.

نمونه کد با مراحل زیر نشان می‌دهد چگونه از API‌ها استفاده کنید:

  1. متد را فراخوانی کنید ListMessages() متد روی شیء imapClient. این متد یک ImapMessageInfoCollection باز می‌گرداند که شامل اطلاعات پیام‌های موجود در صندوق‌پست است.
  2. با استفاده از حلقه foreach، بر روی هر پیام در مجموعه messageInfoCollection تکرار کنید.
  3. متد را فراخوانی کنید ListAttachments() متد روی شیء imapClient، با ارسال ویژگی SequenceNumber از شیء پیام به عنوان پارامتر. این متد یک ImapAttachmentInfoCollection باز می‌گرداند که شامل اطلاعات پیوست‌های پیام است.
  4. با استفاده از حلقه foreach، بر روی هر پیوست در مجموعه attachmentInfoCollection تکرار کنید.
  5. درون حلقه داخلی، می‌توانید به اطلاعات هر پیوست با استفاده از خصوصیات شیء 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);
    }
}

دریافت و ذخیره پیام‌ها

دریافت پیام‌ها از سرور

این ImapClient کلاس می‌تواند پیام‌ها را از یک سرور IMAP دریافت کرده و آن‌ها را در قالب EML بر روی دیسک محلی ذخیره کند. مراحل زیر برای ذخیره پیام‌ها بر روی دیسک ضروری است:

  1. یک نمونه از ImapClient کلاس.
  2. در ImapClient، نام میزبان، پورت، نام کاربری و گذرواژه را مشخص کنید constructor.
  3. پوشه را با استفاده از SelectFolder() متد.
  4. متد را فراخوانی کنید ListMessages متد برای دریافت ImapMessageInfoCollection شیء.
  5. درون ImapMessageInfoCollection مجموعه، فراخوانی کنید SaveMessage() متد که مسیر خروجی و نام فایل را تعیین می‌کند.

کد زیر نشان می‌دهد چگونه پیام‌های ایمیل را از یک سرور دریافت و ذخیره کنید.

// 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");
}

دریافت پیام‌ها به ترتیب نزولی

Aspose.Email ارائه می‌دهد ImapClient.ListMessagesByPage متد که پیام‌ها را با پشتیبانی از صفحه‌بندی فهرست می‌کند. برخی بارگذاری‌های  ImapClient.ListMessagesByPage پذیرش PageSettings به عنوان پارامتر. PageSettings یک  AscendingSorting خاصیتی که وقتی به false تنظیم شود، ایمیل‌ها را به ترتیب نزولی باز می‌گرداند.

کد مثال زیر نحوه استفاده از  AscendingSorting ویژگی PageSettings کلاس برای تغییر ترتیب ایمیل‌ها.

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());
}

ذخیره پیام‌ها در قالب MSG

برای ذخیره ایمیل‌ها در فرمت MSG، ImapClient.FetchMessage() متد باید فراخوانی شود. پیام را در یک نمونه از MailMessage کلاس. MailMessage.Save() متد می‌تواند سپس برای ذخیره پیام به فرمت MSG فراخوانی شود. کد زیر نشان می‌دهد چگونه پیام‌ها را در قالب 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);
}

گروه‌بندی پیام‌های دریافت‌شده

ImapClient ارائه می‌دهد یک FetchMessages متدی که یک iterable از شماره‌های توالی یا شناسهٔ یکتا می‌پذیرد و فهرستی از MailMessage. قطعه کد زیر استفاده از FetchMessages متد برای بازیابی پیام‌ها بر اساس شماره توالی و شناسهٔ یکتا.

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);

دریافت پوشه‌ها و خواندن پیام‌ها به صورت بازگشتی

در این مقاله، بیشتر ImapClient ویژگی‌ها برای ساخت برنامه‌ای استفاده می‌شوند که تمام پوشه‌ها و زیرپوشه‌ها را به صورت بازگشتی از سرور IMAP لیست می‌کند. همچنین پیام‌ها را در هر پوشه و زیرپوشه به فرمت MSG بر روی دیسک محلی ذخیره می‌کند. در دیسک، پوشه‌ها و پیام‌ها همان ساختار سلسله‌مراتبی سرور IMAP ایجاد و ذخیره می‌شوند. قطعه کد زیر نشان می‌دهد چگونه به صورت بازگشتی پیام‌ها و اطلاعات زیرپوشه‌ها را دریافت کنید.

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) { }            
}

پردازش اطلاعات خاص پیام

استخراج پارامترهای اضافی به عنوان اطلاعات خلاصه

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));
    }
}

دریافت اطلاعات سرصفحه List-Unsubscribe

هدر List-Unsubscribe شامل URL برای لغو اشتراک از لیست‌های ایمیل مانند تبلیغات، خبرنامه‌ها و غیره است. برای دریافت هدر List-Unsubscribe، از ListUnsubscribe ویژگی ImapMessageInfo کلاس. مثال زیر نحوه استفاده از آن را نشان می‌دهد ListUnsubscribe ویژگی برای دریافت هدر 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);
}