Skip to content

Instantly share code, notes, and snippets.

@EricLondon
Last active September 19, 2018 12:39
Show Gist options
  • Save EricLondon/aa11e4297516a5daa50b7f13aee48f83 to your computer and use it in GitHub Desktop.
Save EricLondon/aa11e4297516a5daa50b7f13aee48f83 to your computer and use it in GitHub Desktop.
AWS Lambda S3 Notification to SNS with S3 MetaData
'use strict';
// ENV vars
const AWS_REGION_STRING = process.env.AWS_REGION || 'us-east-1';
const AWS_ACCOUNT_ID = process.env.AWS_ACCOUNT_ID;
const SNS_TOPIC_NAME = process.env.SNS_TOPIC_NAME;
const SNS_TOPIC_ARN = `arn:aws:sns:${AWS_REGION_STRING}:${AWS_ACCOUNT_ID}:${SNS_TOPIC_NAME}`;
const AWS = require('aws-sdk');
AWS.config.update({
region: AWS_REGION_STRING
});
const s3 = new AWS.S3();
const sns = new AWS.SNS();
const S3_PATH_MAP = {
0: 'environment',
3: 'customer',
4: 'source',
5: 'file'
};
exports.handler = (event, context, callback) => {
return main(event).then(function(result){
callback(null, result);
}).catch(function(error){
callback(error);
});
};
const main = async (event) => {
let record = event.Records[0];
let pathAttributes = getS3PathAttributes(record);
let s3MetaData = await fetchS3MetaData(record);
let metaData = {
...pathAttributes,
...s3MetaData
};
let messageAttributes = getMessageAttributes(metaData);
let sendSnsResponse = await sendSns(record, messageAttributes);
return sendSnsResponse.MessageId;
}
const getS3PathAttributes = function (record) {
let attributes = {};
try {
let pathSegments = record.s3.object.key.split('/');
Object.entries(S3_PATH_MAP).forEach(
([position, attr]) => {
let value = pathSegments[position];
if (value) {
attributes[attr] = value;
}
}
);
return attributes;
} catch (error) {
console.log('error', error);
return attributes;
}
}
const fetchS3MetaData = async (record) => {
try {
let params = {
Bucket: record.s3.bucket.name,
Key: record.s3.object.key
}
let response = await s3.headObject(params).promise();
return response.Metadata;
} catch (error) {
console.log('error', error);
return {};
}
}
const getMessageAttributes = function(metaData) {
let messageAttributes = {};
Object.entries(metaData).forEach(
([key, value]) => {
messageAttributes[key] = {
DataType: 'String',
StringValue: value
}
}
);
return messageAttributes;
}
const sendSns = async (record, messageAttributes) => {
let params = {
TopicArn: SNS_TOPIC_ARN,
Message: JSON.stringify(record),
MessageStructure: 'string',
MessageAttributes: messageAttributes
}
return await sns.publish(params).promise();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment