Перейти к содержанию

Phoenix

Инструкция для приложений на Phoenix 1.7+ (Elixir). Mailexam подключается как SMTP через Swoosh и адаптер Swoosh.Adapters.SMTP (библиотека gen_smtp).

Что понадобится

  • Аккаунт Mailexam и проект с SMTP-учётными данными.
  • Elixir 1.15+ и Erlang/OTP 26+.

Скопируйте из приветственного письма (или кабинета) для вашего проекта:

  • ВАШ_ЛОГИН — SMTP-логин (например, xxxxx);
  • ВАШ_ПАРОЛЬ — SMTP-пароль (уникальная пара к логину);
  • хост — ВАШ_ЛОГИН.mailexam.ru (совпадает с логином).

1. Зависимости

Создайте проект (по умолчанию в шаблоне уже есть Swoosh Mailer):

mix phx.new my_app
cd my_app

Если проект создан с флагом --no-mailer, добавьте в mix.exs:

defp deps do
  [
    # ... зависимости Phoenix ...
    {:swoosh, "~> 1.17"},
    {:gen_smtp, "~> 1.2"}
  ]
end
mix deps.get

и создайте модуль MyApp.Mailer вручную (см. ниже).

2. Переменные окружения

Перед mix phx.server экспортируйте переменные (или задайте их в Run Configuration IDE):

MAILEXAM_LOGIN=ВАШ_ЛОГИН
MAILEXAM_PASSWORD=ВАШ_ПАРОЛЬ
MAILEXAM_PORT=587
MAIL_FROM=noreply@example.test

Хост SMTP: ВАШ_ЛОГИН.mailexam.ru.

Адрес отправителя

MAIL_FROM может быть любым тестовым адресом — письмо попадёт в Mailexam, а не реальному получателю.

Альтернативные порты

MAILEXAM_PORT=587

В конфиге: tls: :always.

MAILEXAM_PORT=2525

tls: :always, как для 587.

MAILEXAM_PORT=25

В конфиге: tls: :never.

3. Настройка Mailer

lib/my_app/mailer.ex:

defmodule MyApp.Mailer do
  use Swoosh.Mailer, otp_app: :my_app
end

config/runtime.exs (фрагмент — подставьте при старте приложения):

import Config

login = System.get_env("MAILEXAM_LOGIN")
password = System.get_env("MAILEXAM_PASSWORD")
port = String.to_integer(System.get_env("MAILEXAM_PORT") || "587")

if login && password do
  config :my_app, MyApp.Mailer,
    adapter: Swoosh.Adapters.SMTP,
    relay: "#{login}.mailexam.ru",
    username: login,
    password: password,
    port: port,
    tls: if(port in [587, 2525], do: :always, else: :never),
    auth: :always
end

4. Отправка письма

lib/my_app/test_email.ex:

defmodule MyApp.TestEmail do
  import Swoosh.Email

  def deliver(to \\ "user@example.test", subject \\ "Phoenix + Mailexam", body \\ "Тест Mailexam из Phoenix") do
    from = System.get_env("MAIL_FROM") || "noreply@example.test"

    email =
      new()
      |> from(from)
      |> to(to)
      |> subject(subject)
      |> text_body(body)

    MyApp.Mailer.deliver(email)
  end
end

5. Маршрут Phoenix

lib/my_app_web/controllers/mail_controller.ex:

defmodule MyAppWeb.MailController do
  use MyAppWeb, :controller

  def create(conn, params) do
    to = params["to"] || "user@example.test"
    subject = params["subject"] || "Phoenix + Mailexam"
    body = params["body"] || "Тест Mailexam из Phoenix"

    case MyApp.TestEmail.deliver(to, subject, body) do
      {:ok, _} ->
        json(conn, %{status: "ok"})

      {:error, reason} ->
        conn
        |> put_status(:internal_server_error)
        |> json(%{error: inspect(reason)})
    end
  end
end

lib/my_app_web/router.ex:

scope "/", MyAppWeb do
  post "/mail/test", MailController, :create
end

Запуск и проверка:

export MAILEXAM_LOGIN=ВАШ_ЛОГИН
export MAILEXAM_PASSWORD=ВАШ_ПАРОЛЬ
export MAILEXAM_PORT=587
export MAIL_FROM=noreply@example.test

mix phx.server
curl -X POST http://127.0.0.1:4000/mail/test \
  -H 'Content-Type: application/json' \
  -d '{"to":"user@example.test","subject":"Проверка","body":"Привет"}'

Письмо появится в кабинете Mailexam → ваш проект → входящие.

6. Локальная разработка и CI

Среда Рекомендация
local export переменных или .env + direnv
CI секреты MAILEXAM_LOGIN, MAILEXAM_PASSWORD в GitLab CI/CD Variables

Пример для .gitlab-ci.yml:

variables:
  MAILEXAM_LOGIN: $MAILEXAM_LOGIN
  MAILEXAM_PASSWORD: $MAILEXAM_PASSWORD
  MAILEXAM_PORT: "587"
  MAIL_FROM: "noreply@example.test"

После интеграционного теста проверьте доставку через API Mailexam.

7. Типичные проблемы

Ошибка TLS или authentication failed

  • relay должен быть {логин}.mailexam.ru, username — тот же логин из письма.
  • Логин и пароль — пара из письма одного проекта.

Порт 587

  • Нужен tls: :always, не :never.

:smtp_response / timeout

  • Проверьте, что gen_smtp в зависимостях и переменные заданы до mix phx.server.

Письмо не в кабинете

  • Смотрите входящие того же проекта Mailexam.
  • В dev включите логи: config :logger, level: :debug.

См. также