Spec-Zone.ru › Ruby on Rails 8.0

класс ActionMailer::Base

Родитель:
AbstractController::Base
Включенные модули:
ActionMailer::Callbacks, ActionMailer::DeliveryMethods, ActionMailer::QueuedDelivery, ActionMailer::Rescuable, ActionMailer::Parameterized, ActionMailer::Previews, ActionMailer::FormBuilder, AbstractController::Rendering, AbstractController::Helpers, AbstractController::Translation, AbstractController::Callbacks, AbstractController::Caching, ActionView::Layouts

Action Mailer Base

Action Mailer позволяет отправлять электронные письма из вашего приложения, используя модель и представления маллера.

Модели маллера

Для использования Action Mailer необходимо создать модель маллера.

$ bin/rails generate mailer Notifier

Сгенерированная модель наследуется от ApplicationMailer, которая в свою очередь наследуется от ActionMailer::Base. Модель маллера определяет методы, используемые для генерации сообщения электронной почты. В этих методах вы можете настроить переменные, которые будут использоваться в представлениях маллера, параметры самого письма, такие как адрес :from, и вложения.

class ApplicationMailer < ActionMailer::Base
  default from: 'from@example.com'
  layout 'mailer'
end

class NotifierMailer < ApplicationMailer
  default from: 'no-reply@example.com',
          return_path: 'system@example.com'

  def welcome(recipient)
    @account = recipient
    mail(to: recipient.email_address_with_name,
         bcc: ["bcc@example.com", "Order Watcher <watcher@example.com>"])
  end
end

Внутри метода маллера у вас есть доступ к следующим методам:

  • attachments[]= - Позволяет добавить вложения к вашему письму интуитивно; attachments['filename.png'] = File.read('path/to/filename.png')

  • attachments.inline[]= - Позволяет добавить встроенное вложение к вашему письму аналогичным образом, как и attachments[]=

  • headers[]= - Позволяет указать любой заголовок поля в вашем письме, например, headers['X-No-Spam'] = 'True'. Обратите внимание, что объявление заголовка несколько раз добавит множество полей с одинаковым именем. Для получения дополнительной информации прочитайте headers документ.

  • headers(hash) - Позволяет указать несколько заголовков в вашем письме, таких как headers({'X-No-Spam' => 'True', 'In-Reply-To' => '1234@message.id'})

  • mail - Позволяет указать электронную почту, которую нужно отправить.

Хэш, переданный методу mail, позволяет указать любой заголовок, который примет Mail::Message (любой допустимый заголовок электронной почты, включая необязательные поля).

Метод mail, если не передан с блоком, проанализирует ваши представления и отправит все представления с тем же именем, что и метод, поэтому вышеуказанное действие отправит файл представления welcome.text.erb, а также файл представления welcome.html.erb в multipart/alternative письме.

Если вы хотите явно отобразить только определенные шаблоны, передайте блок:

mail(to: user.email) do |format|
  format.text
  format.html
end

Синтаксис блоков также полезен для предоставления информации, специфичной для части:

mail(to: user.email) do |format|
  format.text(content_transfer_encoding: "base64")
  format.html
end

Или даже для отображения специального представления:

mail(to: user.email) do |format|
  format.text
  format.html { render "some_other_template" }
end

Представления маллера

Как и Action Controller, каждый класс маллера имеет соответствующий каталог представлений, в котором каждый метод класса ищет шаблон с его именем.

Для определения шаблона, используемого с маллером, создайте файл .erb с тем же именем, что и метод в вашей модели маллера. Например, в определенном выше маллере шаблон в app/views/notifier_mailer/welcome.text.erb будет использоваться для генерации письма.

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

Письма по умолчанию отправляются в формате простого текста, поэтому пример представления для нашего примера модели может выглядеть так:

Hi <%= @account.name %>,
Thanks for joining our service! Please check back often.

Вы даже можете использовать помощники Action View в этих представлениях. Например:

You got a new note!
<%= truncate(@note.body, length: 25) %>

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

You got a new note from <%= message.from %>!
<%= truncate(@note.body, length: 25) %>

Генерация URL-адресов

URL-адреса могут быть сгенерированы в представлениях маллера с помощью url_for или именованных маршрутов. В отличие от контроллеров из Action Pack, у экземпляра маллера нет контекста о входящем запросе, поэтому вам нужно предоставить все необходимые данные для генерации URL-адреса.

При использовании url_for вам нужно указать :host, :controller, и :action.

<%= url_for(host: "example.com", controller: "welcome", action: "greeting") %>

При использовании именованных маршрутов вам нужно только указать :host.

<%= users_url(host: "example.com") %>

Вы должны использовать стиль named_route_url (который генерирует абсолютные URL-адреса) и избегать использования стиля named_route_path (который генерирует относительные URL-адреса), так как клиенты, читающие письмо, не будут иметь понятия о текущем URL-адресе для определения относительного пути.

Также возможно установить хост по умолчанию, который будет использоваться во всех маллерах, установив параметр :host как параметр конфигурации в config/application.rb.

config.action_mailer.default_url_options = { host: "example.com" }

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

По умолчанию, когда config.force_ssl равно true, сгенерированные для хостов URL-адреса будут использовать протокол HTTPS.

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

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

NotifierMailer.welcome(User.first).deliver_now # sends the email
mail = NotifierMailer.welcome(User.first)      # => an ActionMailer::MessageDelivery object
mail.deliver_now                               # generates and sends the email now

Класс ActionMailer::MessageDelivery — это обёртка вокруг делегата, который вызовет ваш метод для генерации письма. Если вам нужен прямой доступ к делегату или Mail::Message, вы можете вызвать метод message у объекта ActionMailer::MessageDelivery.

NotifierMailer.welcome(User.first).message     # => a Mail::Message object

Action Mailer хорошо интегрирован с Active Job, поэтому вы можете генерировать и отправлять электронные письма в фоновом режиме (например, вне цикла обработки запроса-ответа, чтобы пользователь не ждал):

NotifierMailer.welcome(User.first).deliver_later # enqueue the email sending to Active Job

Обратите внимание, что deliver_later выполнит ваш метод из фонового задания.

Вы никогда не создаёте экземпляр своего класса маллера. Вместо этого вы просто вызываете метод, который вы определили для самого класса. Все методы экземпляров должны возвращать объект сообщения, который будет отправлен.

Письма multipart

Multipart сообщения также могут использоваться неявно, поскольку Action Mailer автоматически обнаруживает и использует multipart шаблоны, где каждый шаблон называется по имени действия, за которым следует тип содержимого. Каждый такой обнаруженный шаблон будет добавлен к сообщению как отдельная часть.

Например, если существуют следующие шаблоны:

  • signup_notification.text.erb

  • signup_notification.html.erb

  • signup_notification.xml.builder

  • signup_notification.yml.erb

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

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

Вложения

Отправка вложений в электронные письма проста:

class NotifierMailer < ApplicationMailer
  def welcome(recipient)
    attachments['free_book.pdf'] = File.read('path/to/file.pdf')
    mail(to: recipient, subject: "New account information")
  end
end

Что (если в каталоге представлений был и шаблон welcome.text.erb, и welcome.html.erb) отправит полное multipart/mixed письмо с двумя частями: первая часть — multipart/alternative с частями текста и HTML письма внутри, а вторая — application/pdf с Base64-кодированной копией книги file.pdf с именем файла free_book.pdf.

Если вам нужно отправлять вложения без содержимого, вам нужно создать для него пустое представление или добавить пустой параметр body, как показано ниже:

class NotifierMailer < ApplicationMailer
  def welcome(recipient)
    attachments['free_book.pdf'] = File.read('path/to/file.pdf')
    mail(to: recipient, subject: "New account information", body: "")
  end
end

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

class NotifierMailer < ApplicationMailer
  def welcome(recipient)
    attachments["free_book.pdf"] = File.read("path/to/file.pdf")
    mail(to: recipient,
         subject: "New account information",
         content_type: "text/html",
         body: "<html><body>Hello there</body></html>")
  end
end

Встроенные вложения

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

class NotifierMailer < ApplicationMailer
  def welcome(recipient)
    attachments.inline['photo.png'] = File.read('path/to/photo.png')
    mail(to: recipient, subject: "Here is what we look like")
  end
end

А затем, чтобы сослаться на изображение в представлении, создайте файл welcome.html.erb и вызовите image_tag, передав вложение, которое вы хотите отобразить, а затем вызовите url на вложении, чтобы получить относительный путь идентификатора содержимого для источника изображения:

<h1>Please Don't Cringe</h1>

<%= image_tag attachments['photo.png'].url -%>

Поскольку мы используем метод image_tag Action View, вы можете передать любые другие параметры, которые хотите:

<h1>Please Don't Cringe</h1>

<%= image_tag attachments['photo.png'].url, alt: 'Our Photo', class: 'photo' -%>

Наблюдение и перехват писем

Action Mailer предоставляет крючки для наблюдателей Mail и методов перехвата. Они позволяют вам регистрировать классы, которые вызываются во время жизненного цикла доставки почты.

Класс наблюдателя должен реализовать метод :delivered_email(message), который будет вызываться один раз для каждого отправленного письма после отправки письма.

Класс перехватчика должен реализовать метод :delivering_email(message), который будет вызываться до отправки письма, позволяя вам вносить изменения в письмо перед его попаданием в агенты доставки. Ваш класс должен вносить необходимые изменения непосредственно в переданный экземпляр Mail::Message.

Хэш по умолчанию

Action Mailer предоставляет некоторые разумные значения по умолчанию для ваших писем, которые обычно указываются в методе по умолчанию внутри определения класса:

class NotifierMailer < ApplicationMailer
  default sender: 'system@example.com'
end

Вы можете передать любое значение заголовка, которое принимает Mail::Message. Из коробки, ActionMailer::Base устанавливает следующее:

  • mime_version: "1.0"

  • charset: "UTF-8"

  • content_type: "text/plain"

  • parts_order: [ "text/plain", "text/enriched", "text/html" ]

parts_order и charset фактически не являются допустимыми полями заголовка Mail::Message, но Action Mailer переводит их соответствующим образом и устанавливает правильные значения.

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

class NotifierMailer < ApplicationMailer
  default 'Content-Transfer-Encoding' => '7bit',
          content_description: 'This is a description'
end

Наконец, Action Mailer также поддерживает передачу объектов Proc и Lambda в хэш по умолчанию, поэтому вы можете определить методы, которые оцениваются по мере генерации сообщения:

class NotifierMailer < ApplicationMailer
  default 'X-Special-Header' => Proc.new { my_method }, to: -> { @inviter.email_address }

  private
    def my_method
      'some complex call'
    end
end

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

Также возможно установить эти параметры по умолчанию, которые будут использоваться во всех маллерах, через параметр конфигурации default_options= в config/application.rb:

config.action_mailer.default_options = { from: "no-reply@example.org" }

Обратные вызовы

Вы можете указать обратные вызовы с помощью before_action и after_action для настройки ваших сообщений и использования before_deliver и after_deliver для обертывания процесса доставки. Например, когда вы хотите добавить встроенные вложения по умолчанию и логировать доставку для всех сообщений, отправляемых определённым классом маллера:

class NotifierMailer < ApplicationMailer
  before_action :add_inline_attachment!
  after_deliver :log_delivery

  def welcome
    mail
  end

  private
    def add_inline_attachment!
      attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
    end

    def log_delivery
      Rails.logger.info "Sent email with message id '#{message.message_id}' at #{Time.current}."
    end
end

Обработка обратных вызовов в Action Mailer выполняется с помощью AbstractController::Callbacks, поэтому вы можете определять и настраивать обратные вызовы так же, как и в классах, унаследованных от ActionController::Base.

Обратите внимание, что если у вас нет особой причины, следует предпочитать использование before_action вместо after_action в ваших классах Action Mailer, чтобы заголовки были обработаны должным образом.

Обработка ошибок

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

Чтобы перехватывать ошибки, возникающие на любой стадии процесса отправки почты, используйте rescue_from:

class NotifierMailer < ApplicationMailer
  rescue_from ActiveJob::DeserializationError do
    # ...
  end

  rescue_from "SomeThirdPartyService::ApiError" do
    # ...
  end

  def notify(recipient)
    mail(to: recipient, subject: "Notification")
  end
end

Предварительный просмотр почтовых сообщений

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

class NotifierMailerPreview < ActionMailer::Preview
  def welcome
    NotifierMailer.welcome(User.first)
  end
end

Методы должны возвращать объект Mail::Message, который можно сгенерировать, вызвав метод почтового сообщения без дополнительных deliver_now / deliver_later. Путь к каталогам предварительного просмотра почтовых сообщений можно настроить с помощью параметра preview_paths, по умолчанию установленного в test/mailers/previews:

config.action_mailer.preview_paths << "#{Rails.root}/lib/mailer_previews"

Обзор всех предварительных просмотров доступен по адресу http://localhost:3000/rails/mailers на экземпляре работающего сервера разработки.

Previews также можно перехватить аналогичным образом, как и отправки, зарегистрировав перехватчик предварительного просмотра, имеющий метод previewing_email:

class CssInlineStyler
  def self.previewing_email(message)
    # inline CSS styles
  end
end

config.action_mailer.preview_interceptors :css_inline_styler

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

Настройка параметров

Эти параметры задаются на уровне класса, как ActionMailer::Base.raise_delivery_errors = true

  • default_options - Вы можете передать его как на уровне класса, так и внутри класса, как описано выше.

  • logger - Логгер используется для генерации информации о выполнении отправки почты, если доступен. Может быть установлен в nil для отключения ведения журнала. Совместим с собственными логгерами Ruby Logger и логгерами Log4r.

  • smtp_settings - Разрешает подробную настройку метода доставки :smtp:

    • :address - Разрешает использование удаленного сервера почты. Просто измените значение с по умолчанию “localhost”.

    • :port - В случае, если ваш сервер почты работает не на порту 25, вы можете изменить его.

    • :domain - Если необходимо указать домен HELO, вы можете сделать это здесь.

    • :user_name - Если для сервера почты требуется аутентификация, укажите имя пользователя в этом параметре.

    • :password - Если для сервера почты требуется аутентификация, укажите пароль в этом параметре.

    • :authentication - Если для сервера почты требуется аутентификация, укажите здесь тип аутентификации. Это символ и один из :plain (пароль будет отправлен в кодировке Base64), :login (пароль будет отправлен в кодировке Base64) или :cram_md5 (сочетает механизм «Вызов/Ответ» для обмена данными и криптографический алгоритм хэширования Message Digest 5 для хэширования важной информации)

    • :enable_starttls - Используйте STARTTLS при подключении к SMTP-серверу и прекратите выполнение, если он не поддерживается. По умолчанию false. Требуется версия Mail gem не ниже 2.7.

    • :enable_starttls_auto - Определяет, включен ли STARTTLS на вашем SMTP-сервере, и начинает его использование. По умолчанию true.

    • :openssl_verify_mode - При использовании TLS можно настроить, как OpenSSL проверяет сертификат. Это очень полезно, если необходимо валидировать самоподписанный и/или сертификат с подстановочным знаком. Можно использовать имя константы OpenSSL для проверки ('none' или 'peer') или непосредственно саму константу (OpenSSL::SSL::VERIFY_NONE или OpenSSL::SSL::VERIFY_PEER).

    • :ssl/:tls Включает использование SMTP/TLS (SMTPS: SMTP через прямое TLS-соединение) для SMTP-соединения.

    • :open_timeout Количество секунд ожидания при попытке открытия соединения.

    • :read_timeout Количество секунд ожидания до истечения времени чтения вызова (read(2)).

  • sendmail_settings - Разрешает переопределение параметров для метода доставки :sendmail.

    • :location - Путь к исполняемому файлу sendmail. По умолчанию /usr/sbin/sendmail.

    • :arguments - Аргументы командной строки. По умолчанию %w[ -i ], с -f sender@address добавленным автоматически перед отправкой сообщения.

  • file_settings - Разрешает переопределение параметров для метода доставки :file.

    • :location - Каталог, в который будут записываться электронные письма. По умолчанию приложение tmp/mails.

  • raise_delivery_errors - Поднятие исключения при неудачной доставке почты.

  • delivery_method - Определяет метод доставки. Возможные значения :smtp (по умолчанию), :sendmail, :test, и :file. Или вы можете указать пользовательский объект метода доставки, например MyOwnDeliveryMethodClass. Обратитесь к документации Mail gem для интерфейса, который вам нужно реализовать для пользовательского агента доставки.

  • perform_deliveries - Определяет, отправляются ли электронные письма из Action Mailer, когда вы вызываете .deliver на сообщении электронной почты или на методе Action Mailer. По умолчанию включено, но может быть отключено для облегчения функционального тестирования.

  • deliveries - Сохраняет массив всех отправленных электронных писем через Action Mailer с delivery_method :test. Очень полезно для модульного и функционального тестирования.

  • delivery_job - Класс задачи, используемый с deliver_later. Почтовые сообщения могут установить его для использования пользовательской задачи доставки. По умолчанию ActionMailer::MailDeliveryJob.

  • deliver_later_queue_name - Имя очереди, используемое deliver_later с по умолчанию delivery_job. Почтовые сообщения могут установить его для использования пользовательского имени очереди.

Константы

PROTECTED_IVARS

Атрибуты

mailer_name[W]

Позволяет установить имя текущего почтового отправителя.

Публичные методы класса

controller_path()
Alias for: mailer_name
default(value = nil) Show source
# File actionmailer/lib/action_mailer/base.rb, line 582
def default(value = nil)
  self.default_params = default_params.merge(value).freeze if value
  default_params
end

Устанавливает значения по умолчанию через конфигурацию приложения:

config.action_mailer.default(from: "no-reply@example.org")

Псевдоним ::default_options=

Также используется как псевдоним: default_options=
default_options=(value = nil)

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

config.action_mailer.default_options = { from: "no-reply@example.org" }
Alias for: default
email_address_with_name(address, name) Show source
# File actionmailer/lib/action_mailer/base.rb, line 607
def email_address_with_name(address, name)
  Mail::Address.new.tap do |builder|
    builder.address = address
    builder.display_name = name.presence
  end.to_s
end

Возвращает электронный адрес в формате “Имя <email@example.com>”.

Если имя является пустой строкой, возвращается только адрес.

mailer_name() Show source
# File actionmailer/lib/action_mailer/base.rb, line 570
def mailer_name
  @mailer_name ||= anonymous? ? "anonymous" : name.underscore
end

Возвращает имя текущего почтового отправителя. Этот метод также используется в качестве пути для поиска представления. Если это анонимный почтовый отправитель, этот метод вернет anonymous вместо этого.

Также используется как псевдоним: controller_path
new() Show source
# File actionmailer/lib/action_mailer/base.rb, line 643
def initialize
  super()
  @_mail_was_called = false
  @_message = Mail.new
end
Вызывает метод суперкласса
register_interceptor(interceptor) Show source
# File actionmailer/lib/action_mailer/base.rb, line 547
def register_interceptor(interceptor)
  Mail.register_interceptor(observer_class_for(interceptor))
end

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

register_interceptors(*interceptors) Show source
# File actionmailer/lib/action_mailer/base.rb, line 521
def register_interceptors(*interceptors)
  interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
end

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

register_observer(observer) Show source
# File actionmailer/lib/action_mailer/base.rb, line 533
def register_observer(observer)
  Mail.register_observer(observer_class_for(observer))
end

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

register_observers(*observers) Show source
# File actionmailer/lib/action_mailer/base.rb, line 511
def register_observers(*observers)
  observers.flatten.compact.each { |observer| register_observer(observer) }
end

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

supports_path?() Show source
# File actionmailer/lib/action_mailer/base.rb, line 942
def self.supports_path? # :doc:
  false
end

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

unregister_interceptor(interceptor) Show source
# File actionmailer/lib/action_mailer/base.rb, line 554
def unregister_interceptor(interceptor)
  Mail.unregister_interceptor(observer_class_for(interceptor))
end

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

unregister_interceptors(*interceptors) Show source
# File actionmailer/lib/action_mailer/base.rb, line 526
def unregister_interceptors(*interceptors)
  interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) }
end

Отменяет регистрацию одного или нескольких ранее зарегистрированных перехватчиков.

unregister_observer(observer) Show source
# File actionmailer/lib/action_mailer/base.rb, line 540
def unregister_observer(observer)
  Mail.unregister_observer(observer_class_for(observer))
end

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

unregister_observers(*observers) Show source
# File actionmailer/lib/action_mailer/base.rb, line 516
def unregister_observers(*observers)
  observers.flatten.compact.each { |observer| unregister_observer(observer) }
end

Отменяет регистрацию одного или нескольких ранее зарегистрированных наблюдателей.

Публичные методы экземпляра

attachments() Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 760
def attachments
  if @_mail_was_called
    LateAttachmentsProxy.new(@_message.attachments)
  else
    @_message.attachments
  end
end

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

mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')

В этом случае Mail получит имя файла и определит тип MIME. Также будут установлены Content-Type, Content-Disposition, и Content-Transfer-Encoding, а содержимое вложения будет закодировано в Base64.

Можно также указать переопределения, передав хеш вместо строки:

mail.attachments['filename.jpg'] = {mime_type: 'application/gzip',
                                    content: File.read('/path/to/filename.jpg')}

Если нужно использовать кодирование отличное от Base64, необходимо передать тип кодирования вместе с предварительно закодированным содержимым, так как Mail не знает, как декодировать данные:

file_content = SpecialEncode(File.read('/path/to/filename.jpg'))
mail.attachments['filename.jpg'] = {mime_type: 'application/gzip',
                                    encoding: 'SpecialEncoding',
                                    content: file_content }

Также можно искать определенные вложения:

# By Filename
mail.attachments['filename.jpg']   # => Mail::Part object or nil

# or by index
mail.attachments[0]                # => Mail::Part (first attachment)
email_address_with_name(address, name) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 684
def email_address_with_name(address, name)
  self.class.email_address_with_name(address, name)
end

Возвращает адрес электронной почты в формате «Имя <email@example.com>».

Если имя пустая строка, возвращается только адрес.

headers(args = nil) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 722
def headers(args = nil)
  if args
    @_message.headers(args)
  else
    @_message
  end
end

Позволяет передавать произвольные заголовки новому объекту Mail::Message, которые будут добавлены к нему.

headers['X-Special-Domain-Specific-Header'] = "SecretValue"

Также можно передать в headers хеш с именами и значениями заголовков, которые затем будут установлены на объекте Mail::Message.

headers 'X-Special-Domain-Specific-Header' => "SecretValue",
        'In-Reply-To' => incoming.message_id

Полученный объект Mail::Message будет содержать следующие заголовки:

X-Special-Domain-Specific-Header: SecretValue

Примечание о замене уже определенных заголовков:

  • subject

  • sender

  • from

  • to

  • cc

  • bcc

  • reply-to

  • orig-date

  • message-id

  • references

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

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

mail(headers = {}, &block) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 869
def mail(headers = {}, &block)
  return message if @_mail_was_called && headers.blank? && !block

  # At the beginning, do not consider class default for content_type
  content_type = headers[:content_type]

  headers = apply_defaults(headers)

  # Apply charset at the beginning so all fields are properly quoted
  message.charset = charset = headers[:charset]

  # Set configure delivery behavior
  wrap_delivery_behavior!(headers[:delivery_method], headers[:delivery_method_options])

  assign_headers_to_message(message, headers)

  # Render the templates and blocks
  responses = collect_responses(headers, &block)
  @_mail_was_called = true

  create_parts_from_responses(message, responses)
  wrap_inline_attachments(message)

  # Set up content type, reapply charset and handle parts order
  message.content_type = set_content_type(message, content_type, headers[:content_type])
  message.charset      = charset

  if message.multipart?
    message.body.set_sort_order(headers[:parts_order])
    message.body.sort_parts!
  end

  message
end

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

Принимает хеш заголовков. Этот хеш позволяет указать наиболее используемые заголовки в сообщении электронной почты:

  • :subject - Тема сообщения. Если тема опущена, Action Mailer запросит у класса Rails I18n переведенную :subject в контексте [mailer_scope, action_name]. Если и это отсутствует, будет переведена человекочитаемая версия action_name

  • :to - Получатель сообщения, может быть строкой адресов или массивом адресов.

  • :from - Отправитель сообщения

  • :cc - Копия сообщения, может быть строкой адресов или массивом адресов.

  • :bcc - Скрытая копия сообщения, может быть строкой адресов или массивом адресов.

  • :reply_to - Установка заголовка Reply-To почтового сообщения.

  • :date - Дата отправки письма.

Можно установить значения по умолчанию для любых из вышеперечисленных заголовков (кроме :date) с помощью метода класса ::default:

class Notifier < ActionMailer::Base
  default from: 'no-reply@test.lindsaar.net',
          bcc: 'email_logger@test.lindsaar.net',
          reply_to: 'bounces@test.lindsaar.net'
end

Если вам нужны другие заголовки, не указанные выше, вы можете передать их в качестве части хеша заголовков или использовать метод headers['name'] = value.

При указании :return_path в качестве заголовка, это значение будет использоваться в качестве адреса «отправителя» для сообщения Mail. Это полезно, когда уведомления об отправке нужно отправлять на другой адрес, чем тот, который указан в :from. Mail фактически будет использовать :return_path вместо :sender и :from для значения «отправитель».

Если вы не передаете блок методу mail, он найдет все шаблоны в путях представления, используя по умолчанию имя маиллера и имя метода, из которого он вызывается, затем интеллектуально создаст части для каждого из этих шаблонов, сделав обоснованные предположения о правильном типе содержимого и последовательности, и вернет полностью подготовленное сообщение Mail::Message для вызова :deliver для отправки.

Например:

class Notifier < ActionMailer::Base
  default from: 'no-reply@test.lindsaar.net'

  def welcome
    mail(to: 'mikel@test.lindsaar.net')
  end
end

Будет искать все шаблоны в «app/views/notifier» с именем «welcome». Если шаблон welcome не существует, будет выброшено исключение ActionView::MissingTemplate.

Однако, это можно настроить:

mail(template_path: 'notifications', template_name: 'another')

Теперь он будет искать все шаблоны в «app/views/notifications» с именем «another».

Если вы передаете блок, вы можете рендерить определенные шаблоны по своему выбору:

mail(to: 'mikel@test.lindsaar.net') do |format|
  format.text
  format.html
end

Вы можете даже рендерить обычный текст непосредственно без использования шаблона:

mail(to: 'mikel@test.lindsaar.net') do |format|
  format.text { render plain: "Hello Mikel!" }
  format.html { render html: "<h1>Hello Mikel!</h1>".html_safe }
end

Что рендерит письмо multipart/alternative с text/plain и text/html частями.

Синтаксис с блоком также позволяет настраивать заголовки частей по желанию:

mail(to: 'mikel@test.lindsaar.net') do |format|
  format.text(content_transfer_encoding: "base64")
  format.html
end
mailer_name() Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 677
def mailer_name
  self.class.mailer_name
end

Возвращает имя объекта маиллера.

Приватные методы экземпляра

default_i18n_subject(interpolations = {}) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 936
def default_i18n_subject(interpolations = {}) # :doc:
  mailer_scope = self.class.mailer_name.tr("/", ".")
  I18n.t(:subject, **interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
end

Переводит subject с помощью класса Rails I18n в контексте [mailer_scope, action_name]. Если перевод для subject в указанном контексте не найден, используется человекочитаемый вариант action_name. Если тема содержит интерполяции, их можно передать через параметр interpolations.

set_content_type(m, user_content_type, class_default) Показать исходный код
# File actionmailer/lib/action_mailer/base.rb, line 914
def set_content_type(m, user_content_type, class_default) # :doc:
  params = m.content_type_parameters || {}
  case
  when user_content_type.present?
    user_content_type
  when m.has_attachments?
    if m.attachments.all?(&:inline?)
      ["multipart", "related", params]
    else
      ["multipart", "mixed", params]
    end
  when m.multipart?
    ["multipart", "alternative", params]
  else
    m.content_type || class_default
  end
end

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

Будет использоваться заданный тип user_content_type, или multipart, если почтовое сообщение содержит вложения. Если вложения встроенные, тип содержимого будет “multipart/related”, иначе “multipart/mixed”.

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

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API