README.md

# Bamboo

Flexible and easy to use email for Elixir.

* **Adapter based** so it can be used with Mandrill, SMTP, or whatever else you want. Comes with a Mandrill adapter out of the box.
* **Easy to format recipients**. You can do `new_email(to: Repo.one(User))` and Bamboo can format the User struct if you implement Bamboo.Formatter.
* **Works out of the box with Phoenix**. Use views and layouts to make rendering email easy.
* **Very composable**. Emails are just a Bamboo.Email struct and be manipulated with plain functions.
* **Easy to unit test**. Because delivery is separated from email creation, no special functions are needed, just assert against fields on the email.
* **Easy to test delivery in integration tests**. As little repeated code as possible.

See the [docs] for the most up to date information.

[docs]: https://hexdocs.pm/bamboo/readme.html

## Adapters

The official Bamboo adapter is for Mandrill, but there are other adapters as well.

The Bamboo.MandrillAdapter **is being used in production and is known to work**.
Refer to the other adapters README's for their status and for installation
instructions.

* Bamboo.MandrillAdapter | [bamboo]
* Bamboo.SendgridAdapter | [bamboo-sendgrid]

[bamboo]: http://github.com/paulcsmith/bamboo
[bamboo-sendgrid]: https://github.com/mtwilliams/bamboo-sendgrid
[create your own adapter]: https://hexdocs.pm/bamboo/Bamboo.Adapter.html

## Basic Usage

Bamboo breaks email creation and email sending into two separate modules. This
is done to make testing easier and to make emails easy to pipe/compose.

```elixir
# In your config/config.exs file
config :my_app, MyApp.Mailer,
  adapter: Bamboo.MandrillAdapter,
  api_key: "my_api_key"

# Somewhere in your application
defmodule MyApp.Mailer do
  use Bamboo.Mailer, otp_app: :my_app
end

# Define your emails
defmodule MyApp.Emails do
  import Bamboo.Email

  def welcome_email do
    new_email(
      to: "foo@example.com",
      from: "me@example.com",
      subject: "Welcome!!!",
      html_body: "<strong>Welcome</strong>",
      text_body: "welcome"
    )
  end
end

# In a controller or some other module
Emails.welcome_email |> Mailer.deliver

# You can also deliver emails in the background with Mailer.deliver_later
Emails.welcome_email |> Mailer.deliver_later
```

## Delivering Emails in the Background

By default delivering later uses `Bamboo.TaskSupervisorStrategy`, but you can
deliver in the background however you want. See [Bamboo.DeliverLaterStrategy].

[Bamboo.DeliverLaterStrategy]: https://hexdocs.pm/bamboo/Bamboo.DeliverLaterStrategy.html

## Composing with Pipes. (Useful for default from address, default layouts, etc.)

```elixir
defmodule MyApp.Emails do
  import Bamboo.Email

  def welcome_email do
    base_email
    |> to("foo@bar.com")
    |> subject("Welcome!!!")
    |> put_header("Reply-To", "someone@example.com")
    |> html_body("<strong>Welcome</strong>")
    |> text_body("Welcome")
  end

  defp base_email do
    # Here you can set a default from, default headers, etc.
    new_email
    |> from("myapp@example.com")
    |> put_html_layout({MyApp.LayoutView, "email.html"})
    |> put_text_layout({MyApp.LayoutView, "text.html"})
  end
end
```

## Handling Recipients

The from, to, cc and bcc addresses can be passed a string, a 2 item tuple or
anything that implements the Bamboo.Formatter protocol. See the [Bamboo.Email docs] for more info and examples.

[Bamboo.Email docs]: https://hexdocs.pm/bamboo/Bamboo.Email.html

## Using Phoenix Views and Layouts

You can use Phoenix views and layouts with Bamboo. See [Bamboo.Phoenix]

[Bamboo.Phoenix]: https://hexdocs.pm/bamboo/Bamboo.Phoenix.html

## Mandrill Specific Functionality (tags, merge vars, etc.)

See [Bamboo.MandrillEmail](https://hexdocs.pm/bamboo/Bamboo.MandrillEmail.html)

## Testing

You can use the `Bamboo.TestAdapter` to make testing your emails a piece of cake.
See documentation for [Bamboo.Test] for more examples.

[Bamboo.Test]: https://hexdocs.pm/bamboo/Bamboo.Test.html

## Installation

To use the latest from master.

  1. Add bamboo to your list of dependencies in `mix.exs`:

    ```elixir
    def deps do
      [{:bamboo, github: "paulcsmith/bamboo"}]
    end
    ```

  2. Ensure bamboo is started before your application:

    ```elixir
    def application do
      [applications: [:bamboo]]
    end
    ```

  3. Add the the Bamboo.TaskSupervior as a child to your supervisor

  ```elixir
  # Usually in lib/my_app_name/my_app_name.ex
  def start(_type, _args) do
    import Supervisor.Spec

    children = [
      # Add the supervisor that handles deliver_later calls
      Bamboo.TaskSupervisorStrategy.child_spec
    ]

    # This part is usually already there.
    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
  ```