Отправка писем с помощью SendGrid SDK для Ruby on Rails с использованием динамических шаблонов писем SendGrid

В предыдущей статье »Преимущества API для отправки почты перед SMTP в Ruby on Rails с помощью MailGun или SendGrid» я объяснил многие преимущества использования API перед SMTP.

В этой статье я расскажу об отправке электронных писем с помощью SendGrid SDK в Ruby on Rails, использовании динамических шаблонов SendGrid и даже включении вложений в письмо.

Добавление SendGrid SDK в Rails

В Gemfile добавьте официальный гем SendGrid:

gem 'sendgrid-ruby', '~> 6.6', '>= 6.6.2'
Войти в полноэкранный режим Выйти из полноэкранного режима

И запустите bundle install.

Динамические шаблоны для SendGrid

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

Эти шаблоны также предоставляют возможности для замены. Например, вы создаете транзакционное письмо, и имя получателя зависит от человека, которому вы отправляете это письмо. Поэтому укажите переменную в шаблоне, например {{name}}, и когда вы отправляете письмо через SDK, отправьте JSON-объект для подстановки значения, как показано ниже:

{
  "name": "Sulman Baig"
}
Войти в полноэкранный режим Выход из полноэкранного режима

Когда вы закончите создание шаблона, вы получите template_id. Сохраните этот идентификатор для дальнейшего использования.

Получите API-ключ SendGrid:

Вы можете получить API-ключ SendGrid, выполнив действия, указанные в официальной документации: https://docs.sendgrid.com/ui/account-and-settings/api-keys#creating-an-api-key.

Отправьте задание по электронной почте:

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

Мы предполагаем использовать приведенный ниже фрагмент кода:

Теперь создайте файл app/jobs/email_job.rb и добавьте следующий код.

Вы можете включить гем sidekiq и вызывать эту работу асинхронно.

# frozen_string_literal: true

require 'sendgrid-ruby'

#### Example Call
# EmailJob.new.perform(
#         @user.id,
#         { name: @user.name },
#         ENV.fetch('EXPORT_TEMPLATE', nil),
#         [
#           {
#             file: @tempfile.path,
#             type: 'application/csv',
#             name: @tempfile.path.split('/').last,
#             content_id: 'export_file'
#           }
#         ]
#       )

# This is the email job that will be sent to the user
class EmailJob
  include SendGrid

  # From Email and Name
  NOREPLY_FROM_EMAIL = 'no-reply@allwallet.app'
  NOREPLY_FROM_NAME = 'All Wallet'

  # include sidekiq to call perform as perform_async
  def perform(user_id, subsitutions, template_id, attachments = nil) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
    # initialize sendgrid api
    sg = SendGrid::API.new(api_key: ENV.fetch('SENDGRID_API_KEY', nil))
    # we will get to_email from user object saved in db
    user = User.kept.find_by(id: user_id)
    return unless user

    # initialize mail object of sendgrid
    mail = Mail.new
    # fill 'from' data from the constants mentioned above
    mail.from = Email.new(email: NOREPLY_FROM_EMAIL, name: NOREPLY_FROM_NAME)
    # personalization is object for email to data and templates
    personalization = Personalization.new
    # add user data to which email to be sent
    personalization.add_to(Email.new(email: user.email, name: user.name))
    # add substitutions to template created in sendgrid to replace the variable in template like `{{name}}`
    # {
    #   "name": "Sulman Baig"
    # }
    personalization.add_dynamic_template_data(subsitutions)
    mail.add_personalization(personalization)
    mail.template_id = template_id

    # If attachments are sent as arguments
    if attachments.present? && attachments.is_a?(Array) && attachments.size.positive?
      attachments.each do |attachment_input|
        attachment = Attachment.new
        # attachment has to be sent as base64 encoded string
        attachment.content = Base64.strict_encode64(File.read(attachment_input[:file])) # file: path of file saved in local or remote
        attachment.type = attachment_input[:type] # type of file e.g. application/csv
        attachment.filename = attachment_input[:name] # filename
        attachment.disposition = 'attachment'
        attachment.content_id = attachment_input[:content_id] # e.g. export_file
        mail.add_attachment(attachment)
      end
    end

    begin
      # Send Email
      sg.client.mail._('send').post(request_body: mail.to_json)
    rescue StandardError => e
      # TODO: capture exception
    end
  end
end
Вход в полноэкранный режим Выйти из полноэкранного режима

GitHub Gist

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

EmailJob.new.perform(
        @user.id,
        { name: @user.name },
        ENV.fetch('EXPORT_TEMPLATE', nil),
        [
          {
            file: @tempfile.path,
            type: 'application/csv',
            name: @tempfile.path.split('/').last,
            content_id: 'export_file'
          }
        ]
      )
Вход в полноэкранный режим Выйти из полноэкранного режима

Счастливого кодинга!

Оцените статью
devanswers.ru
Добавить комментарий