问题
I'm using Amazon Elastic Beanstalk to run a nodejs web page. I just want to send notifications to this webpage from AWS SNS and catch them in real time. So, when i publish to the HTTP endpoint, nothing happens and i don't know how to get the notification.
As Http endpoint, i set my AWS Elastic-Beanstalk http address.
I'm reading the Amazon docs but nowhere i can find how to catch the sns message once at the http endpoint.
Please, any help will be very appreciated . Thanks.
回答1:
The moment you give your HTTP/HTTPS endpoint and create subscription from aws console, what happens is , the Amazon sends a subscription msg to that endpoint. Now this is a rest call, and your app must have a handler for this endpoint, otherwise you miss catching this subscription message. The httpRequest object that your handler is passed, needs to access it's SNSMsgTypeHdr header field. This value will be "SubscriptionConfirmation". You need to catch this particular message first and then get the subscription url. You can handle it in your app itself or maybe print it out, and then manually visit that url to make the subscription. I would ideally suggest to make a subscription to the same topic at the same with your mail id, so that everytime your app gets a messages pushed , your mail id also gets the message(albeit the tokens will be different) but at least you will be sure that the message was pushed to your endpoint. All you need to do is keep working your app to handle the messages at that endpoint as per your requirements then.
回答2:
Try this:
const express = require('express');
const router = express.Router();
const request = require('request');
var bodyParser = require('body-parser')
router.post('/',bodyParser.text(),handleSNSMessage);
module.exports = router;
var handleSubscriptionResponse = function (error, response) {
if (!error && response.statusCode == 200) {
console.log('Yess! We have accepted the confirmation from AWS');
}
else {
throw new Error(`Unable to subscribe to given URL`);
//console.error(error)
}
}
async function handleSNSMessage(req, resp, next) {
try {
let payloadStr = req.body
payload = JSON.parse(payloadStr)
console.log(JSON.stringify(payload))
if (req.header('x-amz-sns-message-type') === 'SubscriptionConfirmation') {
const url = payload.SubscribeURL;
await request(url, handleSubscriptionResponse)
} else if (req.header('x-amz-sns-message-type') === 'Notification') {
console.log(payload)
//process data here
} else {
throw new Error(`Invalid message type ${payload.Type}`);
}
} catch (err) {
console.error(err)
resp.status(500).send('Oops')
}
resp.send('Ok')
}
Note: I didn't use app.use
as that will impact all my other endpoints.
回答3:
There are 3 types of messages with SNS. Subscribe, Unsubscribe, and Notification. You will not get any Notification messages until you have correctly handled the subscribe message. Which involves making an API request to AWS when you receive the Subscribe request.
The call in this case is ConfirmSubscription: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html#confirmSubscription-property
Once you do that, then you will start receiving notification messages and you can handle those as your code allows.
回答4:
After you subscribe your endpoint, Amazon SNS will send a subscription confirmation message to the endpoint. You should have code at the endpoint that retrieves 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.
You can 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.
来源:https://stackoverflow.com/questions/36958160/how-to-confirm-subscribe-and-get-sns-notifications-at-a-http-endpoint