Home

Awesome

Bamboo.ConfigAdapter

In some cooperate environments sending emails isn't simply picking a server and sending it to that server. Sometimes different emails require different types of configurations that are only known at runtime. Does this sound like your problem? This may seem convoluted, but this happens and Bamboo.ConfigAdapter is here to help.

Installation

bamboo_config_adapter can be installed by adding bamboo_config_adapter to your list of dependencies in mix.exs:

def deps do
  [
    {:bamboo_config_adapter, "~> 0.2.0"}
  ]
end

Example using SMTPAdapter

Config

  config :my_app, MyApp.Mailer,
    adapter: Bamboo.ConfigAdapter,
    chained_adapter: Bamboo.SMTPAdapter,
    server: "smtp.domain",
    hostname: "www.mydomain.com",
    username: "your.name@your.domain", # or {:system, "SMTP_USERNAME"}
    password: "pa55word", # or {:system, "SMTP_PASSWORD"}

Or if chained adapter is configured completely at runtime

  config :my_app, MyApp.Mailer,
    adapter: Bamboo.ConfigAdapter

Delivering mail

  def welcome do
    email
    |> Bamboo.ConfigAdapter.Email.put_config(%{server: "smtp.other_domain"})
    |> Mailer.deliver_now()
  end

 def welcome_runtime_adapter do
   email
   |> Bamboo.ConfigAdapter.Email.put_config(%{
      server: "smtp.other_domain",
      chained_adapter: Bamboo.SMTPAdapter})
   |> Mailer.deliver_now()
 end

"""

Testing

If the config option :test_mode is set to true then the email will be sent to Bamboo.TestAdapter instead of the chained_adapter in the config. All config, merged from the config file and any runtime config, will available under the element test_merged_config on the returned email.

Note that the test adapter needs the deliver_later_strategy to be set to Bamboo.ImmediateDeliveryStrategy

For example:

config/test.exs

config :my_app, MyApp.Mailer,
adapter: Bamboo.ConfigAdapter,
deliver_later_strategy: Bamboo.ImmediateDeliveryStrategy,
test_mode: true

my_app/emailer.ex

email
|> Bamboo.ConfigAdapter.Email.put_config(%{
      server: "smtp.other_domain",
      chained_adapter: Bamboo.SMTPAdapter})
|> Mailer.deliver_now()

my_app/test/mailer_test.exs

test "should send welcome email", %{event: event, attributes: attributes} do
  assert {:ok, _} = Emailer.send_message(event, attributes)

  assert_delivered_email_matches(%{test_merged_config: merged_config})
  assert merged_config.adapter == Bamboo.ConfigAdapter
  assert merged_config.chained_adapter == Bamboo.SMTPAdapter
  assert merged_config.server == "smtp.other_domain"
end

Gotchas

Bamboo Adapters must implement a supports_attachments?/0. Since the function takes no arguments there is no way for Bamboo.ConfigAdapter to know if the chained adapter supports attachements. Instead we have opted to always return true, but it is up to you to ensure that attachments will work with the chained adapter.

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/bamboo_config_adapter.