Reputation: 442
I'm trying to connect an SNS topic to my Meteor ( node ) JS application, but it seems like i'm not getting the right response when i try to subscribe and stuff.
I have few questions regarding this matter. but first , this is my topic and code :
Wrote this on my LOCALHOST server :
AWS.config.update({
accessKeyId: 'something',
secretAccessKey: 'someotherthing+a4f23',
region: 'eu-west-1'
});
let sns = new AWS.SNS();
var params = {
Protocol: 'http', /* required */
TopicArn: 'arn:aws:sns:eu-west-1:888472248156:ps-tracking', /* required */
Endpoint: 'http://URL:4000'
};
sns.subscribe(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
I'm still running my node app on LOCALHOST at this point
then i switch to my AWS SNS panel and create a subscription, choose HTTP as protocol and type in the ENDPOINT URL.
First Question Is there any possibility that i can get this to work on localhost without moving it to the live server, if so how ?
so when i run the appliction i get this message in the console :
{ ResponseMetadata: { RequestId: '64a88abb-7997-5f47-bfcc-d8cfc5281ca3' },
SubscriptionArn: 'pending confirmation' }
i switch to my AWS panel i see
even when i move all this to the live server, with the same data, i'm getting this pending message. and i don't know what i should do !
Upvotes: 1
Views: 14224
Reputation: 974
I made an function for typescript to confirm the subscription. Just pass in your header and body from the express route.
Also the content type of the sns request is something like text/plain
and the bodyParser used in most express apps won't process the body so the body.Token
will be empty. To solve this use a middleware before you body parser to augment the request coming in.
Process subscription confirmation
import AWS from "aws-sdk";
const snsInstance = new AWS.SNS();
function isConfirmSubscription(headers: {
'x-amz-sns-message-type': string
}) {
return headers['x-amz-sns-message-type'] === 'SubscriptionConfirmation'
}
function confirmSubscription(
headers: {
'x-amz-sns-topic-arn': string,
'x-amz-sns-message-type': string
},
body: {Token: string}
): Promise<string>{
return new Promise(((resolve, reject) =>{
if(!isConfirmSubscription(headers)){
return resolve('No SubscriptionConfirmation in sns headers')
}
snsInstance.confirmSubscription({
TopicArn: headers['x-amz-sns-topic-arn'],
Token : body.Token
}, (err, res)=>{
console.log(err);
if(err){
return reject(err)
}
return resolve(res.SubscriptionArn);
});
}))
}
SubscriptionConfirmation content type modifier
app.use(function(req, res, next) {
if (req.headers['x-amz-sns-message-type']) {
req.headers['content-type'] = 'application/json;charset=UTF-8';
}
next();
});
Upvotes: 3
Reputation: 88
If you need to confirm the subscription to an SNS Topic, you can use the AWS-NODE-SDK using the Request sent from SNS:
{
"Type" : "SubscriptionConfirmation",
"MessageId" : "165545c9-2a5c-472c-8df2-7ff2be2b3b1b",
"Token" : "2336412f37fb687f5d51e6e241d09c805a5a57b30d712f794cc5f6a988666d92768dd60a747ba6f3beb71854e285d6ad02428b09ceece29417f1f02d609c582afbacc99c583a916b9981dd2728f4ae6fdb82efd087cc3b7849e05798d2d2785c03b0879594eeac82c01f235d0e717736",
"TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
"Message" : "You have chosen to subscribe to the topic arn:aws:sns:us-west-2:123456789012:MyTopic.\nTo confirm the subscription, visit the SubscribeURL included in this message.",
"SubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-west-2:123456789012:MyTopic&Token=2336412f37fb687f5d51e6e241d09c805a5a57b30d712f794cc5f6a988666d92768dd60a747ba6f3beb71854e285d6ad02428b09ceece29417f1f02d609c582afbacc99c583a916b9981dd2728f4ae6fdb82efd087cc3b7849e05798d2d2785c03b0879594eeac82c01f235d0e717736",
"Timestamp" : "2012-04-26T20:45:04.751Z",
"SignatureVersion" : "1",
"Signature" : "EXAMPLEpH+DcEwjAPg8O9mY8dReBSwksfg2S7WKQcikcNKWLQjwu6A4VbeS0QHVCkhRS7fUQvi2egU3N858fiTDN6bkkOxYDVrY0Ad8L10Hs3zH81mtnPk5uvvolIC1CXGu43obcgFxeL3khZl8IKvO61GWB6jI9b5+gLPoBc1Q=",
"SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem"
}
To make the confirmation you will need the TopicArn from the header & Token found on the body:
AWS.config.update({
accessKeyId : 'ACCESS_KEY',
secretAccessKey: 'ACCESS_SECRET_KEY',
region : 'region'
});
// Create S3 Object from AWS SDK
const sns = new AWS.SNS();
// Request options
let options = {
TopicArn: req.headers['x-amz-sns-topic-arn'],
Token : req.body.Token
}
// Confirm Token Subscription
sns.confirmSubscription(options, callback);
Note: AWS will send the SubscriptionConfirmation & Notifications to the same endpoint, you can differentiate those by using the header 'x-amz-sns-message-type'
Upvotes: 1
Reputation: 81336
You need to confirm the subscription.
After you subscribe your endpoint, Amazon SNS will send a subscription confirmation message to the endpoint. You should already have code that performs the actions described in Step 1 deployed to your endpoint. Specifically, the code at the endpoint must retrieve the SubscribeURL value from the subscription confirmation message and either visit the location specified by SubscribeURL itself or make it available to you so that you can manually visit the SubscribeURL, for example, using a web browser. Amazon SNS will not send messages to the endpoint until the subscription has been confirmed. When you visit the SubscribeURL, the response will contain an XML document containing an element SubscriptionArn that specifies the ARN for the subscription. You can also use the Amazon SNS console to verify that the subscription is confirmed: The Subscription ID will display the ARN for the subscription instead of the PendingConfirmation value that you saw when you first added the subscription.
Sending Amazon SNS Messages to HTTP/HTTPS Endpoints
Upvotes: 1