web-dev-qa-db-fra.com

Comment envoyer des paramètres supplémentaires dans la charge via Amazon SNS Push Notification

C’est quelque chose de nouveau que je demande car je n’ai aucune réponse à ce sujet sur SO.

J'utilise Amazon SNS Push pour envoyer Push à mes appareils enregistrés, tout fonctionne bien, je peux enregistrer des appareils sur mon application en premier démarrage, envoyer Push etc. Le problème que je rencontre est que je veux ouvrir une page spécifique quand j'ouvre mon application via Push. Je veux envoyer des paramètres supplémentaires avec la charge utile, mais je ne suis pas en mesure de le faire.

J'ai essayé ce lien: - http://docs.aws.Amazon.com/sns/latest/api/API_Publish.html

nous n'avons qu'une seule clé, "Message", dans laquelle nous pouvons transmettre la charge utile dans la mesure où je le sais.

je veux passer une charge comme celle-ci: - 

{
    aps = {
            alert = "My Push text Msg";
          };
    "id" = "123",
    "s" = "section"
}

ou tout autre format est bon, je voulais juste passer 2-3 valeurs avec charge utile afin que je puisse les utiliser dans mon application.

Le code que j'utilise pour l'envoi de Push est: -

// Load the AWS SDK for PHP
if($_REQUEST)
{
    $title=$_REQUEST["Push_text"];

    if($title!="")
    {
        require 'aws-sdk.phar';


        // Create a new Amazon SNS client
        $sns = Aws\Sns\SnsClient::factory(array(
            'key'    => '...',
            'secret' => '...',
            'region' => 'us-east-1'
        ));

        // Get and display the platform applications
        //print("List All Platform Applications:\n");
        $Model1 = $sns->listPlatformApplications();

        print("\n</br></br>");*/

        // Get the Arn of the first application
        $AppArn = $Model1['PlatformApplications'][0]['PlatformApplicationArn'];

        // Get the application's endpoints
        $Model2 = $sns->listEndpointsByPlatformApplication(array('PlatformApplicationArn' => $AppArn));

        // Display all of the endpoints for the first application
        //print("List All Endpoints for First App:\n");
        foreach ($Model2['Endpoints'] as $Endpoint)
        {
          $EndpointArn = $Endpoint['EndpointArn'];
          //print($EndpointArn . "\n");
        }
        //print("\n</br></br>");

        // Send a message to each endpoint
        //print("Send Message to all Endpoints:\n");
        foreach ($Model2['Endpoints'] as $Endpoint)
        {
          $EndpointArn = $Endpoint['EndpointArn'];

          try
          {
            $sns->publish(array('Message' => $title,
                    'TargetArn' => $EndpointArn));

            //print($EndpointArn . " - Succeeded!\n");
          }
          catch (Exception $e)
          {
            //print($EndpointArn . " - Failed: " . $e->getMessage() . "!\n");
          }
        }
    }
}
?>

Toute aide ou idée sera appréciée. Merci d'avance.

26
mAc

La documentation d'Amazon SNS fait toujours défaut ici, avec quelques indications sur la façon de formater un message pour utiliser une charge personnalisée. Ce FAQ explique comment procéder, mais ne fournit pas d'exemple.

La solution consiste à publier la notification avec le paramètre MessageStructure défini sur json et un paramètre Message codé en json, avec une clé pour chaque protocole de transport. Il doit toujours y avoir une clé default aussi, comme solution de secours. 

Voici un exemple de notifications iOS avec une charge personnalisée:

array(
    'TargetArn' => $EndpointArn,
    'MessageStructure' => 'json',
    'Message' => json_encode(array(
        'default' => $title,
        'APNS' => json_encode(array(
            'aps' => array(
                'alert' => $title,
            ),
            // Custom payload parameters can go here
            'id' => '123',
            's' => 'section'
        ))

    ))
);

Il en va de même pour les autres protocoles. Le format du message json_encoded doit être comme ceci (mais vous pouvez omettre des clés si vous n'utilisez pas le transport):

{ 
    "default": "<enter your message here>", 
    "email": "<enter your message here>", 
    "sqs": "<enter your message here>", 
    "http": "<enter your message here>", 
    "https": "<enter your message here>", 
    "sms": "<enter your message here>", 
    "APNS": "{\"aps\":{\"alert\": \"<message>\",\"sound\":\"default\"} }", 
    "APNS_SANDBOX": "{\"aps\":{\"alert\": \"<message>\",\"sound\":\"default\"} }", 
    "GCM": "{ \"data\": { \"message\": \"<message>\" } }", 
    "ADM": "{ \"data\": { \"message\": \"<message>\" } }" 
}
58
felixdv

A partir d'une fonction Lambda (Node.js), l'appel devrait être:

exports.handler = function(event, context) {

  var params = {
    'TargetArn' : $EndpointArn,
    'MessageStructure' : 'json',
    'Message' : JSON.stringify({
      'default' : $title,
      'APNS' : JSON.stringify({
        'aps' : { 
          'alert' : $title,
          'badge' : '0',
          'sound' : 'default'
        },
        'id' : '123',
        's' : 'section',
      }),
      'APNS_SANDBOX' : JSON.stringify({
        'aps' : { 
          'alert' : $title,
          'badge' : '0',
          'sound' : 'default'
        },
        'id' : '123',
        's' : 'section',
      })
    })
  };

  var sns = new AWS.SNS({apiVersion: '2010-03-31', region: 'us-east-1' });
  sns.publish(params, function(err, data) {
    if (err) {
      // Error
      context.fail(err);
    }
    else {
      // Success
      context.succeed();
    }
  });
}

Vous pouvez simplifier en spécifiant un seul protocole: APNS ou APNS_SANDBOX.

6
rjobidon

Je suis trop inexpérimenté pour commenter ici mais je voudrais attirer l'attention des gens sur le json_encode imbriqué. Ceci est important sans cela, la chaîne APNS ne sera pas analysée par Amazon et n'enverra que la valeur du message par défaut.

Je faisais ce qui suit:

$message = json_encode(array(
   'default'=>$msg,
   'APNS'=>array(
      'aps'=>array(
         'alert'=>$msg,
         'sound'=>'default'
         ),
         'id'=>$id,
         'other'=>$other
       )
     )
   );

Mais cela ne fonctionnera pas. Vous DEVEZ json_encoder le tableau sous 'APNS' séparément comme indiqué dans la réponse de felixdv. Ne me demandez pas pourquoi, car les sorties ont exactement la même apparence dans le journal de ma console. Bien que la documentation montre que la chaîne "json" sous la clé "APNS" devrait être "" enveloppée dans ", alors pensez-vous que cela a quelque chose à voir avec cela.

http://docs.aws.Amazon.com/sns/latest/dg/mobile-Push-send-custommessage.html

Ne vous y trompez pas, car le JSON validera sans ces guillemets.

De plus, je ne suis pas sûr du commentaire de emkman. Sans l'envoi de la clé 'default' dans la structure ci-dessus à un seul ARN d'extrémité, AWS recevrait une erreur.

J'espère que cela accélère l'après-midi.

MODIFIER

Par la suite, le besoin d'imbriquer les json_encodes a été clarifié - il crée des guillemets doubles échappés qui, malgré les docs indiquant qu'ils ne sont pas requis à l'API, concernent la chaîne entière pour GCM et comme ci-dessus le sous-tableau sous APNS pour Apple. C’est peut-être mon implémentation, mais elle est pratiquement prête à utiliser le SDK AWS PHP et était le seul moyen de lui faire envoyer des données personnalisées.

4
Mike Miller

Il est facile de rater le fait que vous devez ajouter APNS_SANDBOX ainsi que APNS pour effectuer des tests localement.

0
Brian F