19

I have a issue with publishing sns to a specific endpoint.

My code:

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);

    }
});

When I use TopicArn, everything is fine. But when I try to send notification to a specific endpoint I take error:

Error sending a message InvalidParameter: Invalid parameter: Topic Name

And I have no idea what kind of parameters it is and from where.

hong4rc
  • 3,999
  • 4
  • 21
  • 40
Alex Cebotari
  • 291
  • 2
  • 4
  • 9

5 Answers5

15

Something similar is working fine for me. I'm able to publish to a specific endpoint using: Apple Push Notification Service Sandbox (APNS_SANDBOX)

You might also want to try and update the aws-sdk, current version is 1.9.0.

Here's my code, TargetArn was copied directly from the SNS console. I omitted some of the data, like &

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);
        }
    });
guya
  • 5,067
  • 1
  • 35
  • 28
  • 2
    You nailed it. The endpoint Arn should look like arn:aws:sns:us-west-2:302467918846:endpoint/APNS_SANDBOX//. – Ondrej Svejdar May 06 '14 at 09:06
  • i'm having the same issue with the php sdk, but my enpoint arn doesn't look quite like that...it's arn:aws:sns:us-east-1:::1234abcf-56de-12ab-34cd-12345abcd678. im' attempting to send sms to a specific endpoint; sending to the entire topic works – Jon B Sep 13 '14 at 20:23
  • @JonB, I'm also attempting to send SMS to a specific endpoint, my endpoint arn format (isn't it a subscription arn indeed?) just like yours one. No luck too... But sending to entire topic works like you do. The others work since they've used "Applications" in the middle but we didn't and we don't have one. So, do you have fixed your issue? if you do, please help me. thanks. – early Mar 10 '16 at 16:32
10

You might have an invalid Region. Check you Region for the Topic and set it accordingly. For example if you are us-west-2 you could do something like

var sns = new aws.SNS({region:'us-west-2'});
Click Ahead
  • 2,782
  • 6
  • 35
  • 60
  • This is what solved a similar issue for me when I countered the error message `aws lambda Invalid parameter: TopicArn`. Wished I could upvote this more than once. Thank you Click Ahead! – yanhan Jun 11 '16 at 07:59
  • A plus one for this one ... this was the problem I had also. I would set this as the answer to the problem – Eduardo Cruz Sep 19 '17 at 21:20
8

None of this will work if you don't massage the payload a bit.

        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);
        });

So, it turns out that you have to specify the message structure (being json). I tried to publish to endpoint from the AWS console and it worked great as long as I selected JSON. Using RAW would do nothing.

In my script was doing was the previous posts were doing:

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

And even though CloudWatch was logging success, I never once got the message. As soon as I added the MessageStructure data and that I properly formatted the payload, it worked like a charm.

The [default] parameter is not useful but I left it in there to show what the structure could look like.

If you don't stringify the payload.GCM part, SNS will barf and say that your message should include a "GCM" element.

The only thing that is annoying is that you are required to know what the endpoint is. I was hoping that you didn't have to format the message based on the endpoint, which really defeats the purpose of SNS in some ways.

E.T
  • 1,095
  • 1
  • 10
  • 19
  • Excellent answer! The JSON for GCM is what I was missing. – KVISH Jul 30 '16 at 07:28
  • You are da real MVP. E.T. I had this problem only with Android, iOS was working perfectly without having to JSON.stringify APNS/APNS_SANDBOX. – Dan Feb 19 '18 at 16:11
  • This is the exact answer I was looking for which I couldn't find anywhere for quite some time. sending the message from the aws sns console and cdk two different things which they didn't mention anywhere! Kudos! – Ravikumar Rajendran Mar 04 '23 at 10:42
1

Are you trying endpoints other that push notifications such as sms? Direct addressing is currently only available for push notifications endpoints. That is the error you will get when you try to publish to a specific endpoint that does not allow direct direct addressing!

http://aws.amazon.com/sns/faqs/#Does_SNS_support_direct_addressing_for_SMS_or_Email

Neo
  • 11,078
  • 2
  • 68
  • 79
0

I was having the exact same issue as you. The problem is the TargetArn that you're using, there's not clear documentation about it. Error happens if you try to put the Application ARN in the TargetArn.

That will produce the error: Invalid parameter: TargetArn Reason: >arn:aws:sns:us-west-2:561315416312351:app/APNS_SANDBOX/com.APP_NAME_HERE.app is >not a valid ARN to publish to.

All you need to do is to put the EndpointArn in the TargetArn.

If you need to see the EndpointArn, you can:

  1. Call listPlatformApplications() to get all your applications ARN's.
  2. Call listEndpointsByPlatformApplication() with the App ARN to get the EndpointArn's list.

Enjoy!