Packages
erlcloud
0.9.1
3.8.3
3.8.2
3.8.1
3.7.6
3.7.4
3.7.3
3.7.2
3.7.1
3.7.0
3.6.8
3.6.7
3.6.5
3.6.4
3.6.3
3.6.2
3.6.1
3.6.0
3.5.16
3.5.15
3.5.14
3.5.13
3.5.12
3.5.11
3.5.10
3.5.9
3.5.8
3.5.7
3.5.6
3.5.5
3.5.4
3.5.3
3.5.2
3.5.1
3.5.0
3.4.5
3.4.3
3.4.1
3.4.0
3.3.9
3.3.8
3.3.7
3.3.6
3.3.5
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.18
3.2.17
3.2.16
3.2.15
3.2.14
3.2.13
3.2.12
3.2.11
3.2.10
3.2.7
3.2.6
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.17
3.1.16
3.1.14
3.1.13
3.1.12
3.1.11
3.1.9
3.1.8
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
2.2.16
2.2.15
2.2.14
2.2.13
2.2.12
2.2.11
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.2
2.2.1
2.2.0
2.1.0
2.0.5
2.0.4
2.0.3
2.0.0
0.13.10
0.13.9
0.13.8
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.0
0.12.0
0.11.0
0.9.2
0.9.2-rc.1
0.9.1
0.9.0
AWS APIs library for Erlang
Current section
Files
Jump to
Current section
Files
src/erlcloud_ses.erl
%% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*-
%% @author Ransom Richardson <ransom@ransomr.net>
%% @doc
%% An Erlang interface to Amazon's Simple Email Service (SES)
%%
%% SendEmail is the only method implemented.
%%
%% @end
-module(erlcloud_ses).
-export([configure/2, configure/3, new/2, new/3]).
-export([
send_email/4, send_email/5, send_email/6
]).
-include("erlcloud.hrl").
-include("erlcloud_aws.hrl").
-define(API_VERSION, "2010-12-01").
%%%------------------------------------------------------------------------------
%%% Library initialization.
%%%------------------------------------------------------------------------------
-spec(new/2 :: (string(), string()) -> aws_config()).
new(AccessKeyID, SecretAccessKey) ->
#aws_config{access_key_id=AccessKeyID,
secret_access_key=SecretAccessKey}.
-spec(new/3 :: (string(), string(), string()) -> aws_config()).
new(AccessKeyID, SecretAccessKey, Host) ->
#aws_config{access_key_id=AccessKeyID,
secret_access_key=SecretAccessKey,
ses_host=Host}.
-spec(configure/2 :: (string(), string()) -> ok).
configure(AccessKeyID, SecretAccessKey) ->
put(aws_config, new(AccessKeyID, SecretAccessKey)),
ok.
-spec(configure/3 :: (string(), string(), string()) -> ok).
configure(AccessKeyID, SecretAccessKey, Host) ->
put(aws_config, new(AccessKeyID, SecretAccessKey, Host)),
ok.
default_config() -> erlcloud_aws:default_config().
%%%------------------------------------------------------------------------------
%%% SendEmail
%%%------------------------------------------------------------------------------
send_email(Destination, Body, Subject, Source) ->
send_email(Destination, Body, Subject, Source, [], default_config()).
send_email(Destination, Body, Subject, Source, #aws_config{} = Config) ->
send_email(Destination, Body, Subject, Source, [], Config);
send_email(Destination, Body, Subject, Source, Opts) ->
send_email(Destination, Body, Subject, Source, Opts, default_config()).
%%------------------------------------------------------------------------------
%% @doc
%% SES API:
%% [http://docs.aws.amazon.com/ses/2010-12-01/APIReference/API_SendEmail.html]
%%
%% ===Example===
%%
%% Simple email send.
%%
%% `
%% {ok, _} =
%% erlcloud_ses:send_email(<<"a@to.com">>, <<"Email Body">>, <<"Subject">>,
%% <<"b@from.com">>, []),
%% '
%%
%% All supported inputs.
%%
%% `
%% {ok, _} =
%% erlcloud_ses:send_email([{bcc_addresses, [<<"a@bcc.com">>, "b@bcc.com"]},
%% {cc_addresses, [<<"c@cc.com">>]},
%% {to_addresses, ["d@to.com"]}],
%% [{html, [{charset, "html charset"},
%% {data, "html data"}]},
%% {text, [{charset, "text charset"},
%% {data, "text data"}]}],
%% [{charset, "subject charset"},
%% {data, "subject data"}],
%% "e@from.com",
%% [{reply_to_addresses, [<<"f@reply.com">>, "g@reply.com"]},
%% {return_path, "return path"}]),
%% '
%% @end
%%------------------------------------------------------------------------------
send_email(Destination, Body, Subject, Source, Opts, Config) ->
Params1 = encode_destination(Destination, []),
Params2 = encode_body(Body, Params1),
Params3 = encode_subject(Subject, Params2),
Params4 = encode_source(Source, Params3),
Params5 = encode_opts(Opts, Params4),
ses_request(Config, "SendEmail", Params5).
%%%------------------------------------------------------------------------------
%%% Encoders
%%%------------------------------------------------------------------------------
encode_list(Prefix, List, Acc) ->
encode_list(Prefix, List, 1, Acc).
encode_list(_, [], _, Acc) ->
Acc;
encode_list(Prefix, [H | T], N, Acc) ->
encode_list(Prefix, T, N + 1, [{Prefix ++ ".member." ++ integer_to_list(N), H} | Acc]).
encode_destination_pairs([], Acc) ->
Acc;
encode_destination_pairs([{bcc_addresses, List} | T], Acc) ->
encode_destination_pairs(T, encode_list("Destination.BccAddresses", List, Acc));
encode_destination_pairs([{cc_addresses, List} | T], Acc) ->
encode_destination_pairs(T, encode_list("Destination.CcAddresses", List, Acc));
encode_destination_pairs([{to_addresses, List} | T], Acc) ->
encode_destination_pairs(T, encode_list("Destination.ToAddresses", List, Acc)).
encode_destination([{_,_} | _] = Destination, Acc) ->
%% List of pairs
encode_destination_pairs(Destination, Acc);
encode_destination([ [_|_] | _ ] = ToAddresses, Acc) ->
%% List of strings
encode_destination_pairs([{to_addresses, ToAddresses}], Acc);
encode_destination(ToAddress, Acc) when is_list(ToAddress) or is_binary(ToAddress) ->
%% Single entry
encode_destination_pairs([{to_addresses, [ToAddress]}], Acc).
encode_content_pairs(_, [], Acc) ->
Acc;
encode_content_pairs(Prefix, [{charset, Charset} | T], Acc) ->
encode_content_pairs(Prefix, T, [{Prefix ++ ".Charset", Charset} | Acc]);
encode_content_pairs(Prefix, [{data, Data} | T], Acc) ->
encode_content_pairs(Prefix, T, [{Prefix ++ ".Data", Data} | Acc]).
encode_content(Prefix, [{_,_} | _] = Content, Acc) ->
%% List of pairs
encode_content_pairs(Prefix, Content, Acc);
encode_content(Prefix, Data, Acc) when is_list(Data) or is_binary(Data) ->
%% Single entry
encode_content_pairs(Prefix, [{data, Data}], Acc).
encode_body_pairs([], Acc) ->
Acc;
encode_body_pairs([{html, Content} | T], Acc) ->
encode_body_pairs(T, encode_content("Message.Body.Html", Content, Acc));
encode_body_pairs([{text, Content} | T], Acc) ->
encode_body_pairs(T, encode_content("Message.Body.Text", Content, Acc)).
encode_body([{_,_} | _] = Body, Acc) ->
%% List of pairs
encode_body_pairs(Body, Acc);
encode_body(Body, Acc) when is_list(Body) or is_binary(Body) ->
%% Single entry
encode_body_pairs([{text, Body}], Acc).
encode_subject(Subject, Acc) ->
encode_content("Message.Subject", Subject, Acc).
encode_source(Source, Acc) when is_list(Source) or is_binary(Source) ->
[{"Source", Source} | Acc].
encode_opts([], Acc) ->
Acc;
encode_opts([{reply_to_addresses, List} | T], Acc) ->
encode_opts(T, encode_list("ReplyToAddresses", List, Acc));
encode_opts([{return_path, ReturnPath} | T], Acc) ->
encode_opts(T, [{"ReturnPath", ReturnPath} | Acc]).
%%%------------------------------------------------------------------------------
%%% Internal Functions
%%%------------------------------------------------------------------------------
ses_request(Config, Action, Params) ->
case erlcloud_aws:update_config(Config) of
{ok, Config1} ->
ses_request_no_update(Config1, Action, Params);
{error, Reason} ->
{error, Reason}
end.
ses_request_no_update(Config, Action, Params) ->
Date = httpd_util:rfc1123_date(),
Signature = base64:encode_to_string(
erlcloud_util:sha256_mac(Config#aws_config.secret_access_key, Date)),
Auth = lists:flatten(
["AWS3-HTTPS AWSAccessKeyId=",
Config#aws_config.access_key_id,
",Algorithm=HmacSHA256,Signature=",
Signature]),
Headers = [{"Date", Date},
{"X-Amzn-Authorization", Auth}],
Headers2 = case Config#aws_config.security_token of
undefined ->
Headers;
Token ->
[{"x-amz-security-token", Token} | Headers]
end,
QParams = [{"Action", Action},
{"Version", ?API_VERSION} |
Params],
Query = erlcloud_http:make_query_string(QParams),
erlcloud_aws:aws_request_form(
post, "https", Config#aws_config.ses_host, 443, "/", Query, Headers2, Config).