Skip to content

Instantly share code, notes, and snippets.

@ikeikeikeike
Created July 24, 2012 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ikeikeikeike/718b043014bc1b3f7270 to your computer and use it in GitHub Desktop.
Save ikeikeikeike/718b043014bc1b3f7270 to your computer and use it in GitHub Desktop.

iPhone/iPadプッシュ通知をpython製アプリケーション pyapns で送る

pyapns

pyapns はApple Push Notification Service(以下APNS)と会話してくれるサーバーアプリケーションで通信はHTTPを使用します。 Twisted baseのWebサーバーとのこと。

Instagram でも使用されていて over a billion push notifications ということなので実績は十分だと思います。

Request

pyapns へのRequestはPython/Ruby製のマルチスレッドクライアントライブラリがあるのでコレを使うのが無難ぽい。

push通知を飛ばす簡単なサンプルコード

from pyapns import configure, provision, notify
configure({'HOST': 'http://localhost:7077/'})
provision('myapp', open('cert.pem').read(), 'sandbox')
notify('myapp', 'hexlified_token_str', {'aps':{'alert': 'Hello!'}})
  • これだけでPush通知を飛ばせます、簡単に試せるのでなかなかよい印象です

一括通知

複数iPhoneへの一括通知はnotify関数の引数にlistで入れるようです

tokens = ["token1", "token2", "token3", "token4"]
notifications = [
    {'aps':{'alert': 'Hellow token 1'}},
    {'aps':{'alert': 'Hellow token 2'}},
    {'aps':{'alert': 'Hellow token 3'}},
    {'aps':{'alert': 'Hellow token 4'}},
]

notify('myapp', tokens, notifications)  # push!!
  • 何やら送信サイズ制限があるみたいなので20件以下にするのが良いとのこと

badge number / sound

バッジナンバー/サウンドはnotifications辞書に追加すればOK

tokens = ["token1", "token2", "token3", "token4"]
notifications = [
    {'aps':{'alert': 'Hellow token 1', 'badge': 2, 'sound': 'flynn.caf'}},
    {'aps':{'alert': 'Hellow token 2', 'badge': 4, 'sound': 'flynn.caf'}},
    {'aps':{'alert': 'Hellow token 3', 'badge': 5, 'sound': 'flynn.caf'}},
    {'aps':{'alert': 'Hellow token 4', 'badge': 8, 'sound': 'flynn.caf'}},
]

notify('myapp', tokens, notifications)  # push!!
  • sound指定したこと無いけど, どんな音の種類があるんだろう

async call

非同期対応と言うことで、Twistedぽくクライアントもcallbackで書いてもらいたいみたい。こんな感でしょたぶん

class Callback(object):

    def __init__(self, app, tokens, notifications):
        self._app = app
        self._tokens = tokens
        self._notifications = notifications

    def errback(self, err):
        """ err

        :param object err: Exception or xmlrpclib.Fault object
        """
        # str(err)
        # traceback.format_exc(sys.exc_info()[2]))

    def success(self, *args, **kwargs):
        pass

    def callback(self, *args, **kwargs):
        """ notify! """
        notify(self._app, self._tokens, self._notifications,
               async=True, callback=self.success, errback=self.errback)

c = Callback(app=app, tokens=tokens, notifications=notifications)
provision(app, cert, env, async=True, callback=c.callback, errback=c.errback)
  • 念のためblockingコードを書かないようにすればいいのかなぁ
  • 上のコードは試してないので動かないと思う

雑感

実際に送った雑感はまぁ速いです。 注意点としてはtokenやらnotificationが間違っているとpyapnsがリスタートして初期化すること、確かpush通知送信途中でも強制だったんでここは何か対応する必要があるんじゃないかなぁ

Upstartコンフィグ

Twistedなんでdeamon化はサポートしていますが自動起動がないでしょう、それじゃイカンでしょうってことでUpstartコンフィグのサンプルも書いておきます

description "APNS server for push notify"
start on runlevel [2345]
stop on runlevel [!2345]

script
  cd /tmp
  exec twistd -n -r epoll web --class=pyapns.server.APNSServer --port=7077
end script
  • UnixはkqueueにすればOK

間違ってたらごめんなさい、それでは

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment