Packages
swoosh
1.26.3
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.
Current section
Files
Jump to
Current section
Files
lib/swoosh/adapters/postal.ex
defmodule Swoosh.Adapters.Postal do
@moduledoc ~S"""
An adapter that sends email using the Postal API.
[Postal](https://docs.postalserver.io/) is open-source, self-hosted mail delivery platform.
For reference: [Postal API docs](https://apiv1.postalserver.io/)
**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.
## Configuration options
* `:api_key` - Postal API key.
* `:base_url` - Base URL where Postal server is running.
## Example
# config/config.exs
config :sample, Sample.Mailer,
adapter: Swoosh.Adapters.Postal,
api_key: "my-api-key",
base_url: "https://my-postal-server.com/"
# lib/sample/mailer.ex
defmodule Sample.Mailer do
use Swoosh.Mailer, otp_app: :sample
end
## Using with provider options
import Swoosh.Email
new()
|> from({"T Stark", "tony.stark@example.com"})
|> to({"Steve Rogers", "steve.rogers@example.com"})
|> to("wasp.avengers@example.com")
|> reply_to("office.avengers@example.com")
|> cc({"Bruce Banner", "hulk.smash@example.com"})
|> cc("thor.odinson@example.com")
|> bcc({"Clinton Francis Barton", "hawk.eye@example.com"})
|> bcc("beast.avengers@example.com")
|> subject("Hello, Avengers!")
|> html_body("<h1>Hello</h1>")
|> text_body("Hello")
|> put_provider_option(:tag, "avengers")
|> put_provider_option(:bounce, true)
"""
use Swoosh.Adapter,
required_config: [:api_key, :base_url]
alias Swoosh.Attachment
alias Swoosh.Email
import Swoosh.Email.Render
@api_endpoint "/api/v1/send/message"
@impl true
def deliver(%Email{} = email, config \\ []) do
body = prepare_body(email) |> Swoosh.json_library().encode!
headers = prepare_headers(config)
url = [base_url(config), @api_endpoint]
case Swoosh.ApiClient.post(url, headers, body, email) do
{:ok, 200, _headers, body} ->
case Swoosh.json_library().decode!(body) do
%{"status" => "success", "data" => data} ->
{:ok, %{id: data["message_id"]}}
%{"status" => _, "data" => data} ->
{:error, {data["code"], data["message"]}}
end
{:ok, code, _headers, body} when code > 399 ->
case Swoosh.json_library().decode(body) do
{:ok, error} -> {:error, {code, error}}
{:error, _} -> {:error, {code, body}}
end
{:error, reason} ->
{:error, reason}
end
end
defp base_url(config), do: config[:base_url]
defp prepare_headers(config) do
[
{"User-Agent", "swoosh/#{Swoosh.version()}"},
{"Content-Type", "application/json"},
{"Accept", "application/json"},
{"X-Server-API-Key", config[:api_key]}
]
end
defp prepare_body(%Email{} = email) do
%{}
|> prepare_from(email)
|> prepare_to(email)
|> prepare_subject(email)
|> prepare_html(email)
|> prepare_text(email)
|> prepare_cc(email)
|> prepare_bcc(email)
|> prepare_reply_to(email)
|> prepare_attachments(email)
|> prepare_tag(email)
|> prepare_bounce(email)
|> prepare_custom_headers(email)
end
defp prepare_from(body, %Email{from: from}),
do: Map.put(body, :from, render_recipient(from))
defp prepare_to(body, %Email{to: to}),
do: Map.put(body, :to, Enum.map(to, &render_recipient(&1)))
defp prepare_cc(body, %Email{cc: []}), do: body
defp prepare_cc(body, %Email{cc: cc}),
do: Map.put(body, :cc, Enum.map(cc, &render_recipient(&1)))
defp prepare_bcc(body, %Email{bcc: []}), do: body
defp prepare_bcc(body, %Email{bcc: bcc}),
do: Map.put(body, :bcc, Enum.map(bcc, &render_recipient(&1)))
defp prepare_reply_to(body, %Email{reply_to: nil}), do: body
defp prepare_reply_to(body, %Email{reply_to: reply_to}),
do: Map.put(body, :reply_to, render_recipient(reply_to))
defp prepare_subject(body, %Email{subject: subject}),
do: Map.put(body, :subject, subject)
defp prepare_text(body, %Email{text_body: nil}), do: body
defp prepare_text(body, %Email{text_body: text_body}), do: Map.put(body, :plain_body, text_body)
defp prepare_html(body, %Email{html_body: nil}), do: body
defp prepare_html(body, %Email{html_body: html_body}), do: Map.put(body, :html_body, html_body)
defp prepare_tag(body, %Email{provider_options: %{tag: tag}}), do: Map.put(body, :tag, tag)
defp prepare_tag(body, _), do: body
defp prepare_bounce(body, %Email{provider_options: %{bounce: bounce}}) when is_boolean(bounce),
do: Map.put(body, :bounce, bounce)
defp prepare_bounce(body, _), do: body
defp prepare_custom_headers(body, %{headers: headers}) when map_size(headers) != 0,
do: Map.put(body, :headers, headers)
defp prepare_custom_headers(body, _), do: body
defp prepare_attachments(body, %Email{attachments: []}), do: body
defp prepare_attachments(body, %Email{attachments: attachments}),
do: Map.put(body, :attachments, Enum.map(attachments, &prepare_attachment(&1)))
defp prepare_attachment(%Attachment{} = attachment) do
%{
name: attachment.filename,
content_type: attachment.content_type,
data: Swoosh.Attachment.get_content(attachment, :base64)
}
end
end