Skip to content

Commit c32a6e1

Browse files
committed
Added optional email cleanup on S3 at end of process
1 parent d681830 commit c32a6e1

File tree

7 files changed

+119
-13
lines changed

7 files changed

+119
-13
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Change Log for aws-lambda-ses-forwarder
22

3+
## 4.3.0 [2017/3/10]
4+
5+
- Added optional `cleanupS3Email` step at the end of process
6+
37
## 4.2.0 [2017/6/20]
48

59
- Removing `Message-ID` header from messages to fix `InvalidParameterValue:

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ the email forwarding mapping from original destinations to new destination.
8888
"Effect": "Allow",
8989
"Action": [
9090
"s3:GetObject",
91-
"s3:PutObject"
91+
"s3:PutObject",
92+
"s3:DeleteObject"
9293
],
9394
"Resource": "arn:aws:s3:::S3-BUCKET-NAME/*"
9495
}

example/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ exports.handler = function(event, context, callback) {
1616
1717
1818
]
19-
}
19+
},
20+
emailCleanupS3: false
2021
}
2122
};
2223
LambdaForwarder.handler(event, context, callback, overrides);

index.js

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ console.log("AWS Lambda SES Forwarder // @arithmetric // Version 4.2.0");
2727
//
2828
// To match a mailbox name on all domains, use a key without the "at" symbol
2929
// and domain part of an email address (i.e. `info`).
30+
//
31+
// - emailCleanupOnS3: true to delete email from S3 bucket
3032
var defaultConfig = {
3133
fromEmail: "[email protected]",
3234
subjectPrefix: "",
@@ -46,7 +48,8 @@ var defaultConfig = {
4648
"info": [
4749
4850
]
49-
}
51+
},
52+
emailCleanupOnS3: false
5053
};
5154

5255
/**
@@ -280,6 +283,34 @@ exports.sendMessage = function(data) {
280283
});
281284
};
282285

286+
/**
287+
* Clean up (delete) the S3 email object
288+
*
289+
* @param {object} data - Data bundle with context, email, etc.
290+
*
291+
* @return {object} - Promise resolved with data.
292+
*/
293+
exports.emailCleanupOnS3 = function(data) {
294+
data.log({level: "info", message: "Deleting email at s3://" +
295+
data.config.emailBucket + '/' + data.config.emailKeyPrefix +
296+
data.email.messageId});
297+
return new Promise(function(resolve, reject) {
298+
data.s3.deleteObject({
299+
Bucket: data.config.emailBucket,
300+
Key: data.config.emailKeyPrefix + data.email.messageId
301+
}, function(err, result) {
302+
if (err) {
303+
data.log({level: "error", message: "deleteObject() returned error:",
304+
error: err, stack: err.stack});
305+
return reject(new Error('Error: Email cleanup on S3 failed.'));
306+
}
307+
data.log({level: "info", message: "emailCleanupOnS3() successful.",
308+
result: result});
309+
resolve(data);
310+
});
311+
});
312+
};
313+
283314
/**
284315
* Handler function to be invoked by AWS Lambda with an inbound SES email as
285316
* the event.
@@ -291,14 +322,6 @@ exports.sendMessage = function(data) {
291322
* configuration, SES object, and S3 object.
292323
*/
293324
exports.handler = function(event, context, callback, overrides) {
294-
var steps = overrides && overrides.steps ? overrides.steps :
295-
[
296-
exports.parseEvent,
297-
exports.transformRecipients,
298-
exports.fetchMessage,
299-
exports.processMessage,
300-
exports.sendMessage
301-
];
302325
var data = {
303326
event: event,
304327
callback: callback,
@@ -309,6 +332,17 @@ exports.handler = function(event, context, callback, overrides) {
309332
s3: overrides && overrides.s3 ?
310333
overrides.s3 : new AWS.S3({signatureVersion: 'v4'})
311334
};
335+
var steps = overrides && overrides.steps ? overrides.steps :
336+
[
337+
exports.parseEvent,
338+
exports.transformRecipients,
339+
exports.fetchMessage,
340+
exports.processMessage,
341+
exports.sendMessage
342+
];
343+
if (data.config.emailCleanupOnS3) {
344+
steps.push(exports.emailCleanupOnS3);
345+
}
312346
Promise.series(steps, data)
313347
.then(function(data) {
314348
data.log({level: "info", message: "Process finished successfully."});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aws-lambda-ses-forwarder",
3-
"version": "4.2.0",
3+
"version": "4.3.0",
44
"description": "Serverless email forwarding using AWS Lambda and SES",
55
"main": "index.js",
66
"scripts": {

test/emailCleanupOnS3.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
2+
/* global describe, it */
3+
4+
var assert = require("assert");
5+
6+
var index = require("../index");
7+
8+
describe('index.js', function() {
9+
describe('#emailCleanupOnS3()', function() {
10+
it('should invoke the AWS S3 SDK to delete the email object',
11+
function(done) {
12+
var data = {
13+
config: {
14+
emailBucket: "bucket",
15+
emailKeyPrefix: "prefix/",
16+
emailCleanupOnS3: true
17+
},
18+
context: {},
19+
email: {
20+
messageId: "abc"
21+
},
22+
log: console.log,
23+
s3: {
24+
deleteObject: function(options, callback) {
25+
callback(null);
26+
}
27+
}
28+
};
29+
index.emailCleanupOnS3(data)
30+
.then(function() {
31+
assert.ok(true, "emailCleanupOnS3 returned successfully");
32+
done();
33+
});
34+
});
35+
36+
it('should result in failure if the AWS S3 SDK cannot delete the object',
37+
function(done) {
38+
var data = {
39+
config: {
40+
emailBucket: "bucket",
41+
emailKeyPrefix: "prefix/",
42+
emailCleanupOnS3: true
43+
},
44+
context: {},
45+
email: {
46+
messageId: "abc"
47+
},
48+
log: console.log,
49+
s3: {
50+
deleteObject: function(options, callback) {
51+
callback(true);
52+
}
53+
}
54+
};
55+
index.emailCleanupOnS3(data)
56+
.catch(function(err) {
57+
assert.ok(err, "emailCleanupOnS3 aborted operation");
58+
done();
59+
});
60+
});
61+
});
62+
});

test/handler.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ describe('index.js', function() {
2121
},
2222
getObject: function(options, callback) {
2323
callback(null, {Body: "email data"});
24+
},
25+
deleteObject: function(options, callback) {
26+
callback(null, {});
2427
}
2528
},
2629
ses: {
@@ -35,7 +38,8 @@ describe('index.js', function() {
3538
3639
3740
]
38-
}
41+
},
42+
emailCleanupOnS3: true
3943
}
4044
};
4145
index.handler(event, context, callback, overrides);

0 commit comments

Comments
 (0)