のーずいだんぷ

主に自分用メモですが、もしかしたら誰かの役に立つかもしれません

AWS SNS でモバイルプッシュ通知の再送期間を変更する

概要

APNsとFCMのモバイルプッシュをSNSでpublish()APIを叩くことで簡単にpush通知を送信することができるが、SNSは再送処理までマネージメントしてくれる。 基本的にはデフォルトで4週間の間再送を続けてくれるようで、その際の再送処理の期間について手動で変更する。

実装のAWS-SDKの言語にはNode.jsを使用する。

具体的にやること説明

使用するAPI

publish()を使用する。

基本的なパラメータ

APIリファレンスに書いてあるとおり、各push通知プロバイダへ共通のpush通知を配信する場合、以下のparamで良いだろう。

docs.aws.amazon.com

param={
    var params = {
      Message: //プッシュのペイロード,
      MessageStructure: "json",
      TargetArn: //application platform endpoint
    };

プッシュのペイロードについては本記事では説明しない。MessageStructureも各人の使用する適切な値を使用する。

追加するパラメータ

上記のパラメータに次のようにTTL属性を追加した形にすればよい。 例ではプッシュ通知プロバイダがFCMの場合を想定している。

param={
    var params = {
      Message: //プッシュのペイロード,
      MessageStructure: "json",
      TargetArn: //application platform endpoint,
      MessageAttributes: {
          "AWS.SNS.MOBILE.FCM.TTL": {
       DataType: "Number",
               StringValue: "86400"
         }  
    };

上記では "AWS.SNS.MOBILE.FCM.TTL": {     DataType: "Number", StringValue: "86400" } と、設定しているように86400秒=1日へ再送期間を変更していることになる。 ちなみに、push通知プロバイダをAPNsの場合は AWS.SNS.MOBILE.APNS.TTL、APNs(sandbox)の場合はAWS.SNS.MOBILE.APNS_SANDBOX.TTLとなる。 その他SNSでサポートしているプッシュ通知プロバイダの情報は以下にまとめてある。

docs.aws.amazon.com

その他再送に関わる話

これらは全て参考に記載されていることであるが、一応記載しておく。

設定できるTTLの値

参考によると以下の制限があることに注意したい。

TTL は発行時間を基準にします。特定のプッシュ通知サービスにプッシュ通知メッセージを発行する前に、Amazon SNS はプッシュ通知のドウェル時間(発行のタイムスタンプからプッシュ通知サービスへの発行直前までの時間)を計算し、残りの TTL をそのプッシュ通知サービスに渡します。TTL がドウェル時間よりも短い場合、Amazon SNS はプッシュ通知メッセージの発行を試みません。

実際に私の経験上、特殊なことをしなければdwellTime(ドウェル時間)は数十ミリ秒なので、仮に再送をしないといった設定にする場合には以実際の配信ステータスを確認してみるのが良いかもしれない。

再送をそもそも行いたくない場合

参考のSNSの説明にもあるが、

プッシュ通知メッセージの TTL を指定する場合、TTL 値は正の整数でなければなりません。ただし、APNs や FCM などのプッシュ通知サービスに対して 0 の値に特定の意味がある場合は除きます。TTL 値を 0 に設定した場合、プッシュ通知サービスに対して 0 に特定の意味がないと、Amazon SNS はメッセージを破棄します。APNs を使用する場合に TTL パラメータを 0 に設定する方法の詳細については、Binary Provider API ドキュメントの「Table A-3 Item identifiers for remote notifications」を参照してください。

実際に確認をしてみるAPNsとFCMに関してはTTL=0のときの挙動が書いてあった。

結論、TTL=0を設定することで再配信しないようにできる。

FCM

FCMはデフォルトで(デバイスがオフラインの間)4週間保持するが、TTL=0の場合、即座に配信(デバイスの状態を考慮しない)するとある。

firebase.google.com

APNs

APNsはhttpヘッダーのapns-expirationによって再送について設定しているようだ。

基本的に最低1回の再送することを保証しているが、このヘッダの値が0の場合はFCM同様即座に配信し、再配信のためにサーバへ保存しないことが記載してある。

developer.apple.com

再送期間の設定の優先度

以下のようは優先度で行われるようだ。

  1. メッセージ属性の TTL
  2. メッセージ本文の TTL
  3. プッシュ通知サービスのデフォルト TTL (サービスごとに異なる)
  4. Amazon SNS のデフォルト TTL (4 週間)

今回のケースではおそらく1を設定しているようにみえる。 例えば2のような設定をしたい場合、FCMでは以下のようにプッシュペイロードにttl属性を加えることで、再送期間を変更できるようだ。

{
  "message":{
     "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
     "notification":{
       "title":"Match update",
       "body":"Arsenal goal in added time, score is now 3-0"
     },
     "android":{
       "ttl":"86400s",
       "notification"{
         "click_action":"OPEN_ACTIVITY_1"
       }
     },
     "apns": {
       "headers": {
         "apns-priority": "5",
       },
       "payload": {
         "aps": {
           "category": "NEW_MESSAGE_CATEGORY"
         }
       }
     },
     "webpush":{
       "headers":{
         "TTL":"86400"
       }
     }
   }
 }

firebase.google.com

参考

docs.aws.amazon.com