Search code examples
jsonpush-notificationmpnsamazon-sns

Amazon SNS: JSON toasts to Windows Phones


When I use the Amazon SNS console to send toast messages to a Windows Phone 8 device (i.e. with the MPNS system), I can only send messages in text format. Selecting "Use platform specific JSON message dictionaries" and sending a JSON toast never seems to get to the device. The default message that you see when you select the platform specific format is a tile notification message, and that does work.

For exmple, the following message neither gives an error nor is displayed in the device:

{
"MPNS": "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\"><wp:Toast><wp:Text1>Amazon</wp:Text1><wp:Text2>hooray</wp:Text2><wp:Param>this_is/my?extra=parameter</wp:Param></wp:Toast></wp:Notification>"
}

This has been tested with a couple of devices: Lumia 620 with Windows Phone 8.0 and Lumia 1020 with 8.1 beta. I have also tried sending messages from a Java backend, but it just shows up as a raw JSON text toast ({ "MPNS": ...) again. What could possibly be wrong? The JSON is valid, the XML is well-formed... I'm at loss.


Solution

  • I have run into the same issue recently, and found a solution. The SNS documentation for MPNS does not emphasise an important step, but it can be found in the sample code and eventually in the message attributes section of the docs.


    You must set two MPNS-specific MessageAttributes on the PublishRequest. Omitting them will cause the delivery to fail with no clues left to investigate: i.e. even if you enable delivery status logs with CloudWatch, providerResponse will be missing.

    For reference, the attributes are the following:

    1. Attribute name: AWS.SNS.MOBILE.MPNS.Type
      Possible values: token (for tile notifications), toast or raw

    2. Attribute name: AWS.SNS.MOBILE.MPNS.NotificationClass
      Possible values: realtime*, priority, regular (realtime worked for me)


    That said, it seems that it is not possible to send custom content to MPNS using the SNS console. But using the API works, so here is an excerpt from the Java sample for using the Java SDK:

    AmazonSNS snsClient = ... /* initialise the client */;
    
    Map<String, MessageAttributeValue> notificationAttributes = new HashMap<String, MessageAttributeValue>();
    notificationAttributes.put("AWS.SNS.MOBILE.MPNS.Type",
            new MessageAttributeValue()
                .withDataType("String")
                .withStringValue("token")); // or "toast" or "raw", depending on the payload
    notificationAttributes.put("AWS.SNS.MOBILE.MPNS.NotificationClass",
            new MessageAttributeValue()
                .withDataType("String")
                .withStringValue("realtime"));
    
    PublishRequest request = new PublishRequest();
    request.setMessageAttributes(notificationAttributes);
    request.setMessageStructure("json");
    
    request.setTargetArn(... /* topic or endpoint ARN */);
    request.setMessage(... /* JSON payload */)
    
    snsClient.publish(request);