mobi-apns
=========

A library for interacting with APNs using HTTP/2 and token based
authentication.

Forked from Gene Sluder’s gobiko.apns
(https://github.com/genesluder/python-apns)

Installation
------------

``pip install mobi-apns``

Requirements
------------

-  Python 3.5+
-  hyper
-  pyjwt
-  cryptography

Usage
-----

Create a client::

        from mobi.apns import APNsClient, APNsMessage
        
        client = APNsClient(
            team_id=TEAM_ID, 
            bundle_id=BUNDLE_ID, 
            auth_key_id=APNS_KEY_ID, 
            auth_key_filepath=APNS_KEY_FILEPATH, 
            use_sandbox=True
        )

Alternatively, you can create a client with the contents of the auth key
file directly::

        client = APNsClient(
            team_id=TEAM_ID, 
            bundle_id=BUNDLE_ID, 
            auth_key_id=APNS_KEY_ID, 
            auth_key=APNS_KEY, 
            use_sandbox=True
        )

If you run into any problems deserializing the key, try wrapping it to
64 lines::

        client = APNsClient(
            team_id=TEAM_ID,
            bundle_id=BUNDLE_ID,
            auth_key_id=APNS_KEY_ID,
            auth_key=APNS_KEY,
            use_sandbox=True,
            wrap_key=True
        )

Construct a message::

        message = APNsMessage('TEST',
                   badge=1,
                   sound='default',
                   loc_key='This is a %@',
                   loc_args=['Test'])

Now you can send a message to a device by specifying its registration
ID::

    client.send_message(
        registration_id, 
        message
    )

Or you can send bulk messages to a list of devices::

    client.send_bulk_message(
        [registration_id_1, registration_id_2], 
        message
    )

Payload
-------

Additional APNs payload values can be passed into the message
construction

::

        message = APNsMessage(
            "All your base are belong to us.",
            badge=None, 
            sound=None, 
            category=None, 
            content_available=False,
            action_loc_key=None, 
            loc_key=None, 
            loc_args=[], 
            extra={}, 
            identifier=None, 
            expiration=None, 
            priority=10, 
            topic=None
        )

Pruning
-------

The legacy binary interface APNs provided an endpoint to check whether a
registration ID had become inactive. Now the service returns a
BadDeviceToken error when you attempt to deliver an alert to an inactive
registration ID. If you need to prune inactive IDs from a database you
can handle the BadDeviceToken exception to do so::

::

    from mobi.apns.exceptions import BadDeviceToken

    try:
        client.send_message(OLD_REGISTRATION_ID, "Message to an invalid registration ID.")
    except BadDeviceToken:
        # Handle invalid ID here
        pass

Same approach if sending by bulk::

::

    from mobi.apns.exceptions import PartialBulkMessage

    try:
        client.send_bulk_message([registration_id1, registration_id2], "Message")
    except PartialBulkMessage as e:
        # Handle list of invalid IDs using e.bad_registration_ids
        pass

Documentation
-------------

-  More information on APNs and an explanation of the above can be found
   ``in this blog post <http://gobiko.com/blog/token-based-authentication-http2-example-apns/>``\ \_.

-  Apple documentation for APNs can be found
   ``here <https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1>``\ \_.

Credits
-------

-  Gene Sluder
