Recherche…


Introduction

Action Mailer vous permet d'envoyer des e-mails depuis votre application à l'aide de classes et de vues de courrier. Les publiposteurs fonctionnent de manière très similaire aux contrôleurs. Ils héritent d'ActionMailer :: Base et vivent dans les applications / les courriers, et ils ont des vues associées qui apparaissent dans les applications / vues.

Remarques

Il est conseillé de traiter l'envoi de courrier électronique de manière asynchrone afin de ne pas bloquer votre serveur Web. Cela peut être fait par le biais de divers services tels que delayed_job .

Basic Mailer

Cet exemple utilise quatre fichiers différents:

  • Le modèle d'utilisateur
  • Le mailer de l'utilisateur
  • Le modèle HTML pour l'e-mail
  • Le modèle en texte brut pour l'e-mail

Dans ce cas, le modèle utilisateur appelle la méthode approved dans l'expéditeur et transmet le post approuvé (la méthode approved dans le modèle peut être appelée par un rappel, par une méthode de contrôleur, etc.). Ensuite, l'expéditeur génère l'e-mail à partir du modèle HTML ou texte brut en utilisant les informations du post transmis (par exemple, le titre). Par défaut, le publiposteur utilise le modèle avec le même nom que la méthode dans le mailer (c'est pourquoi le nom du mailer et les modèles ont le même nom).

user_mailer.rb

class UserMailer < ActionMailer::Base
  default from: "[email protected]"

  def approved(post)
      @title = post.title
      @user = post.user
      mail(to: @user.email, subject: "Your Post was Approved!")
  end
end

user.rb

def approved(post)
    UserMailer.approved(post)
end

approved.html.erb

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>Post Approved</title>
    </head>
    <body>
        <h2>Congrats <%= @user.name %>! Your post (#<%= @title %>) has been approved!</h2>
        <p>We look forward to your future posts!</p>
    </body>
</html>

approved.text.erb

Congrats <%= @user.name %>! Your post (#<%= @title %>) has been approved!
We look forward to your future posts!

Générer un nouveau mailer

Pour générer un nouveau mailer, entrez la commande suivante

rails generate mailer PostMailer 

Cela va générer un fichier de modèle vierge dans app/mailers/post_mailer.rb nommé PostMailer

class PostMailer < ApplicationMailer
end

Deux fichiers de mise en page seront également générés pour la vue email, un pour le format html et un pour le format texte.

Si vous préférez ne pas utiliser le générateur, vous pouvez créer vos propres mailers. Assurez-vous qu'ils héritent d' ActionMailer::Base

Ajout de pièces jointes

ActionMailer permet également de joindre des fichiers.

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

Par défaut, les pièces jointes seront encodées avec Base64 . Pour changer cela, vous pouvez ajouter un hachage à la méthode des pièces jointes.

attachments['filename.jpg'] = {
  mime_type: 'application/gzip',
  encoding: 'SpecialEncoding',
  content: encoded_content
}

Vous pouvez également ajouter des pièces jointes en ligne

attachments.inline['image.jpg'] = File.read('/path/to/image.jpg')

ActionMailer Callbacks

ActionMailer prend en charge trois rappels

  • avant_action
  • après_action
  • around_action

Fournissez-les dans votre classe Mailer

class UserMailer < ApplicationMailer
  after_action :set_delivery_options, :prevent_delivery_to_guests, :set_business_headers

Ensuite, créez ces méthodes sous le mot-clé private

private
  def set_delivery_options
  end

  def prevent_delivery_to_guests
  end

  def set_business_headers
  end
end

Générer une newsletter programmée

Créez le modèle de newsletter :

  rails g model Newsletter name:string email:string

  subl app/models/newsletter.rb

  validates :name, presence: true
  validates :email, presence: true

Créer le contrôleur de newsletter :

  rails g controller Newsletters create
  
  class NewslettersController < ApplicationController
    skip_before_action :authenticate_user!
    before_action :set_newsletter, only: [:destroy]

    def create
      @newsletter = Newsletter.create(newsletter_params)
      if @newsletter.save
        redirect_to blog_index_path
      else
        redirect_to root_path
      end
    end

    private

      def set_newsletter
        @newsletter = Newsletter.find(params[:id])
      end

      def newsletter_params
        params.require(:newsletter).permit(:name, :email)
      end

  end

Après cela, changez la vue create.html.erb pour le nom nex. Nous allons convertir ce fichier en vue partielle qui sera stockée dans le pied de page . Le nom sera _form.html.erb .

Changer le fichier de nom de: À:
app / views / newsletters / create.html.erb app / views / newsletters / _form.html.erb

Après cela, définissez les itinéraires:

  subl app/config/routes.rb
    
  resources :newsletters

Plus tard, nous devons définir le formulaire que nous utiliserons pour enregistrer chaque courrier:

  subl app/views/newsletters/_form.html.erb

  <%= form_for (Newsletter.new) do |f| %>
    <div class="col-md-12" style="margin: 0 auto; padding: 0;">
      <div class="col-md-6" style="padding: 0;">
        <%= f.text_field :name, class: 'form-control', placeholder:'Nombre' %>
      </div>
      <div class="col-md-6" style="padding: 0;">
        <%= f.text_field :email, class: 'form-control', placeholder:'Email' %>
      </div>
    </div>
    <div class="col-md-12" style="margin: 0 auto; padding:0;">
      <%= f.submit class:"col-md-12 tran3s s-color-bg hvr-shutter-out-horizontal", style:'border: none; color: white; cursor: pointer; margin: 0.5em auto; padding: 0.75em; width: 100%;' %>
    </div>
  <% end %>

Et après cela, insérer sur le pied de page:

  subl app/views/layouts/_footer.html.erb

  <%= render 'newsletters/form' %>

Maintenant, installez le - letter_opener - to peut prévisualiser le courrier électronique dans le navigateur par défaut au lieu de l'envoyer. Cela signifie que vous n'avez pas besoin de configurer la remise des e-mails dans votre environnement de développement et que vous n'avez plus besoin d'envoyer accidentellement un e-mail de test à l'adresse de quelqu'un d'autre.

Ajoutez d'abord la gemme à votre environnement de développement et exécutez la commande bundle pour l'installer.

  subl your_project/Gemfile

  gem "letter_opener", :group => :development

Ensuite, définissez la méthode de livraison dans l'environnement de développement:

  subl your_project/app/config/environments/development.rb

  config.action_mailer.delivery_method = :letter_opener

Maintenant, créez une structure de mailer pour gérer l'ensemble des mailers que nous allons travailler. Dans le terminal

  rails generate mailer UserMailer newsletter_mailer

Et dans le UserMailer , nous devons créer une méthode appelée Newsletter Mailer qui sera créée pour contenir le dernier article du blog et sera déclenchée par une action de rake. Nous supposerons que vous aviez une structure de blog créée auparavant.

subl your_project/app/mailers/user_mailer.rb

class UserMailer '[email protected]'

  
  def newsletter_mailer
    @newsletter = Newsletter.all
    @post = Post.last(3)
    emails = @newsletter.collect(&:email).join(", ")
    mail(to: emails, subject: "Hi, this is a test mail.")
  end
  
end

Après cela, créez le modèle de mailer :

subl your_project/app/views/user_mailer/newsletter_mailer.html.erb

<p> Dear Followers: </p>
<p> Those are the lastest entries to our blog. We invite you to read and share everything we did on this week. </p>

<br/>
<table>
<% @post.each do |post| %>
  <%#= link_to blog_url(post) do %>
      <tr style="display:flex; float:left; clear:both;">
        <td style="display:flex; float:left; clear:both; height: 80px; width: 100px;">
          <% if post.cover_image.present? %>
            <%= image_tag post.cover_image.fullsize.url, class:"principal-home-image-slider" %>
          <%# else %>
            <%#= image_tag 'http://your_site_project.com' + post.cover_video, class:"principal-home-image-slider" %>
            <%#= raw(video_embed(post.cover_video)) %>
          <% end %>
        </td>
        <td>
          <h3>
            <%= link_to post.title, :controller => "blog", :action => "show", :only_path => false, :id => post.id %>
          </h3>
          <p><%= post.subtitle %></p>
        </td>
        <td style="display:flex; float:left; clear:both;">
           
        </td>
      </tr>
  <%# end %>
<% end %>
</table>

Puisque nous voulons envoyer le courrier électronique en tant que processus distinct, créons une tâche Rake pour envoyer le courrier électronique. Ajoutez un nouveau fichier appelé email_tasks.rake au répertoire lib / tasks de votre application Rails:

touch lib/taks/email_tasks.rake

desc 'weekly newsletter email'
task weekly_newsletter_email: :environment do
  UserMailer.newsletter_mailer.deliver!
end

L'environnement send_digest_email:: signifie charger l'environnement Rails avant d'exécuter la tâche, vous pouvez donc accéder aux classes d'application (comme UserMailer) dans la tâche.

A présent, l'exécution de la commande rake -T listera la tâche Rake nouvellement créée. Tout tester fonctionne en exécutant la tâche et en vérifiant si l'e-mail est envoyé ou non.

Pour tester si la méthode mailer fonctionne, exécutez la commande rake:

  rake weekly_newsletter_email

À ce stade, nous avons une tâche de rake qui peut être programmée en utilisant crontab . Nous allons donc installer le Gemme Whenever qui est utilisé pour fournir une syntaxe claire pour écrire et déployer des tâches cron.

subl your_project/Gemfile
  
  gem 'whenever', require: false

Ensuite, exécutez la commande suivante pour créer un fichier config / schedule.rb initial pour vous (tant que le dossier de configuration est déjà présent dans votre projet).

  wheneverize .

  [add] writing `./config/schedule.rb'
  [done] wheneverized!

Maintenant, à l'intérieur du fichier de programme, nous devons créer notre JOB CRON et appeler la méthode mailer pour déterminer le JOB CRON afin d'exécuter certaines tâches sans assistance et dans une plage de temps sélectionnée. Vous pouvez utiliser différents types de syntaxe, comme expliqué sur ce lien .

subl your_project/config/schedule.rb

every 1.day, :at => '4:30 am' do
  rake 'weekly_newsletter_email'
end

Cron Job Syntaxe de base

Emplois Cron avec Whenever

Maintenant, pour tester que le Job Cron a été créé avec succès, nous pouvons utiliser la commande suivante pour lire depuis le terminal, notre travail planifié dans CRON SYNTAX:

your_project your_mac_user$ whenever

30 4 * * * /bin/bash -l -c 'cd /Users/your_mac_user/Desktop/your_project && RAILS_ENV=production bundle exec rake weekly_newsletter_email --silent'

Maintenant, pour exécuter le test dans l'environnement de développement, il est judicieux de définir la ligne suivante du fichier principal application.rb pour que l'application sache où sont les modèles qu'elle utilisera.

  subl your_project/config/application.rb

  config.action_mailer.default_url_options = { :host => "http://localhost:3000/" }

Maintenant, pour laisser Capistrano V3 enregistrer le nouveau Job Cron à l’intérieur du serveur et le déclencheur qui va déclencher l’exécution de cette tâche, nous devons ajouter la condition suivante:

  subl your_project/Capfile

  require 'whenever/capistrano'

Et insérez dans le fichier de déploiement l'identifiant que CRON JOB utilisera sur l' environnement et le nom de l' application .

subl your_project/config/deploy.rb

set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:rails_env)}" }

Et prêt, après avoir enregistré les modifications sur chaque fichier, lancez la commande capistrano deploy:

  cap production deploy

Et maintenant votre JOB a été créé et calendarize pour exécuter la méthode Mailer qui est ce que je veux et dans la plage de temps que nous définissons sur ces fichiers.

Intercepteur ActionMailer

Action Mailer fournit des points d'ancrage aux méthodes d'intercepteur. Celles-ci vous permettent d'enregistrer les classes appelées pendant le cycle de vie de la distribution du courrier.

Une classe d'intercepteur doit implémenter la méthode: deliver_email (message) qui sera appelée avant l'envoi du courrier électronique, vous permettant de modifier le courrier électronique avant qu'il ne touche les agents de distribution. Votre classe doit apporter les modifications nécessaires directement à l'instance transmise dans Mail :: Message.

Il peut être utile que les développeurs envoient des e-mails à eux-mêmes et non à de vrais utilisateurs.

Exemple d'enregistrement d'un intercepteur actionmailer:

# config/initializers/override_mail_recipient.rb

if Rails.env.development? or Rails.env.test?
  class OverrideMailRecipient
    def self.delivering_email(mail)
      mail.subject = 'This is dummy subject'
      mail.bcc = '[email protected]'
      mail.to = '[email protected]'
    end
  end
  ActionMailer::Base.register_interceptor(OverrideMailRecipient)
end


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow