Packages
swoosh
1.26.1
1.26.3
1.26.2
1.26.1
1.26.0
1.25.3
1.25.2
1.25.1
1.25.0
1.24.0
1.23.1
1.23.0
1.22.1
1.22.0
1.21.0
1.20.1
1.20.0
1.19.9
1.19.8
1.19.7
1.19.6
1.19.5
1.19.4
1.19.3
1.19.2
1.19.1
1.19.0
1.18.4
1.18.3
1.18.2
1.18.1
1.18.0
1.17.10
1.17.9
1.17.8
retired
1.17.7
retired
1.17.6
1.17.5
1.17.4
retired
1.17.3
1.17.2
1.17.1
1.17.0
1.16.12
1.16.11
1.16.10
1.16.9
1.16.8
1.16.7
1.16.6
1.16.5
1.16.4
1.16.3
1.16.2
retired
1.16.1
retired
1.16.0
1.15.3
1.15.2
1.15.1
1.15.0
1.14.4
1.14.3
1.14.2
1.14.1
1.14.0
1.13.0
1.12.0
1.11.6
1.11.5
1.11.4
1.11.3
1.11.2
1.11.1
retired
1.11.0
1.10.3
1.10.2
1.10.1
1.10.0
1.9.1
1.9.0
1.8.3
1.8.2
1.8.1
1.8.0
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.2
1.5.1
1.5.0
1.4.0
1.3.11
1.3.10
1.3.9
1.3.8
retired
1.3.7
1.3.6
retired
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.2
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.0.9
1.0.8
retired
1.0.7
retired
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.25.6
0.25.5
0.25.4
0.25.3
retired
0.25.2
0.25.1
0.25.0
0.24.4
0.24.3
0.24.2
0.24.1
0.24.0
0.23.5
0.23.4
0.23.3
0.23.2
0.23.1
0.23.0
0.22.2
0.22.1
0.22.0
0.21.1
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.1
0.16.0
0.15.0
0.14.0
0.13.0
0.12.1
0.12.0
0.11.0
0.10.0
0.9.1
0.9.0
0.8.1
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Compose, deliver and test your emails easily in Elixir. Supports SMTP, Sendgrid, Mandrill, Postmark, Mailgun and many more out of the box. Preview your emails in the browser. Test your email sending code.
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/swoosh/adapters/mailpit.ex
defmodule Swoosh.Adapters.Mailpit do
@moduledoc ~s"""
An adapter that sends email to a self-hosted Mailpit server via its HTTP API.
For reference: [Mailpit API docs](https://mailpit.axllent.org/docs/api-v1/)
**This adapter requires an API Client.** Swoosh comes with Hackney, Finch and Req out of the box.
See the [installation section](https://hexdocs.pm/swoosh/Swoosh.html#module-installation)
for details.
## Example
# config/config.exs
config :sample, Sample.Mailer,
adapter: Swoosh.Adapters.Mailpit,
base_url: "https://mailpit.example.com",
api_key: "YnJ...0Rw==" # optional, for Basic Auth
# lib/sample/mailer.ex
defmodule Sample.Mailer do
use Swoosh.Mailer, otp_app: :sample
end
## Using with provider options
import Swoosh.Email
new()
|> from({"Raife Hastings", "raife@example.com"})
|> to({"Jed Haverford", "jed@example.com"})
|> reply_to("raife.hastings@example.com")
|> cc("eliza@example.com")
|> cc({"Jules Landry", "jules@example.com"})
|> bcc("james.reece@example.com")
|> bcc({"Ben Edwards", "ben@example.com"})
|> subject("Hello there")
|> html_body("<h1>Hello</h1>")
|> text_body("Hello")
|> put_provider_option(:tags, ["welcome", "transactional"])
## Provider Options
Supported provider options are the following:
#### Inserted into request body
* `:tags` (list of strings) - Mailpit tags
"""
use Swoosh.Adapter, required_config: [:base_url]
alias Swoosh.Email
@api_endpoint "/api/v1/send"
@provider_options_body_fields [:tags]
def deliver(%Email{} = email, config \\ []) do
headers = build_headers(config)
body = email |> prepare_body() |> Swoosh.json_library().encode!()
url = prepare_url(config)
case Swoosh.ApiClient.post(url, headers, body, email) do
{:ok, code, _headers, body} when code in 200..399 ->
decoded = Swoosh.json_library().decode!(body)
{:ok, %{id: decoded["ID"]}}
{:ok, code, _headers, body} when code >= 400 ->
case Swoosh.json_library().decode(body) do
{:ok, error} -> {:error, {code, error}}
{:error, _} -> {:error, {code, body}}
end
{:error, reason} ->
{:error, reason}
end
end
defp prepare_url(config), do: [base_url(config), @api_endpoint]
defp base_url(config), do: config[:base_url]
defp build_headers(config) do
base = [
{"Accept", "application/json"},
{"Content-Type", "application/json"},
{"User-Agent", "swoosh/#{Swoosh.version()}"}
]
case config[:api_key] do
api_key when is_binary(api_key) -> [{"Authorization", "Basic #{api_key}"} | base]
_ -> base
end
end
defp prepare_body(email) do
%{}
|> prepare_from(email)
|> prepare_to(email)
|> prepare_cc(email)
|> prepare_bcc(email)
|> prepare_subject(email)
|> prepare_text(email)
|> prepare_html(email)
|> prepare_attachments(email)
|> prepare_reply_to(email)
|> prepare_custom_headers(email)
|> prepare_provider_options(email)
end
defp recipient({name, email}) when is_binary(name) and name != "" and is_binary(email),
do: %{"Email" => email, "Name" => name}
defp recipient({_, email}) when is_binary(email),
do: %{"Email" => email}
defp recipient(email) when is_binary(email),
do: %{"Email" => email}
defp recipient_email({_, email}) when is_binary(email), do: email
defp recipient_email(email) when is_binary(email), do: email
defp recipient_email(_), do: nil
defp prepare_from(body, %{from: from}),
do: Map.put(body, "From", recipient(from))
defp prepare_from(body, _), do: body
defp prepare_to(body, %{to: to}) when is_list(to) and to != [],
do: Map.put(body, "To", Enum.map(to, &recipient/1))
defp prepare_to(body, _), do: body
defp prepare_cc(body, %{cc: []}), do: body
defp prepare_cc(body, %{cc: cc}), do: Map.put(body, "Cc", Enum.map(cc, &recipient/1))
defp prepare_cc(body, _), do: body
defp prepare_bcc(body, %{bcc: []}), do: body
defp prepare_bcc(body, %{bcc: bcc}) do
emails = Enum.flat_map(bcc, fn item -> [recipient_email(item)] end)
Map.put(body, "Bcc", emails)
end
defp prepare_bcc(body, _), do: body
defp prepare_subject(body, %{subject: subject}) when is_binary(subject),
do: Map.put(body, "Subject", subject)
defp prepare_subject(body, _), do: body
defp prepare_text(body, %{text_body: nil}), do: body
defp prepare_text(body, %{text_body: text}), do: Map.put(body, "Text", text)
defp prepare_text(body, _), do: body
defp prepare_html(body, %{html_body: nil}), do: body
defp prepare_html(body, %{html_body: html}), do: Map.put(body, "HTML", html)
defp prepare_html(body, _), do: body
defp prepare_attachments(body, %{attachments: []}), do: body
defp prepare_attachments(body, %{attachments: attachments}) do
atts =
Enum.map(attachments, fn attachment ->
content = Swoosh.Attachment.get_content(attachment, :base64)
att_map =
%{
"Filename" => attachment.filename,
"Content" => content
}
|> maybe_put("ContentType", attachment.content_type)
case attachment.type do
:inline ->
content_id = attachment.cid || attachment.filename
Map.put(att_map, "ContentID", content_id)
_ ->
att_map
end
end)
Map.put(body, "Attachments", atts)
end
defp prepare_attachments(body, _), do: body
defp prepare_reply_to(body, %{reply_to: nil}), do: body
defp prepare_reply_to(body, %{reply_to: reply_to}) do
replies = List.wrap(reply_to)
Map.put(body, "ReplyTo", Enum.map(replies, &recipient/1))
end
defp prepare_reply_to(body, _), do: body
defp prepare_custom_headers(body, %{headers: headers}) when map_size(headers) == 0,
do: body
defp prepare_custom_headers(body, %{headers: headers}),
do: Map.put(body, "Headers", headers)
defp prepare_custom_headers(body, _), do: body
defp prepare_provider_options(body, %{provider_options: opts}) do
case Map.take(opts, @provider_options_body_fields) do
map when map_size(map) > 0 -> Map.merge(body, map)
_ -> body
end
end
defp prepare_provider_options(body, _), do: body
defp maybe_put(map, _key, nil), do: map
defp maybe_put(map, _key, ""), do: map
defp maybe_put(map, key, value), do: Map.put(map, key, value)
end