如何将SNS发布到特定的终端点?

19
我在发布SNS到特定端点时遇到了问题。
我的代码如下:

我遇到的问题是:

var AWS = require('aws-sdk');
AWS.config.loadFromPath('/web/config.json');

var sns = new AWS.SNS();
sns.publish({
    // TopicArn:'arn:aws:sns:us-west-2:302467918846:MyTestTopik',
    TargetArn: 'arn:aws:sns:us-west-2:302467918846:MyTestTopik:613ee49c-d4dc-4354-a7e6-c1d9d8277c56',
    Message: "Success!!! ",
    Subject: "TestSNS"
}, function(err, data) {
    if (err) {
        console.log("Error sending a message " + err);
    } else {
        console.log("Sent message: " + data.MessageId);

    }
});

在我使用TopicArn时一切正常。但是当我尝试向特定端点发送通知时,我会遇到错误:

发送消息时出错。InvalidParameter:无效参数:主题名称。

我不知道这是什么参数,也不知道它是从哪里来的。


1
你最终找到问题出在哪里了吗?我在使用PHP时也遇到了同样的问题。 - Moshe Marciano
我遇到了同样的问题,原因是所选地区设置有误。请检查您的地区设置。 - dieend
5个回答

15

类似的方法对我来说很有效。我能够使用以下方式发布到特定的端点:Apple Push Notification Service Sandbox (APNS_SANDBOX)。

你也可以尝试更新aws-sdk,当前版本是1.9.0。

这是我的代码,TargetArn直接从SNS控制台复制而来。我省略了一些数据,比如 &。

var sns = new AWS.SNS();
var params = {
    TargetArn:'arn:aws:sns:us-west-2:302467918846:endpoint/APNS_SANDBOX/<APP_NAME>/<USER_TOKEN>'
    Message:'Success!!! ',
    Subject: 'TestSNS'
};

sns.publish(params, function(err,data){
        if (err) {
            console.log('Error sending a message', err);
        } else {
            console.log('Sent message:', data.MessageId);
        }
    });

2
你做得很好。终端节点ARN应该看起来像arn:aws:sns:us-west-2:302467918846:endpoint/APNS_SANDBOX/<APP_NAME>/<USER_TOKEN>。 - Ondrej Svejdar
我在使用PHP SDK时遇到了相同的问题,但我的终端ARN看起来并不完全像那样...它是arn:aws:sns:us-east-1:<SUBSCRIBER>:<TOPIC_NAME>:1234abcf-56de-12ab-34cd- 12345abcd678。我正在尝试向特定终端发送短信;发送到整个主题可以正常工作。 - Jon B
@JonB,我也试图向特定的端点发送短信,我的端点arn格式(确实不是订阅arn吗?)与你的一样。但是也没有成功...但是像你这样向整个主题发送短信是可以的。其他人之所以能够成功,是因为他们在中间使用了“应用程序”,但我们没有,也没有一个。那么,你解决了问题吗?如果你解决了,请帮帮我。谢谢。 - early

10
你可能拥有一个无效的区域。检查你的区域是否符合该主题并相应地进行设置。例如,如果你是在us-west-2区域,可以进行如下操作:
var sns = new aws.SNS({region:'us-west-2'});

这就是当我遇到错误信息 aws lambda Invalid parameter: TopicArn 时,解决了类似问题的方法。真希望我能多次点赞。谢谢 Click Ahead! - yanhan
这个加一...这也是我的问题。我会将这个设为问题的答案。 - Eduardo Cruz

8

如果您不对有效载荷进行一些处理,那么这些都将无法运作。

        var arn = 'ENDPOINT_ARN';
        console.log("endpoint arn: " + arn);

        var payload = {
            default: message_object.message,
            GCM: {
                data: {
                    message: message_object.message
                }
            }
        };

        // The key to the whole thing is this
        //
        payload.GCM = JSON.stringify(payload.GCM);
        payload = JSON.stringify(payload);

        // Create the params structure
        //
        var params= { 
            TargetArn: arn,
            Message: payload,
            MessageStructure: 'json' // Super important too
        };

        sns.publish(params , function(error, data) {
            if (error) {
                console.log("ERROR: " + error.stack);
            }
            else {
                console.log("data: " + JSON.stringify(data));
            }

            context.done(null, data);
        });

原来需要指定消息结构(即json)。当我在AWS控制台选择JSON时,尝试向终端点发布,结果很好。使用RAW则无效。

在我的脚本中,我正在做之前的帖子所做的事情:

var params = {
    TargetArn: arn,
    Message:'Success!!! ',
    Subject: 'TestSNS'
};

尽管CloudWatch记录了成功日志,但我从未收到过消息。 一旦我添加了MessageStructure数据并正确格式化有效载荷,它就像魔法一样正常工作了。
[默认]参数没有用处,但我将其保留在那里以展示结构可能的样子。
如果您不将payload.GCM部分字符串化,SNS会报错并说您的消息应包括一个“GCM”元素。
唯一让人讨厌的是您需要知道端点是什么。我希望您不必根据端点格式化消息,这在某些方面确实削弱了SNS的目的。

非常好的回答!GCM的JSON是我所缺少的。 - KVISH
你真是MVP。E.T. 我只在Android上遇到了这个问题,而iOS却完美地工作,且无需JSON.stringify APNS/APNS_SANDBOX。 - Dan
这正是我寻找已久却无法在任何地方找到的确切答案。从AWS SNS控制台和CDK发送消息是两件不同的事情,他们没有在任何地方提到!赞! - Ravikumar Rajendran

1

0

我遇到了和你一模一样的问题。问题出在你使用的TargetArn上,关于它并没有清晰的文档说明。如果你试图将应用程序ARN放入TargetArn中,就会发生错误。

这将产生错误:无效参数:TargetArn原因:>arn:aws:sns:us-west-2:561315416312351:app/APNS_SANDBOX/com.APP_NAME_HERE.app不是要发布的有效ARN。

你需要做的就是将EndpointArn放入TargetArn中。

如果你需要查看EndpointArn,可以:

  1. 调用listPlatformApplications()获取所有应用程序ARN。
  2. 使用App ARN调用listEndpointsByPlatformApplication()获取EndpointArn列表。

享受吧!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接