Amazon-SNS
view release on metacpan or search on metacpan
lib/Amazon/SNS.pm view on Meta::CPAN
Amazon::SNS::Topic->new({
'sns' => $self,
'arn' => $_->{'TopicArn'},
})
} @{$r->{'ListTopicsResult'}{'Topics'}[0]{'member'}};
}
sub Subscribe
{
my ($self, $protocol, $topicarn, $endpoint) = @_;
$self->dispatch({
'Action' => 'Subscribe',
'Protocol' => $protocol,
'TopicArn' => $topicarn,
'Endpoint' => $endpoint,
});
}
sub Unsubscribe
{
my ($self, $arn) = @_;
$self->dispatch({
'Action' => 'Unsubscribe',
'SubscriptionArn' => $arn,
});
}
sub dispatch
{
my ($self, $args) = @_;
$self->error(undef);
$self->service('http://sns.eu-west-1.amazonaws.com')
unless defined $self->service;
# sanitize args
do { delete $args->{$_} unless defined $args->{$_} } for (keys %$args);
# add signature elements
$args->{'Timestamp'} = $self->timestamp;
$args->{'AWSAccessKeyId'} = $self->key;
$args->{'SignatureVersion'} = 2;
$args->{'SignatureMethod'} = 'HmacSHA256';
$args->{'Version'} = '2010-03-31';
if (defined($args->{'Attributes'}) and ref($args->{'Attributes'}) eq 'HASH') {
foreach my $attr (keys %{$args->{'Attributes'}}) {
$args->{$attr} = $args->{'Attributes'}->{$attr};
}
delete $args->{'Attributes'};
}
# build URI
my $uri = URI->new($self->service);
$uri->path('/');
$uri->query(join('&', map { $_ . '=' . URI::Escape::uri_escape_utf8($args->{$_}, '^A-Za-z0-9\-_.~') } sort keys %$args ));
# create signature
$args->{'Signature'} = hmac_sha256_base64(join("\n", 'POST', $uri->host, $uri->path, $uri->query), $self->secret);
# padding
while (length($args->{'Signature'}) % 4) {
$args->{'Signature'} .= '=';
}
# rewrite query string
$uri->query(join('&', map { $_ . '=' . URI::Escape::uri_escape_utf8($args->{$_}, '^A-Za-z0-9\-_.~') } sort keys %$args ));
my $response = LWP::UserAgent->new->post($self->service, 'Content' => $uri->query);
$self->status_code($response->code);
if ($response->is_success) {
return XMLin($response->content,
'SuppressEmpty' => 1,
# 'KeyAttr' => { },
'ForceArray' => [ qw/ Topics member / ],
);
} else {
print $response->content, "\n";
$self->error(
($response->content =~ /^<.+>/)
? eval { XMLin($response->content)->{'Error'}{'Message'} || $response->status_line }
: $response->status_line
);
}
print STDERR 'ERROR: ', $self->error, "\n"
if $self->debug;
return undef;
}
sub timestamp {
return sprintf("%04d-%02d-%02dT%02d:%02d:%02d.000Z", sub {
($_[5]+1900, $_[4]+1, $_[3], $_[2], $_[1], $_[0])
}->(gmtime(time)));
}
1;
package Amazon::SNS::Topic;
use strict;
use warnings;
use base qw(Class::Accessor);
use JSON;
__PACKAGE__->mk_accessors(qw/ sns arn /);
sub Publish
{
my ($self, $msg, $subj) = @_;
# XXX croak on invalid arn
my $structure = undef;
# support JSON payload
if (ref($msg) eq 'HASH') {
$structure = 'json';
$msg = encode_json($msg);
( run in 1.927 second using v1.01-cache-2.11-cpan-5837b0d9d2c )