Current section

Files

Jump to
bamboo_elastic_email lib bamboo elastic_email.ex
Raw

lib/bamboo/elastic_email.ex

defmodule Bamboo.ElasticEmail do
@moduledoc """
Helper functions for manipulating Bamboo.Email to enable Elastic Email
functionality.
"""
alias Bamboo.Email
@doc """
Add attachment identifiers to the email.
> Names or IDs of attachments previously uploaded to your account (via the
> File/Upload request) that should be sent with this e-mail.
"""
@spec attachments(Email.t(), [binary(), ...] | binary()) :: Email.t()
def attachments(%Email{} = email, attachments) do
put_elastic_send_option(email, :attachments, List.wrap(attachments))
end
@doc """
Sets the channel for the email.
> An ID field (max 191 chars) that can be used for reporting [will default
> to HTTP API or SMTP API]
"""
@spec channel(Email.t(), binary()) :: Email.t()
def channel(%Email{} = email, channel) do
put_elastic_send_option(email, :channel, String.slice(channel, 0..190))
end
@doc """
Sets the character set for the email or one of the MIME parts. Overrides the
global default of "utf-8".
> Text value of charset encoding for example: iso-8859-1, windows-1251,
> utf-8, us-ascii, windows-1250 and more…
The `part` parameter is interpreted as:
- `:amp`: sets the `charsetBodyAmp` option (the AMP body MIME part)
- `:html`: sets the `charsetBodyHtml` option (the HTML body MIME part)
- `:text`: sets the `charsetBodyText` option (the text body MIME part)
Any other value sets the global `charset` option.
"""
@spec charset(Email.t(), part :: nil | :amp | :html | :text, binary()) :: Email.t()
def charset(%Email{} = email, part \\ nil, charset) do
put_elastic_send_option(
email,
case part do
:amp -> :charset_body_amp
:html -> :charset_body_html
:text -> :charset_body_text
_ -> :charset
end,
charset
)
end
@doc """
Sets the data source of the email.
> Name or ID of the previously uploaded file (via the File/Upload request)
> which should be a CSV list of Recipients.
"""
@spec data_source(Email.t(), binary()) :: Email.t()
def data_source(%Email{} = email, name) do
put_elastic_send_option(email, :data_source, name)
end
@doc """
Sets the email encoding type. The default encoding is `:base64`, which is
the recommended value. Either `:base64` or `:quoted_printable` is
recommended if you are validating your domain(s) with DKIM.
Supported encoding types are:
- `:none`: no encoding
- `:raw_7bit`: Raw 7bit. Must be plain ASCII.
- `:raw_8bit`: Raw 8bit.
- `:quoted_printable`: Quoted printable format.
- `:base64`: Base64
- `:uue`: UU
"""
@spec encoding_type(Email.t(), atom) :: Email.t()
def encoding_type(%Email{} = email, encoding) do
put_elastic_send_option(
email,
:encoding_type,
case encoding do
:none -> 0
:raw_7bit -> 1
:raw_8bit -> 2
:quoted_printable -> 3
:uue -> 5
_ -> 4
end
)
end
@doc "The name or names of a contact list you would like to send to."
@spec lists(Email.t(), [binary(), ...] | binary()) :: Email.t()
def lists(%Email{} = email, lists) do
put_elastic_send_option(email, :lists, Enum.join(List.wrap(lists), ";"))
end
@doc """
Sets merge parameters. The params must be a list of maps or keyword lists
(or other 2-tuple lists).
> Repeated list of string keys and string values
> Request parameters prefixed by merge_ like merge_firstname,
> merge_lastname. If sending to a template you can send merge_ fields to
> merge data with the template. Template fields are entered with
> {firstname}, {lastname} etc.
"""
@spec merge(Email.t(), map() | keyword() | [map() | keyword(), ...]) :: Email.t()
def merge(%Email{} = email, params) do
put_elastic_send_option(email, :merge, Enum.flat_map(List.wrap(params), &to_merge_params/1))
end
@doc """
The file name of a previously uploaded attachment which is a CSV list of
Recipients.
"""
@spec merge_source_filename(Email.t(), binary()) :: Email.t()
def merge_source_filename(%Email{} = email, filename) do
put_elastic_send_option(email, :merge_source_filename, filename)
end
@doc "Name of the custom IP Pool to be used in the sending process."
@spec pool_name(Email.t(), binary()) :: Email.t()
def pool_name(%Email{} = email, name) do
put_elastic_send_option(email, :pool_name, name)
end
@doc "Optional header returned in notifications."
@spec post_back(Email.t(), binary()) :: Email.t()
def post_back(%Email{} = email, post_back) do
put_elastic_send_option(email, :post_back, post_back)
end
@doc """
The name or names of the Contact segment(s) you wish to send. Use :all
for all active contacts.
"""
@spec segments(Email.t(), :all | binary() | [binary() | :all, ...]) :: Email.t()
def segments(%Email{} = email, segments) do
segments =
segments
|> List.wrap()
|> Enum.map(&if(match?(:all, &1), do: "0", else: &1))
|> Enum.uniq()
|> Enum.join(";")
put_elastic_send_option(email, :segments, segments)
end
@doc "The ID of an email template you have created in your account."
@spec template(Email.t(), binary()) :: Email.t()
def template(%Email{} = email, template) do
put_elastic_send_option(email, :template, template)
end
@doc """
The number of minutes in the future this email should be sent up to a
maximum of 1 year (524,160 minutes).
"""
@spec time_off_set_minutes(Email.t(), 1..524_160) :: Email.t()
def time_off_set_minutes(%Email{} = email, minutes) when is_integer(minutes) do
put_elastic_send_option(
email,
:time_off_set_minutes,
cond do
minutes < 1 -> 1
minutes > 524_160 -> 524_160
true -> minutes
end
)
end
@doc "Indicates whether clicks should be tracked on this email."
@spec track_clicks(Email.t(), boolean) :: Email.t()
def track_clicks(%Email{} = email, track_clicks) do
put_elastic_send_option(email, :track_clicks, track_clicks)
end
@doc "Indicates whether opens should be tracked on this email."
@spec track_opens(Email.t(), boolean) :: Email.t()
def track_opens(%Email{} = email, track_opens) do
put_elastic_send_option(email, :track_opens, track_opens)
end
@doc "Set UTM Marketing Parameters for campaign links."
@spec utm_parameters(
Email.t(),
%{optional(:campaign | :content | :medium | :source) => binary()} | keyword
) :: Email.t()
def utm_parameters(%Email{} = email, params) do
merge_elastic_send_options(email, Map.new(params, &to_utm_parameter/1))
end
defp put_elastic_send_option(%{private: private} = email, key, value) do
send_options =
private
|> Map.get(:elastic_send_options, %{})
|> Map.put(key, value)
%{email | private: Map.put(private, :elastic_send_options, send_options)}
end
defp merge_elastic_send_options(%{private: private} = email, %{} = options) do
send_options =
private
|> Map.get(:elastic_send_options, %{})
|> Map.merge(options)
%{email | private: Map.put(private, :elastic_send_options, send_options)}
end
defp to_merge_params({k, v}), do: [{"merge_#{k}", v}]
defp to_merge_params(params) when is_list(params) or is_map(params),
do: Enum.map(params, &to_merge_params/1)
defp to_utm_parameter({:campaign, value}), do: {:utm_campaign, value}
defp to_utm_parameter({:content, value}), do: {:utm_content, value}
defp to_utm_parameter({:medium, value}), do: {:utm_medium, value}
defp to_utm_parameter({:source, value}), do: {:utm_source, value}
end