DirectumRX Development Studio. Автоматическая рассылка писем при помощи SMTP протокола

18 4

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

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

Этапы реализации:

  • разработка функции по отправке писем;
  • разработка и настройка фонового процесса;
  • настройка конфигурационного файла.

Функция по отправке письма

Для работы с SMTP протоколом создадим экземпляр класса System.Net.Mail.SmtpClient, а также экземпляр класса System.Net.Mail.MailMessage для отправляемого письма. Для письма доступны свойства в которых необходимо указать содержимое, тему, наличия кода html, а также кодировки.

Пример функции по отправки письма.

/// <summary>
/// Отправка письма.
/// </summary>
/// <param name="address">Email с которого отправляется письмо.</param>
/// <param name="body">Текст письма.</param>
private void SendMail(string address, string body)
{
  using (var mailClient = new System.Net.Mail.SmtpClient())
  {
    using (var mail = new System.Net.Mail.MailMessage
           {
             Body = body,
             IsBodyHtml = false,
             Subject = DirRX.ServiceModule.Resources.MailSubject,
             HeadersEncoding = System.Text.Encoding.UTF8,
             SubjectEncoding = System.Text.Encoding.UTF8,
             BodyEncoding = System.Text.Encoding.UTF8
           })
    {
      mail.To.Add(address);
      mailClient.Send(mail);
    }
  }
}

Дополнительные можно добавить вложения в письмо.

mail.Attachments.AddRange(…);

Или указать важность.

mail.Priority = System.Net.Mail.MailPriority.High;

Настройка фонового процесса.

Создадим новый фоновый процесс, который будет отрабатывать раз в сутки.



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

var beginningPreviousDay = Calendar.PreviousDay(Calendar.Today);
var endPreviousDay = Calendar.EndOfDay(beginningPreviousDay);
var letters = Sungero.RecordManagement.IncomingLetters.GetAll(l => Calendar.Between(l.RegistrationDate, beginningPreviousDay, endPreviousDay));

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

foreach (var group in letters.GroupBy(l => l.Correspondent.Email))
{
  var body = new StringBuilder();
  var operationChangeRegistration = new Enumeration(Constants.Module.ChangeRegistration);	
  foreach (var letter in group)
  {
    // Исключаем письма у которых были изменены регистрационные данные.
    var isChangeReg = letter.History.GetAll().ToList().Any(x => x.Operation ==
    operationChangeRegistration);

    if (!isChangeReg)
      body.AppendLine(DirRX.ServiceModule.Resources.MailBodyFormat(letter.Name)).AppendLine();
  }	
		
  if (body.Length != 0)
  {
    // Если есть информация, то вставляем заголовок в начало и отправляем письмо.
    body.Insert(0, DirRX.ServiceModule.Resources.MailBodySubject + Environment.NewLine);
    SendMail(group.Key, body.ToString());
  }
}

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

public const string ChangeRegistration = "RegChange";

Настройка конфигурационного файла.

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

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

Адрес, с которого будет отправлено письмо.

<var name="SMTP_FROM" value="address@mail.ru" />

SMTP-сервер и используемый порт с которого будет отправлено письмо.

<var name="SMTP_HOST" value="192.168.1.1" />
<var name="SMTP_PORT" value="25" />

Данные для подключения к серверу.

<var name="SMTP_USERNAME" value="User" />
<var name="SMTP_PASSWORD" value="Password" />

Использование SSL сертификата.

<var name="SMTP_ENABLE_SSL" value="false" />

Результат

В результате работы фонового процесса контрагентам будут рассылаться письма вида:

Таким образом, DirectumRX предоставляет удобный способ для работы с рассылкой писем при помощи SMTP-протокола. Благодаря этому есть возможность решить задачи по рассылке писем с минимальными затратами.

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

18
Авторизуйтесь, чтобы оценить материал.
2
Денис Архипов

А это не противоречит: Запрещенные возможности (Создание объектов с помощью new)

Денис Архипов: обновлено 28.02.2019 в 17:58
Александр Манохин: обновлено 01.03.2019 в 07:55
Пётр Рябов

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

Валерий Позднев

Падает в SendMail на using (var mailClient = new System.Net.Mail.SmtpClient()) с ошибкой выхода за границы индексов при вызове SendMail("directum@generalcomp.ru", "Test");.

Произошло исключение.
В отлаживаемом приложении произошло исключение типа System.IndexOutOfRangeException.
System.IndexOutOfRangeException: Индекс находился вне границ массива.
   

Валерий Позднев: обновлено 22.03.2019 в 09:22
Валерий Позднев: обновлено 22.03.2019 в 09:23
Валерий Позднев

Разобрался. В одной конфигурации письма отправлялись, в другой, как оказалось, падало на отсутствии настроек в C:\inetpub\wwwroot\DrxAgentLocal\_ConfigSettings.xml. Подчеркиваю, в DrxAgentLocal ! Так что инициализация using (var mailClient = new System.Net.Mail.SmtpClient()) приводила к ошибке парсинга порта. Вот отсутствие остального систему устраивало, а порт она не может распарсить, понимаешь ли. Но такая дурацкая ошибка хотя бы помогла понять причину креша.

Авторизуйтесь, чтобы написать комментарий