Ruby on Rails
ActionMailer
Szukaj…
Wprowadzenie
Action Mailer umożliwia wysyłanie wiadomości e-mail z aplikacji przy użyciu klas i widoków mailera. Mailery działają bardzo podobnie do kontrolerów. Dziedziczą po ActionMailer :: Base i mieszkają w aplikacji / mailerach i mają powiązane widoki, które pojawiają się w aplikacji / widokach.
Uwagi
Wskazane jest przetwarzanie asynchroniczne wysyłania wiadomości e-mail, aby nie wiązać serwera WWW. Można to zrobić za pomocą różnych usług, takich jak delayed_job
.
Basic Mailer
W tym przykładzie wykorzystano cztery różne pliki:
- Model użytkownika
- Mailer użytkownika
- Szablon HTML dla wiadomości e-mail
- Szablon zwykłego tekstu dla wiadomości e-mail
W takim przypadku model użytkownika wywołuje metodę approved
w programie post
i przekazuje zatwierdzoną wiadomość (metoda approved
w modelu może zostać wywołana przez wywołanie zwrotne, z metody kontrolera itp.). Następnie program pocztowy generuje wiadomość e-mail z szablonu HTML lub zwykłego tekstu na podstawie informacji z przekazanego post
(np. Tytułu). Domyślnie program pocztowy używa szablonu o tej samej nazwie co metoda w programie pocztowym (dlatego zarówno metoda programu pocztowego, jak i szablony mają nazwę „zatwierdzona”).
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
zatwierdzony.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>
zatwierdzony.tekst.erb
Congrats <%= @user.name %>! Your post (#<%= @title %>) has been approved!
We look forward to your future posts!
Generowanie nowego mailera
Aby wygenerować nowy program pocztowy, wprowadź następujące polecenie
rails generate mailer PostMailer
Spowoduje to wygenerowanie pustego pliku szablonu w app/mailers/post_mailer.rb
o nazwie PostMailer
class PostMailer < ApplicationMailer
end
Zostaną również wygenerowane dwa pliki układu dla widoku e-mail, jeden dla formatu HTML i jeden dla formatu tekstowego.
Jeśli wolisz nie używać generatora, możesz tworzyć własne mailery. Upewnij się, że dziedziczą po ActionMailer::Base
Dodawanie załączników
ActionMailer
umożliwia także dołączanie plików.
attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
Domyślnie załączniki będą kodowane przy użyciu Base64
. Aby to zmienić, możesz dodać skrót do metody załączników.
attachments['filename.jpg'] = {
mime_type: 'application/gzip',
encoding: 'SpecialEncoding',
content: encoded_content
}
Możesz także dodawać załączniki wbudowane
attachments.inline['image.jpg'] = File.read('/path/to/image.jpg')
Oddzwanianie ActionMailer
ActionMailer obsługuje trzy połączenia zwrotne
- przed działaniem
- następstwo
- około aktywności
Podaj je w swojej klasie Mailer
class UserMailer < ApplicationMailer
after_action :set_delivery_options, :prevent_delivery_to_guests, :set_business_headers
Następnie utwórz te metody pod private
słowem kluczowym
private
def set_delivery_options
end
def prevent_delivery_to_guests
end
def set_business_headers
end
end
Wygeneruj zaplanowany biuletyn
Utwórz model biuletynu :
rails g model Newsletter name:string email:string subl app/models/newsletter.rb validates :name, presence: true validates :email, presence: true
Utwórz kontroler biuletynu :
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
Następnie zmień widok create.html.erb na nazwę nex. Konwertujemy ten plik do częściowego widoku, który będzie przechowywany w stopce . Nazwą będzie _form.html.erb .
Zmień nazwę pliku z: | Do: |
---|---|
app / views / newsletters / create.html.erb | app / views / newsletters / _form.html.erb |
Następnie ustaw trasy:
subl app/config/routes.rb resources :newsletters
Później musimy ustawić formularz, w którym będziemy zapisywać każdą pocztę:
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 %>
A następnie wstaw stopkę:
subl app/views/layouts/_footer.html.erb <%= render 'newsletters/form' %>
Teraz zainstaluj - letter_opener - aby wyświetlić podgląd wiadomości e-mail w domyślnej przeglądarce zamiast jej wysyłać. Oznacza to, że nie musisz konfigurować dostarczania wiadomości e-mail w środowisku programistycznym i nie musisz się już martwić przypadkowym wysłaniem wiadomości e-mail testowej na adres innej osoby.
Najpierw dodaj klejnot do środowiska programistycznego i uruchom polecenie pakietu, aby go zainstalować.
subl your_project/Gemfile gem "letter_opener", :group => :development
Następnie ustaw metodę dostarczania w środowisku programistycznym:
subl your_project/app/config/environments/development.rb config.action_mailer.delivery_method = :letter_opener
Teraz utwórz Strukturę Mailera, aby zarządzać całością mailerów, którymi będziemy pracować. W terminalu
rails generate mailer UserMailer newsletter_mailer
Wewnątrz UserMailer musimy stworzyć metodę o nazwie Newsletter Mailer, która zostanie utworzona w celu umieszczenia wewnątrz najnowszego posta na blogu i zostanie zwolniona za pomocą akcji rake. Zakładamy, że masz już utworzoną strukturę bloga.
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
Następnie utwórz szablon 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>
Ponieważ chcemy wysłać wiadomość e-mail jako osobny proces, utwórzmy zadanie Rake, aby wysłać wiadomość e-mail. Dodaj nowy plik o nazwie email_tasks.rake do katalogu lib / tasks swojej aplikacji Rails:
touch lib/taks/email_tasks.rake desc 'weekly newsletter email' task weekly_newsletter_email: :environment do UserMailer.newsletter_mailer.deliver! end
Środowisko send_digest_email:: oznacza załadowanie środowiska Rails przed uruchomieniem zadania, dzięki czemu można uzyskać dostęp do klas aplikacji (takich jak UserMailer) w ramach zadania.
Teraz uruchomienie polecenia prowizji -T wyświetli listę nowo utworzonego zadania prowizji. Sprawdź, czy wszystko działa, uruchamiając zadanie i sprawdzając, czy wiadomość e-mail została wysłana, czy nie.
Aby sprawdzić, czy metoda mailera działa, uruchom polecenie rake:
rake weekly_newsletter_email
W tym momencie mamy działające zadanie rake, które można zaplanować za pomocą crontab . Zainstalujemy więc aplikację Ever Ever Gem, która służy do zapewnienia jasnej składni do pisania i wdrażania zadań cron.
subl your_project/Gemfile gem 'whenever', require: false
Następnie uruchom następną komendę, aby utworzyć dla Ciebie początkowy plik config / schedule.rb (o ile folder konfiguracji jest już obecny w projekcie).
wheneverize . [add] writing `./config/schedule.rb' [done] wheneverized!
Teraz, w pliku harmonogramu, musimy utworzyć nasz CRON JOB i wywołać metodę mailer wewnątrz określania CRON JOB, aby wykonać niektóre zadania bez pomocy i w wybranym przedziale czasu. Możesz użyć różnych rodzajów składni, jak wyjaśniono w tym linku .
subl your_project/config/schedule.rb every 1.day, :at => '4:30 am' do rake 'weekly_newsletter_email' end
Aby przetestować zadanie Cron zostało pomyślnie utworzone, możemy użyć następnego polecenia do odczytu od terminala, naszego zaplanowanego zadania w 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'
Teraz, aby uruchomić test w środowisku programistycznym, rozsądnie jest ustawić następny wiersz w pliku głównym application.rb , aby aplikacja wiedziała, w jakich modelach będzie używać.
subl your_project/config/application.rb config.action_mailer.default_url_options = { :host => "http://localhost:3000/" }
Teraz, aby umożliwić Capistrano V3 zapisanie nowego zadania Cron wewnątrz serwera i wyzwalacza, który uruchomi wykonanie tego zadania, musimy dodać kolejny wymóg:
subl your_project/Capfile require 'whenever/capistrano'
I wstaw do pliku wdrażania identyfikator, którego CRON JOB będzie używał w odniesieniu do środowiska i nazwę aplikacji .
subl your_project/config/deploy.rb set :whenever_identifier, ->{ "#{fetch(:application)}_#{fetch(:rails_env)}" }
I gotowe, po zapisaniu zmian w każdym pliku, uruchom polecenie wdrażania capistrano:
cap production deploy
A teraz twoja praca została utworzona i kalendarza, aby uruchomić metodę Mailera, która jest tym, czego chcę i w zakresie czasu, który ustalamy na tych plikach.
ActionMailer Interceptor
Action Mailer zapewnia przechwytywanie metod przechwytujących. Umożliwiają one rejestrację klas wywoływanych podczas cyklu życia dostarczania poczty.
Klasa przechwytująca musi implementować metodę: delivering_email (wiadomość), która zostanie wywołana przed wysłaniem wiadomości e-mail, umożliwiając modyfikację wiadomości e-mail, zanim dotrze ona do agentów dostarczających. Twoja klasa powinna wprowadzić wszelkie potrzebne modyfikacje bezpośrednio w przekazanej instancji Mail :: Message.
Programiści mogą wysyłać wiadomości e-mail do siebie, a nie rzeczywistych użytkowników.
Przykład rejestracji przechwytywacza 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