Форматировать сообщение JSON в стиле APNS в Python для использования с Amazon SNS

Я создаю приложение iOS, и для наших push-уведомлений мы используем Simple Notification Service (SNS) Amazon.

SNS замечательно, но документация довольно скудная. Я использую boto, библиотеку Amazon Python, и я выяснил, как отправлять текстовые push-уведомления:

device_arn = 'MY ENDPOINT ARN GOES HERE'
plain_text_message = 'a plaintext message'
sns.publish(message=plain_text_message,target_arn=device_arn)

Однако из документации не ясно, как создать сообщение Apple Push Notification Service (APNS). Мне нужно отправить звук и значок вместе с push-уведомлением, но не могу понять, как отформатировать JSON для сообщения.

Вот моя лучшая догадка:

message = {'default':'default message', 'message':{'APNS_SANDBOX':{'aps':{'alert':'inner message','sound':'mySound.caf'}}}}
messageJSON = json.dumps(message,ensure_ascii=False)
sns.publish(message=messageJSON,target_arn=device_arn,message_structure='json')

Однако, когда я запускаю этот код, все, что я вижу в уведомлении, это "сообщение по умолчанию", что означает, что Amazon SNS отклонил мой формат сообщения и вместо него отобразил default.

Как правильно отформатировать этот JSON?

Ответы

Ответ 1

Я понял это! Оказывается, полезная нагрузка APNS должна быть закодирована как строка в большей полезной нагрузке - и она полностью работает.

Здесь конечный рабочий код:

apns_dict = {'aps':{'alert':'inner message','sound':'mySound.caf'}}
apns_string = json.dumps(apns_dict,ensure_ascii=False)
message = {'default':'default message','APNS_SANDBOX':apns_string}
messageJSON = json.dumps(message,ensure_ascii=False)
sns.publish(message=messageJSON,target_arn=device_arn,message_structure='json')

Здесь вы найдете обзор того, что происходит в этом коде:

Сначала создайте словарь для Python для APNS:

apns_dict = {'aps':{'alert':'inner message','sound':'mySound.caf'}}

Во-вторых, возьмите этот словарь и превратите его в строку в формате JSON:

apns_string = json.dumps(apns_dict,ensure_ascii=False)

В-третьих, поместите эту строку в большую полезную нагрузку:

message = {'default':'default message','APNS_SANDBOX':apns_string}

Затем мы кодируем это в своей собственной строке в формате JSON:

messageJSON = json.dumps(message,ensure_ascii=False)

Полученная строка затем может быть опубликована с помощью boto:

sns.publish(message=messageJSON,target_arn=device_arn,message_structure='json')

Ответ 2

Когда я использую инструмент публикации SNS, он автогенерирует JSON, который выглядит следующим образом:

{ 
    "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\"} }", 
    "GCM": "{ \"data\": { \"message\": \"<message>\" } }", 
    "ADM": "{ \"data\": { \"message\": \"<message>\" } }" 
 }

Это выглядит ближе к спецификации, о которой говорит Apple, в разделе Уведомление полезной нагрузки". Там, где указано, что сообщение должно быть

a JSON dictionary object (as defined by RFC 4627). 
This dictionary must contain another dictionary identified by the key aps.
The aps dictionary contains one or more properties

Вы пытались предоставить сообщение ближе к этой спецификации? Что-то вроде этого, например:

{
    'default':'default message', 
    {
        'aps':{
            'alert':'inner message',
            'sound':'mySound.caf'
         }
    }
 }

Или после примера из инструмента публикации публикации SNS:

{
    'default':'default message',
    'APNS': {
        'aps':{
            'alert':'inner message',
            'sound':'mySound.caf'
         }\
     }
 }

Возможно также использование их обратного слэша.