2011-11-04 11 views

Odpowiedz

1

użyłem Net :: Amazon :: AWSSign w połączeniu z niewielką skryptu:

#!/usr/bin/perl 

use Net::Amazon::AWSSign; 

$ACCESS_KEY_ID="<my key id>"; 
$SECRET_KEY="<my secret key>"; 
$TOPIC_ARN='<my topic arn>'; 
$TOPIC_ARN =~ s/:/%3A/g; 
$MESSAGE="This is a test"; 

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); 

$year += 1900; 
$mon+=1; 

$timestamp = sprintf("%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d.000Z", 
     $year,$mon,$mday,$hour,$min,$sec); 
$timestamp =~ s/:/%3A/g; 

$REQUEST="http://sns.us-east-1.amazonaws.com/". 
"?TopicArn=$TOPIC_ARN". 
"&Message=$MESSAGE". 
"&Action=Publish". 
"&SignatureVersion=2". 
"&SignatureMethod=HmacSHA256". 
"&Timestamp=$timestamp". 
"&AWSAccessKeyId=$ACCESS_KEY_ID"; 

my $awsSign=new Net::Amazon::AWSSign("$ACCESS_KEY_ID", "$SECRET_KEY"); 

$signed = $awsSign->addRESTSecret($REQUEST); 

$res = `curl -s -o- '$signed'`; 
if ($res =~ /<error>/) { 
     print "ERROR!\n"; 
     return 1; 
} 

0; 

I rzeczywiście używany XML :: Proste w końcu, i zdał rezultat od Curl do XMLIn, do analizowania XML, który zwraca Amazon. Rób to, co chcesz ...

2

Amazon::SNS istnieje. Dokumenty są dość nieliczne, ale wygląda na to, że mają podstawy, a jakość kodu wygląda dla mnie dobrze.

+0

Tak. Próbowałem tego. Liczne liczne problemy. – Brad

+0

@Brad proszę dać mi znać problemy, z którymi się spotkałeś. Najbardziej dostępna wersja dostępna na https://github.com/dwery/amazon-sns – dwery

0

Użyłem Brada jako punktu wyjścia, dzięki Brad! Miałem zmienić czas lokalny na gmtime. Nie korzystałem również z tematów, ale z docelowych ARN i używania uwierzytelniania opartego na rolach. Musiałem przekazać hasło SecurityToken, aby działało, a Wiadomość działa tylko dla Androida push, kiedy umieściłem go w opakowaniu json GCM. W kodzie używam mojej nazwy aplikacji w TargetARN, aby wykryć platformę i odpowiednio dostosować ładunek. Uwaga: kod systemu Windows jest nietestowany.

Jednym z ostatnich notatek jest zwariowane zagnieżdżone kodowanie json, które wydaje się być wymagane od SNS.

sub send_sns 
{ 
# required arguments: endpoint (AWS SNS endpoint), message 
     my $args = shift; 
     my $TargetArn=encode_url($args->{endpoint}); 
     my $message=$args->{message}; 
     my $data = {}; 
     my $json = JSON->new->utf8->allow_nonref; 
     if ($args->{endpoint} =~ /GCM\/[a-z]+_android\//) { 
#    Android 
       $data->{data}{message}=$args->{message}; 
       my $dataString = $json->encode($data); 
       $message = '{"GCM": '.$json->encode($dataString).'}'; 
     } elsif ($args->{endpoint} =~ /APNS\/[a-z]+_apple_ios\//) { 
#    iOS 
       $data->{aps}{alert}=$args->{message}; 
       my $dataString = $json->encode($data); 
       $message = '{"APNS": '.$json->encode($dataString).'}'; 
     } elsif ($args->{endpoint} =~ /ADM\/[a-z]+_windows\//) { 
#    windows (incomplete) 
       $data->{data}{message}=$args->{message}; 
       my $dataString = $json->encode($data); 
       $message = '{"ADM": '.$json->encode($dataString).'}'; 
     } 
     use Net::Amazon::AWSSign; 
     my $credentials = qx[ curl -s --fail http://169.254.169.254/latest/meta-data/iam/security-credentials/myrole ]; 
     my $credObj = decode_json($credentials); 
     my $ACCESS_KEY_ID=$credObj->{AccessKeyId}; 
     my $SECRET_KEY=$credObj->{SecretAccessKey}; 
     my $token=$credObj->{Token}; 
     my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time); 
     $year += 1900; 
     $mon+=1; 
     my $timestamp = sprintf("%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d.000Z", 
         $year,$mon,$mday,$hour,$min,$sec); 
     $timestamp =~ s/:/%3A/g; 
     my $REQUEST="http://sns.us-east-1.amazonaws.com/". 
       "?TargetArn=$TargetArn". 
       "&Message=$message". 
       "&Action=Publish". 
       "&SignatureVersion=2". 
       "&SignatureMethod=HmacSHA256". 
       "&Timestamp=$timestamp". 
       "&SecurityToken=$token". 
       "&MessageStructure=json". 
       "&AWSAccessKeyId=$ACCESS_KEY_ID"; 
     my $awsSign=new Net::Amazon::AWSSign("$ACCESS_KEY_ID", "$SECRET_KEY"); 
     my $signed = $awsSign->addRESTSecret($REQUEST); 
     $res = `curl -s -o- '$signed'`; 
print "returns: $res\n" if -t; 
     if ($res =~ /<error>/) { 
       print "ERROR!\n"; 
       return 1; 
     } else { 
       return 0; 
     } 
}