问的新东西,因为我在SO上没有得到任何答案。
我正在使用Amazon SNS Push向我的注册设备发送推送,一切正常,我可以首先在我的应用程序上注册设备,可以发送推送等。我面临的问题是,当我通过推送打开我的应用程序时,我想打开一个特定的页面。我想发送一些带有有效载荷的额外参数,但我无法做到这一点。
我试过这个链接:-http://docs.aws.amazon.com/sns/latest/api/API_Publish.html
我们只有一个密钥,即"消息",据我所知,我们可以在其中传递有效载荷。
我想传递这样的有效载荷:-
{
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");
}
}
}
}
?>
此处仍然缺少 Amazon SNS 文档,几乎没有关于如何格式化消息以使用自定义负载的指针。此常见问题解答解释了如何执行此操作,但不提供示例。
解决方案是发布通知,将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>'" } }"
}
从 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
。
我太缺乏经验,无法在这里发表评论,但我想提请人们注意嵌套json_encode。这很重要,没有它,亚马逊将不会解析 APNS 字符串,它只会发送默认消息值。
我正在执行以下操作:
$message = json_encode(array(
'default'=>$msg,
'APNS'=>array(
'aps'=>array(
'alert'=>$msg,
'sound'=>'default'
),
'id'=>$id,
'other'=>$other
)
)
);
但这行不通。您必须分别json_encode"APNS"下的数组,如 felixdv 的答案所示。不要问我为什么,因为输出在我的控制台日志中看起来完全相同。尽管文档显示"APNS"键下的 json 字符串应该包装在 " 中,但怀疑这与它有关。
http://docs.aws.amazon.com/sns/latest/dg/mobile-push-send-custommessage.html
不过不要被愚弄,因为如果没有这些双引号,JSON将进行验证。
我也不确定埃姆克曼的评论。如果没有将上述结构中的"默认"键发送到单个终端节点 ARN,我将收到来自 AWS 的错误。
希望能加快某人的下午。
编辑
随后清除了嵌套json_encodes的需要 - 它创建了转义的双引号,尽管文档说 API 不需要它们,但它们适用于 GCM 的整个字符串,并且与苹果 APNS 下的子数组相同。这可能是我的实现,但它几乎是使用 AWS PHP SDK 开箱即用的,并且是使其发送自定义数据的唯一方法。
很容易错过您需要添加APNS_SANDBOX以及APNS以进行本地测试。