Сборщики почты. Как собрать письма из разных ящиков в одном месте

  • 01.05.2019

По мере активной деятельности в сети, у меня накопилось много почтовых аккаунтов, часть из которых, я активно использую для разных целей. Почтовых программ я не использую, а заходить и проверять почту в каждом ящике – долго, поэтому решил настроить сбор почты в одном месте. В этом посте расскажу о том, как настроить сбор почты с разных ящиков на одном аккаунте gmail.

Большая часть моих аккаунтов на яндексе и на gmail для домена. Почта с большинства аккаунтов, уже давно собирается на одном аккаунте gmail, но не вся, и периодически приходиться заходить и проверять другие почтовые аккаунты. Плюс отправка писем от имени другого аккаунта, настроена по простой схеме, когда почта отправляется через домен и аккаунт gmail, а не через почтовый сервер, на котором находится другой ящик. В общем, решил всё основательно упорядочить и настроить, собрать почту со всех активных аккаунтов в одном месте, на одном домене прикрученном к gmail, который давно взял специально для этих целей.

Так сложилось, что я никогда не использовал почтовых программ, не нравятся мне они. Gmail, я считаю, намного удобней. Ничего не нужно загружать себе на компьютер, удобный поиск, удобная группировка писем в цепочки и не только. Короче, тут я даже не думал, для работы с почтой, я использовал, и буду использовать gmail. Плюс также в том, что Вы можете получить доступ к архиву почты с любого компьютера. О том, как завести gmail для домена, можно прочитать в посте .

И так, к сути. Ниже приведу инструкцию, как я настроил сбор почты в одном месте, на аккаунте gmail для домена.

Что мне было нужно?

  1. Сбор почты с разных ящиков/аккаунтов на одном аккаунте gmail.
  2. Иметь возможность отправлять письма от имени другого аккаунта и не палить адрес .
  3. Помечать письма, полученные на разные аккаунты.

Всё. Больше ничего мне не нужно.

Начнём по порядку.

1. Сбор почты с разных ящиков/аккаунтов на одном аккаунте gmail

Здесь есть несколько путей.

1) Настроить пересылку почты с другого ящика/аккаунта на ваш основной аккаунт

У большинства развитых почтовых сервисов, есть такая возможность. У меня аккаунты на яндекс и на gmail, поэтому здесь опишу настройку пересылки почты для этих почтовиков.

Пересылка/Сбор почты с другого аккаунта Gmail

Переходим в аккаунте, с которого хотим пересылать почту, в Настройки => Пересылка и POP/IMAP

Отмечаете “Включить POP для всех писем”, выбираете, что нужно сделать пересылаемыми письмами. У меня стоит “Сохранить копию письма во входящих”. Вводите адрес, на который хотите пересылать почту.

После этого, на добавленный для пересылки емайл, приходит код подтверждения. Вводите код.

Затем выбираете пересылать на добавленный адрес и действие с письмами после пересылки:

Всё. Теперь все письма будут пересылаться на указанный вами емайл.

Пересылка/Сбор для почты с яндекс

Переходите в Настройка => Правила обработки почты => Создать правило.

Создаёте правило “Переслать по адресу” и отмечаете “сохранить копию при пересылке”. Жмёте создать правило.

После этого на емайл указанный для пересылке приходит письмо с ссылкой. Переходите по ссылке и нажимаете “Включить правило”.

Всё. Теперь вся почта с аккаунта яндекс будет пересылаться на указанный вами емайл.

2) Собирать почту с помощью сборщика почты gmail

Этот способ, лично я, использую только для сбора почты если:

  • нет возможности настроить пересылку почты с другого ящика/аккаунта
  • если нужно собрать всю уже имеющуюся почту с другого ящика/аккаунта

Почему только в этих случаях?

Потому что:

Во-первых , есть ограничение, и Вы сможете собирать почту только с 5 аккаунтов, не больше. Это ограничение для бесплатного аккаунта, на коммерческом варианте, насколько я знаю, такого ограничения нет, но могу ошибаться.

Во-вторых , задержка по времени. Гугл сам выбирает время, через которое он будет собирать вашу почту с другого аккаунта. Можно, конечно, проверить руками, в настройках почты, выбрать нужный аккаунт и нажать проверить, но это уже не то. Если же Вы настроите пересылку с другого почтового аккаунта, то письма будут приходить моментально.

Как настроить сбор почты с помощью сборщика gmail

Переходите Настройки => Аккаунты => Получать почту из других аккаунтов => Добавить свой почтовый аккаунт

Добавляете емайл, с которого хотите собирать почту. Вводите данные и выбираете нужные действия. Данные для разных почтовых серверов – разные. Нужно уточнять. Для большинства крупных почтовиков типа яндекс, мейл, нужные настройки вводятся по умолчанию правильно.

Подробно настройка отправки писем от имени другого аккаунта описана ниже, при рассмотрении пункта 2 – “Иметь возможность отправлять письма от имени другого аккаунта и не палиться”. После этого, gmail будет собирать почту с добавленного почтового ящика.

2. Иметь возможность отправлять письма от имени другого аккаунта и не палиться

Для того, чтобы настроить возможность отправки почты от имени другого аккаунта, переходим в Настройки => Аккаунты => Добавить другой свой адрес электронной почты.

Вводим адрес и желаемое имя, которое будет указано при отправке письма.

Здесь предлагают 2 варианта, простой и посложнее:

  • отправлять через почту gmail на домене (более простая настройка)
  • отправлять через серверы SMTP почтовика, на котором находится аккаунт (рекомендуется для профессиональных доменов)

Раньше мне не хотелось замарачиваться с настройкой и я выбирал первый вариант. Но при первом варианте, получатель, насколько я понимаю, будет видеть, что письмо отправлено совершенно с другого домена, а возможно, можно будет увидеть реальный адрес отправителя.

При втором варианте, почта отправляется с сервера, на котором находиться другой аккаунт. При этом, на сколько я знаю, адрес и домен не палятся, а отображаются те адреса и домен, от имени которых отправлено письмо. Поэтому я выбираю второй вариант.

Выбираем “Защищенное соединение с использованием TLS”, рекомендуемое gmail. Вводим адрес SMTP сервера. Для яндекса это smtp.yandex.ru порт 25. Это всё указано по умолчанию. Порт я ставил и другой, вроде тоже работало. Для gmail — smtp.gmail.com порт 587. Для других почтовых сервисов, нужно уточнять адрес smtp сервера.

После этого, на добавленный емайл придёт код. Вводите код и подтверждаете емайл.

Всё. Теперь Вы можете отправлять письма от имени другого аккаунта.

3. Помечать письма, отправленные на разные емайл адреса

Для того, чтобы проще ориентироваться, где и какие письма, создадим ярлыки для каждого аккаунта или группы аккаунтов и настроим фильтры.

Создаём ярлыки для писем

Переходим в Настройки => Ярлыки и создаём ярлык.

Создаём фильтр для писем

Переходим в Настройки=> Фильтры => Создать новый фильтр и создаём фильтр.

При создании фильтра, есть много настроек. Я создаю фильтр по адресату, кому адресовано письмо.

Мне нужно только пометить письмо ярлыком, поэтому я выбираю только “ Применить ярлык ”, выбираю ярлык и нажимаю “Создать фильтр”. Всё. Теперь все письма, адресованные на конкретный емайл, будут помечены ярлыком.

Таким образом, я теперь получаю письма более чем с 20 различных аккаунтов и имею возможность отвечать от имени этих аккаунтов, не паля основной адрес, с одного места. Теперь мне не нужно заходить в разные аккаунты, чтобы проверить почту и ответить, что экономит много времени. Возможно, и вам пригодится такое решение и поможет инструкция.

Gmail рулит!)

Есть чем дополнить – пишите!

Разумеется, всё должно быть распараллелено. Тут на сцену выходит моя любимая библиотека TPL DataFlow .

Забирать почту будем по POP3. Все «модные штучки» IMAP в данной задаче излишни - надо как можно быстрее и проще забрать исходник письма и удалить его на сервера. POP3 тут хватит за глаза. Используем OpenPop.NET .

В качестве факультатива прикрутим мониторинг в Zabbix . (Мы же собрались работать 24/7 и выдавать хваленую скорость - нужно следить за этим).

Поехали

Создаем обычное консольное приложение. Открываем NuGet консоль и ставим все нужные пакеты:

Install-Package Nlog Install-Package OpenPop.NET Install-Package TopShelf Install-Package Microsoft.TPL.DataFlow
Переходим в папку проекта, создаем App.Debug.config и App.Release.config. Выгружаем проект из студии, открываем его код (Здесь и далее TopCrawler.csproj). В секцию с конфигом добавляем:

Конфигурации

App.config App.config


А ниже собственный таргет для MSBuild:

Transform target

$(TargetFileName).config


Лично я привык именно таким способом - по старинке - добавлять трансформацию конфигов для разделения сред.
Для удобства предлагаю strongly-type конфиги. Отдельный класс будет читать конфигурацию. (О теоретических аспектах такого решения можно пообщаться в комментах). Конфиги, логи, мониторинг - отличный повод реализовать паттерн Singleton.

Создаем в проекте одноименную папку (должен же быть порядок). Внутри создаем 3 класса - Config, Logger, Zabbix. Наш логгер:

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


Мониторинг с помощью Zabbix заслуживает отдельного поста, поэтому я просто оставлю тут класс, реализующий агента:

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 Host; public string Key; public string Value; } 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 = 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.Sleep(30); else throw; } } while (received < size); } #endregion } }


Конфиги… Пора уже делать хоть что-то интересное. Во-первых, в конфигах будем хранить ящики, которые мы опрашиваем. Во вторых настройки DataFlow. Предлагаю так:

Конфиги



Итак, хост и порт куда конектится, юзер и пароль - тут всё понятно. Дальше тип ящика. Допустим, служба используется маркетингом (как и другими отделами). У них есть ящики, куда сваливаются автоответы на рассылки, а также отчеты о спаме FBL . Сам ящик уже категоризирует письмо, поэтому для таких ситуаций сразу задаем тип ящика. С настройками DataFlow будет понятно дальше, когда начнем создавать объекты. Тут у нас будут собственные секции в конфиге. Мануалов куча как это сделать, поэтому просто покажу результат:

Определяем типы

#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


Создаем секции

///

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


///

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


Полную реализацию конфига писать не буду, подразумевается, что в процессе разработки туда будут добавляться нужные нам параметры.

Наши кастомные настройки прочитаем так:

Читаем

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.Log.Fatal("Error at reading config: {0}", ex.Message); throw; } }


Как-то очень затянуто получается, а мы даже не дошли до самого интересного.

Опустим пока обвязку из TopShelf, счетчики производительности, общение с БД и перейдем к делу! Создаем класс Crawler - ядро. Для начала читаем почту:

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 //Тут будет остановка DataFlow конвейера if (_stopPipeline) Logger.Log.Warn("Pipeline has been stopped by user"); }
Вот тут лень взяла свое и я решил не заморачиваться - если ящиков порядка 20-30 можно под каждый запустить таск и не париться о количестве потоков. (Разрешаю закидать помидорами.)

Переходим к самому чтению:

Private void GetMails(MailboxInfo info) { try { using (var client = new Pop3Client()) {
Сразу посчитаем тайминги доступа к ящику - пригодится для диагностики сети и загруженности сервера.

//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();
Отправляем данные в Zabbix. Всё просто - указываем имя хоста (как оно заведено в Zabbix), ключ (опять таки строго, как в Zabbix) и строковое значение.

//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);
DataFlow pipeline будет создана при создании класса Crawler. Считаем, что наш первый этап - отсортировать письмо.

While (!_sortMailDataBlock.Post(mailInfo)) Thread.Sleep(500);
Видите, как просто - сам конвейер один. Все таски, читающие почту, кидают туда сообщения по одному. Если блок занят, Post вернет false и мы просто подождем пока он не освободится. Текущий потом в это время продолжает работать. Вот это я называю параллелизм без забот.

Сообщение ушло на конвейер, теперь его можно со спокойной душой сохранить в RAW архив (да-да! всё, что читаем - сохраняем в файловый архив. Служба поддержки нам потом скажет спасибо).

Настроим, например, ротацию архива:

NLog.config



Потом на него можно натравить logStash , но это уже другая история…

//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(); } }
Здесь мы использовали статические счетчики ошибок (в разрезе типов ящиков), где ErrorsCounters - это:

Public static Dictionary ErrorsCounters = new Dictionary();
А сами счетчики можно сделать так:

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


Перейдем к созданию конвейера. Допустим, у нас есть ящики, куда сыпятся автоответы. Такие письма надо распарсить (что за автоответ, от кого, по какой рассылке и т.д.) и сложить результат в хранилище (БД). Допустим, есть ящики, куда падают FBL отчеты. Такие письма сразу складываем в базу. Все прочие письма считаем «полезными» - их надо проверить на спам и отправить во внешнюю систему, например, CRM.

Как вы уже поняли, данный пример в основном рассматривает применение сборщика для задач маркетинга - сбор статистики по доставке почты, информация о спаме.

Итак, мы определились с рабочим потоком. Объявляем необходимые блоки в классе Crawler:

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; ...
Создаем метод инициализации и создаем блоки конвейера (для инициализации блоков используем наши замечательные секции из конфигов):

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 });
Собираем конвейер в соответствии с нашей схемой:

//*** 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*/
Как видим, всё предельно просто - связываем блок со следующим (с возможностью задания условия связи). Все блоки исполняются параллельно. Каждый блок имеет степень параллелизма и емкость (с помощью емкости можно регулировать очередь перед блоком, то есть блок сообщение принял, но еще не обрабатывает). Таким образом, можно задавать высокую степень параллелизма для «сложных» и долгих операций, как, например, парсинг содержимого письма.

Не буду описывать матчасть DataFlow, лучше всё прочесть в первоисточнике 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(); }); }
Всё, на самом деле конвейер уже работает, можно постить в него сообщения. Осталось только остановить его дополнив наш метод Start:

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(); _addToBounceDataBlock.Completion.Wait(); if (_stopPipeline) Logger.Log.Warn("Pipeline has been stopped by user"); }


Переходим к делегатам.
Сортировка… Ну, допустим у нас всё просто (усложнить то всегда успеем):

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; }
Спам фильтр. Это на домашнюю работу - используйте SpamAssassin .
Вот вам делегат:

Private MessageInfo FilterSpam(MessageInfo mail) { //TODO: Add SpamAssassin logic return mail; }
И классы для работы с API SpamAssassin (ссылка на проект).
А мы переходим к парсингу писем. Парсим мы автоответы. Тут вступает в дело MEF.
Создаем проект (dll) с интерфейсами для наших плагинов (Назовем Interfaces).
Добавляем интерфейс:

Public interface ICondition { string Check(Message mimeMessage); } public interface IConditionMetadata { Type Type { get; } }
И… всё. Наш TopCrawler зависит от этого проекта и проект с плагинами тоже будет использовать его.
Создаем новый проект (тоже dll), назовем Conditions.
Добавим типы автоответов:

#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 ManyConnections = "BounceTypeManyConnections"; } #endregion
И классы, реализующие наш интерфейс:

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.NotFound: null; } } ... public class ConditionTimeout2: ICondition { return BounceType.Timeout; } ...
Как вы заметилиб всё дело в атрибутах. С помощью них плагины и будут загружены.
Возвращаемся к нашему проекту и загружаем плагины:

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); } } ...
LoadPlugins дергаем в конструкторе нашего класса. Объяснять подробно про механизм загрузки не буду - гугл справится лучше.

Переходим к нашему делегату проверки типа Bounce. Условия будут применяться по очереди, пока не сработает первое - исключающий метод:

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; }
Таким образомб если появляется новая логикаб достаточно просто добавить в проект с плагинами новый класс, реализующий наш интерфейс и - вуаля! Пример второго плагина по определению отправителя письма прикладывать не буду - итак уже длинный пост (Автоответ сгенерировал сам сервер, поэтому отправителя тоже надо распарсить из заголовков письма) .

С записью результатов в БД тоже ничего необычного. Например, так:

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.Output }; cmd.SelectCommand.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.SelectCommand.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; } }


Простите, что не успел показать TopShelf - пост и так уже слишком раздулся.

Выводы

В этом уроке мы узнали, что задача сбора почты может оказаться не такой простой. Разработанное ядро позволяет быстро добавлять новые шаги процесса - DataFlow-блоки, не затрагивая существующую логику. Подсистема плагинов позволяет быстро наращивать скриптоподобную логику парсинга, а сам DataFlow распараллеливает все вычисления (причем мы имеем возможность гибко настраивать многопоточность под конкретную машину). TopShelf дает нам возможность запускать сервис как в режиме службы, так и в консольном режиме для облегчения отладки.

Фух… Если будет интересно, дальше расскажу, как поставить это на рельсы Continious Integration, настроить автобилды и выпуск релиза через VS Release Management .

Теги: Добавить метки

Если автоматически настроить соединение сборщика с сервером невозможно

Первый сбор почты произойдет в течение нескольких минут после того, как вы настроите сборщик. Сборщик обращается к другому почтовому серверу от нескольких раз в час до раза в несколько дней. Вручную установить или изменить время сбора нельзя. Оно зависит от используемого протокола (POP3 или IMAP), а также от особенностей работы сервера, с которого собирается почта. Именно поэтому письма могут приходить с задержкой.

Собрать почту с другого ящика на Яндексе

Собирать новые письма

Если вы хотите собирать почту с другого вашего ящика на Яндексе, вы можете настроить в нем правило пересылки . После подтверждения правила все новые письма будут перенаправляться в ваш текущий ящик.

Забрать старую почту

Чтобы собрать старые письма с другого ящика на Яндексе:

Выбрать папку для сбора писем

  1. Откройте страницу настроек сбора почты .
  2. Нажмите ссылку Удалить .
  3. Подтвердите удаление.
  4. Создайте новый сборщик с использованием протокола POP3.

После этого в настройках появится возможность выбрать папку для сбора писем.

Отредактировать настройки сборщика

Чтобы отключить сборщик, перейдите на страницу Сбор почты и нажмите ссылку выкл .

Если сборщик больше не нужен, нажмите на название сборщика, а затем на ссылку Удалить .

Написать письмо от имени подключенного ящика

Если вы хотите, чтобы письмо для получателя пришло с вашего адреса электронной почты на другом сервисе (например, Gmail или Mail.Ru), добавьте этот адрес на странице Адреса электронной почты и подтвердите доступ к нему. После подтверждения вы сможете выбрать в поле От кого не только алиас вашего адреса на Яндексе , но и адрес почты на другом сервисе.

Внимание. Если вы добавляете адрес ящика на другом почтовом сервисе, настройте сбор писем с него в ящик на Яндексе. Без настроенного сборщика отправлять письма с такого адреса не получится. При настройке сборщика вместо логина укажите адрес полностью, например [email protected] .

Если даже при корректно настроенном сборщике у вас не получается отправлять письма с адреса на другом почтовом сервисе, это значит, что правила безопасности этого сервиса запрещают отправлять письма через другие почтовые сервисы, в том числе и через Яндекс.Почту.

Что можно делать с собранными письмами

С собранными письмами можно делать все то же самое, что и с другими письмами в ящике, но есть особенности:

Удаление писем

Если удалить собранное письмо, оно удалится только из того ящика, куда было собрано. В исходном ящике письмо останется.

Правила обработки писем

Правила обработки работают только для писем, собранных в папку Входящие . Если письмо собрано в другую папку, правило для него не сработает.

Черный список

Черный список не работает для собранных с другого вашего ящика писем. Чтобы заблокировать такие письма, перейдите в почтовый ящик, с которого собираются письма, и в нем настройте черный список.

Не работает сбор писем

Это пошаговое руководство поможет вам решить проблемы, связанные с работой сборщика писем. Прежде чем приступить, откройте Яндекс.Почту в новой вкладке , чтобы выполнять рекомендации.

Выберите проблему:

Уточните, сборщик раньше собирал письма?

  1. Отключите сборщик почты: перейдите на страницу Сбор почты и нажмите ссылку выкл .
  2. Подождите 2-3 часа.
  3. Включите сборщик обратно.

Смените пароль в почтовом ящике, с которого собираются письма. После\\n этого подождите 2-3 часа - столько времени требуется, чтобы новый пароль\\n точно заработал.\\n

    \\n
  1. Перейдите в настройки сбора почты .
  2. \\n
  3. Нажмите на название сборщика в списке подключенных ящиков, а затем\\n нажмите ссылку Настроить .
  4. \\n
  5. Нажмите ссылку Настройка соединения с\\n сервером .
  6. \\n
  7. В Параметрах соединения введите новый\\n пароль.
  8. \\n
  9. Нажмите кнопку Сохранить изменения .
  10. \\n
\\n \\n \\n Письма не собираются с ящика на Gmail \\n \\n
    \\n
  1. На странице Безопасность и вход установите переключатель\\n Ненадежные приложения в положение Ненадежные\\n приложения разрешены .
  2. \\n
  3. Аккаунты Google .
  4. \\n
  5. создайте пароль приложения для сборщика\\n писем.
  6. \\n
\\n

Подключите сборщик почты заново, уже с новым паролем:

    \\n
  1. Перейдите в настройки сбора почты .
  2. \\n
  3. Нажмите на название сборщика в списке подключенных ящиков, а затем нажмите ссылку\\n Настроить .
  4. \\n
  5. Нажмите ссылку .
  6. \\n
  7. В Параметрах соединения введите новый пароль.
  8. \\n
  9. Нажмите кнопку Сохранить изменения .
  10. \\n
\\n \\n \\n \\n\\n
  • \\\\n

    Проверьте, что в настройках вашего почтового ящика на Яндексе включен доступ\\\\n по протоколам POP3 или IMAP:

    \\\\n \\\\n

  • \\\\n
  • \\\\n

    Убедитесь, что в настройках почтового ящика, с которого собираются письма,\\\\n активирован доступ по протоколам POP3 или IMAP.

    \\\\n \\\\n \\\\n

    Rambler

    \\\\n \\\\n \\\\n \\\\n

    Gmail

      \\\\n
    1. Пересылки и\\\\n POP/IMAP .
    2. \\\\n
    3. В блоке Доступ по протоколу POP (пункт\\\\n Состояние ) установите переключатель в положение\\\\n Включить POP для всех писем (даже для тех, которые уже\\\\n загружены) .
    4. \\\\n
    5. В блоке Доступ по протоколу IMAP (пункт\\\\n Состояние ) установите переключатель в положение\\\\n Включить IMAP .
    6. \\\\n
    7. Нажмите кнопку Сохранить изменения .
    8. \\\\n
    \\\\n

    \\\\n \\\\n \\\\n \\\\n

    Mail.ru

    В почтовом сервисе Mail.ru доступ к протоколам IMAP и POP3 активирован по\\\\n умолчанию.

    \\\\n \\\\n \\\\n \\\\n

    Outlook.com (hotmail.com)

    Почтовый сервис Outlook.com может передавать письма только по протоколу POP. Чтобы\\\\n активировать доступ по протоколу POP:

    \\\\n \\\\n \\\\n \\\\n

    Yahoo

    Почтовый сервис Yahoo может передавать письма только по протоколу IMAP. Этот протокол\\\\n включен по умолчанию.

    \\\\n \\\\n \\\\n \\\\n\\\\n

    Если вашего почтового сервиса нет в списке, обратитесь за информацией в службу\\\\n поддержки этого сервиса.

    Возможно, возникли проблемы на том почтовом сервисе, с\\\\\\\\n ящика на котором собираются письма. Чтобы решить проблему,\\\\\\\\n настройте пересылку с того почтового ящика, с которого\\\\\\\\n собираются письма. Перед настройкой пересылки отключите\\\\\\\\n сборщик на Яндексе - иначе письма будут приходить в\\\\\\\\n двойном экземпляре.\\\\\\\\n

    Чтобы узнать, как настроить пересылку писем с другого\\\\\\\\n почтового ящика в ящик на Яндексе, обратитесь к разделу\\\\\\\\n помощи другого почтового сервиса.

    \\\\\\\\n "}]}}\\\\">

    Возможно, возникли проблемы на том почтовом сервисе, с\\\\n ящика на котором собираются письма. Чтобы решить проблему,\\\\n настройте пересылку с того почтового ящика, с которого\\\\n собираются письма. Перед настройкой пересылки отключите\\\\n сборщик на Яндексе - иначе письма будут приходить в\\\\n двойном экземпляре.


  • \\\\n \\\\n "}]}}\\">
      \\n \\n \\n \\n

      \\n \\n \\n

      Rambler

      \\n \\n \\n \\n

      Gmail

        \\n
      1. Перейдите в настройки ящика Gmail, а затем на вкладку Пересылки и\\n POP/IMAP .
      2. \\n
      3. В блоке Доступ по протоколу POP .
      4. \\n
      5. В блоке Доступ по протоколу IMAP
      6. \\n
      7. Нажмите кнопку Сохранить изменения .
      8. \\n
      \\n

      \\n \\n \\n \\n

      Mail.ru

      \\n \\n \\n \\n

      Outlook.com (hotmail.com)

      \\n \\n \\n \\n

      Yahoo

      \\n \\n \\n \\n\\n

      Чтобы узнать, как настроить пересылку писем с другого\\\\n почтового ящика в ящик на Яндексе, обратитесь к разделу\\\\n помощи другого почтового сервиса.

      \\\\n "}]}}\\">


      \\n
    \\n

    \\n\\n "}]}}\">

    Смените пароль в почтовом ящике, с которого собираются письма. После этого подождите 2-3 часа - столько времени требуется, чтобы новый пароль точно заработал.

    Подключите сборщик почты заново, уже с новым паролем:

    1. Перейдите в настройки сбора почты .
    2. Нажмите ссылку Настройка соединения с сервером .
    3. В Параметрах соединения введите новый пароль.
    4. Нажмите кнопку Сохранить изменения .
    Письма не собираются с ящика на Gmail

    Если вы настроили сбор писем с ящика на Gmail:

    1. На странице Безопасность и вход установите переключатель Ненадежные приложения в положение Ненадежные приложения разрешены .
    2. Предоставьте доступ сборщику на странице Аккаунты Google .
    3. Если вы используете двухэтапную аутентификацию для входа в аккаунт Google, создайте пароль приложения для сборщика писем.

    Подключите сборщик почты заново, уже с новым паролем:

    1. Перейдите в настройки сбора почты .
    2. Нажмите на название сборщика в списке подключенных ящиков, а затем нажмите ссылку Настроить .
    3. Нажмите ссылку Настройка соединения с сервером .
    4. В Параметрах соединения введите новый пароль.
    5. Нажмите кнопку Сохранить изменения .
    \\n

    Проверьте, что в настройках вашего почтового ящика на Яндексе включен доступ\\n по протоколам POP3 или IMAP:

    \\n \\n

    Убедитесь, что в настройках почтового ящика, с которого собираются письма,\\n активирован доступ по протоколам POP3 или IMAP.

    \\n \\n \\n

    Rambler

    \\n \\n \\n \\n

    Gmail

      \\n
    1. Перейдите в настройки ящика Gmail, а затем на вкладку Пересылки и\\n POP/IMAP .
    2. \\n
    3. В блоке Доступ по протоколу POP (пункт\\n Состояние ) установите переключатель в положение\\n Включить POP для всех писем (даже для тех, которые уже\\n загружены) .
    4. \\n
    5. В блоке Доступ по протоколу IMAP (пункт\\n Состояние ) установите переключатель в положение\\n Включить IMAP .
    6. \\n
    7. Нажмите кнопку Сохранить изменения .
    8. \\n
    \\n

    \\n \\n \\n \\n

    Mail.ru

    В почтовом сервисе Mail.ru доступ к протоколам IMAP и POP3 активирован по\\n умолчанию.

    \\n \\n \\n \\n

    Outlook.com (hotmail.com)

    Почтовый сервис Outlook.com может передавать письма только по протоколу POP. Чтобы\\n активировать доступ по протоколу POP:

    \\n \\n \\n \\n

    Yahoo

    Почтовый сервис Yahoo может передавать письма только по протоколу IMAP. Этот протокол\\n включен по умолчанию.

    \\n \\n \\n \\n\\n

    Если вашего почтового сервиса нет в списке, обратитесь за информацией в службу\\n поддержки этого сервиса.

    Возможно, возникли проблемы на том почтовом сервисе, с\\\\n ящика на котором собираются письма. Чтобы решить проблему,\\\\n настройте пересылку с того почтового ящика, с которого\\\\n собираются письма. Перед настройкой пересылки отключите\\\\n сборщик на Яндексе - иначе письма будут приходить в\\\\n двойном экземпляре.\\\\n

    Чтобы узнать, как настроить пересылку писем с другого\\\\n почтового ящика в ящик на Яндексе, обратитесь к разделу\\\\n помощи другого почтового сервиса.

    \\\\n "}]}}\\">

    Возможно, возникли проблемы на том почтовом сервисе, с\\n ящика на котором собираются письма. Чтобы решить проблему,\\n настройте пересылку с того почтового ящика, с которого\\n собираются письма. Перед настройкой пересылки отключите\\n сборщик на Яндексе - иначе письма будут приходить в\\n двойном экземпляре.

    Чтобы узнать, как настроить пересылку писем с другого\\n почтового ящика в ящик на Яндексе, обратитесь к разделу\\n помощи другого почтового сервиса.


    \\n \\n "}]}}\">

      Rambler

      Gmail

      1. Перейдите в настройки ящика Gmail, а затем на вкладку Пересылки и POP/IMAP .
      2. В блоке Доступ по протоколу POP .
      3. В блоке Доступ по протоколу IMAP
      4. Нажмите кнопку Сохранить изменения .

      Mail.ru

      Outlook.com (hotmail.com)

      Yahoo

      Возможно, возникли проблемы на том почтовом сервисе, с\\n ящика на котором собираются письма. Чтобы решить проблему,\\n настройте пересылку с того почтового ящика, с которого\\n собираются письма. Перед настройкой пересылки отключите\\n сборщик на Яндексе - иначе письма будут приходить в\\n двойном экземпляре.\\n

      Чтобы узнать, как настроить пересылку писем с другого\\n почтового ящика в ящик на Яндексе, обратитесь к разделу\\n помощи другого почтового сервиса.

      \\n "}]}}\">

      Возможно, возникли проблемы на том почтовом сервисе, с ящика на котором собираются письма. Чтобы решить проблему, настройте пересылку с того почтового ящика, с которого собираются письма. Перед настройкой пересылки отключите сборщик на Яндексе - иначе письма будут приходить в двойном экземпляре.

      Чтобы узнать, как настроить пересылку писем с другого почтового ящика в ящик на Яндексе, обратитесь к разделу помощи другого почтового сервиса.




      Проверьте, что в настройках вашего почтового ящика на Яндексе включен доступ по протоколам POP3 или IMAP:

      Убедитесь, что в настройках почтового ящика, с которого собираются письма, активирован доступ по протоколам POP3 или IMAP.

      Rambler

      Gmail

      1. Перейдите в настройки ящика Gmail, а затем на вкладку Пересылки и POP/IMAP .
      2. В блоке Доступ по протоколу POP (пункт Состояние ) установите переключатель в положение Включить POP для всех писем (даже для тех, которые уже загружены) .
      3. В блоке Доступ по протоколу IMAP (пункт Состояние ) установите переключатель в положение Включить IMAP .
      4. Нажмите кнопку Сохранить изменения .

      Mail.ru

      В почтовом сервисе Mail.ru доступ к протоколам IMAP и POP3 активирован по умолчанию.

      Outlook.com (hotmail.com)

      Почтовый сервис Outlook.com может передавать письма только по протоколу POP. Чтобы активировать доступ по протоколу POP:

      Yahoo

      Почтовый сервис Yahoo может передавать письма только по протоколу IMAP. Этот протокол включен по умолчанию.

      Если вашего почтового сервиса нет в списке, обратитесь за информацией в службу поддержки этого сервиса.

      Проверьте, не установлен ли в настройках ящика запрет на скачивание\\n писем из конкретных папок или писем за конкретный период.\\n

      Почтовая служба Outlook.com (hotmail.com, live.com) разрешает\\n пересылать письма только из папки Входящие .\\n Если вы хранили письма в другой папке, переместите их в папку\\n Входящие .

      \\n "}]}}\">

      Проверьте, не установлен ли в настройках ящика запрет на скачивание писем из конкретных папок или писем за конкретный период.

      Почтовая служба Outlook.com (hotmail.com, live.com) разрешает пересылать письма только из папки Входящие . Если вы хранили письма в другой папке, переместите их в папку Входящие .


      Проверьте, что в настройках вашего почтового ящика на Яндексе включен доступ по протоколам POP3 или IMAP:

      Убедитесь, что в настройках почтового ящика, с которого собираются письма, активирован доступ по протоколам POP3 или IMAP.

      Rambler

      Gmail

      1. Перейдите в настройки ящика Gmail, а затем на вкладку Пересылки и POP/IMAP .
      2. В блоке Доступ по протоколу POP (пункт Состояние ) установите переключатель в положение Включить POP для всех писем (даже для тех, которые уже загружены) .
      3. В блоке Доступ по протоколу IMAP (пункт Состояние ) установите переключатель в положение Включить IMAP .
      4. Нажмите кнопку Сохранить изменения .

      Mail.ru

      В почтовом сервисе Mail.ru доступ к протоколам IMAP и POP3 активирован по умолчанию.

      Outlook.com (hotmail.com)

      Почтовый сервис Outlook.com может передавать письма только по протоколу POP. Чтобы активировать доступ по протоколу POP:

      Yahoo

      Почтовый сервис Yahoo может передавать письма только по протоколу IMAP. Этот протокол включен по умолчанию.

      Если вашего почтового сервиса нет в списке, обратитесь за информацией в службу поддержки этого сервиса.

      Проверьте правильность вводимого пароля - наберите его в текстовом\\n редакторе, скопируйте и вставьте в поле ввода пароля. Если вы уверены, что\\n пароль верный, но сборщик не подключается, попробуйте авторизоваться в\\n ящике, с которого хотите собирать письма.\\n "}]}}\">

      Проверьте правильность вводимого пароля - наберите его в текстовом редакторе, скопируйте и вставьте в поле ввода пароля. Если вы уверены, что пароль верный, но сборщик не подключается, попробуйте авторизоваться в ящике, с которого хотите собирать письма.


    Скорость работы сборщика зависит от количества писем в том ящике, из которого собираются письма, и от работы сервера, на котором находится этот ящик. Задержки в сборе писем могут также происходить из-за особенностей протоколов, по которым работает сборщик.

    Чтобы получать письма мгновенно, настройте переадресацию из другого ящика в ящик на Яндексе. Перед настройкой переадресации отключите сборщик - иначе письма будут приходить в двойном экземпляре.

    Выбрать папку для сбора писем нельзя в том случае, если вы настроили сборщик по протоколу IMAP - он не предусматривает возможности собирать письма в заданную папку, т.к. копирует структуру папок полностью. Вы можете изменить протокол на POP3, для этого:

    1. Откройте страницу настроек сбора почты .
    2. Нажмите на адрес нужного сборщика.
    3. Нажмите ссылку Удалить .
    4. Подтвердите удаление.

    WebAsyst Почта позволяет просматривать и отвечать на письма, приходящие на ваши почтовые адреса, расположенные на различных почтовых серверах, например: mail.ru, yandex.ru, gmail.com.

    Почтовые адреса, расположенные на других серверах, будем называть внешними . Для каждого внешнего адреса в папке Входящие создается отдельная ветка. Новая почта проверяется автоматически, ежеминутно. При поступлении новых сообщений, название ящика, в который поступили письма, выделяется жирным.

    В действительности, WebAsyst Почта не забирает письма с внешнего почтового сервера, а лишь узнает об их поступлении и читает заголовки. Конечно, если вы откроете письмо, щелкнув по его заголовку, то WebAsyst Почта прочитает и все содержимое письма. Однако, само письмо останется на почтовом сервере, и будет доступно через собственный веб-интерфейс почтовой службы или из почтовой программы, например Outlook или The Bat!.

    WebAsyst Почта позволяет выполнять все основные операции с сообщениями, поступившими во внешние почтовые ящики:

    • просмотр сообщений и вложенных файлов
    • ответ отправителю и пересылка сообщения на другие адреса
    • удаление или перемещение в папку WebAsyst Почты для постоянного хранения (при этих операциях оригинальное сообщение будет удалено с почтового сервера)

    Зачем нужно собирать сообщения с других почтовых серверов?

    Как правило, каждая почтовая служба предоставляет свой веб-интерфейс для работы с почтой. Тем не менее, воспользоваться сборщиком почты WebAsyst удобно, например, в следующих случаях:

    1. Когда необходимо видеть всю корреспонденцию, приходящую на разные почтовые адреса, в едином месте – на одной веб-странице.
    2. Когда вы обычно работаете в офисе с помощью почтовой программы Outlook Express и уехали в командировку без офисного компьютера. В этом случае WebAsyst Почта предоставит вам доступ ко всем вашим почтовым ящикам с любого компьютера, подключенного к интернету.
    3. Когда к письмам, приходящим на различные адреса, необходимо предоставить доступ другим сотрудникам без необходимости пересылки этих сообщений – WebAsyst Почта позволяет гибко настраивать права доступа для каждой папки.
    4. Наконец, когда на вашем почтовом сервере просто нет веб-интерфейса, или он не удобен в использовании.
    • Сборщик почты с ваших ящиков на других почтовых системах

    В прошлый раз я начал серию статей о сборе почты с нескольких различных ящиков, созданных даже на разных сервисах, в один основной ящик, который пользователь постоянно контролирует и ему проще работать только с ним одним, нежели чем отдельно просматривать все свои электронные ящики. Подробнее о необходимости сбора почты и о её реализации на сервисе GMail, читайте .

    Эту серию статей я планирую пока что на 3 статьи. Сегодня расскажу о настройке сбора почты в не менее известном почтовом сервисе - Яндекс.

    Сбор почты с других аккаунтов в Яндекс настраивается так же просто как и в других сервисах.

    Процесс настройки сбора почты в сервисе Яндекс.

    Чтобы подключить возможность собирать всю почту в ваш ящик на Яндекс с любых ваших аккаунтов на этом же или других почтовых сервисах в первую очередь войдите в свой аккаунт на Яндекс, который будет являться основным. Именно в него будете собирать почту с других ящиков.

    Откройте раздел настроек почты и выберите “Сбор почты с других ящиков”.

    Собирать почту вы можете с любых ящиков, расположенных на любых почтовых сервисах, а не только с ваших почт, расположенных на том же сервисе Яндекс!

    В примере для этой статьи будет показан процесс сбора писем с почты Mail.ru.

    Введите полный адрес электронной почты, откуда будете собирать письма и пароль от неё, после чего нажмите “Включить сборщик”.

    Если вы указали верные логин и пароль от почты, то в следующем окне появится сообщение об успешном соединении и здесь можно произвести некоторые настройки сбора писем. К примеру, вы можете присвоить собираемым письмам метку, а также отображать старые пересылаемые письма как прочтённые. Отметьте нужные вам опции после чего внизу укажите ещё раз пароль от вашей второй почты и нажмите “Сохранить изменения” . Почта начнёт собираться минут через 10.

    В этом окне настроек у вас не получится выбрать отдельную папку для сбора писем с подключённого ящика. Изначально будет указана папка “Входящие” и она не меняется. Это связано с тем, что изначально почта собирается по протоколу IMAP и этот протокол копирует полностью структуру папок с подключенной вами почты.

    Если 2 варианта заставить всё-таки собираемую почту сортироваться по папкам:

      Изменить настройки сбора почты и поставить протокол POP3, вместо IMAP (который задаётся изначально);

      Настроить позже фильтрацию писем, т. е. создать условие, при котором получаемая почта будет попадать в нужную вам папку, минуя “Входящие”.

    Второй вариант, думаю, более предпочтителен, особенно для новичков, чтобы не ковыряться в настройках соединения с другой почтой.

    Теперь все письма, поступающие на подключённую вами почту, будут стекаться в текущую, которая является вашей основной. И тогда уже нет надобности заходить отдельно во вторую почту для проверки новых писем в ней.

    Как посмотреть отдельно все письма, собираемые из подключенной почты?

    После добавления почты, вы увидите ярлык с её названием слева под папками для писем. Пример:

    Кликнув по этому ярлыку вы увидите отдельно все письма из подключённого ящика.

    Как изменить настройки или отключить сбор почты с определённого ящика?

    Если вам нужно что-либо поменять в настройках сбора почты из добавленного ящика, то вы можете это сделать там же в настройках почты Яндекса, через раздел “Сбор почты с других ящиков”.

    Если нужно выключить или снова включить сбор почты с определённого подключённого ящика, нажмите на переключатель “Вкл. / Выкл.” в списке подключённых ящиков.

    Если нужно открыть настройки сбора почты , кликните по названию ящика , после чего кликните по появившейся ссылке “Настроить”. В результате откроется такое же окно настроек, как при подключении почты ().

    Заключение.

    В заключение хочу отметить, что обычно со сбором электронной почты в сервис Яндекс проблем никаких нет и ничего не нужно настраивать во второй почте (которую подключаете). Но есть очень капризный сервис по имени GMail:) Вот при его подключении (причём не только к Яндекс, но к даже к самому себе) очень часто возникают проблемы и связано это с повышенной безопасностью этой гугловской почты. Нет, не спорю, безопасность - это хорошо! Но иногда это достигает уровня маразма, например, когда Gmail блокирует подключение к своему же второму ящику GMail, причём вход в оба выполнен с одного компьютера и одного IP:)) О подобных проблемах именно с подключением почт Google я расскажу в отдельной статье.