Давайте посмотрим, насколько простой SMTP с elixir / erlang. Я начал экспериментировать с этим в основном как с учебным пособием, чтобы лучше познакомиться с elixir / erlang, я также пытаюсь лучше документировать свое обучение. Я предварю этот пост этим, я не эксперт, поэтому любые предложения или рекомендации приветствуются.

Что такое SMPT?

Проще говоря, это текстовый протокол, в котором почта отправляется и принимается с помощью нескольких простых текстовых команд. Обычно это соединение осуществляется по TCP. Вы можете думать о сеансе SMTP как о написании письма, вам нужен конверт, который определяет, кому предназначено сообщение, от кого оно, а также для хранения сообщения, которое вы хотите отправить. Кроме того, вы можете включить дополнительную метаинформацию в виде заголовков. Вот пример простого сеанса Telnet с нашим SMPT-сервером:

В этом сеансе от клиента были переданы четыре ключевые текстовые команды:

HELO: Эта команда позволяет клиентам узнать, какие параметры поддерживает сервер. Вы можете думать об этом как о начальном «Привет». Важно отметить, что многие серверы поддерживают ESMTP (расширенный SMTP) и переход на простой SMTP. В приведенном ниже примере вы можете увидеть команду EHLO, в которой сервер отвечает включенными параметрами:

ПОЧТА ОТ: устанавливает отправителя, сервер ожидает, что отправитель находится в том же домене, который был отправлен с начальными командами HELO / EHLO.

RCPT TO: устанавливает получателя. RCPT читается как «получатель».

ДАННЫЕ: указывает, что следующий поток будет состоять из содержания сообщения. Здесь вы также можете установить любые метаданные для сообщения. В нашем примере мы избыточно устанавливаем From: и To:, вы должны указать такие вещи, как тема, тип контента и целый ряд других заголовков.

Приложение "Эликсир"

Разобравшись с ускоренным курсом, давайте перейдем к тому, ради чего вы сюда пришли, - к самому приложению. Мы собираемся создать приложение Elixir OTP под названием Messenger, которое будет получать от нас электронные письма. Для этого мы собираемся использовать библиотеку erlang gen_smtp, мы действительно стоим на плечах гигантов, gen_smtp - это почти полная реализация протокола SMTP на erlang.

Сначала давайте сгенерируем новое приложение OTP, обязательно укажите команду — sup, чтобы mix сгенерировал для нас наше дерево наблюдения:

Затем откройте mix.exs и добавьте gen_smtp в качестве зависимости:

Затем запустите mix deps.get, чтобы сбросить gen_smtp. gen_smtp ожидает некоторую конфигурацию при запуске, поэтому давайте добавим это сейчас в config/config.exs:

Мы предоставляем порт 2525 вместо стандартного SMTP-порта 25, поскольку процесс BEAM не запускается от имени пользователя root (к счастью), мы не можем привязаться к портам ниже 1024. Есть несколько способов обойти это в производственной среде, либо отредактируйте свой ip для пересылки с 2525 на 25. Или установите возможности для двоичного файла BEAM: sudo setcap ‘cap_net_bind_service=ep’ Elixir.Messenger.beam, чтобы он мог связываться с портами без необходимости полных прав суперпользователя. Вот полный список опций, которые вы можете предоставить.

Теперь мы можем настроить нашего супервизора, который будет запускать :gen_smtp_server как дочерний процесс, для организации я собираюсь изменить lib/messenger.ex (наш основной модуль) на точку входа в приложение:

И измените mix.exs, чтобы также использовать основной модуль:

Что касается настоящего руководителя, я переименовал lib/messenger/application.ex в lib/messenger/supervisor.ex:

Хорошо, давайте быстро рассмотрим, что мы только что сделали с нашим руководителем. Мы определили воркер для модуля :gen_smtp_server (это модуль erlang от gen_smtp). Мы предоставили параметры Messenger.Server (модуль обратного вызова, который реализует поведение :gen_smtp_server_session) и наш smtp_opts, который мы определили ранее. Мы почти готовы к запуску нашего приложения. Сначала нам нужно реализовать поведение :gen_smtp_server_session, которое само реализует поведение gen_server. Я собираюсь показать только функции, необходимые для обработки основных команд, продемонстрированных ранее, однако вы должны реализовать полное поведение. Вы можете увидеть весь пример в репозитории GitHub. Давайте создадим файл по адресу lib/messenger/server.ex:

Здесь мы обрабатываем все входящие текстовые команды, о которых мы говорили. Каждый раз, когда мы сталкиваемся с важными для нас данными, например, с полями from и to, мы просто помещаем их в наше состояние, которое начиналось как пустая карта. handle_DATA - самая интересная функция, именно здесь вы получите все, что предусмотрено после команды ДАННЫЕ. Здесь вы можете проанализировать другие входящие заголовки, сохранить сообщение для последующей обработки и т. Д.

Это был минимальный пример того, как получать электронные письма через SMTP с помощью ellixir. Мы даже не обсуждали тестирование или различные методы анализа электронной почты. При производстве необходимо учитывать и множество других факторов, включая включение STARTTLS, обработку любых расширений по вашему желанию и т. Д.

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

Вы можете найти все приложение на GitHub здесь: https://github.com/jonlunsford/messenger