¿Cómo puedo enviar parámetros adicionales en la carga útil a través de notificaciones push de Amazon SNS?

7 minutos de lectura

avatar de usuario de mac
Mac

Esto es algo nuevo que estoy preguntando ya que no tengo ninguna respuesta en SO.

Estoy usando Amazon SNS Push para enviar notificaciones a mis dispositivos registrados, todo funciona bien, puedo registrar dispositivos en el primer inicio de mi aplicación, puedo enviar notificaciones, etc. El problema al que me enfrento es que quiero abrir una página específica cuando abro mi aplicación a través de push. Quiero enviar algunos parámetros adicionales con la carga útil, pero no puedo hacerlo.

Intenté este enlace: –
http://docs.aws.amazon.com/sns/latest/api/API_Publish.html

solo tenemos una clave, es decir, “Mensaje”, en la que podemos pasar la carga útil hasta donde yo sé.

Quiero pasar una carga útil como esta: –

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

o cualquier otro formato está bien, solo quería pasar 2-3 valores junto con la carga útil para poder usarlos en mi aplicación.

El código que estoy usando para enviar push es: –

// 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");
          }
        }
    }
}
?>

  • Bueno, obtuve la solución, Amazon debería haberlo mencionado en su documentación de implementación, pronto subiré la respuesta.

    – Mac

    20 de septiembre de 2013 a las 5:12

  • Hola, por favor comparte la solución, estoy atascado en el mismo problema 🙂

    – felixdv

    24 de septiembre de 2013 a las 2:26

  • ¿alguna vez encontraste cuál era el problema? Tengo lo mismo: todo lo que puedo enviar es el mensaje predeterminado. Estoy en una plataforma diferente pero el mismo problema: stackoverflow.com/q/22366310/850969

    – MikeT

    13/03/2014 a las 18:32

  • La solución se da a continuación, ¿tiene algún otro problema?

    – Mac

    18 de marzo de 2014 a las 12:24

  • oye, ¿dónde puedo descargar “aws-sdk.phar”?

    – Codesen

    5 de mayo de 2014 a las 8:15

Todavía falta la documentación de Amazon SNS aquí, con algunos consejos sobre cómo formatear un mensaje para usar una carga útil personalizada. Estas preguntas frecuentes explica cómo hacerlo, pero no proporciona un ejemplo.

La solución es publicar la notificación con el MessageStructure parámetro establecido en json y un Message parámetro que está codificado en json, con una clave para cada protocolo de transporte. Siempre tiene que haber un default clave también, como una alternativa.

Este es un ejemplo de notificaciones de iOS con una carga útil personalizada:

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'
        ))

    ))
);

Lo mismo ocurre con otros protocolos también. El formato del mensaje json_encoded debe ser así (pero puede omitir claves si no usa el transporte):

{ 
    "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>\" } }" 
}

  • Al publicar directamente en un punto final móvil, no es necesario que haya una clave predeterminada. Tiene que haber un default clave o una clave de valor GCM, APNSo APNS_SANDBOX. Omitir la clave predeterminada le ahorrará bytes, ya que todas las claves y valores cuentan para el límite de 256 kb.

    – emkman

    10 de julio de 2014 a las 1:26


  • Aquí hay un enlace a la documentación. docs.aws.amazon.com/sns/latest/dg/… Me tomo bastante tiempo encontrarlo…

    – esamatti

    8 de febrero de 2016 a las 13:29

  • ¿Es posible configurar el sonido para GCM?

    – Llegar

    25 de marzo de 2016 a las 7:11

  • hola @felixdv… ¿podrías revisar esto? stackoverflow.com/questions/43079796/… ¡Muy apreciado!

    – i_raqz

    29 de marzo de 2017 a las 10:18

avatar de usuario de rjobidon
rjobidón

Desde una función Lambda (Node.js) la llamada debería ser:

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();
    }
  });
}

Puede simplificar especificando solo un protocolo: APNS o APNS_SANDBOX.

  • Esto funciona en su mayor parte, excepto que ha perdido el par clave-valor de sonido. Debe colocarse dentro del objeto aps junto con el par clave-valor de alerta.

    – usuario3344977

    14 de octubre de 2016 a las 4:39

  • @ user3344977 Gracias, corregí mi respuesta. Documentación oficial de APNS: desarrollador.apple.com/library/content/documentation/…

    – rjobidón

    16 de octubre de 2016 a las 3:03


  • Hola chicos, tengo un problema en el que ninguno de mis datos personalizados se recibe en el extremo de los dispositivos, y también el valor de la tecla ‘sonido’ no está definido. Alguna idea ? @rjobidon

    –Vince

    31 de mayo de 2017 a las 0:12

  • Hola, @Vince. No entiendo por qué, porque la documentación de Amazon dice que puede enviar pares clave-valor personalizados en la sección específica de la plataforma y dentro de la carga útil de JSON. docs.aws.amazon.com/sns/latest/dg/… Inspeccione su carga dentro de la devolución de llamada de la aplicación (_:didReceiveRemoteNotification:).

    – rjobidón

    5 de junio de 2017 a las 2:28

  • @rjobidon, mi solución fue asegurarme de tener la carga útil correcta. Estaba enviando un PN a una aplicación distribuida a través de un vuelo de prueba, pero mi servidor aún estaba estructurando la carga útil del mensaje como “APNS_SANDBOX” y no como “APNS”. Consejos para otros, asegúrese de que su carga útil se dirija al entorno correcto.

    –Vince

    5 de junio de 2017 a las 5:30

Avatar de usuario de Mike Miller
mike molinero

Soy demasiado inexperto para comentar aquí, pero me gustaría llamar la atención de la gente sobre el json_encode anidado. Esto es importante sin él, Amazon no analizará la cadena APNS y solo enviará el valor del mensaje predeterminado.

Estaba haciendo lo siguiente:

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

Pero esto no funcionará. DEBE json_encode la matriz en ‘APNS’ por separado, como se muestra en la respuesta de felixdv. No me preguntes por qué, ya que los resultados se ven exactamente iguales en el registro de mi consola. Aunque los documentos muestran que la cadena json debajo de la clave ‘APNS’ debe estar envuelta en “”, sospeche que esto tiene algo que ver con eso.

http://docs.aws.amazon.com/sns/latest/dg/mobile-push-send-custommessage.html

Sin embargo, no se deje engañar, ya que JSON se validará bien sin estas comillas dobles.

Además, no estoy seguro sobre el comentario de emkman. Sin la clave ‘predeterminada’ en la estructura anterior que se envía a un único ARN de punto final, recibiría un error de AWS.

Espero que eso acelere la tarde de alguien.

EDITAR

Posteriormente, se aclaró la necesidad de anidar json_encodes: crea comillas dobles escapadas que, a pesar de que los documentos dicen que no se requieren en la API, son para toda la cadena para GCM y, como se muestra arriba, la matriz secundaria en APNS para Apple. Esta puede ser mi implementación, pero está bastante lista para usar con el SDK de PHP de AWS y era la única forma de enviar datos personalizados.

Es fácil pasar por alto que necesita agregar APNS_SANDBOX y APNS para probar localmente.

¿Ha sido útil esta solución?