boto自体使うのが初めてだったので、おかしい所があるかもしれないが動作はした。APNsのSSL証明書作成等は毎度の事なので省略。Application ARNはAWS Consoleから既に作成してあるとする。
endpointは一度作成したら、保存しておけば再度 create_platform_endpoint する必要は無い。
Topicにぶらさげるデバイスの数は1万が上限との事なので、アプリのユーザー全員に送信するといった場合にはTopicを分けるか、全てのEndpointに送信するかどちらかになる。あまり楽させてはくれない様だ。Endpointを削除した場合、Topicから勝手にunsubscribeされると思いきやそうでもなかった。
Payloadを一度作った後、文字列にして再度JSONにつっこむという面倒な事が必要。
デバイス指定でメッセージ送信する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # -*- coding: utf-8 -*- import boto.sns AWS_ACCESS_KEY = 'xxxx' AWS_SECRET_ACCESS_KEY = 'yyyyyyyy' APPLICATION_ARN = \ 'arn:aws:sns:ap-northeast-1:0000:app/APNS_SANDBOX/aaaa' # SNSに接続 sns_connection = boto.sns.connect_to_region( 'ap-northeast-1' , aws_access_key_id = AWS_ACCESS_KEY, aws_secret_access_key = AWS_SECRET_ACCESS_KEY) # 送信先デバイスを指定してendpointを作成 res = sns_connection.create_platform_endpoint( platform_application_arn = APPLICATION_ARN, token = 'xxxxxxxx' ) endpoint = res.get( 'CreatePlatformEndpointResponse' )\ .get( 'CreatePlatformEndpointResult' ).get( 'EndpointArn' ) # endpointに送信 sns_connection.publish(target_arn = endpoint, message = u "Hello World" ) |
Topic経由でメッセージ送信する
Topicをsubscribeしているデバイスに一斉送信するパターン、Topicをsubscribeする際の第二引数はbotoのソースを読んでもわからなかったが、AWSコンソールのTopic管理画面から推測すると "application" を指定したら良い気がする。そして実際に動作する。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # -*- coding: utf-8 -*- import boto.sns AWS_ACCESS_KEY = 'xxxx' AWS_SECRET_ACCESS_KEY = 'yyyyyyyy' APPLICATION_ARN = \ 'arn:aws:sns:ap-northeast-1:0000:app/APNS_SANDBOX/aaaa' # SNSに接続 sns_connection = boto.sns.connect_to_region( 'ap-northeast-1' , aws_access_key_id = AWS_ACCESS_KEY, aws_secret_access_key = AWS_SECRET_ACCESS_KEY) # 送信先デバイスを指定してEndpointを作成 res = sns_connection.create_platform_endpoint( platform_application_arn = APPLICATION_ARN, token = 'xxxxxxxx' ) endpoint = res.get( 'CreatePlatformEndpointResponse' )\ .get( 'CreatePlatformEndpointResult' ).get( 'EndpointArn' ) # Topicを作成 res = sns_connection.create_topic( 'test_topic' ) topic = res.get( 'CreateTopicResponse' )\ .get( 'CreateTopicResult' ).get( 'TopicArn' ) # TopicをSubscribe sns_connection.subscribe(topic, 'application' , endpoint) # Topicに送信 sns_connection.publish(topic = topic, message = u "Hello World for Topic subscriber" ) |
JSON形式でbadgeやalertを送る
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # Payloadの中身 message = json.dumps({ "aps" : { "alert" : { "body" : "Hey Hey" , "action-loc-key" : None }, "badge" : 100 } }) # Payloadの長さチェック if len (message) > 255 : raise "APNs payload over 255 bytes!!!!" # 送信先プラットフォームの指定、本番であればAPNS # Android向けのPushもここで同時に指定できる data = json.dumps({ "APNS_SANDBOX" : message}) # message_structure='json'を指定してPublish try : sns_con.publish( target_arn = endpoint, message = data, message_structure = 'json' ) except BotoServerError, e: logger.warn( "BotoServerError status:%s %s %s" , e.status, e.reason, e.error_message) |