Twisted client for Apple Push Notification Service (APNs)
Python Shell
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
apns
.gitignore
.travis.yml
LICENSE
README.md
release.sh
setup.py
tox.ini

README.md

Twisted client for APNs

Build status Version Code Climate

Overview

Twisted-APNs is an implementation of provider-side client for Apple Push Notification Service, based on official iOS documentation. It uses Twisted networking engine.

Features

  • Sending notifications through gateway service
  • Querying feedback service for failed remote notifications

Requirements

  • Python>=2.7
  • Twisted (version 15.0.0 known to work)
  • pyOpenSSL

Download

Installation

You can install it easily from PyPi by single command:

pip install twisted-apns

or clone source code and run:

python setup.py install

Usage examples

Sending a notification

First, do the necessary imports and set up logging for debug purposes:

import logging

from apns.gatewayclient import GatewayClientFactory
from apns.notification import Notification
from twisted.internet import reactor


logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())

Then create an instance of gateway client factory, specifying intended endpoint (pub for production or dev for development purposes), and setting a path to your provider certificate:

# Make sure /apn-dev.pem exists or pass valid path.
factory = GatewayClientFactory('dev', '/apn-dev.pem')
reactor.connectSSL(factory.hostname,
                   factory.port,
                   factory,
                   factory.certificate.options())

The code below sends a sample notification with JSON-encoded payload to device identified with supplied token (in hex):

def send():
    token = '00'  # Set to something valid.
    payload = {'aps': {'alert': "What's up?",
                       'sound': 'default',
                       'badge': 3}}
    notification = Notification(token=token,
                                expire=Notification.EXPIRE_IMMEDIATELY,
                                payload=payload)
    factory.send(notification)

reactor.callLater(1, send)
reactor.run()

If token is valid console outputs:

Gateway connection made: gateway.push.apple.com:2195
Gateway send notification

If not (like 00) error is returned:

Gateway connection made: gateway.sandbox.push.apple.com:2195
Gateway send notification
Gateway error received: <ErrorResponse: Invalid token size>
Gateway connection lost: Connection was closed cleanly.
Gateway connection made: gateway.sandbox.push.apple.com:2195

Querying list of invalidated tokens

The following code connects to the feedback service and prints tokens which should not be used anymore:

import logging

from apns.feedbackclient import FeedbackClientFactory
from apns.feedback import Feedback
from twisted.internet import reactor

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())

# Make sure /apn-dev.pem exists or pass valid path.
factory = FeedbackClientFactory('dev', '/apn-dev.pem')
reactor.connectSSL(factory.hostname,
                   factory.port,
                   factory,
                   factory.certificate.options())

def onFeedbacks(feedbacks):
    for f in feedbacks:
        print "It would be better to stop sending notifications to", f.token

factory.listen(FeedbackClientFactory.EVENT_FEEDBACKS_RECEIVED, onFeedbacks)

reactor.run()

Contributing

You are highly encouraged to participate in the development, simply use GitHub's fork/pull request system.