Sending scheduled or automated emails from your application is a very common problem with a number of solutions. In this write-up I am going to demonstrate one particularly easy approach to adding email functionality to your Phoenix App. Phoenix is a web framework written in Elixir that is enjoying a meteoric rise in popularity recently. Many people are jumping onto the Phoenix bandwagon for its explicit, non-magical and functional approach to development.
For this demonstration, I am going to use an external library that integrates Mailgun into my Phoenix application. Phoenix includes the Elixir configuration file mix.exs
which we will use to add our new dependency. We will add {:mailgun, "~> 0.1.1"}
to the list of "deps" our project is currently using.
defp deps do
[{:phoenix, "~> 0.13"},
{:phoenix_html, "~> 1.0"},
{:phoenix_ecto, "~> 0.3"},
{:postgrex, ">= 0.0.0"},
{:phoenix_live_reload, "~> 0.4"},
{:cowboy, "~> 1.0"},
{:mailgun, "~> 0.1.1"}]
end
Running mix deps.get
from our terminal will pull in all required files for including our new Mailgun library dependency.
$ mix deps.get
Running dependency resolution
Dependency resolution completed successfully
mailgun: v0.1.1
* Getting mailgun (Hex package)
Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/mailgun-0.1.1.tar)
Using locally cached package
Unpacked package tarball (/Users/david/.hex/packages/mailgun-0.1.1.tar)
Now we need to setup our Mailgun configuration in config/config.exs
. First, however, you will need to jump over to http://mailgun.com and sign up for a free sandbox account. Once you are logged in, you will want to add your first domain (under the Domains tab in the top navigation). Once created, you can click on this new domain to view the API Base URL
and API Key
. We will need to add both of these values to our config file. In your config.exs
add the following information:
config :my_app, mailgun_domain: "YOUR_MAILGUN_DOMAIN",
mailgun_key: System.get_env("MAILGUN_API_KEY")
Next we need to create a Mailer module to use throughout our application. In your lib
directory, create a new file named mailer.ex
(not required - just my preference). Within that new file you will need to define our new Mailer module and reference our Mailgun Client and configuration information.
defmodule MyApp.Mailer do
use Mailgun.Client, domain: Application.get_env(:my_app, :mailgun_domain),
key: Application.get_env(:my_app, :mailgun_key)
end
I generally add a module attribute specifying the from address of my emails within the Mailer module.
@from "[email protected]"
Finally, I add simple functions to handle the html and text versions of my application specific emails.
def send_welcome_text_email(email) do
send_email to: email,
from: @from,
subject: "Welcome!",
text: "Welcome to MyApp!"
end
def send_welcome_html_email(email) do
send_email to: email,
from: @from,
subject: "Welcome!",
text: "<strong>Welcome to MyApp</strong>"
end
Once I have my email functions complete, I ready to send emails throughout my Phoenix app.
MyApp.Mailer.send_welcome_html_email(user.email)
Should you want or need to send attachments along with your email it is equally simple. All we need to do is add an attachments
key to our email and provide it with a list of maps that respond to path
and filename
. And thats it! The Mailgun library we are using handles reading the actual file so long as we give it a valid path.
def send_welcome_html_email(email) do
send_email to: email,
from: @from,
subject: "Welcome!",
text: "<strong>Welcome to MyApp</strong>",
attachments: [%{path: "priv/my_file.csv", filename: "my_file.csv"}]
end
You will most likely want to write your markup for an HTML email outside of the Mailer module. This is extremely easy to accomplish. You will want to update the text
of your email to point at an external view. This would look like:
text: Phoenix.View.render_to_string(MyApp.EmailView, "welcome.html", some_var: some_var),
Congratulations. You can now send emails throughout your Phoenix application. For more information please check out the following sources:
Cheers!
David