Giter Club home page Giter Club logo

mailman's Introduction

Mailman

Mailman provides a clean way of defining mailers in your Elixir apps. It allows you to send multi-part email messages containing text and html parts. It encodes messages with a proper quoted-printable encoding. It also allows you to send attachments.

To be able to send emails, you only need to provide the SMTP config (like an external SMTP server along with credentials etc.). You also need to define your emails along with text and/or html templates. Mailman uses Eex as a templating language but will likely be extended to provide other choices as well in the future.

A quick example

  defmodule MyApp.Mailer do
    def deliver(email) do
      Mailman.deliver(email, config)
    end

    def config do
      %Mailman.Context{
          config:   %Mailman.LocalSmtpConfig{ port: 1234 },
          composer: %Mailman.EexComposeConfig{}
        }
    end
  end
  
  # somewhere where you start other services in your app:
  Mailman.LocalServer.start 1234 # just pass the port number you want

  # somewhere else:
  def testing_email do
    %Mailman.Email{
      subject: "Hello Mailman!",
      from: "[email protected]",
      to: [ "[email protected]" ],
      cc: [ "testy2#tester1234.com", "[email protected]" ],
      bcc: [ "[email protected]" ],
      data: [
        name: "Yo"
        ],
      text: "Hello! <%= name %> These are Unicode: qżźół",
      html: """
<html>
<body>
 <b>Hello! <%= name %></b> These are Unicode: qżźół
</body>
</html>
      """
      }
  end

And then to actually send an email:

  MyApp.Mailer.deliver testing_email

Configuring the mailing context

There are two parts in the configuration data for how Mailman works:

  • Composer config
  • Adapter config

The first one specifies how emails will be rendered. The second one, how will they be delivered.

For now, only the %Mailman.EexComposeConfig{} is available for configuring the composer. The library is ready to support any other composer you might want to implement.

There are three adapter configs at the moment: external smtp, local smtp and the testing one. The latter will soon support handling the queue of emails to ease testing of the email sending part of your apps.

You don't access those adapters directly. Instead, you specify a config of your choice and the library does all the rest for you. The three config options corresponding with adapters are: %Mailman.LocalSmtpConfig{}, %Mailman.SmtpConfig{} and %Mailman.TestConfig{}.

%Mailman.Context{
    config:   %Mailman.LocalSmtpConfig{ port: 1234 },
    composer: %Mailman.EexComposeConfig{}
  }

Note that to be able to use the local and the test configs, you'll need to start either local SMTP server or the testing service:

  Mailman.LocalServer.start(1234)
  # or:
  Mailman.TestServer.start

In this example we're setting up the library to use the local SMTP server created along with the app. In order for this to work you still have to create this process:

pid = Mailman.LocalServer.start(1234)

Configuration using Mix.Config

You can pass context configuration to Mailman using Mix.Config. If you do set config field value in Mailman.Context struct, or if you set it to nil, Mailman expect to read the value from Mix.Config, generally in your config,exs file.

Here is an example mix.exs file snippet for Mailman:

config :mailman,
  relay: "localhost",
  port: 1025,
  auth: :never

Defining emails

The email struct is defined as:

defstruct subject: "", 
  from: "", 
  to: [], 
  cc: [], 
  bcc: [], 
  attachments: [], # This has to be %Mailman.Attachment{}. More about attachments below
  data: %{}, # This is the context for EEx. You put here data for your <%= %> placeholders
  html: "", # Actual html template
  text: "", # Actual plain template
  delivery: nil # If the message was created through parsing of the delivered email - this holds the 'Date' header

Attaching files

A dedicated struct has been created for describing attachments. In this version, there's a function that takes a binary representing a path to a file that's constructing this struct for you. So you can add attachments to your email definitions like this:

attachments: [
  Mailman.Attachment.inline!("test/data/blank.png")
  ],

This reads the file from disk, encodes it with base64 and discovers the proper mime-type. Attachments are also properly decoded from existing emails (more on that below).

Parsing delivered emails

If you have the source of rendered email as a binary, you can use the Mailman.Email.parse!/1 function to turn it into%Mailman.Email{}.

Here's an example from the test suite:

{:ok, message} = MyApp.Mailer.deliver(email_with_attachments)
email = Mailman.Email.parse! message

At this point, if the source contains the 'Date' header (meaning that it was put through a mailing system) — it will have the 'delivery' field non-empty.

Inspecting deliveries when testing

When you use the TestServer you can take a look at the deliveries whith:

  Mailman.TestServer.deliveries

Also, if you want to clear this list:

  Mailman.TestServer.clear_deliveries

Using with Hex

There's one gotcha currently when using the package with Hex. Because of the dependency on the eiconv library and it's absence in the Hex database, you have to specify it as a dependency on your own in your mix.exs

As an example:

defp deps do
  [
    {:mailman, "~> 0.1.0"},
    {:eiconv, github: "zotonic/eiconv"}
  ]
end

This way you'll be able to use the parse! function to parse delivered emails.

TODOs

  • A SMTP config that would use internal server/process coming with :gen_smtp
  • A testing config that stores deliveries
  • Ability to send attachments
  • Ability to provide CC and BCC
  • Unit testing (somewhat in progress)

Contributors

mailman's People

Contributors

dejanstrbac avatar swerter avatar mremond avatar danmcclain avatar houshuang avatar hamann avatar lowks avatar maxneuvians avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.