{"id":47423,"date":"2014-07-29T17:36:57","date_gmt":"2014-07-29T14:36:57","guid":{"rendered":"https:\/\/www.altoros.com\/blog\/?p=47423"},"modified":"2021-12-10T11:41:00","modified_gmt":"2021-12-10T08:41:00","slug":"email-on-rails","status":"publish","type":"post","link":"https:\/\/www.altoros.com\/blog\/email-on-rails\/","title":{"rendered":"E-mails in Ruby on Rails"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#Sending_an_e-mail\" >Sending an e-mail<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#Receiving_an_e-mail\" >Receiving an e-mail<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#Address_tags\" >Address tags<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#Ruby_on_Rails_Mailman_and_address_tagging\" >Ruby on Rails, Mailman, and address tagging<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#Further_reading\" >Further reading<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#About_the_author\" >About the author<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"Sending_an_e-mail\"><\/span>Sending an e-mail<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/11\/ruby-rails-logo-small.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/11\/ruby-rails-logo-small.jpg\" alt=\"\" width=\"94\" height=\"120\" class=\"alignright size-full wp-image-57920\" \/><\/a><\/p>\n<p>In Ruby on Rails, an e-mail is sent with the use of the <code style=\"color: black; background-color: #e6e6e6;\">ActionMailer::Base<\/code> class. You can check the <a href=\"https:\/\/api.rubyonrails.org\/classes\/ActionMailer\/Base.html\" rel=\"noopener noreferrer\" target=\"_blank\">documentation<\/a> to get more details.<\/p>\n<p>&nbsp;<br \/>\n<b>Configuration<\/b><\/p>\n<p>It appears to be convenient to configure <code style=\"color: black; background-color: #e6e6e6;\">ActionMailer<\/code> in different ways for different environments.<\/p>\n<p>&nbsp;<br \/>\n<b>Development<\/b><\/p>\n<p>A great tool for this environment is the <a href=\"https:\/\/github.com\/ryanb\/letter_opener\" rel=\"noopener noreferrer\" target=\"_blank\">Letter Opener<\/a> gem. It intercepts all outgoing e-mails and opens each e-mail in a separate tab of your default browser instead of sending it right away. This allows you not to worry about sending unwanted e-mails by accident to your real users&#8217; mailboxes, as well as not to bother your customers and testers during development or debugging some mailer. Below is an example of <code style=\"color: black; background-color: #e6e6e6;\">ActionMailer<\/code> config for the development environment.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"c1\"># config\/environments\/development.rb<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">perform_deliveries<\/span> <span class=\"o\">=<\/span> <span class=\"kp\">true<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">raise_delivery_errors<\/span> <span class=\"o\">=<\/span> <span class=\"kp\">true<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">delivery_method<\/span> <span class=\"o\">=<\/span> <span class=\"ss\">:letter_opener<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">default_url_options<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span> <span class=\"ss\">host: <\/span><span class=\"s1\">'localhost:3000'<\/span><span class=\"p\">,<\/span> <span class=\"ss\">protocol: <\/span><span class=\"s1\">'http'<\/span> <span class=\"p\">}<\/span><\/code><\/pre>\n<p>Another option is to use the <a href=\"https:\/\/github.com\/sj26\/mailcatcher\" rel=\"noopener noreferrer\" target=\"_blank\">MailCatcher<\/a> gem, which is also great. However, Letter Opener is just simpler, so I prefer using it.<\/p>\n<p>&nbsp;<br \/>\n<b>Staging<\/b><\/p>\n<p>It\u2019s rather common to have a three-environment infrastructure: development, staging, and production. The staging environment is usually used by testers and\/or customers for testing features to work properly before releasing them to production. In this case, it\u2019s important for a tester to be able to verify that some e-mail is sent successfully and implemented correctly. At the same time, e-mails should not be sent to real users. In this case, <a href=\"https:\/\/github.com\/ryanb\/letter_opener\">Letter Opener<\/a> is not an option. <a href=\"https:\/\/github.com\/sj26\/mailcatcher\">MailCatcher<\/a> would be suitable here, but again, there is a simpler and more convenient option\u2014<a href=\"https:\/\/mailtrap.io\/\" rel=\"noopener noreferrer\" target=\"_blank\">Mailtrap<\/a>. You can register a basic account (which is pretty sufficient in most cases) for free. With this approach, e-mail delivery is actually performed, but to the Mailtrap inbox instead of end users&#8217;. In addition, as expected, Mailtrap provides a web interface to manage sent e-mails. Below is an example of <code style=\"color: black; background-color: #e6e6e6;\">ActionMailer<\/code> config for the staging environment.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"c1\"># config\/environments\/staging.rb<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">perform_deliveries<\/span> <span class=\"o\">=<\/span> <span class=\"kp\">true<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">raise_delivery_errors<\/span> <span class=\"o\">=<\/span> <span class=\"kp\">false<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">delivery_method<\/span> <span class=\"o\">=<\/span> <span class=\"ss\">:smtp<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">smtp_settings<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">user_name: <\/span><span class=\"s1\">'examplecom-staging-g8257th95725e9k1'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">password: <\/span><span class=\"s1\">'mypassword'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">address: <\/span><span class=\"s1\">'mailtrap.io'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">port: <\/span><span class=\"s1\">'2525'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">authentication: :plain<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"p\">}<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">default_url_options<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span> <span class=\"ss\">host: <\/span><span class=\"s1\">'staging.example.com'<\/span><span class=\"p\">,<\/span> <span class=\"ss\">protocol: <\/span><span class=\"s1\">'http'<\/span>  <span class=\"p\">}<\/span><\/code><\/pre>\n<p>&nbsp;<br \/>\n<b>Production<\/b><\/p>\n<p>In this environment, everything is pretty obvious, as you should have <code style=\"color: black; background-color: #e6e6e6;\">ActionMailer<\/code> to be configured for e-mail delivery to real users. The <code style=\"color: black; background-color: #e6e6e6;\">ActionMailer<\/code> config example for the production environment looks like this.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"c1\"># config\/environments\/development.rb<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">perform_deliveries<\/span> <span class=\"o\">=<\/span> <span class=\"kp\">true<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">raise_delivery_errors<\/span> <span class=\"o\">=<\/span> <span class=\"kp\">false<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">delivery_method<\/span> <span class=\"o\">=<\/span> <span class=\"ss\">:smtp<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">smtp_settings<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"ss\">address: <\/span><span class=\"s1\">'mail.example.com'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"ss\">domain: <\/span><span class=\"s1\">'example.com'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"ss\">user_name: <\/span><span class=\"s1\">'myusername'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"ss\">password: <\/span><span class=\"s1\">'mypassword'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"ss\">authentication: :plain<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"ss\">enable_starttls_auto: <\/span><span class=\"kp\">true<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"ss\">port: <\/span><span class=\"mi\">587<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"p\">}<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">default_url_options<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span> <span class=\"ss\">host: <\/span><span class=\"s1\">'example.com'<\/span><span class=\"p\">,<\/span> <span class=\"ss\">protocol: <\/span><span class=\"s1\">'http'<\/span> <span class=\"p\">}<\/span><\/code><\/pre>\n<p>By the way, if anyone uses Gmail for sending an e-mail, below is an example of <a href=\"https:\/\/ru.wikipedia.org\/wiki\/SMTP\" rel=\"noopener noreferrer\" target=\"_blank\">Simple Mail Transfer Protocol<\/a> settings for it.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"n\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">action_mailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">smtp_settings<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">address: <\/span><span class=\"s1\">'smtp.gmail.com'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">domain: <\/span><span class=\"s1\">'example.com'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">user_name: <\/span><span class=\"s1\">'myusername@gmail.com'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">password: <\/span><span class=\"s1\">'mypassword'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">authentication: :plain<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">enable_starttls_auto: <\/span><span class=\"kp\">true<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">port: <\/span><span class=\"mi\">587<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"p\">}<\/span><\/code><\/pre>\n<p>&nbsp;<br \/>\n<b>Mailers<\/b><\/p>\n<p>Instead of inheriting your mailers directly from <code style=\"color: black; background-color: #e6e6e6;\">ActionMailer::Base<\/code>, it is more convenient to create a parent <code style=\"color: black; background-color: #e6e6e6;\">ApplicationMailer<\/code> mailer class where you can configure default mailer properties, such as <code style=\"color: black; background-color: #e6e6e6;\">layout<\/code> and <code style=\"color: black; background-color: #e6e6e6;\">from<\/code>. Later, you can create your mailers inherited from it.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"c1\"># app\/mailers\/application_mailer.rb<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">class<\/span> <span class=\"nc\">ApplicationMailer<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ActionMailer<\/span><span class=\"o\">::<\/span><span class=\"no\">Base<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">layout<\/span> <span class=\"s1\">'application_mailer'<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">default<\/span> <span class=\"ss\">from: <\/span><span class=\"s1\">'postoffice@example.com'<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<p>Having a <code style=\"color: black; background-color: #e6e6e6;\">layout<\/code> provides you with obvious advantages of DRYing your e-mail views (for example, you can easily add a shared header and footer).<\/p>\n<pre><code class=\"language-haml\" data-lang=\"haml\"><span class=\"c\">\/ app\/views\/layouts\/application_mailer.html.haml<br data-jekyll-commonmark-ghpages=\"\"><\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"nt\">%html<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"nt\">%head<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"nt\">%meta<\/span><span class=\"p\">{<\/span><span class=\"s1\">'http-equiv'<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"s2\">\"Content-Type\"<\/span><span class=\"p\">,<\/span> <span class=\"ss\">content: <\/span><span class=\"s2\">\"text\/html; charset=UTF-8\"<\/span><span class=\"p\">}<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"nt\">%body<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"p\">=<\/span> <span class=\"n\">render<\/span> <span class=\"s1\">'shared\/email_header'<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"nt\">%hr<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"p\">=<\/span> <span class=\"k\">yield<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"nt\">%hr<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"p\">=<\/span> <span class=\"n\">render<\/span> <span class=\"s1\">'shared\/email_footer'<\/span><\/code><\/pre>\n<p>&nbsp;<br \/>\n<b>A custom mailer<\/b><\/p>\n<p>So, let\u2019s suppose that your application provides users with a capability to send in-site  messages to each other with an option to send an e-mail to a recipient user, as well (via a checkbox, etc.). For the purpose, a possible simplified <code style=\"color: black; background-color: #e6e6e6;\">create<\/code> action responding to JavaScript format could look something like this.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"c1\"># app\/controllers\/messages_controller.rb<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">class<\/span> <span class=\"nc\">MessagesController<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ApplicationController<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">def<\/span> <span class=\"nf\">create<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"vi\">@recipient<\/span> <span class=\"o\">=<\/span> <span class=\"no\">User<\/span><span class=\"p\">.<\/span><span class=\"nf\">find<\/span><span class=\"p\">(<\/span><span class=\"n\">params<\/span><span class=\"p\">[<\/span><span class=\"ss\">:recipient_id<\/span><span class=\"p\">])<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"vi\">@message<\/span> <span class=\"o\">=<\/span> <span class=\"n\">current_user<\/span><span class=\"p\">.<\/span><span class=\"nf\">messages<\/span><span class=\"p\">.<\/span><span class=\"nf\">build<\/span><span class=\"p\">(<\/span><span class=\"n\">message_params<\/span><span class=\"p\">)<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"k\">if<\/span> <span class=\"vi\">@message<\/span><span class=\"p\">.<\/span><span class=\"nf\">save<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"no\">MessageMailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">new_message<\/span><span class=\"p\">(<\/span><span class=\"vi\">@message<\/span><span class=\"p\">,<\/span> <span class=\"n\">recipient<\/span><span class=\"p\">).<\/span><span class=\"nf\">deliver<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"k\">else<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"c1\"># some error processing<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<p>By the way, for performance and usability reasons, it is better to send e-mails asynchronously, for example, using <a href=\"https:\/\/github.com\/mperham\/sidekiq\">Sidekiq<\/a> gem. In this case, your code would look like this.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"no\">MessageMailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">delay<\/span><span class=\"p\">.<\/span><span class=\"nf\">new_message<\/span><span class=\"p\">(<\/span><span class=\"vi\">@message<\/span><span class=\"p\">,<\/span> <span class=\"n\">recipient<\/span><span class=\"p\">)<\/span><\/code><\/pre>\n<p>Ok, let\u2019s look at our <code style=\"color: black; background-color: #e6e6e6;\">MessageMailer<\/code>.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"c1\"># app\/mailers\/message_mailer.rb<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">class<\/span> <span class=\"nc\">MessageMailer<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ApplicationMailer<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">def<\/span> <span class=\"nf\">new_message<\/span><span class=\"p\">(<\/span><span class=\"n\">message<\/span><span class=\"p\">,<\/span> <span class=\"n\">recipient<\/span><span class=\"p\">)<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"vi\">@message<\/span> <span class=\"o\">=<\/span> <span class=\"n\">message<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"n\">mail<\/span><span class=\"p\">({<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"ss\">subject: <\/span><span class=\"n\">message<\/span><span class=\"p\">.<\/span><span class=\"nf\">subject<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"ss\">to: <\/span><span class=\"n\">recipient<\/span><span class=\"p\">.<\/span><span class=\"nf\">email<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"p\">})<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<p>And we should have a corresponding view.<\/p>\n<pre><code class=\"language-haml\" data-lang=\"haml\"><span class=\"c\">\/ app\/views\/message_mailer\/new_message.html.haml<br data-jekyll-commonmark-ghpages=\"\"><\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"nt\">%h2<\/span><span class=\"p\">=<\/span> <span class=\"vi\">@message<\/span><span class=\"p\">.<\/span><span class=\"nf\">subject<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"nt\">%p<\/span><span class=\"p\">=<\/span> <span class=\"n\">simple_format<\/span> <span class=\"vi\">@message<\/span><span class=\"p\">.<\/span><span class=\"nf\">content<\/span><\/code><\/pre>\n<p>That is all. A basic e-mail should now be sent after invoking the <code style=\"color: black; background-color: #e6e6e6;\">create<\/code> action of <code style=\"color: black; background-color: #e6e6e6;\">MessagesController<\/code>.<\/p>\n<p>&nbsp;<br \/>\n<b>A pretty <code style=\"color: black; background-color: #e6e6e6;\">From<\/code> field<\/b><\/p>\n<p>Let\u2019s modify the <code style=\"color: black; background-color: #e6e6e6;\">From<\/code> field of the e-mail a bit in order to clearly see who has sent you a message when you receive such an e-mail. Let\u2019s also not show an e-mail address of the actual user an e-mail address (let\u2019s assume it is for private reasons), but instead we\u2019ll use the e-mail address that we set as a default one in the <code style=\"color: black; background-color: #e6e6e6;\">ApplicationMailer<\/code> class.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"n\">mail<\/span><span class=\"p\">({<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">from: <\/span><span class=\"s2\">\"<\/span><span class=\"si\">#{<\/span><span class=\"n\">message<\/span><span class=\"p\">.<\/span><span class=\"nf\">author<\/span><span class=\"p\">.<\/span><span class=\"nf\">full_name<\/span><span class=\"si\">}<\/span><span class=\"s2\"> &lt;<\/span><span class=\"si\">#{<\/span><span class=\"n\">default_params<\/span><span class=\"p\">[<\/span><span class=\"ss\">:from<\/span><span class=\"p\">]<\/span><span class=\"si\">}<\/span><span class=\"s2\">&gt;\"<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">subject: <\/span><span class=\"n\">message<\/span><span class=\"p\">.<\/span><span class=\"nf\">subject<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">to: <\/span><span class=\"n\">recipient<\/span><span class=\"p\">.<\/span><span class=\"nf\">email<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"p\">})<\/span><\/code><\/pre>\n<p>Assuming a message was sent by John Doe. Gmail will show the email was sent as from \u201cJohn Doe.\u201d Most e-mail clients, however, will show it as from \u201cJohn Doe &lt;postoffice@example.com&gt;.\u201d I think it looks much better than just from \u201cpostoffice@example.com.\u201d Besides, it allows you to search for e-mails based on the actual sender.<\/p>\n<p><b>Attachments<\/b><\/p>\n<p>Suppose that we want to send some file attachments along with an e-mail. As file uploads are out of the scope of this blog post, let\u2019s just assume that we have the following models.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">class<\/span> <span class=\"nc\">Message<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ActiveRecord<\/span><span class=\"o\">::<\/span><span class=\"no\">Base<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"no\">MAX_ATTACHMENTS_TOTAL_SIZE<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">20<\/span> <span class=\"o\">*<\/span> <span class=\"mi\">1024<\/span> <span class=\"o\">*<\/span> <span class=\"mi\">1024<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">has_many<\/span> <span class=\"ss\">:content_files<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">belongs_to<\/span> <span class=\"ss\">:author<\/span><span class=\"p\">,<\/span> <span class=\"ss\">class_name: <\/span><span class=\"s1\">'User'<\/span><span class=\"p\">,<\/span> <span class=\"ss\">foreign_key: <\/span><span class=\"s1\">'created_by'<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">class<\/span> <span class=\"nc\">ContentFile<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ActiveRecord<\/span><span class=\"o\">::<\/span><span class=\"no\">Base<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">mount_uploader<\/span> <span class=\"ss\">:attachment<\/span><span class=\"p\">,<\/span> <span class=\"no\">ContentFileUploader<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">belongs_to<\/span> <span class=\"ss\">:message<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<p>In the example above, the <code style=\"color: black; background-color: #e6e6e6;\">ContentFile<\/code> model has a mounted <code style=\"color: black; background-color: #e6e6e6;\">:attachment<\/code>\u2014the <a href=\"https:\/\/github.com\/carrierwaveuploader\/carrierwave\">CarrierWave<\/a> uploader (yep, I prefer to use <a href=\"https:\/\/github.com\/carrierwaveuploader\/carrierwave\">CarrierWave<\/a> for file uploads).<\/p>\n<p>You should also keep in mind that you can\u2019t send an arbitrary amount of data in attachments, as it\u2019s most likely that e-mail size will be limited at the destination mail server. For example, the current Gmail total limit of e-mail size limit (including body and attachments) is equal to 25 MB. So, we should process attachments somehow taking into account their size. There are plenty of options that you could implement, including blocking messages with attachment size overlimit from being sent at all. To my mind, though, a better solution is to send just as much data as possible, and if there are attachments that were not sent then explicitly, tell about it to the recipient user and invite him to see an original message at your website. Code responsible for this could be as follows.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">class<\/span> <span class=\"nc\">MessageMailer<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ApplicationMailer<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">def<\/span> <span class=\"nf\">new_message<\/span><span class=\"p\">(<\/span><span class=\"n\">message<\/span><span class=\"p\">,<\/span> <span class=\"n\">recipient<\/span><span class=\"p\">)<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"vi\">@message<\/span> <span class=\"o\">=<\/span> <span class=\"n\">message<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"n\">total_attachments_size<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"n\">message<\/span><span class=\"p\">.<\/span><span class=\"nf\">content_files<\/span><span class=\"p\">.<\/span><span class=\"nf\">each<\/span> <span class=\"k\">do<\/span> <span class=\"o\">|<\/span><span class=\"n\">content_file<\/span><span class=\"o\">|<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"k\">next<\/span> <span class=\"k\">if<\/span> <span class=\"n\">total_attachments_size<\/span> <span class=\"o\">+<\/span> <span class=\"n\">content_file<\/span><span class=\"p\">.<\/span><span class=\"nf\">filesize<\/span> <span class=\"o\">&gt;=<\/span> <span class=\"no\">Message<\/span><span class=\"o\">::<\/span><span class=\"no\">MAX_ATTACHMENTS_TOTAL_SIZE<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"n\">attachments<\/span><span class=\"p\">[<\/span><span class=\"n\">content_file<\/span><span class=\"p\">.<\/span><span class=\"nf\">title<\/span><span class=\"p\">]<\/span> <span class=\"o\">=<\/span> <span class=\"no\">File<\/span><span class=\"p\">.<\/span><span class=\"nf\">read<\/span><span class=\"p\">(<\/span><span class=\"n\">content_file<\/span><span class=\"p\">.<\/span><span class=\"nf\">attachment<\/span><span class=\"p\">.<\/span><span class=\"nf\">file<\/span><span class=\"p\">.<\/span><span class=\"nf\">path<\/span><span class=\"p\">)<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"n\">total_attachments_size<\/span> <span class=\"o\">+=<\/span> <span class=\"n\">content_file<\/span><span class=\"p\">.<\/span><span class=\"nf\">filesize<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"n\">mail<\/span><span class=\"p\">({<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"ss\">from: <\/span><span class=\"s2\">\"<\/span><span class=\"si\">#{<\/span><span class=\"n\">message<\/span><span class=\"p\">.<\/span><span class=\"nf\">author<\/span><span class=\"p\">.<\/span><span class=\"nf\">full_name<\/span><span class=\"si\">}<\/span><span class=\"s2\"> &lt;<\/span><span class=\"si\">#{<\/span><span class=\"n\">default_params<\/span><span class=\"p\">[<\/span><span class=\"ss\">:from<\/span><span class=\"p\">]<\/span><span class=\"si\">}<\/span><span class=\"s2\">&gt;\"<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"ss\">subject: <\/span><span class=\"n\">message<\/span><span class=\"p\">.<\/span><span class=\"nf\">subject<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"ss\">to: <\/span><span class=\"n\">recipient<\/span><span class=\"p\">.<\/span><span class=\"nf\">email<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"p\">})<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<p>The algorithm above, of course, is not the most perfect one and can be improved in many ways, depending on your needs. This implementation tries to create attachments based on first uploaded files first, assuming that they are the most important. Then it tries to add as many files as possible up to the provided limit, skipping large files causing overlimit.<\/p>\n<p>As for <code style=\"color: black; background-color: #e6e6e6;\">content_file.filesize<\/code>, I usually store filesize in a database for faster access to it and to avoid additional disk operations.<\/p>\n<p>Great! Now, we can send e-mails with attachments. Next, let\u2019s see how to receive an e-mail in Ruby on Rails.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Receiving_an_e-mail\"><\/span>Receiving an e-mail<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Without any doubts, it would be very useful to not only send e-mails but also receive them and process in the context of your Ruby on Rails application. The most common solution for this task is to use the <a href=\"https:\/\/github.com\/mailman\/mailman\">Mailman<\/a> gem. Setting up Mailman is pretty simple. Let\u2019s see how to configure it to fetch an e-mail from a Gmail account. First, add it to your <code style=\"color: black; background-color: #e6e6e6;\">Gemfile<\/code><\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"n\">gem<\/span> <span class=\"s1\">'mailman'<\/span><span class=\"p\">,<\/span> <span class=\"ss\">require: <\/span><span class=\"kp\">false<\/span><\/code><\/pre>\n<p>and run <code style=\"color: black; background-color: #e6e6e6;\">bundle install<\/code>. Next, let\u2019s create a file that we will use to run Mailman as a background process.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"c1\"># script\/mailman_daemon<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"c1\">#!\/usr\/bin\/env ruby<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"nb\">require<\/span> <span class=\"s1\">'daemons'<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"no\">Daemons<\/span><span class=\"p\">.<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"s1\">'script\/mailman_server'<\/span><span class=\"p\">)<\/span><\/code><\/pre>\n<p>We will be able to run it almost as a standard UNIX daemon.<\/p>\n<pre><code class=\"language-bash\" data-lang=\"bash\">bundle <span class=\"nb\">exec <\/span>script\/mailman_daemon start|stop|restart|status<\/code><\/pre>\n<p>Next, let\u2019s create the actual Mailman server script. Below is an example of how it could look like.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"c1\">#!\/usr\/bin\/env ruby<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"nb\">require<\/span> <span class=\"s2\">\"mailman\"<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"no\">Mailman<\/span><span class=\"p\">.<\/span><span class=\"nf\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">logger<\/span> <span class=\"o\">=<\/span> <span class=\"no\">Logger<\/span><span class=\"p\">.<\/span><span class=\"nf\">new<\/span><span class=\"p\">(<\/span><span class=\"no\">File<\/span><span class=\"p\">.<\/span><span class=\"nf\">expand_path<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"..\/..\/log\/mailman.log\"<\/span><span class=\"p\">,<\/span> <span class=\"kp\">__FILE__<\/span><span class=\"p\">))<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"no\">Mailman<\/span><span class=\"p\">.<\/span><span class=\"nf\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">poll_interval<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">60<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"no\">Mailman<\/span><span class=\"p\">.<\/span><span class=\"nf\">config<\/span><span class=\"p\">.<\/span><span class=\"nf\">pop3<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">server: <\/span><span class=\"s1\">'pop.gmail.com'<\/span><span class=\"p\">,<\/span> <span class=\"ss\">port: <\/span><span class=\"mi\">995<\/span><span class=\"p\">,<\/span> <span class=\"ss\">ssl: <\/span><span class=\"kp\">true<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">username: <\/span><span class=\"s1\">'myemail@gmail.com'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"ss\">password: <\/span><span class=\"s1\">'mypassword'<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"p\">}<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"no\">Mailman<\/span><span class=\"o\">::<\/span><span class=\"no\">Application<\/span><span class=\"p\">.<\/span><span class=\"nf\">run<\/span> <span class=\"k\">do<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">to<\/span> <span class=\"s1\">'%folder%@example.com'<\/span> <span class=\"k\">do<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"c1\"># at this point we have \"message\" and \"params\" methods available<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"c1\"># so you can check fetched message and params. Everything before the \"@\" character<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"c1\"># will be available as params[:folder]<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"no\">Mailman<\/span><span class=\"p\">.<\/span><span class=\"nf\">logger<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span> <span class=\"n\">message<\/span><span class=\"p\">.<\/span><span class=\"nf\">inspect<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"no\">Mailman<\/span><span class=\"p\">.<\/span><span class=\"nf\">logger<\/span><span class=\"p\">.<\/span><span class=\"nf\">info<\/span> <span class=\"n\">params<\/span><span class=\"p\">.<\/span><span class=\"nf\">inspect<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">default<\/span> <span class=\"k\">do<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"c1\"># this is a catch-all route<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<p>We configured Mailman to get an e-mail from a Gmail account via the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Post_Office_Protocol\" rel=\"noopener noreferrer\" target=\"_blank\">Post Office Protocol<\/a> once in a minute. Within the <code style=\"color: black; background-color: #e6e6e6;\">Mailman::Application.run<\/code> block, we define rules to determine how to process an e-mail in a way very similar to the Ruby on Rails router approach\u2014you define routes one by one, and the first suitable route\u2019s block will be executed. Pretty simple, isn\u2019t it? Great! Now, you can both send and receive e-mail in Ruby on Rails.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Address_tags\"><\/span>Address tags<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Another very important and useful technique anyone should be familiar with is address tagging, which is sometimes referenced as sub-addressing (e.g., in <a href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc5233#section-1\" rel=\"noopener noreferrer\" target=\"_blank\">RFC 5233<\/a>). The point of this technique is that you can provide some additional info when you send an e-mail right in an email address after a certain separator (usually the <code style=\"color: black; background-color: #e6e6e6;\">+<\/code> character) this way: <code style=\"color: black; background-color: #e6e6e6;\">me+tag1-tag2@example.com<\/code>. All e-mails sent to this address will be actually delivered to the <code style=\"color: black; background-color: #e6e6e6;\">me@example.com<\/code> address.<\/p>\n<p>One of the most well-known use cases of this technique is to determine web sites whose database was stolen (or sold, who knows). So, imagine that you have an e-mail address <code style=\"color: black; background-color: #e6e6e6;\">johndoe@example.com<\/code>, and you want to register at some web site <code style=\"color: black; background-color: #e6e6e6;\">www.awesomesite.com<\/code>. During registration, provide your e-mail as <code style=\"color: black; background-color: #e6e6e6;\">johndoe+www.awesomesite.com@example.com<\/code>. If after some period of time you start receiving magic pills advertising e-mails with the <code style=\"color: black; background-color: #e6e6e6;\">To<\/code> header field equal to <code style=\"color: black; background-color: #e6e6e6;\">johndoe+www.awesomesite.com@example.com<\/code>, then it\u2019s pretty obvious where those spammers got your e-mail. Sometimes web sites can have e-mail validation rules that will reject your e-mail address containing <code style=\"color: black; background-color: #e6e6e6;\">+<\/code> or some other characters.<\/p>\n<p>You should also keep in mind that this technique can\u2019t be used in some cases, because not all mail servers support it or have it enabled by default (e.g., Gmail supports it). So, if you\u2019re setting up your own mail server, then you should better check the documentation to be sure.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Ruby_on_Rails_Mailman_and_address_tagging\"><\/span>Ruby on Rails, Mailman, and address tagging<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>A very interesting functionality can be achieved by combining the Ruby on Rails, Mailman, and address tagging techniques. Imagine you have a website where users can send messages to each other, and you also automatically send a copy of a message by e-mail (or users can manually choose to send a copy to email)\u2014a pretty standard feature. It would be great if a recipient user could reply to your e-mail right in his\/her e-mail client. Let\u2019s see how we can do it. Further, I provide a pseudo-code that can lack some details, but is sufficient to get the idea.<\/p>\n<p>Let\u2019s suppose we have following models.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">class<\/span> <span class=\"nc\">User<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ActiveRecord<\/span><span class=\"o\">::<\/span><span class=\"no\">Base<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">class<\/span> <span class=\"nc\">MessageDelivery<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ActiveRecord<\/span><span class=\"o\">::<\/span><span class=\"no\">Base<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">belongs_to<\/span> <span class=\"ss\">:recipient<\/span><span class=\"p\">,<\/span> <span class=\"ss\">class_name: <\/span><span class=\"s2\">\"User\"<\/span><span class=\"p\">,<\/span> <span class=\"ss\">foreign_key: <\/span><span class=\"s2\">\"recipient_id\"<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">belongs_to<\/span> <span class=\"ss\">:message<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">class<\/span> <span class=\"nc\">Message<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ActiveRecord<\/span><span class=\"o\">::<\/span><span class=\"no\">Base<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">belongs_to<\/span> <span class=\"ss\">:author<\/span><span class=\"p\">,<\/span> <span class=\"ss\">class_name: <\/span><span class=\"s2\">\"User\"<\/span><span class=\"p\">,<\/span> <span class=\"ss\">foreign_key: <\/span><span class=\"s2\">\"author_id\"<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">has_many<\/span> <span class=\"ss\">:message_deliveries<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">has_many<\/span> <span class=\"ss\">:recipients<\/span><span class=\"p\">,<\/span> <span class=\"ss\">through: :message_deliveries<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<p>The <code style=\"color: black; background-color: #e6e6e6;\">MessagesController<\/code> controller with the <code style=\"color: black; background-color: #e6e6e6;\">create<\/code> action responsible for sending messages looks like this.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">class<\/span> <span class=\"nc\">MessagesController<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ApplicationController<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">def<\/span> <span class=\"nf\">create<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"vi\">@message<\/span> <span class=\"o\">=<\/span> <span class=\"no\">Message<\/span><span class=\"p\">.<\/span><span class=\"nf\">new<\/span><span class=\"p\">(<\/span><span class=\"n\">message_params<\/span><span class=\"p\">)<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"k\">if<\/span> <span class=\"vi\">@message<\/span><span class=\"p\">.<\/span><span class=\"nf\">save<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"vi\">@message<\/span><span class=\"p\">.<\/span><span class=\"nf\">recipients<\/span><span class=\"p\">.<\/span><span class=\"nf\">each<\/span> <span class=\"k\">do<\/span> <span class=\"o\">|<\/span><span class=\"n\">recipient<\/span><span class=\"o\">|<\/span><br data-jekyll-commonmark-ghpages=\"\">        <span class=\"c1\"># as I mentioned previously it's strongly recommended to process email sending in background<\/span><br data-jekyll-commonmark-ghpages=\"\">        <span class=\"no\">MessageMailer<\/span><span class=\"p\">.<\/span><span class=\"nf\">delay<\/span><span class=\"p\">.<\/span><span class=\"nf\">email_copy<\/span><span class=\"p\">(<\/span><span class=\"vi\">@message<\/span><span class=\"p\">,<\/span> <span class=\"n\">recipient<\/span><span class=\"p\">)<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"k\">else<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"c1\"># some error processing<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<p>Our mailer class, <code style=\"color: black; background-color: #e6e6e6;\">MessageMailer<\/code>, could look like this.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">class<\/span> <span class=\"nc\">ApplicationMailer<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ActionMailer<\/span><span class=\"o\">::<\/span><span class=\"no\">Base<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">layout<\/span> <span class=\"s1\">'application_mailer'<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">default<\/span> <span class=\"ss\">from: <\/span><span class=\"s1\">'postoffice@example.com'<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"k\">class<\/span> <span class=\"nc\">MessageMailer<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">ApplicationMailer<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">def<\/span> <span class=\"nf\">email_copy<\/span><span class=\"p\">(<\/span><span class=\"n\">message<\/span><span class=\"p\">,<\/span> <span class=\"n\">recipient<\/span><span class=\"p\">,<\/span> <span class=\"n\">options<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{})<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"vi\">@message<\/span> <span class=\"o\">=<\/span> <span class=\"n\">message<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"n\">mail<\/span><span class=\"p\">({<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"ss\">from: <\/span><span class=\"s2\">\"<\/span><span class=\"si\">#{<\/span><span class=\"n\">message<\/span><span class=\"p\">.<\/span><span class=\"nf\">author<\/span><span class=\"p\">.<\/span><span class=\"nf\">full_name<\/span><span class=\"si\">}<\/span><span class=\"s2\"> &lt;<\/span><span class=\"si\">#{<\/span><span class=\"n\">default_params<\/span><span class=\"p\">[<\/span><span class=\"ss\">:from<\/span><span class=\"p\">]<\/span><span class=\"si\">}<\/span><span class=\"s2\">&gt;\"<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"ss\">subject: <\/span><span class=\"s2\">\"New message\"<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"ss\">to: <\/span><span class=\"n\">recipient<\/span><span class=\"p\">.<\/span><span class=\"nf\">email<\/span><span class=\"p\">,<\/span><br data-jekyll-commonmark-ghpages=\"\">      <span class=\"ss\">reply_to: <\/span><span class=\"n\">default_params<\/span><span class=\"p\">[<\/span><span class=\"ss\">:from<\/span><span class=\"p\">].<\/span><span class=\"nf\">gsub<\/span><span class=\"p\">(<\/span><span class=\"s1\">'@'<\/span><span class=\"p\">,<\/span> <span class=\"s2\">\"+f-<\/span><span class=\"si\">#{<\/span><span class=\"n\">recipient<\/span><span class=\"p\">.<\/span><span class=\"nf\">uuid<\/span><span class=\"si\">}<\/span><span class=\"s2\">-t-<\/span><span class=\"si\">#{<\/span><span class=\"vi\">@message<\/span><span class=\"p\">.<\/span><span class=\"nf\">author<\/span><span class=\"p\">.<\/span><span class=\"nf\">uuid<\/span><span class=\"si\">}<\/span><span class=\"s2\">-m-<\/span><span class=\"si\">#{<\/span><span class=\"vi\">@message<\/span><span class=\"p\">.<\/span><span class=\"nf\">uuid<\/span><span class=\"si\">}<\/span><span class=\"s2\">@\"<\/span><span class=\"p\">),<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"p\">})<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\"><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<p>In the example above, I set the <code style=\"color: black; background-color: #e6e6e6;\">Reply-to<\/code> field to contain our default <code style=\"color: black; background-color: #e6e6e6;\">From<\/code> e-mail address with addition of some useful information, using address tagging. What it gives is that a user will still receive e-mails from the <code style=\"color: black; background-color: #e6e6e6;\">postoffice@example.com<\/code> address.  When a user hits \u201cReply\u201d in his email client, however, than the <code style=\"color: black; background-color: #e6e6e6;\">To<\/code> e-mail address will be equal to the one we passed in the <code style=\"color: black; background-color: #e6e6e6;\">Reply-to<\/code> field. Of course, we make an assumption that a user will not change it (I think that in most cases he\/she will not indeed.)<\/p>\n<p>To my mind, it\u2019s better to send some hashed values rather than just plain ids, as the system will be more resistant to fraud actions in this case. It\u2019s also better to use one-time hashes and expire them after a message is received.<\/p>\n<p>The Mailman route for catching such e-mails can look like this.<\/p>\n<pre><code class=\"language-ruby\" data-lang=\"ruby\"><span class=\"no\">Mailman<\/span><span class=\"o\">::<\/span><span class=\"no\">Application<\/span><span class=\"p\">.<\/span><span class=\"nf\">run<\/span> <span class=\"k\">do<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"n\">to<\/span> <span class=\"s1\">'f-%from_uuid%-t-%to_uuid%-m-%message_uuid%@'<\/span> <span class=\"k\">do<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"c1\"># here you can load all records that you need<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"n\">from_user<\/span> <span class=\"o\">=<\/span> <span class=\"no\">User<\/span><span class=\"p\">.<\/span><span class=\"nf\">find_by_uuid<\/span><span class=\"p\">(<\/span><span class=\"n\">params<\/span><span class=\"p\">[<\/span><span class=\"ss\">:from_uuid<\/span><span class=\"p\">])<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"n\">to_user<\/span> <span class=\"o\">=<\/span> <span class=\"no\">User<\/span><span class=\"p\">.<\/span><span class=\"nf\">find_by_uuid<\/span><span class=\"p\">(<\/span><span class=\"n\">params<\/span><span class=\"p\">[<\/span><span class=\"ss\">:to_uuid<\/span><span class=\"p\">])<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"n\">original_message<\/span> <span class=\"o\">=<\/span> <span class=\"no\">Message<\/span><span class=\"p\">.<\/span><span class=\"nf\">find_by_uuid<\/span><span class=\"p\">(<\/span><span class=\"n\">params<\/span><span class=\"p\">[<\/span><span class=\"ss\">:message_uuid<\/span><span class=\"p\">])<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"c1\"># and perform some processing<\/span><br data-jekyll-commonmark-ghpages=\"\">    <span class=\"c1\"># remember that at this point you have access to a Mailman \"message\" method which returns Mailman message object - you can get all details of the incoming email from it<\/span><br data-jekyll-commonmark-ghpages=\"\">  <span class=\"k\">end<\/span><br data-jekyll-commonmark-ghpages=\"\"><span class=\"k\">end<\/span><\/code><\/pre>\n<p>In Mailman, you can create a new reply-message and also send its copy by e-mail. This way, you\u2019ll implement such a system where users can exchange messages with each other directly from their e-mail clients, and in the meantime, there will be created messages on your web site.<\/p>\n<p>As a bonus, you\u2019ll get the capability to collect user\u2019s alternative e-mails. Some users can have e-mail forwarding enabled in their mailboxes, so the actual reply can come from an e-mail address that is not present in your database. It allows you to implement user sign-in based on an alternative e-mail apart from the one that a user provided during a registration.<\/p>\n<p>You should also notice that if you have to put some users in the <code style=\"color: black; background-color: #e6e6e6;\">CC<\/code> or <code style=\"color: black; background-color: #e6e6e6;\">BCC<\/code> fields, you will not be able to recognize a user who utilized an alternative e-mail to reply to your message. It will happen, because you will be able only to put author\u2019s universally unique identifier (uuid) to the e-mail <code style=\"color: black; background-color: #e6e6e6;\">Reply-to <\/code>address, while putting recipient\u2019s uuid will not be possible due to a lot of <code style=\"color: black; background-color: #e6e6e6;\">CC<\/code> recipients, which will not make sense. So, when a user will employ an alternative e-mail, you will just not have it in the database. In this case, you\u2019ll have to determine who sent a reply message only based on the \u201cFrom\u201d field of the incoming e-mail.<\/p>\n<p>Ok, at this point I stop. I hope this post was useful to you. Thanks for reading!<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Further_reading\"><\/span>Further reading<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/love-ruby\/\">Love Ruby on Rails<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/performance-comparison-of-ruby-frameworks-app-servers-template-engines-and-orms-2016\/\">Performance Comparison of Ruby Frameworks 2016<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/simple-fast-application-sinatra-espresso-padrino-goliath-rails\/\">A Simple and a Fast App: Sinatra, Espresso, Padrino, Goliath, and Ruby on Rails<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"About_the_author\"><\/span>About the author<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/07\/Anton-Trushkevich.png\" width=\"110\" class=\"alignright size-thumbnail wp-image-64162\" \/><\/p>\n<p><small><a href=\"https:\/\/www.linkedin.com\/in\/anton-trushkevich-380b5465\/\" rel=\"noopener noreferrer\" target=\"_blank\">Anton Trushkevich<\/a> is a highly skilled Ruby developer with more than 9 years of experience. Find him on <a href=\"https:\/\/github.com\/trushkevich\" rel=\"noopener noreferrer\" target=\"_blank\">GitHub<\/a>.<\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Different aspects of work with email in Ruby on Rails<\/p>\n","protected":false},"author":34,"featured_media":57959,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":"","_links_to":"","_links_to_target":""},"categories":[214],"tags":[1000,895],"class_list":["post-47423","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-github","tag-research-and-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>E-mails in Ruby on Rails | Altoros<\/title>\n<meta name=\"description\" content=\"This blog post explores different scenarios of working with e-mails in Ruby on Rails: sending and receiving an e-mail, as well as using address tagging.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.altoros.com\/blog\/email-on-rails\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"E-mails in Ruby on Rails | Altoros\" \/>\n<meta property=\"og:description\" content=\"Different aspects of work with email in Ruby on Rails\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.altoros.com\/blog\/email-on-rails\/\" \/>\n<meta property=\"og:site_name\" content=\"Altoros\" \/>\n<meta property=\"article:published_time\" content=\"2014-07-29T14:36:57+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-12-10T08:41:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/07\/e-mails-in-ruby-on-rails-featured-image.gif\" \/>\n\t<meta property=\"og:image:width\" content=\"1025\" \/>\n\t<meta property=\"og:image:height\" content=\"433\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/gif\" \/>\n<meta name=\"author\" content=\"Alena Vasilenko\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alena Vasilenko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.altoros.com\/blog\/email-on-rails\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/email-on-rails\/\",\"name\":\"E-mails in Ruby on Rails | Altoros\",\"isPartOf\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/07\/e-mails-in-ruby-on-rails-featured-image.gif\",\"datePublished\":\"2014-07-29T14:36:57+00:00\",\"dateModified\":\"2021-12-10T08:41:00+00:00\",\"author\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/019e8147b835bc8f1b4abd8a4fa42c7f\"},\"description\":\"Different aspects of work with email in Ruby on Rails\",\"breadcrumb\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.altoros.com\/blog\/email-on-rails\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#primaryimage\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/07\/e-mails-in-ruby-on-rails-featured-image.gif\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/07\/e-mails-in-ruby-on-rails-featured-image.gif\",\"width\":1025,\"height\":433},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.altoros.com\/blog\/email-on-rails\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.altoros.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"E-mails in Ruby on Rails\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\",\"url\":\"https:\/\/www.altoros.com\/blog\/\",\"name\":\"Altoros\",\"description\":\"Insight\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.altoros.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/019e8147b835bc8f1b4abd8a4fa42c7f\",\"name\":\"Alena Vasilenko\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2019\/06\/alena-vasilenko-author-e1561752194994-96x96.jpg\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2019\/06\/alena-vasilenko-author-e1561752194994-96x96.jpg\",\"caption\":\"Alena Vasilenko\"},\"description\":\"Alena Vasilenko is Communications Manager at Altoros. She has proven track record of supporting R&amp;D engineers in their research activities on such topics as big data and cloud computing, translating the research results into easy-to-understand stories.\",\"url\":\"https:\/\/www.altoros.com\/blog\/author\/alena-vasilenko\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"E-mails in Ruby on Rails | Altoros","description":"This blog post explores different scenarios of working with e-mails in Ruby on Rails: sending and receiving an e-mail, as well as using address tagging.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.altoros.com\/blog\/email-on-rails\/","og_locale":"en_US","og_type":"article","og_title":"E-mails in Ruby on Rails | Altoros","og_description":"Different aspects of work with email in Ruby on Rails","og_url":"https:\/\/www.altoros.com\/blog\/email-on-rails\/","og_site_name":"Altoros","article_published_time":"2014-07-29T14:36:57+00:00","article_modified_time":"2021-12-10T08:41:00+00:00","og_image":[{"width":1025,"height":433,"url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/07\/e-mails-in-ruby-on-rails-featured-image.gif","type":"image\/gif"}],"author":"Alena Vasilenko","twitter_misc":{"Written by":"Alena Vasilenko","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.altoros.com\/blog\/email-on-rails\/","url":"https:\/\/www.altoros.com\/blog\/email-on-rails\/","name":"E-mails in Ruby on Rails | Altoros","isPartOf":{"@id":"https:\/\/www.altoros.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.altoros.com\/blog\/email-on-rails\/#primaryimage"},"image":{"@id":"https:\/\/www.altoros.com\/blog\/email-on-rails\/#primaryimage"},"thumbnailUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/07\/e-mails-in-ruby-on-rails-featured-image.gif","datePublished":"2014-07-29T14:36:57+00:00","dateModified":"2021-12-10T08:41:00+00:00","author":{"@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/019e8147b835bc8f1b4abd8a4fa42c7f"},"description":"Different aspects of work with email in Ruby on Rails","breadcrumb":{"@id":"https:\/\/www.altoros.com\/blog\/email-on-rails\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.altoros.com\/blog\/email-on-rails\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/email-on-rails\/#primaryimage","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/07\/e-mails-in-ruby-on-rails-featured-image.gif","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2014\/07\/e-mails-in-ruby-on-rails-featured-image.gif","width":1025,"height":433},{"@type":"BreadcrumbList","@id":"https:\/\/www.altoros.com\/blog\/email-on-rails\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.altoros.com\/blog\/"},{"@type":"ListItem","position":2,"name":"E-mails in Ruby on Rails"}]},{"@type":"WebSite","@id":"https:\/\/www.altoros.com\/blog\/#website","url":"https:\/\/www.altoros.com\/blog\/","name":"Altoros","description":"Insight","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.altoros.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/019e8147b835bc8f1b4abd8a4fa42c7f","name":"Alena Vasilenko","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2019\/06\/alena-vasilenko-author-e1561752194994-96x96.jpg","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2019\/06\/alena-vasilenko-author-e1561752194994-96x96.jpg","caption":"Alena Vasilenko"},"description":"Alena Vasilenko is Communications Manager at Altoros. She has proven track record of supporting R&amp;D engineers in their research activities on such topics as big data and cloud computing, translating the research results into easy-to-understand stories.","url":"https:\/\/www.altoros.com\/blog\/author\/alena-vasilenko\/"}]}},"_links":{"self":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47423","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/users\/34"}],"replies":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/comments?post=47423"}],"version-history":[{"count":26,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47423\/revisions"}],"predecessor-version":[{"id":65350,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47423\/revisions\/65350"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media\/57959"}],"wp:attachment":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media?parent=47423"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/categories?post=47423"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/tags?post=47423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}