2011-11-04 13 views

Respuesta

1

utilicé Net :: Amazon :: AWSSign en conjunción con una pequeña secuencia de comandos:

#!/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; 

realidad utilicé XML :: Simple en el final, y se pasa el resultado a partir del rizo a XMLIn, para analizar el XML que Amazon devuelve. Haz lo que quieras ...

2

Amazon::SNS existe. Los documentos son bastante escasos, pero parece que es lo básico, y la calidad del código se ve bien para mí.

+0

Sí. Intenté eso. Numerosos numerosos problemas – Brad

+0

@Brad por favor, hágamelo saber los problemas que ha enfrentado. Versión más reciente disponible en https://github.com/dwery/amazon-sns – dwery

0

Utilicé Brad's como punto de partida, ¡gracias Brad! Tuve el cambio del horario local a gmtime. Tampoco estaba usando temas, sino ARNs de destino y el uso de la autenticación basada en roles. Tuve que pasar el SecurityToken para que funcione y el mensaje solo funcionó para Android cuando lo puse en un contenedor GCM json. En el código, uso mi nombre de aplicación en TargetARN para detectar la plataforma y ajustar la carga útil en consecuencia. Nota: Código de Windows no probado.

Una última nota importante es la loca codificación anidada json que parece ser necesaria para 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; 
     } 
} 
Cuestiones relacionadas