web-dev-qa-db-ja.com

Amazon SNSプッシュ通知を介してペイロードで追加パラメーターを送信する方法

これは、SOでの回答がまだないので、新しい質問です。

登録済みのデバイスにプッシュを送信するためにAmazon SNSプッシュを使用していますが、すべてが正常に機能しています。アプリにデバイスを最初に登録したり、プッシュを送信したりできます。私が直面している問題は、特定のページを開きたいことです。プッシュでアプリを開いたとき。ペイロードと共に追加のパラメーターを送信したいのですが、それができません。

私はこのリンクを試しました:- http://docs.aws.Amazon.com/sns/latest/api/API_Publish.html

キーは1つだけです。つまり、「メッセージ」で、私が知る限りペイロードを渡すことができます。

私はこのようなペイロードを渡したいです:-

{
    aps = {
            alert = "My Push text Msg";
          };
    "id" = "123",
    "s" = "section"
}

または他の任意の形式で問題ありません。ペイロードを一緒に2〜3個の値を渡して、アプリで使用できるようにしたかっただけです。

プッシュの送信に使用しているコードは次のとおりです。

// Load the AWS SDK for PHP
if($_REQUEST)
{
    $title=$_REQUEST["Push_text"];

    if($title!="")
    {
        require 'aws-sdk.phar';


        // Create a new Amazon SNS client
        $sns = Aws\Sns\SnsClient::factory(array(
            'key'    => '...',
            'secret' => '...',
            'region' => 'us-east-1'
        ));

        // Get and display the platform applications
        //print("List All Platform Applications:\n");
        $Model1 = $sns->listPlatformApplications();

        print("\n</br></br>");*/

        // Get the Arn of the first application
        $AppArn = $Model1['PlatformApplications'][0]['PlatformApplicationArn'];

        // Get the application's endpoints
        $Model2 = $sns->listEndpointsByPlatformApplication(array('PlatformApplicationArn' => $AppArn));

        // Display all of the endpoints for the first application
        //print("List All Endpoints for First App:\n");
        foreach ($Model2['Endpoints'] as $Endpoint)
        {
          $EndpointArn = $Endpoint['EndpointArn'];
          //print($EndpointArn . "\n");
        }
        //print("\n</br></br>");

        // Send a message to each endpoint
        //print("Send Message to all Endpoints:\n");
        foreach ($Model2['Endpoints'] as $Endpoint)
        {
          $EndpointArn = $Endpoint['EndpointArn'];

          try
          {
            $sns->publish(array('Message' => $title,
                    'TargetArn' => $EndpointArn));

            //print($EndpointArn . " - Succeeded!\n");
          }
          catch (Exception $e)
          {
            //print($EndpointArn . " - Failed: " . $e->getMessage() . "!\n");
          }
        }
    }
}
?>

任意の助けやアイデアがいただければ幸いです。前もって感謝します。

30
mAc

Amazon SNSのドキュメントにはまだ不足しており、カスタムペイロードを使用するようにメッセージをフォーマットする方法についてのポインタはほとんどありません。 このFAQ はその方法を説明していますが、例は示していません。

解決策は、MessageStructureパラメーターをjsonに設定し、jsonエンコードされたMessageパラメーターを使用して、各トランスポートプロトコルのキーを指定して通知を発行することです。フォールバックとして、常にdefaultキーも必要です。

これは、カスタムペイロードを使用したiOS通知の例です。

array(
    'TargetArn' => $EndpointArn,
    'MessageStructure' => 'json',
    'Message' => json_encode(array(
        'default' => $title,
        'APNS' => json_encode(array(
            'aps' => array(
                'alert' => $title,
            ),
            // Custom payload parameters can go here
            'id' => '123',
            's' => 'section'
        ))

    ))
);

他のプロトコルについても同様です。 json_encodedメッセージの形式は次のようにする必要があります(ただし、トランスポートを使用しない場合は、キーを省略できます)。

{ 
    "default": "<enter your message here>", 
    "email": "<enter your message here>", 
    "sqs": "<enter your message here>", 
    "http": "<enter your message here>", 
    "https": "<enter your message here>", 
    "sms": "<enter your message here>", 
    "APNS": "{\"aps\":{\"alert\": \"<message>\",\"sound\":\"default\"} }", 
    "APNS_SANDBOX": "{\"aps\":{\"alert\": \"<message>\",\"sound\":\"default\"} }", 
    "GCM": "{ \"data\": { \"message\": \"<message>\" } }", 
    "ADM": "{ \"data\": { \"message\": \"<message>\" } }" 
}
59
felixdv

Lambda関数(Node.js)からの呼び出しは次のようになります。

exports.handler = function(event, context) {

  var params = {
    'TargetArn' : $EndpointArn,
    'MessageStructure' : 'json',
    'Message' : JSON.stringify({
      'default' : $title,
      'APNS' : JSON.stringify({
        'aps' : { 
          'alert' : $title,
          'badge' : '0',
          'sound' : 'default'
        },
        'id' : '123',
        's' : 'section',
      }),
      'APNS_SANDBOX' : JSON.stringify({
        'aps' : { 
          'alert' : $title,
          'badge' : '0',
          'sound' : 'default'
        },
        'id' : '123',
        's' : 'section',
      })
    })
  };

  var sns = new AWS.SNS({apiVersion: '2010-03-31', region: 'us-east-1' });
  sns.publish(params, function(err, data) {
    if (err) {
      // Error
      context.fail(err);
    }
    else {
      // Success
      context.succeed();
    }
  });
}

APNSまたはAPNS_SANDBOXの1つのプロトコルのみを指定することで簡略化できます。

7
rjobidon

私はここでコメントするには経験が浅いのですが、ネストされたjson_encodeに人々の注意を喚起したいと思います。これがなければ重要です。APNS文字列はAmazonによって解析されず、デフォルトのメッセージ値のみを送信します。

私は次のことをしていました:

$message = json_encode(array(
   'default'=>$msg,
   'APNS'=>array(
      'aps'=>array(
         'alert'=>$msg,
         'sound'=>'default'
         ),
         'id'=>$id,
         'other'=>$other
       )
     )
   );

しかし、これは機能しません。 felixdvの回答に示されているように、配列を「APNS」の下に個別にjson_encodeする必要があります。出力がコンソールログでまったく同じに見えるので、理由を聞かないでください。ドキュメントでは「APNS」キーの下のjson文字列は「」でラップする必要があることを示していますが、これには何か関係があると考えられます。

http://docs.aws.Amazon.com/sns/latest/dg/mobile-Push-send-custommessage.html

ただし、JSONはこれらの二重引用符なしで問題なく検証されるため、だまされないでください。

また、emkmanのコメントもわかりません。上記の構造の「デフォルト」キーを単一のエンドポイントARNに送信しないと、AWSからエラーを受け取ります。

それが誰かの午後をスピードアップすることを願っています。

編集

続いてjson_encodesをネストする必要性を明らかにしました-それはエスケープされた二重引用符を作成しますが、APIで必要なarentはGCMの文字列全体であり、上記のようにAppleのAPNSの下のサブ配列です。これはおそらく私の実装ですが、AWS PHP SDKを使用して、ほとんどそのままでカスタムデータを送信する唯一の方法でした。

4
Mike Miller

ローカルでテストするためにAPNS_SANDBOXとAPNSを追加する必要があることは見落としがちです。

0
Brian F