genesluder / python-apns

A library for interacting with APNs using HTTP/2 and token-based authentication.
MIT License
90 stars 50 forks source link

Update client.py #21

Closed felipeben closed 3 years ago

felipeben commented 5 years ago

First of all thank you so much for this project, it's brilliant and it helped me out a lot! There is just one minor correction that I made. The "extra" key needs to be inside the "aps" key for it to work. so I changed it to aps_data.update(extra) instead of data.update(extra) and moved it to run before data["aps"] = aps_data. Let me know what you think and thanks again!

belkka commented 4 years ago

Creating the Remote Notification Payload:

The most important part of the payload is the aps dictionary, which contains Apple-defined keys and is used to determine how the system receiving the notification should alert the user, if at all. The examples also includes keys whose names include the string “acme”, which represent custom data included by a fictional app.

Example 1. The following payload contains an aps dictionary with a simple alert message. The acme2 key contains an array of app-specific data.

{
   "aps" : { "alert" : "Message received from Bob" },
   "acme2" : [ "bang",  "whiz" ]
}

Payload Key Reference:

The payload is a JSON dictionary object (as defined by RFC 4627) that you create on your server. The JSON dictionary object must contain an aps key, the value of which is a dictionary containing data used by the system to deliver the notification ... In addition to the aps dictionary, the JSON dictionary can include custom keys and values with your app-specific content.

The aps dictionary contains the keys used by Apple to deliver the notification to the user’s device. The keys specify the type of interactions that you want the system to use when alerting the user. Table 9-1 lists the keys to include in this dictionary along with the type of information to include in each. Any other keys in the aps dictionary are ignored by Apple.

According to apple.com, aps dictionary is for apple-defined keys and app-specific extra data goes to the root JSON object of payload. Actually, since unknown keys in the aps dictionary are ignored by Apple, you do can use it to deliver app-specific data, but

  1. it's weird
  2. "extra" dictionary keys may collide with aps dictionary keys. Even if they don't at the moment, Apple may introduce new "aps" keys in future, and they may overlap app-specific ones

The purpose of having a single reserved "aps" object for Apple-specific data (instead of using the root object for this) is exactly to avoid this problem. This allows you to use any payload keys except "aps" and never care about possible overlapping with Apple keys.

On the other hand, we probably need to validate the extra dict, to prevent accidental overriding the aps dictionary:

https://github.com/genesluder/python-apns/blob/68f3ae5c2a88cb7c8880cb6370a30cf848177642/gobiko/apns/client.py#L169-L170