未来は僕以外の手の中

SI屋がIT技術やビジネスのことなどを気ままに書き綴ってみるなど

Urban Airshipを利用してGoogle App EngineからPush Notificationを行う

iPhone OS 3.0からApple Push Notification Service(APNs)が使えるようになった。
iPhone/iPadバイス上のアプリケーションの更新データがサーバ上にあることを
ユーザに知らせる機能で、これによりユーザは受動的に更新情報を検知することが可能となる。

詳細や実装方法などは

などが詳しい。


しかし、Provider(Push通知するサーバ)としてGoogle App Engineでの運用を検討する場合、
APNsはSSL通信を行うためSSLが限定されているGAEをそのまま利用することができない。
そこで、Urban Airshipというサービスを利用するとGAEからもPush通知することができる。


以下、ツール工房 覚書のUrban Airship記事より引用

Urban Airship は、iPhone アプリ開発者向けに、プッシュ通知(APNs)とアプリ内課金(In App Purchase)のソースコードクラウドサービスを提供する会社です。
Django で作成した APNs サーバの運用方法を検討していて、このような会社があることを知りました。APNs を月当たり 100,000 メッセージまで無料で送信できますので、コンセプトを確認するには十分だと思います。

APNsサーバとの接続はUrban Airshipに任せて、GAEからはUrban AirshipにPush情報を
ポストするようにすればPush通知ができそうである。ということで登録してみることにする。


まずはAPNsサーバと通信するために必要なProvider証明書(Push SSL Certificate)を
Urban Airshipに渡しておく必要がある。
やり方はこちら→Exporting Your Push Notification Key


これがうまくいくと登録したPush Notification対応アプリに対して

  • Application Key
  • Application (Master) Secret

というのが発行される。
これはUrban Airshipに対してPush情報をポストする際に使用するBasic認証のユーザIDと
パスワードである。


Urban AirshipのPush Notification APIをみると

An HTTP POST to https://go.urbanairship.com/api/push/ performs a push notification to one or more users. The payload is in JSON with content-type application/json

とあるので、/api/push/にjsonデータをポストすれば良さそうである。
ということで、以下のようなコードを実装してみる。

import urllib
import urllib2
from django.utils import simplejson

URL = "http://go.urbanairship.com/api/push/"
USER = "<Application Key>"
PASS = "<Application Master Secret>"
DEVICE_TOKEN = "<64 characters string>"

# ユーザ名とパスワードを登録する
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
password_mgr.add_password(None, URL, USER, PASS)

# Postするjsonデータ
pushdata = {"device_tokens":[DEVICE_TOKEN],
             "aps":{
                "alert":"新着データがありますよん",
                "badge":4,
                "sound":"default"
             }
           }

# 辞書(dict)->json形式に変換
pushdata = simplejson.dumps(pushdata)

# ヘッダ指定
headers = {"content-type": "application/json"}

# 認証情報付きでアクセスする
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
opener = urllib2.build_opener(handler)
urllib2.install_opener(opener)

req = urllib2.Request(URL, pushdata, headers)
f = urllib2.urlopen(req)


GAEでは単純にimport simplejsonと記述しても使えないので以下のように記述する。

from django.utils import simplejson


以上のコードを実行すると、GAEからポストしたPush情報をUrban AirshipがAPNsサーバに
SSL通信で送り、無事にAPNsサーバからiPhoneにPush通知が来ることになる。



これによりGAEからAPNsへはPush通知ができなくても、間にUrban Airshipをはさむことで
無事にPush通知をすることができた。めでたしめでたし!?


…GAE→Urban Airship間はSSL通信じゃないので盗聴される可能性があるな、どうするんだろ(´Д`)