How to set up smartphones and PCs. Informational portal
  • home
  • Errors
  • The best mail collector. Mail collector (making simple things difficult)

The best mail collector. Mail collector (making simple things difficult)

Switching from one tab from Gmail to another with Yandex.Mail is quite tedious. And if you have a dozen accounts with different mail providers, checking new correspondence in the morning turns into torture. By combining letters in one place, you will get rid of this inconvenience.

Web interface

Most email providers provide a built-in feature to collect emails from multiple mailboxes. For example, let's try to collect letters from all your mailboxes in one Gmail account.

First of all, make sure that the mail service from where you want to collect letters has POP access. Then go to your Gmail settings and click on "Settings" in the upper right corner. Go to the "Accounts" tab and look for the "Receive mail from other accounts" section.

Add an account, enter your email address and click Next, then enter your password. To make the exchange of mail between providers more secure, make sure that the option "Always use secure connection (SSL) when receiving mail" is enabled. Then click on "Add account".

Now emails arriving at the added address will be automatically collected in the Inbox of your Gmail. You can add as many postal addresses as you need.

Desktop clients

Email needs software. Yes, you can do a lot in the web mail client (sometimes much more than Google currently allows you to do in Gmail). But the web interface cannot be compared to a native application. Even the most modern Web UI is a bottleneck for mail handling.

Rafe Needleman, Сnet.com

The great thing about desktop email clients is that they can aggregate emails from multiple accounts. At the same time, you can work with dozens of addresses and not even think about which provider stores this or that message.

Most desktop email clients have a generic Inbox built in. Even if your favorite client only supports separate inbox folders, you can still easily collect them together using smart filters.

Despite the fact that Outlook is designed to manage multiple mailboxes at the same time, it still displays a separate Inbox for each account. But this can be easily corrected with filters.

Open Outlook, go to the "Folders" tab and click "Create Search Folder" on the toolbar. Then select Create Custom Search Folder. Click on "Select" but do not select any search criteria so that all new messages will be sent to the folder. Name the folder whatever you want, such as All Mail.

Click on "Browse", select all folders and mailboxes from which you want to collect mail, and check the "Search in subfolders" option.

Now, in the smart folder you created, letters from all mail accounts that you added to Outlook will appear. You can enable the "Show in favorites" option so that your new mail is always in sight.

Mac mail client provides a single inbox for all connected accounts. Just add your accounts, and all new emails will be collected in one place.

Thunderbird makes it easy to collect all your emails in one inbox. Go to the "View" menu (if the menu bar is not displayed, press Alt). Then choose "Folders" → "Consolidated". You will now have one Inbox for new emails, one Drafts folder, one Sent Items folder, and one Archive folder. You do not have to search for a long time, what is where. In this case, messages will, as before, be stored on the servers of your mail providers.

Mobile clients

Unified Inbox is available in many mobile email clients, including Gmail. The Gmail app collects your inbox from all your email accounts, including Yahoo, Outlook, or other services.

If you don't like Google's app, you can try third-party email clients such as Outlook or MyMail.

Maybe you have your own ideas on how to group mail in one place? Share in the comments.

Instructions

Log into your account, for this, go to the following link http://gmail.com and enter your username and password.

Click on the gear icon in the upper right corner of "Accounts and Imports". Then go to the "Send emails as" section and click on the "Add your own email address" link.

In the new pop-up window, enter the first and last name to which the added e-mail is registered, as well as the address of the e-mail box. Click on the "Next step" button.

Next, the screen will ask you how to send letters using this address - using the Gmail service or the mail interface from QIP. It is advisable to specify Gmail, fewer settings, therefore, less time will be spent. Click on the Next Action button.

In the next window, you are notified that after clicking the "Send Confirmation" button, you will need to check the specified e-mail so that Gmail is sure of the validity of the e-mail address. Click the button and open your mailbox in a new tab.

Review your unread emails and open the email with the heading "Gmail Confirmation". Click the link to confirm the existence of this email address, or copy the code.

If you copied the code, paste it into the empty field of the "Add another ..." window and click the "Verify" button. After some time, this window will automatically close and a new e-mail will appear in the "Send mails as" list.

Now, similarly to the one described, you need to add a new address to the "Collect mail from other accounts" block. To do this, click on the link "Add your POP3 mail account".

In the new pop-up window, enter the email address. Click on the Next Action button. In the next window, you must enter a password and activate the options "Always use a secure connection" and "Assign a shortcut to incoming emails". Then click the "Add account" button. After some time, this window will automatically close and a new e-mail will appear in the "Collect mail from other accounts" list.

E-mail has become an integral part of the life of users on the Internet. There are many resources that provide a mailbox. Check often needed Existence box, its authenticity. If you need to know about the authenticity of an email address, then there is nothing difficult about it.

Instructions

Register an email address with the same name if you are interested in an email created on some free resource. A pre-existing e-mail cannot be registered again. All known mail servers are provided with a callback system. In this case, you will receive an error notification, which will inform you about the impossibility of further registration.

Try to write a letter from an available email box to the desired e-mail. The message can be with or without text. Send it and check after some time your e-mail for sent letters. If you were notified that your letter did not reach the desired address, then perhaps this mail does not exist.

Register in the "My World" network. This is a social network in Runet, in which many users communicate. Use the search on the accounts of other users. Enter the desired e-mail in the search box, which is located in the right corner at the top of the site page. You can click on the "People" button. You will be taken to a search for accounts based on various criteria. Just enter the e-mail you are interested in in the field that you will find under the name "Search". You must click "Find". If the mailing address is valid, then you will see information about the owner of the mail.

If you have mailboxes on other mail services, set up a mail collector so that all information is in one place.

For the collector to work correctly, you must configure it only under the Mail.Ru account. Make sure you are logged into your Mail.Ru account before you start collecting emails from other mail services.

To add a box:

  1. Click on the logo of the service on which you have the box. If your service is not in the list, click "Other mail".
  2. Enter the name of the mailbox and password to it, click "Add". If you see an error message, check the correctness of the data entered and try again. If the information is correct, you will receive a confirmation and you can continue to configure the mail collector.

Depending on which protocol supports the service on which the mailbox is located, the setting may differ:

IMAP

  1. Specify in which folder you want to move letters and click "Save".
  2. If you have personal folders in the mailbox from which you will collect mail, they will be attached to the selected folder.

System folders are also synchronized: Drafts, Sent Items, Spam and Trash. If you are going to import messages from a third-party mailbox to the Inbox folder, specify whether you want to apply filters configured in the current mailbox to incoming messages.

If the collection of letters is configured using the IMAP protocol, you will be able to reply to letters from the mailbox to which the letter was sent.

POP3

  1. Set the checkbox "All mail" to import all letters from the mailbox. If you want to mark all imported emails as read, check the Mark all old emails as read checkbox.
  2. Select in which folder you want to put letters from this mailbox. If you want to create a new folder, check the box under the drop-down list and enter the name of the folder.
  3. To apply filters that are configured in the mailbox to messages from other servers, check the box next to "Apply filters to received messages."
  4. Click "Save".

Thus, you can specify up to 9 mailboxes from which letters will be collected. To disable the mail collector, set the switch to the OFF position. If you want to edit the settings, click "Edit". To remove a collector, click Remove.

This article will focus on what "mail from other mailboxes" and "collecting letters from other accounts" are. Reviews of postal services and comparisons.

As the functionality of mail services is updated, we will publish news at the end of this article.

Mail.ru mail service, Yandex and Google search engines have been offering very useful and necessary functionality for several years, which allows you to combine all other e-mail accounts in one mail. In other words, it is worth adding and configuring all your "mails" once, and it will be possible to manage them in one window without constantly entering a username and password.

Mail services offer us a huge storage space for all incoming emails, a user-friendly interface, good management functionality, and much more. To test the capabilities of the listed mail services, we will highlight three parameters to assess their work: 1) you need to manage various e-mail accounts, including from various services and sites, through one mail client; 2) have a personal signature and name for each mail; 3) delete letters from the servers of those mail accounts that have been added to mail, yandex or google mail.

Our task looks like this:

So let's get started. We are the first to test the service from Mail.ru, which tells us: “You can collect mail from all your mailboxes into one mailbox on Mail.ru.

Configure collection of emails from any server using the IMAP or POP3 protocol. " To add external mail other than @mail, @inbox, @list, @bk, you need to have at least one mail that is already available on the listed servers from mail. In other words, first register mail-mail, and then add other mail accounts. The registration process for mail is simple, it makes no sense to describe it, but we will describe adding other e-mails to this mail account.


Next, you will be prompted to enter your login and password from any mailbox that you use, and within 3-5 minutes "Mail collector from mail" will create a folder with the name of the added mail next to the folders "inbox", "sent", "spam" and other.


In fact, the letter collector will start working within 10-15 minutes and will add all letters to the newly created folder from the mailbox you specified. All incoming letters for a new e-mail will come to this folder, it will also become possible to send letters from the attached mailbox. When creating a new letter, the "From" field will appear, in which you can select from which mailbox the letter will be sent.


The pluses of the Mail.ru mail service include the simplicity of adding and the ease of configuring other mailboxes, the absence of the need to specify various protocols (POP3, SMTP). This is very important because not every user knows what it is.

The disadvantages of Mail.ru are that it is impossible to assign a name and signature for each newly added mail (any new e-mail, except for the main one), that is, the name and signature of the main mail will be distributed to each address and that's it. Another big drawback is that when uploading messages to mail, there is no way to automatically delete original messages from the attached mailbox server. Why is it so important to delete messages from the server of the added mailbox? This will avoid filling up the attached mail, because external e-mail accounts are usually too small to store emails. For example, if the mail space in an external account is full, Mail.ru will not display any new letters until you enter the external mail interface and directly delete letters from there to free up space. Plus, we tie mail to Mail in the hope of getting a lot of storage space for our mail, which may be limited by hosting resources. Thus, despite the fact that Mail.ru offers an almost unlimited volume of mailbox, when you add mail from another domain zone (for example), your resources of the added e-mail will not increase in Mail.ru, but will continue to be limited by resources hosting (in our case, primer.ru resources).

The ability to add other mail to the Mail service did not suit our task on two points out of three, totaling one point.


True, Mail.ru has another way of adding external mail, or more precisely, connecting or logging into external mail. It looks like this:


This method is not suitable for our task, since it is not a mail collector, but a user mode that connects to mail and loads all folders and letters into the mail interface each time. But here it is possible to add a personal signature and name for each mail, it is possible to send letters from the configured mail. Deleting messages from loaded mailboxes does not work, because it is not a mail collector.

Important! Some users mistakenly think that if the letters are displayed in mail, then the mail from which the download occurred can be cleared. Note again that Mail.ru works as a mail viewer, and if you clear the mail, it will be deleted both in the main mailbox and in the mail.

The second test subject is Yandex with his mail collector. The tasks are similar: collect mail, assign a signature and name for each mail, and delete all mail from the added mailbox.

The Yandex mail collector is configured in a similar way, but if the mail is connected from some site, for example site.ru, then additional settings will need to be specified, see the screenshot.


The Mail service did this work for us, while Yandex offers to manually set all the settings from third-party mail. There is nothing complicated here: in the login field, enter the full name of the mail (), in the server field, enter only the domain (site.ru), it is better to leave all other settings by default, or change if you know what you are doing. After successfully adding mail, the following message will appear:


Unlike Mail collector, Yandex offers to choose whether to save the originals of letters in the added mailbox or not. In everything else, the Yandex mail collector works in a similar way to Mail.ru, it is possible to select a mailbox from which to send a letter. But Yandex has the same problem with the signature of letters: there is no way to set an individual name and signature for each added mailbox.


Judging by the navigation, there is a possibility of adding an individual signature for each mailbox, but in reality it does not work. We select the mail, write down the name and signature, click save. That's it, the signature is saved and works, but it is also saved for all other mailboxes, that is, by assigning a name and signature to one mailbox, you automatically change these parameters in all mails combined in Yandex. Even if you select any other box, the signature will now be the same everywhere.

In total, Yandex successfully coped with collecting and sorting mail, can delete originals of letters from the added mailbox, but cannot work with signatures! The mail collector from Yandex did not cope with our task and scores two points out of three.


I would like to note that, having "rummaged" in all three services for assembling letters, it seems that Mail has "slapped" its functionality in a hurry. Although it will satisfy most users, to be honest, Mail made a mail collector for show, to check out the competitive race. Everything works well and without failures, but the collector from Mail did not cope with our task. There are several ad units in the mail interface, but they do not interfere with working with letters.

As for Yandex, which created the letter collector a long time ago, it seems that this particular industry is not being supported, because fixing such a simple functionality (the ability to add multiple signatures for mailboxes) should not be difficult for such a powerful search engine. Nevertheless, Yandex has another unique functionality that allows you to bind domains to their dns servers, and then create and configure mail. But such operations and settings require knowledge and time. And although there is nothing complicated there, in any case, it is not for the majority of users of the Russian Internet. Great advantage- no ads in the Yandex mail interface! Minus- Limit in the letter collector to 10 mailboxes.

The finalist and winner is a letter collector from Google, who coped with our task with a bang, despite even limit of 5 boxes

Recently, the next version of Mail.Ru Mail for iPhone and iPad has been released. The main update is one, but significant: it is the ability to collect all user's mailboxes in one place, namely in the Mail.Ru Mail application.

All mail in one place. Most of us have several emails - for work, for registration on all kinds of forums, coupon sites and online stores, and for the soul (read - for communication with friends, relatives, etc.). In the previous version of the Mail.Ru application, the developers took the first step towards streamlining the management of the "zoo" of accounts: they added support for multiple mailboxes.

Now, in the Mail.Ru Mail client, you can work not only with mailboxes on this service, but also with accounts of Gmail, Rambler, Outlook and other providers that support IMAP / POP3. Switching between boxes is very simple - it's a matter of one click. While a user is browsing one account, others wait patiently for their turn.

The application does not rearrange the order in different boxes in its own way. In each of the accounts, you can continue to follow exactly the logic of work to which you have managed to get used to. For example, in the interface of the Mail.Ru application, the names and structure of folders, checkboxes and other settings of the mailbox on Gmail will remain the same as in the large version of Gmail. In addition, in the application, you can individually configure each of the accounts: set a signature, enable or disable the display of icons, configure the operation of the push-notification system.


Push notifications. Advanced push notifications deserve a separate mention. Firstly (and this is one of the main bonuses of the application), they can be enabled even for accounts on those services that cannot send push.

Secondly, they can be configured exactly as you like, specifying in detail what time they come and what to report. It is possible to mark the addressees by name, messages from which you are ready to read day and night (for example, letters from your mother), or strictly from 9 to 19:00 (most likely, these will be letters from clients or colleagues). You can turn alerts on or off for specific accounts, folders, or recipients.

The developers have carefully provided a button that allows you to turn off notifications about mailings from social networks or coupon services at once. You can also set the content of push notifications: perhaps, for privacy reasons, you want to hide the recipient's name or the subject of the letter.

Fast actions. For convenient work with letters in the application there is a menu of quick actions. To call these magic buttons, you just need to swipe from right to left on the desired message in the list of letters. With their help, you can delete a letter, put a check mark, move it to another folder, send it to spam, etc. All actions are performed in one click.

Avatars of addressees and services will help to navigate in the mail. They are visible in the list of emails, when reading and writing emails, and, as already mentioned, in push notifications. When reading and writing a letter, the user sees the avatar of the sender or addressee, as well as a preview of the attachments. If photos or drawings are attached, thumbnails of the images are displayed. By the way, you can view attachments without leaving the checkout, i.e. right in the app.

Caching. Caching will be very useful in those places where the Internet is not very good, for example, in the subway. The owner of a smartphone with the Mail.Ru mail client will be able to read texts and watch photos even in the absence of a network.

Hints. The application prompts you for the desired email, you should enter the first letters in the address bar (provided that you have written to this addressee at least once - it doesn't matter in the main version of Mail or in the application). In addition, the client, at your request, will add contacts from the phone to the list of respondents.

Let's be objective - the Mail.Ru mail application is made to last. And if you use fancy pushes before, enjoy the avatars in the list of letters, etc. it was possible only if there was a mailbox on Mail.Ru, but now users of the same Mail.Ru will be able to collect the rest of the mailboxes in the application (and those who prefer other services, at least test the client).

I continue a series of articles about the function of collecting mail to one main e-mail box from any other located on any mail services. In the last article, we talked about setting up mail collection on the Yandex service, which is as easy as shelling pears. And in this article I will talk about how to do the same in another, no less popular today service - Mail.ru, where many still keep their main e-mail box, despite the fact that, for example, the GMail service has clear advantages (I have described setting up mail collection in Gmail). But as they say, to each his own and sometimes it's just a matter of habit :)

Setting up mail collection in the Mail.ru service is as easy as, for example, on Yandex. Just a few simple steps and everything will be ready, mail will start flowing from the mailboxes you connected to one, on Mail.

The process of setting up mail collection in the Mail.ru service

First of all, log into your account on Mail, where you will collect mail from other e-mail boxes and open the "Letters" section (the mail is located there).

Now you need to go to the mail settings. To do this, click the "More" button at the top and select "Settings".

You can also open the settings by clicking in the upper right corner on your email address and then selecting “Mail Settings”.

Then go to the "Mail from other mailboxes" section.

The first connection window of the second e-mail box will open.

Let me remind you that the second e-mail box from which you want to collect letters can be located on any service, not just Mail!

In the example for this article, we will consider connecting a mailbox located on the Yandex.

In this window, you need to specify the username and password for the mail that you are connecting. If the mailbox you connect is located on one of the services listed below, then click the appropriate button at the top, enter the full address of the connected mail below and click “Add mailbox”:

If the mailbox that you want to connect is located on some other service (not from the list above), then click the "Other mail" button at the top, after which you need to enter the full address of the connected mail, the password from it and click "Add mailbox".

If you have not yet entered your second mail in this browser, which you are connecting, then in the next window you will need to enter your username and password from it. Example:

After that, click "Allow" (you allow mail on Mail.ru to use some of the data of the connected second mail).

If everything went well, you will receive a message that the collector has been added. Now you need to choose which folder to collect mail: in a specially created folder by the name of the mail you connected or in the inbox. It's up to you to decide, but, in my opinion, it is more convenient when mail collected from another mailbox goes to a separate folder. One way or another, then this can be configured by filtering letters.

The option “Apply filters to received emails” means that all filters that you have already configured in the main mail on Mail will also apply to mail received from the connected mailbox. Disable or not is up to you.

That's it, the letter collector is set up! Now, within a few minutes (sometimes the process is delayed if there are a lot of letters on the connected mail), mail from the second mailbox will begin to flow into your main one.

In this way, you can connect as many mails as you like to collect.

How to separately see all letters from the connected mail?

You can look at the letters separately if, when setting up mail collection in Mail, you indicated that letters should be collected in a separate folder with the name of the connected mailbox. In this case, open this folder and you will see all the letters you need. Example:

If you did not immediately configure the receipt of letters in a separate folder, you can configure it at any time by opening the created collector (more on this below).

Configuring the created letter collector, disabling and enabling it

Sometimes you may need to make changes to the settings of the mail collector you created in Mail, and also disable it or enable it again.

This can be done in the same section “Settings” - “Mail from other mailboxes”, where you originally created your mail collector.

Here you will see the generated collector. If you want to turn it off or on again, click on the corresponding switch. If you need to open the collector settings, click "Change".

And the same settings for the letter collector will open, as at the stage of its creation (see).

This article will focus on what "mail from other mailboxes" and "collecting letters from other accounts" are. Reviews of postal services and comparisons.

As the functionality of mail services is updated, we will publish news at the end of this article.

Mail.ru mail service, Yandex and Google search engines have been offering very useful and necessary functionality for several years, which allows you to combine all other e-mail accounts in one mail. In other words, it is worth adding and configuring all your "mails" once, and it will be possible to manage them in one window without constantly entering a username and password.

Mail services offer us a huge storage space for all incoming emails, a user-friendly interface, good management functionality, and much more. To test the capabilities of the listed mail services, we will highlight three parameters to assess their work: 1) you need to manage various e-mail accounts, including from various services and sites, through one mail client; 2) have a personal signature and name for each mail; 3) delete letters from the servers of those mail accounts that have been added to mail, yandex or google mail.

Our task looks like this:

So let's get started. We are the first to test the service from Mail.ru, which tells us: “You can collect mail from all your mailboxes into one mailbox on Mail.ru.

Configure collection of emails from any server using the IMAP or POP3 protocol. " To add external mail other than @mail, @inbox, @list, @bk, you need to have at least one mail that is already available on the listed servers from mail. In other words, first register mail-mail, and then add other mail accounts. The registration process for mail is simple, it makes no sense to describe it, but we will describe adding other e-mails to this mail account.

Next, you will be prompted to enter your login and password from any mailbox that you use, and within 3-5 minutes "Mail collector from mail" will create a folder with the name of the added mail next to the folders "inbox", "sent", "spam" and other.

In fact, the letter collector will start working within 10-15 minutes and will add all letters to the newly created folder from the mailbox you specified. All incoming letters for a new e-mail will come to this folder, it will also become possible to send letters from the attached mailbox. When creating a new letter, the "From" field will appear, in which you can select from which mailbox the letter will be sent.

The pluses of the Mail.ru mail service include the simplicity of adding and the ease of configuring other mailboxes, the absence of the need to specify various protocols (POP3, SMTP). This is very important because not every user knows what it is.

The disadvantages of Mail.ru are that it is impossible to assign a name and signature for each newly added mail (any new e-mail, except for the main one), that is, the name and signature of the main mail will be distributed to each address and that's it. Another big drawback is that when uploading messages to mail, there is no way to automatically delete original messages from the attached mailbox server. Why is it so important to delete messages from the server of the added mailbox? This will avoid filling up the attached mail, because external e-mail accounts are usually too small to store emails. For example, if the mail space in an external account is full, Mail.ru will not display any new letters until you enter the external mail interface and directly delete letters from there to free up space. Plus, we tie mail to Mail in the hope of getting a lot of storage space for our mail, which may be limited by hosting resources. Thus, despite the fact that Mail.ru offers an almost unlimited volume of mailbox, when adding mail from another domain zone (for example, [email protected]), your added e-mail resources will not increase in Mail.ru, but will continue to be limited by hosting resources (in our case, primer.ru resources).

The ability to add other mail to the Mail service did not suit our task on two points out of three, totaling one point.

True, Mail.ru has another way of adding external mail, or more precisely, connecting or logging into external mail. It looks like this:

This method is not suitable for our task, since it is not a mail collector, but a user mode that connects to mail and loads all folders and letters into the mail interface each time. But here it is possible to add a personal signature and name for each mail, it is possible to send letters from the configured mail. Deleting messages from loaded mailboxes does not work, because it is not a mail collector.

Important! Some users mistakenly think that if the letters are displayed in mail, then the mail from which the download occurred can be cleared. Note again that Mail.ru works as a mail viewer, and if you clear the mail, it will be deleted both in the main mailbox and in the mail.

The second test subject is Yandex with his mail collector. The tasks are similar: collect mail, assign a signature and name for each mail, and delete all mail from the added mailbox.

The Yandex mail collector is configured in a similar way, but if the mail is connected from some site, for example site.ru, then additional settings will need to be specified, see the screenshot.

The Mail service did this work for us, while Yandex offers to manually set all the settings from third-party mail. There is nothing complicated here: in the login field, enter the full name of the mail ( [email protected]), in the server field, enter only the domain (site.ru), it is better to leave all other settings by default, or change if you know what you are doing. After successfully adding mail, the following message will appear:

Unlike Mail collector, Yandex offers to choose whether to save the originals of letters in the added mailbox or not. In everything else, the Yandex mail collector works in a similar way to Mail.ru, it is possible to select a mailbox from which to send a letter. But Yandex has the same problem with the signature of letters: there is no way to set an individual name and signature for each added mailbox.

Judging by the navigation, there is a possibility of adding an individual signature for each mailbox, but in reality it does not work. We select the mail, write down the name and signature, click save. That's it, the signature is saved and works, but it is also saved for all other mailboxes, that is, by assigning a name and signature to one mailbox, you automatically change these parameters in all mails combined in Yandex. Even if you select any other box, the signature will now be the same everywhere.

In total, Yandex successfully coped with collecting and sorting mail, can delete originals of letters from the added mailbox, but cannot work with signatures! The mail collector from Yandex did not cope with our task and scores two points out of three.

I would like to note that, having "rummaged" in all three services for assembling letters, it seems that Mail has "slapped" its functionality in a hurry. Although it will satisfy most users, to be honest, Mail made a mail collector for show, to check out the competitive race. Everything works well and without failures, but the collector from Mail did not cope with our task. There are several ad units in the mail interface, but they do not interfere with working with letters.

As for Yandex, which created the letter collector a long time ago, it seems that this particular industry is not being supported, because fixing such a simple functionality (the ability to add multiple signatures for mailboxes) should not be difficult for such a powerful search engine. Nevertheless, Yandex has another unique functionality that allows you to bind domains to their dns servers, and then create and configure mail. But such operations and settings require knowledge and time. And although there is nothing complicated there, in any case, it is not for the majority of users of the Russian Internet. Great advantage- no ads in the Yandex mail interface! Minus- Limit in the letter collector to 10 mailboxes.

The finalist and winner is a letter collector from Google, who coped with our task with a bang, despite even limit of 5 boxes

Of course, everything should be parallelized. This is where my favorite TPL DataFlow library comes into play.

We will collect mail using POP3. All the "fashionable things" of IMAP in this task are superfluous - you need to pick up the source of the letter as quickly and easily as possible and delete it on the server. POP3 is enough for the eyes here. We are using OpenPop.NET.

As an optional feature, we will tighten monitoring in Zabbix. (We are going to work 24/7 and give out the vaunted speed - you need to monitor this).

Go

Let's create a regular console application. Open the NuGet console and install all the necessary packages:

Install-Package Nlog Install-Package OpenPop.NET Install-Package TopShelf Install-Package Microsoft.TPL.DataFlow
Go to the project folder, create App.Debug.config and App.Release.config. Unload the project from the studio, open its code (Hereinafter, TopCrawler.csproj). Add to the section with the config:

Configurations

App.config App.config


And below is the custom target for MSBuild:

Transform target

$ (TargetFileName) .config


Personally, I got used to it in this way - the old fashioned way - to add the transformation of configs to separate environments.
For convenience, I suggest strongly-type configs. A separate class will read the configuration. (You can talk about the theoretical aspects of such a solution in the comments). Configs, logs, monitoring are a great reason to implement the Singleton pattern.

Create a folder of the same name in the project (there must be an order). Inside, we create 3 classes - Config, Logger, Zabbix. Our logger:

Logger

static class Logger (public static NLog.Logger Log (get; private set;) public static NLog.Logger Archive (get; private set;) static Logger () (Log = LogManager.GetLogger ("Global"); Archive = LogManager. GetLogger ("Archivator");))


Monitoring with Zabbix deserves a separate post, so I'll just leave the class that implements the agent here:

Zabbix

namespace TopCrawler.Singleton (///

/// Singleton: zabbix sender class /// static class Zabbix (public static ZabbixSender Sender (get; private set;) static Zabbix () (Sender = new ZabbixSender (Config.ZabbixServer, Config.ZabbixPort);)) struct ZabbixItem (public string Value; public string Key; public string ;) class ZabbixSender (internal struct SendItem (// ReSharper disable InconsistentNaming - Zabbix is ​​case sensitive public string host; public string key; public string value; public string clock; // ReSharper restore InconsistentNaming) #pragma warning disable 0649 internal struct ZabbixResponse ( public string Response; public string Info;) #pragma warning restore 0649 #region --- Constants --- public const string DefaultHeader = "ZBXD \ x01"; public const string SendRequest = "sender data"; public const int DefaultTimeout = 10000 ; #endregion #region --- Fields --- private readonly DateTime _dtUnixMinTime = DateTime.SpecifyKind (new DateTime (1970, 1, 1), DateTimeKind.Utc); private readonly int _timeout; private readonly string _zabbixserver; private readonly int _zabbixport; #endregion #region --- Constructors --- public ZabbixSender (string zabbixserver, int zabbixport): this (zabbixserver, zabbixport, DefaultTimeout) () public ZabbixSender (string zabbixserver, int zabbixport, int timeout) (_zabbixserver = zabbixport zabbixport; _timeout = timeout;) #endregion #region --- Methods --- public string SendData (ZabbixItem itm) (return SendData (new List (1) (itm)); ) public string SendData (List lstData) (try (var serializer = new JavaScriptSerializer (); var values ​​= new List (lstData.Count); values.AddRange (lstData.Select (itm => new SendItem (host = itm.Host, key = itm.Key, value = itm.Value, clock = Math.Floor ((DateTime.Now.ToUniversalTime () - _dtUnixMinTime). TotalSeconds) .ToString (CultureInfo.InvariantCulture)))); var json = serializer.Serialize (new (request = SendRequest, data = values.ToArray ())); var header = Encoding.ASCII.GetBytes (DefaultHeader); var length = BitConverter.GetBytes ((long) json.Length); var data = Encoding.ASCII.GetBytes (json); var packet = new byte; Buffer.BlockCopy (header, 0, packet, 0, header.Length); Buffer.BlockCopy (length, 0, packet, header.Length, length.Length); Buffer.BlockCopy (data, 0, packet, header.Length + length.Length, data.Length); using (var socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) (socket.Connect (_zabbixserver, _zabbixport); socket.Send (packet); // Header var buffer = new byte; ReceivData (socket , buffer, 0, buffer.Length, _timeout); if (DefaultHeader! = Encoding.ASCII.GetString (buffer, 0, buffer.Length)) throw new Exception ("Invalid header"); // Message length buffer = new byte ; ReceivData (socket, buffer, 0, buffer.Length, _timeout); var dataLength = BitConverter.ToInt32 (buffer, 0); if (dataLength == 0) throw new Exception ("Invalid data length"); // Message buffer = new byte; ReceivData (socket, buffer, 0, buffer.Length, _timeout); var response = serializer.Deserialize (Encoding.ASCII.GetString (buffer, 0, buffer.Length)); return string.Format ("Response: (0), Info: (1)", response.Response, response.Info); )) catch (Exception e) (return string.Format ("Exception: (0)", e);)) private static void ReceivData (Socket pObjSocket, byte buffer, int offset, int size, int timeout) (var startTickCount = Environment.TickCount; var received = 0; do (if (Environment.TickCount> startTickCount + timeout) throw new TimeoutException (); try (received + = pObjSocket.Receive (buffer, offset + received, size - received, SocketFlags.None) ;) catch (SocketException ex) (if (ex.SocketErrorCode == SocketError.WouldBlock || ex.SocketErrorCode == SocketError.IOPending || ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable) Thread throwleep; 30); else ) while (received< size); } #endregion } }


Configs ... It's time to do at least something interesting. First, we will store the boxes that we are polling in the configs. Secondly, the DataFlow settings. I suggest this:

Configs



So, the host and port where it connects, the user and the password - everything is clear here. Next is the type of box. Let's say the service is being used by marketing (as well as other departments). They have mailboxes where auto-replies to mailings are dumped, as well as FBL spam reports. The mailbox itself already categorizes the letter, therefore, for such situations, we immediately set the mailbox type. With the DataFlow settings, it will be clear later when we start creating objects. Here we will have our own sections in the config. There are a lot of manuals on how to do this, so I'll just show the result:

Defining types

#region --- Types --- static class MailboxType (public const string Bo = "bo"; public const string Crm = "crm"; public const string Fbl = "fbl"; public const string Bounce = "bounce";) class MailboxInfo (public string Type (get; set;) public string Hostname (get; set;) public string User (get; set;) public string Password (get; set;) public int Port (get; set;)) class DataBlockOptions (public int Maxdop (get; set;) public int BoundedCapacity (get; set;) public DataBlockOptions () (Maxdop = 1; BoundedCapacity = 1;)) #endregion


Create sections

///

/// Custom config section /// public class CustomSettingsConfigSection: ConfigurationSection (public CredentialsCollection CredentialItems (get (return base ["CredentialsList"] as CredentialsCollection;)) public DataBlockOptionsCollection DataFlowOptionsItems (get (return base ["DataFlowOptionsList)"] as DataBlockOption;


///

/// Custom collection - credentials list /// public class CredentialsCollection: ConfigurationElementCollection, IEnumerable (protected override ConfigurationElement CreateNewElement () (return new CredentialsElement ();) protected override object GetElementKey (ConfigurationElement element) (return ((CredentialsElement) element) .Username;) public CredentialsElement this (get (return BaseGet (index) as CredentialsElement;) ) public new IEnumerator < Count; i++) { yield return BaseGet(i) as CredentialsElement; } } } /// /// Custom credentials item /// public class CredentialsElement: ConfigurationElement (public string Hostname (get (return base ["hostname"] as string;)) public string Username (get (return base ["username"] as string;)) public string Password (get (return base ["password"] as string;)) public string Type (get (return base ["type"] as string;)) public string Port (get (return base ["port"] as string;))) /// /// Custom collection - DataBlock options list /// public class DataBlockOptionsCollection: ConfigurationElementCollection, IEnumerable (protected override ConfigurationElement CreateNewElement () (return new DataBlockOptionsElement ();) protected override object GetElementKey (ConfigurationElement element) (return ((DataBlockOptionsElement) element) .Name;) public CredentialsElement this (get (return BaseGet (index) as CredentialsElement;) ) public new IEnumerator GetEnumerator () (for (var i = 0; i< Count; i++) { yield return BaseGet(i) as DataBlockOptionsElement; } } } /// /// Custom DataBlock options item /// public class DataBlockOptionsElement: ConfigurationElement (public string Name (get (return base ["name"] as string;)) public string Maxdop (get (return base ["maxdop"] as string;)) public string BoundedCapacity (get (return base ["boundedcapacity"] as string;)))


I will not write the full implementation of the config, it is assumed that during the development process the parameters we need will be added there.

Let's read our custom settings like this:

Read

public List CredentialsList (get; private set;) public Dictionary DataFlowOptionsList (get; private set;) ... static Config () (try (var customConfig = (CustomSettingsConfigSection) ConfigurationManager.GetSection ("CustomSettings"); // Get mailboxes foreach (var item in customConfig.CredentialItems) CredentialsList.Add ( new MailboxInfo (Hostname = item.Hostname, Port = Convert.ToInt32 (item.Port), User = item.Username, Type = item.Type, Password = item.Password)); // Get DataFlow settings foreach (var item in customConfig.DataFlowOptionsItems) DataFlowOptionsList.Add (item.Name, new DataBlockOptions (Maxdop = Convert.ToInt32 (item.Maxdop), BoundedCapacity = Convert.ToInt32 (item.BoundedCapacity)));) catch (Exception ex) (Logger Fatal ("Error at reading config: (0)", ex.Message); throw;))


Somehow it turns out very protracted, and we have not even gotten to the most interesting.

For now, let's omit the TopShelf binding, performance counters, communication with the database and get down to business! We create the Crawler class - the core. First, we read the mail:

Private volatile bool _stopPipeline; ... public void Start () (do (var getMailsTasks = _config.CredentialsList.Select (credentials => Task.Run (() => GetMails (credentials))). ToList (); foreach (var task in getMailsTasks) task .Wait (); Thread.Sleep (2000);) while (! _StopPipeline); // Stop pipeline - wait for completion of all endpoints // This will stop the DataFlow pipeline if (_stopPipeline) Logger.Log.Warn ("Pipeline has been stopped by user ");)
Here laziness took its toll and I decided not to bother - if there are about 20-30 boxes, you can run a task for each and not worry about the number of threads. (Allow me to shower with tomatoes.)

Let's move on to the reading itself:

Private void GetMails (MailboxInfo info) (try (using (var client = new Pop3Client ()) (
Let's immediately calculate the timings of access to the mailbox - useful for diagnosing the network and server load.

// Get Zabbix metrics var stopwatch = new Stopwatch (); stopwatch.Start (); // Get mail count client.Connect (info.Hostname, info.Port, false); client.Authenticate (info.User, info.Password); stopwatch.Stop ();
Sending data to Zabbix. It's simple - we specify the hostname (as it is in Zabbix), the key (again, strictly, as in Zabbix) and the string value.

// Send it to Zabbix Zabbix.Sender.SendData (new ZabbixItem (Host = Config.HostKey, Key = info.Type + Config.TimingKey, Value = stopwatch.ElapsedMilliseconds.ToString ())); Logger.Log.Debug ("Send [(0)] timing to Zabbix: connected to" (1) "as" (2) ", timing (3) ms", info.Type, info.Hostname, info.User, stopwatch.ElapsedMilliseconds); var count = client.GetMessageCount (); if (count == 0) return; Logger.Log.Debug ("We" ve got new (0) messages in "(1)" ", count, info.User); // Send messages to sorting block for (var i = 0; i< count; i++) { try { var mailInfo = new MessageInfo { IsSpam = false, Mail = client.GetMessage(i + 1), Type = MessageType.UNKNOWN, Subtype = null, Recipient = null, Mailbox = info }; Logger.Log.Debug("Download message from "{0}". Size: {1}b", info.User, mailInfo.Mail.RawMessage.Length);
The DataFlow pipeline will be created when the Crawler class is created. We believe that our first step is to sort the letter.

While (! _SortMailDataBlock.Post (mailInfo)) Thread.Sleep (500);
You see how simple it is - the conveyor itself is one. All tasks that read mail send messages there one at a time. If the block is busy, Post will return false and we'll just wait until it's free. The current sweat continues to work at this time. This is what I call worry-free concurrency.

The message went to the conveyor, now you can save it in a RAW archive with peace of mind (yes, everything that we read - we save it to a file archive. The support service will thank us later).

Let's set up, for example, the rotation of the archive:

NLog.config



Then you can set logStash on it, but that's another story ...

// Save every mail to archive Logger.Log.Debug ("Archive message"); Logger.Archive.Info (Functions.MessageToString (mailInfo.Mail)); ) catch (Exception ex) (Logger.Log.Error ("Parse email error: (0)", ex.Message); Functions.ErrorsCounters.Increment (); // Archive mail anyway Logger.Log.Debug ("Archive message "); Logger.Archive.Info (Encoding.Default.GetString (client.GetMessageAsBytes (i + 1)));) if (_config.DeleteMail) client.DeleteMessage (i + 1); if (_stopPipeline) break; ) Logger.Log.Debug ("Done with" (0) "", info.User); )) catch (Exception ex) (Logger.Log.Error ("General error - type: (0), message: (1)", ex, ex.Message); Functions.ErrorsCounters.Increment ();))
Here we used static error counters (in terms of box types), where ErrorsCounters are:

Public static Dictionary ErrorsCounters = new Dictionary ();
And the counters themselves can be done like this:

Counter.cs

class Counter (private long _counter; public Counter () (_counter = 0;) public void Increment () (Interlocked.Increment (ref _counter);) public long Read () (return _counter;) public long Refresh () (return Interlocked .Exchange (ref _counter, 0);) public void Add (long value) (Interlocked.Add (ref _counter, value);) public void Set (long value) (Interlocked.Exchange (ref _counter, value);))


Let's move on to creating a pipeline. Let's say we have boxes where auto-responses are poured into. Such letters must be parsed (what kind of auto-reply, from whom, by which mailing list, etc.) and put the result in the storage (DB). Let's say there are boxes where FBL reports fall. We add such letters to the database at once. We consider all other letters "useful" - they should be checked for spam and sent to an external system, for example, CRM.

As you already understood, this example mainly considers the use of the collector for marketing tasks - collecting statistics on mail delivery, information about spam.

So, we have decided on the workflow. We declare the necessary blocks in the Crawler class:

Class MessageInfo (public bool IsSpam (get; set;) public Message Mail (get; set;) public string Subtype (get; set;) public string Recipient (get; set;) public MessageType Type (get; set;) public MailboxInfo Mailbox (get; set;)) class Crawler (// Pipeline private TransformBlock _sortMailDataBlock; private TransformBlock _spamFilterDataBlock; private TransformBlock _checkBounceDataBlock; private TransformBlock _identifyDataBlock; private ActionBlock _addToCrmDataBlock; private ActionBlock _addToFblDataBlock; private ActionBlock _addToBounceDataBlock; ...
We create an initialization method and create pipeline blocks (we use our wonderful sections from the configs to initialize the blocks):

Public void Init () (// *** Create pipeline *** // Create TransformBlock to get message type var blockOptions = _config.GetDataBlockOptions ("_ sortMailDataBlock"); _sortMailDataBlock = new TransformBlock (mail => SortMail (mail), new ExecutionDataflowBlockOptions (MaxDegreeOfParallelism = blockOptions.Maxdop, BoundedCapacity = blockOptions.BoundedCapacity)); // Create TransformBlock to filter spam blockOptions = _config.GetDataBlockOptions ("_ spamFilterDataBlock"); _spamFilterDataBlock = new TransformBlock (mail => FilterSpam (mail), new ExecutionDataflowBlockOptions (MaxDegreeOfParallelism = blockOptions.Maxdop, BoundedCapacity = blockOptions.BoundedCapacity)); // Create TransformBlock to sort bounces blockOptions = _config.GetDataBlockOptions ("_ checkBounceDataBlock"); _checkBounceDataBlock = new TransformBlock (mail => BounceTypeCheck (mail), new ExecutionDataflowBlockOptions (MaxDegreeOfParallelism = blockOptions.Maxdop, BoundedCapacity = blockOptions.BoundedCapacity)); // Create TransformBlock to identify bounce owner blockOptions = _config.GetDataBlockOptions ("_ identifyDataBlock"); _identifyDataBlock = new TransformBlock (mail => GetRecipient (mail), new ExecutionDataflowBlockOptions (MaxDegreeOfParallelism = blockOptions.Maxdop, BoundedCapacity = blockOptions.BoundedCapacity)); // Create ActionBlock to send mail to CRM blockOptions = _config.GetDataBlockOptions ("_ addToCrmDataBlock"); _addToCrmDataBlock = new ActionBlock (mail => AddToCrm (mail), new ExecutionDataflowBlockOptions (MaxDegreeOfParallelism = blockOptions.Maxdop, BoundedCapacity = blockOptions.BoundedCapacity)); // Create ActionBlock to send FBL to MailWH blockOptions = _config.GetDataBlockOptions ("_ addToFblDataBlock"); _addToFblDataBlock = new ActionBlock (mail => AddToFbl (mail), new ExecutionDataflowBlockOptions (MaxDegreeOfParallelism = blockOptions.Maxdop, BoundedCapacity = blockOptions.BoundedCapacity)); // Create ActionBlock to send Bounce to MailWH blockOptions = _config.GetDataBlockOptions ("_ addToBounceDataBlock"); _addToBounceDataBlock = new ActionBlock (mail => AddToBounce (mail), new ExecutionDataflowBlockOptions (MaxDegreeOfParallelism = blockOptions.Maxdop, BoundedCapacity = blockOptions.BoundedCapacity));
We assemble the conveyor in accordance with our scheme:

// *** Build pipeline *** _sortMailDataBlock.LinkTo (_spamFilterDataBlock, info => info.Type == MessageType.GENERAL); _sortMailDataBlock.LinkTo (_addToFblDataBlock, info => info.Type == MessageType.FBL); _sortMailDataBlock.LinkTo (_checkBounceDataBlock, info => info.Type == MessageType.BOUNCE); _sortMailDataBlock.LinkTo (DataflowBlock.NullTarget (), info => info.Type == MessageType.UNKNOWN); / * STUB * / _checkBounceDataBlock.LinkTo (_identifyDataBlock); _identifyDataBlock.LinkTo (_addToBounceDataBlock); _spamFilterDataBlock.LinkTo (_addToCrmDataBlock, info =>! info.IsSpam); _spamFilterDataBlock.LinkTo (DataflowBlock.NullTarget (), info => info.IsSpam); / * STUB * /
As you can see, everything is extremely simple - we connect the block with the next one (with the ability to set the connection condition). All blocks are executed in parallel. Each block has a degree of parallelism and capacity (using capacity, you can adjust the queue before the block, that is, the block has received a message, but is not yet processing). Thus, you can set a high degree of parallelism for "complex" and time-consuming operations, such as parsing email content.

I will not describe the DataFlow materiel, it is better to read everything in the original source TPL DataFlow.

SortMailDataBlock.Completion.ContinueWith (t => (if (t.IsFaulted) ((IDataflowBlock) _spamFilterDataBlock) .Fault (t.Exception); else _spamFilterDataBlock.Complete ();)); _sortMailDataBlock.Completion.ContinueWith (t => (if (t.IsFaulted) ((IDataflowBlock) _addToFblDataBlock) .Fault (t.Exception); else _addToFblDataBlock.Complete ();)); _sortMailDataBlock.Completion.ContinueWith (t => (if (t.IsFaulted) ((IDataflowBlock) _checkBounceDataBlock) .Fault (t.Exception); else _checkBounceDataBlock.Complete ();)); _spamFilterDataBlock.Completion.ContinueWith (t => (if (t.IsFaulted) ((IDataflowBlock) _addToCrmDataBlock) .Fault (t.Exception); else _addToCrmDataBlock.Complete ();)); _checkBounceDataBlock.Completion.ContinueWith (t => (if (t.IsFaulted) ((IDataflowBlock) _identifyDataBlock) .Fault (t.Exception); else _identifyDataBlock.Complete ();)); _identifyDataBlock.Completion.ContinueWith (t => (if (t.IsFaulted) ((IDataflowBlock) _addToBounceDataBlock) .Fault (t.Exception); else _addToBounceDataBlock.Complete ();)); )
Everything, in fact, the pipeline is already working, you can post messages to it. It remains only to stop it by adding our Start method:

Start

public void Start () (do (var getMailsTasks = _config.CredentialsList.Select (credentials => Task.Run (() => GetMails (credentials))). ToList (); foreach (var task in getMailsTasks) task.Wait ( ); Thread.Sleep (2000);) while (! _StopPipeline); // Stop pipeline - wait for completion of all endpoints _sortMailDataBlock.Complete (); _addToCrmDataBlock.Completion.Wait (); _addToFblDataBlock.Completion.Wait (); _addBlockToBounce .Completion.Wait (); if (_stopPipeline) Logger.Log.Warn ("Pipeline has been stopped by user");)


Moving on to the delegates.
Sorting ... Well, let's say everything is simple here (we always have time to complicate it):

Private MessageInfo SortMail (MessageInfo mail) (switch (mail.Mailbox.Type) (case MailboxType.Crm: mail.Type = MessageType.GENERAL; break; case MailboxType.Bounce: mail.Type = MessageType.BOUNCE; break; case MailboxType. Fbl: mail.Type = MessageType.FBL; break;) return mail;)
Spam filter. This is for homework - use SpamAssassin.
Here's a delegate for you:

Private MessageInfo FilterSpam (MessageInfo mail) (// TODO: Add SpamAssassin logic return mail;)
And classes for working with the SpamAssassin API (link to the project).
And we move on to parsing letters. We parse autoreplies. This is where MEF comes in.
Create a project (dll) with interfaces for our plugins (Let's call Interfaces).
Add the interface:

Public interface ICondition (string Check (Message mimeMessage);) public interface IConditionMetadata (Type Type (get;))
And ... that's it. Our TopCrawler depends on this project and the plugin project will use it too.
Create a new project (also dll), name it Conditions.
Let's add auto-reply types:

#region --- Types --- static class BounceType (public const string Full = "BounceTypeFull"; public const string Timeout = "BounceTypeTimeout"; public const string Refused = "BounceTypeRefused"; public const string NotFound = "BounceTypeNotFound"; public const string Inactive = "BounceTypeInactive"; public const string OutOfOffice = "BounceTypeOutOfOffice"; public const string HostNotFound = "BounceTypeHostNotFound"; public const string NotAuthorized = "BounceTypeNotAuthorized"; public const string ManyTypeNotAuthorized
And the classes that implement our interface:

Public class ConditionNotFound1: ICondition (public string Check (Message mimeMessage) (if (! MimeMessage.MessagePart.IsMultiPart) return null; const string pattern = "Diagnostic-Code:. + Smtp. + 550"; var regexp = new Regex (pattern , RegexOptions.IgnoreCase); return mimeMessage.MessagePart.MessageParts.Any (part => part.ContentType.MediaType == "message / delivery-status" && regexp.IsMatch (part.GetBodyAsText ()))? BounceType: null ;)) ... public class ConditionTimeout2: ICondition (return BounceType.Timeout;) ...
As you can see, it's all about attributes. With the help of them plugins will be loaded.
We return to our project and load the plugins:

Class Crawler (... // Plugins public IEnumerable > BounceTypeConditions (get; set;) private void LoadPlugins () (try (var container = new CompositionContainer (new DirectoryCatalog (_config.PluginDirectory), true); container.ComposeParts (this);) catch (Exception ex) (Logger.Log .Error ("Unable to load plugins: (0)", ex.Message);)) ...
We pull LoadPlugins in the constructor of our class. I will not explain in detail about the loading mechanism - Google will do better.

Moving on to our Bounce type validation delegate. The conditions will be applied in turn until the first one, the exclusive method, is triggered:

Private MessageInfo BounceTypeCheck (MessageInfo mailInfo) (try (foreach (var condition in BounceTypeConditions) (var res = condition.Value.Check (mailInfo.Mail); if (res == null) continue; mailInfo.Subtype = res; Logger.Log .Debug ("Bounce type condition [(0)] triggered for message [(1)]", condition.Metadata.Type, mailInfo.Mail.Headers.MessageId); break;)) catch (Exception ex) (Logger.Log .Error ("Failed to determine bounce type for message" (0) ": (1)", mailInfo.Mail.Headers.MessageId, ex.Message); Logger.ErrorsCounters.Increment ();) return mailInfo;)
Thus, if a new logic appears, it is enough to simply add a new class to the project with plugins that implements our interface and - voila! I will not attach an example of the second plug-in to determine the sender of the letter - this is already a long post (The auto-reply was generated by the server itself, so the sender must also be parsed from the headers of the letter).

There is nothing unusual with the recording of results in the database. For example, like this:

Private void AddToBounce (MessageInfo mail) (try (MailWH.BounceAdd (mail); Functions.ProcessedCounters.Increment (); Functions.Log.Debug ("Send Bounce to MailWH");) catch (Exception ex) (Functions.Log. Error ("Error saving Bounce message" (0) "to MailWH: (1)", mail.Mail.Headers.MessageId, ex.Message); Functions.ErrorsCounters.Increment ();))

BounceAdd

public static long BounceAdd (MessageInfo message) (using (var conn = new SqlConnection (ConnectionString)) using (var cmd = new SqlDataAdapter ("BounceAdd", conn)) (var body = message.Mail.FindFirstPlainTextVersion () == null? message.Mail.FindFirstHtmlVersion (). GetBodyAsText (): message.Mail.FindFirstPlainTextVersion (). GetBodyAsText (); var outId = new SqlParameter ("@ ID", SqlDbType.BigInt) (Direction = ParameterDirection) (Direction = ParameterDirection); .CommandType = CommandType.StoredProcedure; cmd.SelectCommand.Parameters.Add (new SqlParameter ("@ RawMessage", message.Mail.RawMessage)); cmd.SelectCommand.Parameters.Add (new SqlParameter ("@ Message", body)) ; cmd.SelectCommand.Parameters.Add (new SqlParameter ("@ Subject", message.Mail.Headers.Subject ?? "")); cmd.SelectCommand.Parameters.Add (new SqlParameter ("@ MessageID", message.Mail .Headers.MessageId ?? "")); cmd.SelectCommand.Parameters.Add (new SqlParameter ("@ AddressTo", message.Mail.Headers.To.Address ?? "")); cmd.SelectComm and.Parameters.Add (new SqlParameter ("@ AddressFrom", message.Mail.Headers.From.Address ?? "")); cmd.SelectCommand.Parameters.Add (new SqlParameter ("@ DateRecieved", DateTime.Now)); cmd.SelectCommand.Parameters.Add (new SqlParameter ("@ BounceTypeSysName", (object) message.Subtype ?? DBNull.Value)); cmd.SelectCommand.Parameters.Add (new SqlParameter ("@ SourceFrom", (object) message.Recipient ?? DBNull.Value)); // TODO: Add ListId support cmd.SelectCommand.Parameters.Add (new SqlParameter ("@ ListId", DBNull.Value)); cmd.SelectCommand.Parameters.Add (outId); conn.Open (); cmd.SelectCommand.ExecuteNonQuery (); return outId.Value as long? ?? 0; ))


Forgive me for not having time to show TopShelf - the post is already too bloated.

conclusions

In this tutorial, we learned that collecting mail can be tricky. The developed core allows you to quickly add new process steps - DataFlow blocks, without affecting the existing logic. The plug-in subsystem allows you to quickly build up script-like parsing logic, and DataFlow itself parallelizes all calculations (and we have the ability to flexibly configure multithreading for a specific machine). TopShelf gives us the ability to run a service in both service mode and console mode for easier debugging.

Fuh ... If it's interesting, I'll tell you further how to put it on the rails of Continious Integration, set up autobuilds and release a release through VS Release Management.

Tags: Add Tags

Top related articles