Packages
erlcloud
3.6.8
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_sns.erl
%%% Amazon SNS.
%%% Events are parsed according to http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.html
%%% TODO add all the missing functions for the different actions
-module(erlcloud_sns).
-author('elbrujohalcon@inaka.net').
-export([add_permission/3, add_permission/4,
create_platform_application/2, create_platform_application/3,
create_platform_application/4, create_platform_application/5,
list_platform_applications/0, list_platform_applications/1,
list_platform_applications/2, list_platform_applications/3,
get_platform_application_attributes/1, get_platform_application_attributes/2,
set_platform_application_attributes/2, set_platform_application_attributes/3,
create_platform_endpoint/2, create_platform_endpoint/3,
create_platform_endpoint/4, create_platform_endpoint/5,
create_platform_endpoint/6,
list_endpoints_by_platform_application/1, list_endpoints_by_platform_application/2,
list_endpoints_by_platform_application/3, list_endpoints_by_platform_application/4,
create_topic/1, create_topic/2,
delete_endpoint/1, delete_endpoint/2, delete_endpoint/3,
delete_topic/1, delete_topic/2,
list_topics/0, list_topics/1, list_topics/2,
list_topics_all/0, list_topics_all/1,
list_subscriptions/0,
list_subscriptions/1,
list_subscriptions/2,
list_subscriptions_all/0,
list_subscriptions_all/1,
list_subscriptions_by_topic/1,
list_subscriptions_by_topic/2,
list_subscriptions_by_topic/3,
list_subscriptions_by_topic_all/1,
list_subscriptions_by_topic_all/2,
get_endpoint_attributes/1,
get_endpoint_attributes/2,
get_endpoint_attributes/3,
set_endpoint_attributes/2,
set_endpoint_attributes/3,
publish_to_topic/2, publish_to_topic/3, publish_to_topic/4,
publish_to_topic/5, publish_to_target/2, publish_to_target/3,
publish_to_target/4, publish_to_target/5, publish_to_phone/2,
publish_to_phone/3, publish_to_phone/4, publish/5, publish/6,
confirm_subscription/1, confirm_subscription/2, confirm_subscription/3,
confirm_subscription2/2, confirm_subscription2/3, confirm_subscription2/4,
set_topic_attributes/3, set_topic_attributes/4,
get_topic_attributes/1, get_topic_attributes/2,
set_subscription_attributes/3, set_subscription_attributes/4,
get_subscription_attributes/1, get_subscription_attributes/2,
subscribe/3, subscribe/4,
unsubscribe/1, unsubscribe/2
]).
-export([parse_event/1, get_event_type/1, parse_event_message/1,
get_notification_attribute/2]).
-export([new/2, new/3, configure/2, configure/3]).
-include("erlcloud.hrl").
-include("erlcloud_aws.hrl").
-define(API_VERSION, "2010-03-31").
-opaque sns_event() :: jsx:json_term().
-opaque sns_notification() :: sns_message().
-type sns_event_type() :: subscription_confirmation | notification.
-export_type([sns_event/0, sns_event_type/0, sns_notification/0]).
-type sns_endpoint_attribute() :: custom_user_data
| enabled
| token.
-type sns_message_attributes() :: [{string(), string() | binary() | number()}].
-type sns_endpoint() :: [{arn, string()} | {attributes, [{arn|sns_endpoint_attribute(), string()}]}].
-type sns_permission() :: all
| add_permission
| confirm_subscription
| create_platform_application
| create_platform_endpoint
| create_topic
| delete_endpoint
| delete_platform_application
| delete_topic
| get_endpoint_attributes
| get_platform_application_attributes
| get_subscription_attributes
| get_topic_attributes
| list_endpoints_by_platform_application
| list_platform_applications
| list_subscriptions
| list_subscriptions_by_topic
| list_topics
| publish
| remove_permission
| set_endpoint_attributes
| set_platform_application_attributes
| set_subscription_attributes
| set_topic_attributes
| subscribe
| unsubscribe.
-type sns_acl() :: [{string(), sns_permission()}].
-type sns_message() :: string() | jsx:json_term().
-type sns_application_attribute() :: event_endpoint_created
| event_endpoint_deleted
| event_endpoint_updated
| event_delivery_failure
| platform_credential
| platform_principal
| success_feedback_role_arn
| failure_feedback_role_arn
| success_feedback_sample_rate.
-type sns_application() :: [{arn, string()} | {attributes, [{arn|sns_application_attribute(), string()}]}].
-type(sns_topic_attribute_name () :: 'Policy' | 'DisplayName' | 'DeliveryPolicy').
-type(sns_subscription_attribute_name () :: 'DeliveryPolicy' | 'RawMessageDelivery' | 'FilterPolicy').
-type(sns_subscribe_protocol_type () :: http | https | email | 'email-json' | sms | sqs | application).
-export_type([sns_acl/0, sns_endpoint_attribute/0, sns_message_attributes/0,
sns_message/0, sns_application/0, sns_endpoint/0]).
-spec add_permission(string(), string(), sns_acl()) -> ok.
add_permission(TopicArn, Label, Permissions) ->
add_permission(TopicArn, Label, Permissions, default_config()).
-spec add_permission(string(), string(), sns_acl(), aws_config()) -> ok.
add_permission(TopicArn, Label, Permissions, Config)
when is_list(TopicArn),
is_list(Label), length(Label) =< 80,
is_list(Permissions) ->
sns_simple_request(Config, "AddPermission",
[{"Label", Label}, {"TopicArn", TopicArn}
| erlcloud_aws:param_list(
encode_permissions(Permissions),
{"AWSAccountId.member", "ActionName.member"})]).
-spec create_platform_endpoint(string(), string()) -> string().
create_platform_endpoint(PlatformApplicationArn, Token) ->
create_platform_endpoint(PlatformApplicationArn, Token, "").
-spec create_platform_endpoint(string(), string(), string()) -> string().
create_platform_endpoint(PlatformApplicationArn, Token, CustomUserData) ->
create_platform_endpoint(PlatformApplicationArn, Token, CustomUserData, []).
-spec create_platform_endpoint(string(), string(), string(), [{sns_endpoint_attribute(), string()}]) -> string().
create_platform_endpoint(PlatformApplicationArn, Token, CustomUserData, Attributes) ->
create_platform_endpoint(PlatformApplicationArn, Token, CustomUserData, Attributes, default_config()).
-spec create_platform_endpoint(string(), string(), string(), [{sns_endpoint_attribute(), string()}], aws_config()) -> string().
create_platform_endpoint(PlatformApplicationArn, Token, CustomUserData, Attributes, Config) ->
Doc =
sns_xml_request(
Config, "CreatePlatformEndpoint",
[{"PlatformApplicationArn", PlatformApplicationArn},
{"Token", Token},
{"CustomUserData", CustomUserData}
| encode_attributes(Attributes)
]),
erlcloud_xml:get_text(
"CreatePlatformEndpointResult/EndpointArn", Doc).
-spec create_platform_endpoint(string(), string(), string(), [{sns_endpoint_attribute(), string()}], string(), string()) -> string().
create_platform_endpoint(PlatformApplicationArn, Token, CustomUserData, Attributes, AccessKeyID, SecretAccessKey) ->
create_platform_endpoint(PlatformApplicationArn, Token, CustomUserData, Attributes, new_config(AccessKeyID, SecretAccessKey)).
-spec create_platform_application(string(), string()) -> string().
create_platform_application(Name, Platform) ->
create_platform_application(Name, Platform, []).
-spec create_platform_application(string(), string(), [{sns_endpoint_attribute(), string()}]) -> string().
create_platform_application(Name, Platform, Attributes) ->
create_platform_application(Name, Platform, Attributes, default_config()).
-spec create_platform_application(string(), string(), [{sns_endpoint_attribute(), string()}], aws_config()) -> string().
create_platform_application(Name, Platform, Attributes, Config) ->
Doc =
sns_xml_request(
Config, "CreatePlatformApplication",
[{"Name", Name},
{"Platform", Platform}
| encode_attributes(Attributes)
]),
erlcloud_xml:get_text(
"CreatePlatformApplicationResult/PlatformApplicationArn", Doc).
-spec create_platform_application(string(), string(), [{sns_endpoint_attribute(), string()}], string(), string()) -> string().
create_platform_application(Name, Platform, Attributes, AccessKeyID, SecretAccessKey) ->
create_platform_application(Name, Platform, Attributes, new_config(AccessKeyID, SecretAccessKey)).
-spec get_platform_application_attributes(string()) -> sns_application().
get_platform_application_attributes(PlatformApplicationArn) ->
get_platform_application_attributes(PlatformApplicationArn, default_config()).
-spec get_platform_application_attributes(string(), aws_config()) -> sns_application().
get_platform_application_attributes(PlatformApplicationArn, Config) ->
Params = [{"PlatformApplicationArn", PlatformApplicationArn}],
Doc = sns_xml_request(Config, "GetPlatformApplicationAttributes", Params),
Decoded =
erlcloud_xml:decode(
[{attributes, "GetPlatformApplicationAttributesResult/Attributes/entry",
fun extract_attribute/1
}],
Doc),
[{arn, PlatformApplicationArn} | Decoded].
-spec set_platform_application_attributes(string(), [{sns_application_attribute(), string()}]) -> string().
set_platform_application_attributes(PlatformApplicationArn, Attributes) ->
set_platform_application_attributes(PlatformApplicationArn, Attributes, default_config()).
-spec set_platform_application_attributes(string(), [{sns_application_attribute(), string()}], aws_config()) -> string().
set_platform_application_attributes(PlatformApplicationArn, Attributes, Config) ->
Params = [{"PlatformApplicationArn", PlatformApplicationArn}] ++ encode_attributes(Attributes),
Doc = sns_xml_request(Config, "SetPlatformApplicationAttributes", Params),
erlcloud_xml:get_text("ResponseMetadata/RequestId", Doc).
-spec create_topic(string()) -> string().
create_topic(TopicName) ->
create_topic(TopicName, default_config()).
-spec create_topic(string(), aws_config()) -> string().
create_topic(TopicName, Config)
when is_record(Config, aws_config) ->
Doc = sns_xml_request(Config, "CreateTopic", [{"Name", TopicName}]),
erlcloud_xml:get_text("/CreateTopicResponse/CreateTopicResult/TopicArn", Doc).
-spec confirm_subscription(sns_event()) -> string().
confirm_subscription(SnsEvent) ->
confirm_subscription(SnsEvent, default_config()).
-spec confirm_subscription(sns_event(), aws_config()) -> string().
confirm_subscription(SnsEvent, Config) ->
Token = binary_to_list(proplists:get_value(<<"Token">>, SnsEvent, <<>>)),
TopicArn = binary_to_list(proplists:get_value(<<"TopicArn">>, SnsEvent, <<>>)),
confirm_subscription2(Token, TopicArn, Config).
-spec confirm_subscription(sns_event(), string(), string()) -> string().
confirm_subscription(SnsEvent, AccessKeyID, SecretAccessKey) ->
confirm_subscription(SnsEvent, new_config(AccessKeyID, SecretAccessKey)).
-spec confirm_subscription2(string(), string()) -> string().
confirm_subscription2(Token, TopicArn) ->
confirm_subscription2(Token, TopicArn, default_config()).
-spec confirm_subscription2(string(), string(), aws_config()) -> string().
confirm_subscription2(Token, TopicArn, Config) ->
Doc =
sns_xml_request(
Config, "ConfirmSubscription",
[{"Token", Token},
{"TopicArn", TopicArn}
]),
erlcloud_xml:get_text(
"ConfirmSubscriptionResult/SubscriptionArn", Doc).
-spec confirm_subscription2(string(), string(), string(), string()) -> string().
confirm_subscription2(Token, TopicArn, AccessKeyID, SecretAccessKey) ->
confirm_subscription2(Token, TopicArn, new_config(AccessKeyID, SecretAccessKey)).
-spec delete_endpoint(string()) -> ok.
delete_endpoint(EndpointArn) ->
delete_endpoint(EndpointArn, default_config()).
-spec delete_endpoint(string(), aws_config()) -> ok.
delete_endpoint(EndpointArn, Config) ->
sns_simple_request(Config, "DeleteEndpoint", [{"EndpointArn", EndpointArn}]).
-spec delete_endpoint(string(), string(), string()) -> ok.
delete_endpoint(EndpointArn, AccessKeyID, SecretAccessKey) ->
delete_endpoint(EndpointArn, new_config(AccessKeyID, SecretAccessKey)).
-spec delete_topic(string()) -> ok.
delete_topic(TopicArn) ->
delete_topic(TopicArn, default_config()).
-spec delete_topic(string(), aws_config()) -> ok.
delete_topic(TopicArn, Config)
when is_record(Config, aws_config) ->
sns_simple_request(Config, "DeleteTopic", [{"TopicArn", TopicArn}]).
-spec get_endpoint_attributes(string()) -> sns_endpoint().
get_endpoint_attributes(EndpointArn) ->
get_endpoint_attributes(EndpointArn, default_config()).
-spec get_endpoint_attributes(string(), aws_config()) -> sns_endpoint().
get_endpoint_attributes(EndpointArn, Config) ->
Params = [{"EndpointArn", EndpointArn}],
Doc = sns_xml_request(Config, "GetEndpointAttributes", Params),
Decoded =
erlcloud_xml:decode(
[{attributes, "GetEndpointAttributesResult/Attributes/entry",
fun extract_attribute/1
}],
Doc),
[{arn, EndpointArn} | Decoded].
-spec get_endpoint_attributes(string(), string(), string()) -> sns_endpoint().
get_endpoint_attributes(EndpointArn, AccessKeyID, SecretAccessKey) ->
get_endpoint_attributes(EndpointArn, new_config(AccessKeyID, SecretAccessKey)).
-spec set_endpoint_attributes(string(), [{sns_endpoint_attribute(), string()}]) -> string().
set_endpoint_attributes(EndpointArn, Attributes) ->
set_endpoint_attributes(EndpointArn, Attributes, default_config()).
-spec set_endpoint_attributes(string(), [{sns_endpoint_attribute(), string()}], aws_config()) -> string().
set_endpoint_attributes(EndpointArn, Attributes, Config) ->
Doc = sns_xml_request(Config, "SetEndpointAttributes", [{"EndpointArn", EndpointArn} |
encode_attributes(Attributes)]),
erlcloud_xml:get_text("ResponseMetadata/RequestId", Doc).
-spec list_endpoints_by_platform_application(string()) -> [{endpoints, [sns_endpoint()]} | {next_token, string()}].
list_endpoints_by_platform_application(PlatformApplicationArn) ->
list_endpoints_by_platform_application(PlatformApplicationArn, undefined).
-spec list_endpoints_by_platform_application(string(), undefined|string()) -> [{endpoints, [sns_endpoint()]} | {next_token, string()}].
list_endpoints_by_platform_application(PlatformApplicationArn, NextToken) ->
list_endpoints_by_platform_application(PlatformApplicationArn, NextToken, default_config()).
-spec list_endpoints_by_platform_application(string(), undefined|string(), aws_config()) -> [{endpoints, [sns_endpoint()]} | {next_token, string()}].
list_endpoints_by_platform_application(PlatformApplicationArn, NextToken, Config) ->
Params =
case NextToken of
undefined -> [{"PlatformApplicationArn", PlatformApplicationArn}];
NextToken -> [{"PlatformApplicationArn", PlatformApplicationArn}, {"NextToken", NextToken}]
end,
Doc = sns_xml_request(Config, "ListEndpointsByPlatformApplication", Params),
Decoded =
erlcloud_xml:decode(
[{endpoints, "ListEndpointsByPlatformApplicationResult/Endpoints/member",
fun extract_endpoint/1
},
{next_token, "ListEndpointsByPlatformApplicationResult/NextToken", text}],
Doc),
Decoded.
-spec list_endpoints_by_platform_application(string(), undefined|string(), string(), string()) -> [{endpoints, [sns_endpoint()]} | {next_token, string()}].
list_endpoints_by_platform_application(PlatformApplicationArn, NextToken, AccessKeyID, SecretAccessKey) ->
list_endpoints_by_platform_application(PlatformApplicationArn, NextToken, new_config(AccessKeyID, SecretAccessKey)).
-spec list_topics() -> [{topics, [[{arn, string()}]]} | {next_token, string()}].
list_topics() ->
list_topics(default_config()).
-spec list_topics(undefined | string() | aws_config()) -> [{topics, [[{arn, string()}]]} | {next_token, string()}].
list_topics(Config) when is_record(Config, aws_config) ->
list_topics(undefined, Config);
list_topics(NextToken) ->
list_topics(NextToken, default_config()).
-spec list_topics(undefined | string(), aws_config()) -> [{topics, [[{arn, string()}]]} | {next_token, string()}].
list_topics(NextToken, Config) ->
Params =
case NextToken of
undefined -> [];
NextToken -> [{"NextToken", NextToken}]
end,
Doc = sns_xml_request(Config, "ListTopics", Params),
Decoded =
erlcloud_xml:decode(
[{topics, "ListTopicsResult/Topics/member",
fun extract_topic_arn/1
},
{next_token, "ListTopicsResult/NextToken", text}],
Doc),
Decoded.
-spec list_topics_all() -> [[{arn, string()}]].
list_topics_all() ->
list_topics_all(default_config()).
-spec list_topics_all(aws_config()) -> [[{arn, string()}]].
list_topics_all(Config) ->
list_all(fun list_topics/2, topics, Config, undefined, []).
-spec list_subscriptions() -> proplist().
list_subscriptions() ->
list_subscriptions(default_config()).
-spec list_subscriptions(string() | aws_config()) -> proplist().
list_subscriptions(Config) when is_record(Config, aws_config) ->
list_subscriptions(undefined, Config);
list_subscriptions(NextToken) when is_list(NextToken) ->
list_subscriptions(NextToken, default_config()).
-spec list_subscriptions(undefined | string(), aws_config()) -> proplist().
list_subscriptions(NextToken, Config) when is_record(Config, aws_config) ->
Params =
case NextToken of
undefined -> [];
NextToken -> [{"NextToken", NextToken}]
end,
Doc = sns_xml_request(Config, "ListSubscriptions", Params),
Decoded =
erlcloud_xml:decode(
[{subscriptions, "ListSubscriptionsResult/Subscriptions/member",
fun extract_subscription/1
},
{next_token, "ListSubscriptionsResult/NextToken", text}],
Doc),
Decoded.
-spec list_subscriptions_all() -> proplist().
list_subscriptions_all() ->
list_subscriptions_all(default_config()).
-spec list_subscriptions_all(aws_config()) -> proplist().
list_subscriptions_all(Config) ->
list_all(fun (Token, Cfg) ->
list_subscriptions(Token, Cfg) end,
subscriptions, Config, undefined, []).
-spec list_subscriptions_by_topic(string()) -> proplist().
list_subscriptions_by_topic(TopicArn) when is_list(TopicArn) ->
list_subscriptions_by_topic(TopicArn, default_config()).
-spec list_subscriptions_by_topic(string(), string() | aws_config()) -> proplist().
list_subscriptions_by_topic(TopicArn, Config) when is_record(Config, aws_config) ->
list_subscriptions_by_topic(TopicArn, undefined, Config);
list_subscriptions_by_topic(TopicArn, NextToken) when is_list(NextToken) ->
list_subscriptions_by_topic(TopicArn, NextToken, default_config()).
-spec list_subscriptions_by_topic(string(), undefined | string(), aws_config()) -> proplist().
list_subscriptions_by_topic(TopicArn, NextToken, Config) when is_record(Config, aws_config) ->
Params =
case NextToken of
undefined -> [];
NextToken -> [{"NextToken", NextToken}]
end,
Doc = sns_xml_request(Config, "ListSubscriptionsByTopic", [{"TopicArn", TopicArn}| Params]),
Decoded =
erlcloud_xml:decode(
[{subscriptions, "ListSubscriptionsByTopicResult/Subscriptions/member",
fun extract_subscription/1
},
{next_token, "ListSubscriptionsByTopicResult/NextToken", text}],
Doc),
Decoded.
-spec list_subscriptions_by_topic_all(string()) -> proplist().
list_subscriptions_by_topic_all(TopicArn) ->
list_subscriptions_by_topic_all(TopicArn, default_config()).
-spec list_subscriptions_by_topic_all(string(), aws_config()) -> proplist().
list_subscriptions_by_topic_all(TopicArn, Config) ->
list_all(fun (Token, Cfg) ->
list_subscriptions_by_topic(TopicArn, Token, Cfg) end,
subscriptions, Config, undefined, []).
-spec list_platform_applications() -> [sns_application()].
list_platform_applications() ->
list_platform_applications(undefined).
-spec list_platform_applications(undefined|string()) -> [sns_application()].
list_platform_applications(NextToken) ->
list_platform_applications(NextToken, default_config()).
-spec list_platform_applications(undefined|string(), aws_config()) -> [sns_application()].
list_platform_applications(NextToken, Config) ->
Params =
case NextToken of
undefined -> [];
NextToken -> [{"NextToken", NextToken}]
end,
Doc = sns_xml_request(Config, "ListPlatformApplications", Params),
Decoded =
erlcloud_xml:decode(
[{applications, "ListPlatformApplicationsResult/PlatformApplications/member",
fun extract_application/1
}],
Doc),
proplists:get_value(applications, Decoded, []).
-spec list_platform_applications(undefined|string(), string(), string()) -> [sns_application()].
list_platform_applications(NextToken, AccessKeyID, SecretAccessKey) ->
list_platform_applications(NextToken, new_config(AccessKeyID, SecretAccessKey)).
-spec publish_to_topic(string(), sns_message()) -> string().
publish_to_topic(TopicArn, Message) ->
publish_to_topic(TopicArn, Message, undefined).
-spec publish_to_topic(string(), sns_message(), undefined|string()) -> string().
publish_to_topic(TopicArn, Message, Subject) ->
publish_to_topic(TopicArn, Message, Subject, default_config()).
-spec publish_to_topic(string(), sns_message(), undefined|string(), aws_config()) -> string().
publish_to_topic(TopicArn, Message, Subject, Config) ->
publish(topic, TopicArn, Message, Subject, Config).
-spec publish_to_topic(string(), sns_message(), undefined|string(), string(), string()) -> string().
publish_to_topic(TopicArn, Message, Subject, AccessKeyID, SecretAccessKey) ->
publish_to_topic(TopicArn, Message, Subject, new_config(AccessKeyID, SecretAccessKey)).
-spec publish_to_target(string(), sns_message()) -> string().
publish_to_target(TargetArn, Message) ->
publish_to_target(TargetArn, Message, undefined).
-spec publish_to_target(string(), sns_message(), undefined|string()) -> string().
publish_to_target(TargetArn, Message, Subject) ->
publish_to_target(TargetArn, Message, Subject, default_config()).
-spec publish_to_target(string(), sns_message(), undefined|string(), aws_config()) -> string().
publish_to_target(TargetArn, Message, Subject, Config) ->
publish(target, TargetArn, Message, Subject, Config).
-spec publish_to_target(string(), sns_message(), undefined|string(), string(), string()) -> string().
publish_to_target(TargetArn, Message, Subject, AccessKeyID, SecretAccessKey) ->
publish_to_target(TargetArn, Message, Subject, new_config(AccessKeyID, SecretAccessKey)).
%% TargetArn can be a phone number string, e.g. "+55 (11) 9999-7777"
-spec publish_to_phone(string(), sns_message()) -> string().
publish_to_phone(TargetArn, Message) ->
publish_to_phone(TargetArn, Message, default_config()).
-spec publish_to_phone(string(), sns_message(), aws_config()) -> string().
publish_to_phone(TargetArn, Message, Config) ->
publish(phone, TargetArn, Message, undefined, Config).
-spec publish_to_phone(string(), sns_message(), string(), string()) -> string().
publish_to_phone(TargetArn, Message, AccessKeyID, SecretAccessKey) ->
publish(phone, TargetArn, Message, undefined, new_config(AccessKeyID, SecretAccessKey)).
%% @doc
%% Publish API:
%% [http://docs.aws.amazon.com/sns/latest/api/API_Publish.html]
-spec publish(topic|target|phone, string(), sns_message(), undefined|string(), aws_config()) -> string().
publish(Type, RecipientArn, Message, Subject, Config) ->
publish(Type, RecipientArn, Message, Subject, [], Config).
-spec publish(topic|target|phone, string(), sns_message(), undefined|string(), sns_message_attributes(), aws_config()) -> string().
publish(Type, RecipientArn, Message, Subject, Attributes, Config) ->
RecipientParam =
case Type of
topic -> [{"TopicArn", RecipientArn}];
target -> [{"TargetArn", RecipientArn}];
phone -> [{"PhoneNumber", RecipientArn}]
end,
MessageParams =
case Message of
[{_,_} |_] ->
EncodedMessage = jsx:encode(Message),
[{"Message", EncodedMessage},
{"MessageStructure", "json"}];
Message ->
[{"Message", Message}]
end,
SubjectParam =
case Subject of
undefined -> [];
Subject -> [{"Subject", Subject}]
end,
AttributesParam = message_attributes(Attributes),
Doc =
sns_xml_request(
Config, "Publish",
RecipientParam ++ MessageParams ++ SubjectParam ++ AttributesParam),
erlcloud_xml:get_text(
"PublishResult/MessageId", Doc).
-spec parse_event(iodata()) -> sns_event().
parse_event(EventSource) ->
jsx:decode(EventSource, [{return_maps, false}]).
-spec get_event_type(sns_event()) -> sns_event_type().
get_event_type(Event) ->
case proplists:get_value(<<"Type">>, Event) of
<<"SubscriptionConfirmation">> -> subscription_confirmation;
<<"Notification">> -> notification
end.
-spec parse_event_message(sns_event()) -> sns_notification() | binary().
parse_event_message(Event) ->
Message = proplists:get_value(<<"Message">>, Event, <<>>),
case get_event_type(Event) of
subscription_confirmation -> Message;
notification -> jsx:decode(Message, [{return_maps, false}])
end.
-spec get_notification_attribute(binary(), sns_notification()) -> sns_application_attribute() | binary().
get_notification_attribute(<<"EventType">>, Notification) ->
case proplists:get_value(<<"EventType">>, Notification) of
<<"EndpointCreated">> -> event_endpoint_created;
<<"EndpointDeleted">> -> event_endpoint_deleted;
<<"EndpointUpdated">> -> event_endpoint_updated;
<<"DeliveryFailure">> -> event_delivery_failure
end;
get_notification_attribute(Attribute, Notification) ->
proplists:get_value(Attribute, Notification).
-spec set_topic_attributes(sns_topic_attribute_name(), string()|binary(), string()) -> ok.
set_topic_attributes(AttributeName, AttributeValue, TopicArn) ->
set_topic_attributes(AttributeName, AttributeValue, TopicArn, default_config()).
-spec set_topic_attributes(sns_topic_attribute_name(), string()|binary(), string(), aws_config()) -> ok.
set_topic_attributes(AttributeName, AttributeValue, TopicArn, Config)
when is_record(Config, aws_config) ->
sns_simple_request(Config, "SetTopicAttributes", [
{"AttributeName", AttributeName},
{"AttributeValue", AttributeValue},
{"TopicArn", TopicArn}]).
-spec get_topic_attributes (string()) -> [{attributes, [{atom(), string()}]}].
get_topic_attributes(TopicArn) ->
get_topic_attributes(TopicArn, default_config()).
-spec get_topic_attributes(string(), aws_config()) -> [{attributes, [{atom(), string()}]}].
get_topic_attributes(TopicArn, Config)
when is_record(Config, aws_config) ->
Params = [{"TopicArn", TopicArn}],
Doc = sns_xml_request(Config, "GetTopicAttributes", Params),
Decoded =
erlcloud_xml:decode(
[{attributes, "GetTopicAttributesResult/Attributes/entry",
fun extract_attribute/1
}],
Doc),
Decoded.
-spec set_subscription_attributes(sns_subscription_attribute_name(), string()|binary(), string()) -> ok.
set_subscription_attributes(AttributeName, AttributeValue, SubscriptionArn) ->
set_subscription_attributes(AttributeName, AttributeValue, SubscriptionArn, default_config()).
-spec set_subscription_attributes(sns_subscription_attribute_name(), string()|binary(), string(), aws_config()) -> ok.
set_subscription_attributes(AttributeName, AttributeValue, SubscriptionArn, Config)
when is_record(Config, aws_config) ->
sns_simple_request(Config, "SetSubscriptionAttributes", [
{"AttributeName", AttributeName},
{"AttributeValue", AttributeValue},
{"SubscriptionArn", SubscriptionArn}]).
-spec get_subscription_attributes (string()) -> [{attributes, [{sns_subscription_attribute_name() | atom(), string()}]}].
get_subscription_attributes(SubscriptionArn) ->
get_subscription_attributes(SubscriptionArn, default_config()).
-spec get_subscription_attributes(string(), aws_config()) -> [{attributes, [{sns_subscription_attribute_name() | atom(), string()}]}].
get_subscription_attributes(SubscriptionArn, Config)
when is_record(Config, aws_config) ->
Params = [{"SubscriptionArn", SubscriptionArn}],
Doc = sns_xml_request(Config, "GetSubscriptionAttributes", Params),
Decoded =
erlcloud_xml:decode(
[{attributes, "GetSubscriptionAttributesResult/Attributes/entry",
fun extract_attribute/1
}],
Doc),
Decoded.
-spec subscribe(string(), sns_subscribe_protocol_type(), string()) -> Arn::string().
subscribe(Endpoint, Protocol, TopicArn) ->
subscribe(Endpoint, Protocol, TopicArn, default_config()).
-spec subscribe(string(), sns_subscribe_protocol_type(), string(), aws_config()) -> Arn::string().
subscribe(Endpoint, Protocol, TopicArn, Config)
when is_record(Config, aws_config) ->
Doc = sns_xml_request(Config, "Subscribe", [
{"Endpoint", Endpoint},
{"Protocol", atom_to_list(Protocol)},
{"TopicArn", TopicArn}]),
erlcloud_xml:get_text("/SubscribeResponse/SubscribeResult/SubscriptionArn", Doc).
-spec unsubscribe(string()) -> ok.
unsubscribe(SubArn) ->
unsubscribe(SubArn, default_config()).
-spec unsubscribe(string(), aws_config()) -> ok.
unsubscribe(SubArn, Config)
when is_record(Config, aws_config) ->
sns_simple_request(Config, "Unsubscribe", [{"SubscriptionArn", SubArn}]).
-spec new(string(), string()) -> aws_config().
new(AccessKeyID, SecretAccessKey) ->
#aws_config{
access_key_id=AccessKeyID,
secret_access_key=SecretAccessKey
}.
-spec new(string(), string(), string()) -> aws_config().
new(AccessKeyID, SecretAccessKey, Host) ->
#aws_config{
access_key_id=AccessKeyID,
secret_access_key=SecretAccessKey,
sns_host=Host
}.
-spec configure(string(), string()) -> ok.
configure(AccessKeyID, SecretAccessKey) ->
put(aws_config, new(AccessKeyID, SecretAccessKey)),
ok.
-spec configure(string(), string(), string()) -> ok.
configure(AccessKeyID, SecretAccessKey, Host) ->
put(aws_config, new(AccessKeyID, SecretAccessKey, Host)),
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% PRIVATE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
encode_attributes(Attributes) ->
lists:foldl(
fun({Index, {Key, Value}}, Acc) ->
Prefix = "Attributes.entry." ++ integer_to_list(Index),
[{Prefix ++ ".key", encode_attribute_name(Key)},
{Prefix ++ ".value", Value} | Acc]
end, [], lists:zip(lists:seq(1, length(Attributes)), Attributes)).
encode_attribute_name(platform_credential) -> "PlatformCredential";
encode_attribute_name(platform_principal) -> "PlatformPrincipal";
encode_attribute_name(event_endpoint_created) -> "EventEndpointCreated";
encode_attribute_name(event_endpoint_deleted) -> "EventEndpointDeleted";
encode_attribute_name(event_endpoint_updated) -> "EventEndpointUpdated";
encode_attribute_name(event_delivery_failure) -> "EventDeliveryFailure";
encode_attribute_name(success_feedback_role_arn) -> "SuccessFeedbackRoleArn";
encode_attribute_name(failure_feedback_role_arn) -> "FailureFeedbackRoleArn";
encode_attribute_name(success_feedback_sample_rate) -> "SuccessFeedbackSampleRate";
encode_attribute_name(enabled) -> "Enabled";
encode_attribute_name(token) -> "Token".
encode_permissions(Permissions) ->
[encode_permission(P) || P <- Permissions].
encode_permission({AccountId, Permission}) ->
{AccountId,
case Permission of
all -> "*";
add_permission -> "AddPermission";
confirm_subscription -> "ConfirmSubscription";
create_platform_application -> "CreatePlatformApplication";
create_platform_endpoint -> "CreatePlatformEndpoint";
create_topic -> "CreateTopic";
delete_endpoint -> "DeleteEndpoint";
delete_platform_application -> "DeletePlatformApplication";
delete_topic -> "DeleteTopic";
get_endpoint_attributes -> "GetEndpointAttributes";
get_platform_application_attributes -> "GetPlatformApplicationAttributes";
get_subscription_attributes -> "GetSubscriptionAttributes";
get_topic_attributes -> "GetTopicAttributes";
list_endpoints_by_platform_application -> "ListEndpointsByPlatformApplication";
list_platform_applications -> "ListPlatformApplications";
list_subscriptions -> "ListSubscriptions";
list_subscriptions_by_topic -> "ListSubscriptionsByTopic";
list_topics -> "ListTopics";
publish -> "Publish";
remove_permission -> "RemovePermission";
set_endpoint_attributes -> "SetEndpointAttributes";
set_platform_application_attributes -> "SetPlatformApplicationAttributes";
set_subscription_attributes -> "SetSubscriptionAttributes";
set_topic_attributes -> "SetTopicAttributes";
subscribe -> "Subscribe";
unsubscribe -> "Unsubscribe"
end}.
default_config() -> erlcloud_aws:default_config().
new_config(AccessKeyID, SecretAccessKey) ->
#aws_config{
access_key_id=AccessKeyID,
secret_access_key=SecretAccessKey
}.
sns_simple_request(Config, Action, Params) ->
sns_request(Config, Action, Params),
ok.
sns_xml_request(Config, Action, Params) ->
case erlcloud_aws:aws_request_xml4(post,
scheme_to_protocol(Config#aws_config.sns_scheme),
Config#aws_config.sns_host, Config#aws_config.sns_port, "/",
[{"Action", Action}, {"Version", ?API_VERSION} | Params],
"sns", Config) of
{ok, XML} -> XML;
{error, {http_error, _, _BadRequest, Body}} ->
XML = element(1, xmerl_scan:string(binary_to_list(Body))),
ErrCode = erlcloud_xml:get_text("Error/Code", XML),
ErrMsg = erlcloud_xml:get_text("Error/Message", XML),
erlang:error({sns_error, ErrCode, ErrMsg});
{error, Reason} ->
erlang:error({sns_error, Reason})
end.
sns_request(Config, Action, Params) ->
case erlcloud_aws:aws_request_xml4(post,
scheme_to_protocol(Config#aws_config.sns_scheme),
Config#aws_config.sns_host, Config#aws_config.sns_port, "/",
[{"Action", Action}, {"Version", ?API_VERSION} | Params],
"sns", Config) of
{ok, _Response} -> ok;
{error, {http_error, 400, _BadRequest, Body}} ->
XML = element(1, xmerl_scan:string(binary_to_list(Body))),
ErrCode = erlcloud_xml:get_text("Error/Code", XML),
ErrMsg = erlcloud_xml:get_text("Error/Message", XML),
erlang:error({sns_error, ErrCode, ErrMsg});
{error, Reason} ->
erlang:error({sns_error, Reason})
end.
list_all(Fun, Type, Config, Token, Acc) ->
Res = Fun(Token, Config),
List = proplists:get_value(Type, Res),
case proplists:get_value(next_token, Res) of
"" ->
lists:foldl(fun erlang:'++'/2, [], [List | Acc]);
NextToken ->
list_all(Fun, Type, Config, NextToken, [List | Acc])
end.
extract_endpoint(Nodes) ->
[erlcloud_xml:decode(
[{arn, "EndpointArn", text},
{attributes, "Attributes/entry", fun extract_attribute/1}
], Node) || Node <- Nodes].
extract_application(Nodes) ->
[erlcloud_xml:decode(
[{arn, "PlatformApplicationArn", text},
{attributes, "Attributes/entry", fun extract_attribute/1}
], Node) || Node <- Nodes].
extract_attribute(Nodes) ->
[{parse_key(erlcloud_xml:get_text("key", Node)),
erlcloud_xml:get_text("value", Node)}
|| Node <- Nodes].
extract_subscription(Nodes) ->
[erlcloud_xml:decode(
[{topic_arn, "TopicArn", text},
{protocol, "Protocol", text},
{arn, "SubscriptionArn", text},
{owner, "Owner", text},
{endpoint, "Endpoint", text}
], Node) || Node <- Nodes].
extract_topic_arn(Nodes) ->
[erlcloud_xml:decode([{arn, "TopicArn", text}], Node) || Node <- Nodes].
parse_key("Enabled") -> enabled;
parse_key("CustomUserData") -> custom_user_data;
parse_key("Token") -> token;
parse_key("EventEndpointCreated") -> event_endpoint_created;
parse_key("EventEndpointDeleted") -> event_endpoint_deleted;
parse_key("EventEndpointUpdated") -> event_endpoint_updated;
parse_key("EventDeliveryFailure") -> event_delivery_failure;
% Subscription attribute names.
parse_key("RawMessageDelivery") -> 'RawMessageDelivery';
parse_key("ConfirmationWasAuthenticated") -> 'ConfirmationWasAuthenticated';
parse_key("FilterPolicy") -> 'FilterPolicy';
parse_key("DeliveryPolicy") -> 'DeliveryPolicy';
parse_key(OtherKey) -> list_to_atom(string:to_lower(OtherKey)).
scheme_to_protocol(S) when is_list(S) -> s2p(string:to_lower(S));
scheme_to_protocol(_) -> erlang:error({sns_error, badarg}).
s2p("http://") -> "http";
s2p("https://") -> "https";
s2p(X) -> erlang:error({sns_error, {unsupported_scheme, X}}).
-spec message_attributes(sns_message_attributes()) -> [{string(), string()}].
message_attributes(Attributes) ->
EnumeratedAttrs = lists:zip(lists:seq(1, length(Attributes)), Attributes),
lists:flatmap(
fun({Num, {Name, Value}}) ->
[format_attribute_field(Num, Field) || Field <- fields_for_attribute(Name, Value)]
end,
EnumeratedAttrs).
-spec format_attribute_field(integer(), {string(), string()}) -> {string(), string()}.
format_attribute_field(Num, {Key, Value}) ->
StrNum = integer_to_list(Num),
{"MessageAttributes.entry." ++ StrNum ++ "." ++ Key, Value}.
-spec fields_for_attribute(string(), string() | binary() | number()) -> [{string(), string()}].
fields_for_attribute(Name, Value) ->
[{"Name", Name} | fields_for_attribute(Value)].
-spec fields_for_attribute(string() | binary() | number()) -> [{string(), string()}].
fields_for_attribute(Value) when is_list(Value) ->
[{"Value.DataType", "String"}, {"Value.StringValue", Value}];
fields_for_attribute(Value) when is_binary(Value) ->
[{"Value.DataType", "Binary"}, {"Value.BinaryValue", base64:encode_to_string(Value)}];
fields_for_attribute(Value) when is_float(Value) ->
[{"Value.DataType", "Number"}, {"Value.StringValue", float_to_list(Value)}];
fields_for_attribute(Value) when is_integer(Value) ->
[{"Value.DataType", "Number"}, {"Value.StringValue", integer_to_list(Value)}].