Created
October 19, 2021 14:56
-
-
Save NEbere/97d53274aa186bd2e69ba774f0afad39 to your computer and use it in GitHub Desktop.
simple code to show SNS topic subscription, confirmation and notification handling via expressJS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express') | |
const AWS = require("aws-sdk") | |
var bodyParser = require('body-parser') | |
const MessageValidator = require('sns-validator') | |
var jsonParser = bodyParser.json() | |
const config = { | |
"SNS_TOPIC_ARN": "", | |
"USER_ARN": "", | |
"USER_ACCESS_KEY_ID": "", | |
"USER_SECRET_ACCESS_KEY": "", | |
"DLQ_ARN": "" | |
}; | |
// exponential backoff retry times = 20 - 3 - 2 - 5 = 20 - 10 = 10 | |
// 10 times retry (with exponential backoff from 1 second to 60 seconds) | |
const deliveryPolicy = { | |
"healthyRetryPolicy": { | |
"minDelayTarget": 1, | |
"maxDelayTarget": 60, // maximum value of 3,600 seconds | |
"numRetries": 20, // The total number of retries, including immediate, pre-backoff, backoff, and post-backoff retries. max of 100 | |
"numNoDelayRetries": 3, // retry 5 times immediately in the no-delay phase | |
"numMinDelayRetries": 2, // retry 2 times, 1 second apart in the pre-backoff phase | |
"numMaxDelayRetries": 5, // 10 times 60 seconds apart in the post-backoff phase | |
"backoffFunction": "exponential" | |
}, | |
} | |
const redrivePolicy = { | |
"deadLetterTargetArn": config.DLQ_ARN | |
} | |
const app = express() | |
const port = 3030 | |
app.use( | |
express.json({ | |
type: [ | |
'application/json', | |
'text/plain', // AWS sends this content-type for its messages/notifications | |
], | |
}) | |
) | |
// const credentials = new AWS.SharedIniFileCredentials({profile: 'sns_profile'}); | |
const SNS = new AWS.SNS({ | |
credentials: { | |
accessKeyId: config.USER_ACCESS_KEY_ID, | |
secretAccessKey: config.USER_SECRET_ACCESS_KEY, | |
}, | |
region: 'eu-central-1' | |
}) | |
app.get('/', (req, res) => { | |
res.send({ response: 'Hello World!' }) | |
}) | |
// Endpoint used to create subscription via http request | |
app.post('/subscribe', (req, res) => { | |
let params = { | |
Protocol: 'HTTPS', | |
TopicArn: config.SNS_TOPIC_ARN, | |
Endpoint: '', | |
Attributes: { | |
DeliveryPolicy: JSON.stringify(deliveryPolicy), | |
RedrivePolicy: JSON.stringify(redrivePolicy) | |
}, | |
ReturnSubscriptionArn: true | |
}; | |
SNS.subscribe(params, (err, data) => { | |
if (err) { | |
console.log({err, msg: "error subscribing to topic"}); | |
} else { | |
console.log(data); | |
res.send({data, msg: "success to topic"}); | |
} | |
}); | |
}); | |
// function used to call the confirmSubscription action on SNS | |
const confirmSubscription = (request) => { | |
console.log('running confirmSubscription', request.body) | |
const { Token, TopicArn } = request.body | |
const params = { | |
Token, | |
TopicArn | |
} | |
SNS.confirmSubscription(params, function(err, data) { | |
if (err) console.log({err, stack: err.stack, message: "error confirming subscription"}); // an error occurred | |
else console.log({data, message:"successfuly confirmed subscription"}); // successful response | |
}); | |
} | |
// The HTTP endpoint registered on AWS for | |
app.post('/notifications', jsonParser, (req, res) => { | |
const validator = new MessageValidator(); | |
const messageType = req.body.Type | |
validator.validate(req.body, function (err, message) { | |
if (err) { | |
// Your message could not be validated. | |
console.log(err, 'error validating message') | |
return; | |
} | |
// SNS subscription confirmation | |
if (messageType == 'SubscriptionConfirmation') { | |
confirmSubscription(req) | |
console.log({body:req.body, messageType}) | |
} | |
// SNS notifications | |
if (messageType == 'Notification') { | |
const { Message} = req.body | |
console.log({messageType, Message:JSON.parse(Message)}) | |
} | |
}); | |
// res.sendStatus(500).send({message: 'cannot process request'}) | |
res.send("success") | |
}); | |
app.listen(port, () => { | |
console.log(`Example app listening at http://localhost:${port}`) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment