Skip to content
This repository was archived by the owner on Apr 3, 2019. It is now read-only.

Commit cccd899

Browse files
authored
feat(logging): Log email template header if available (#1466), r=@jbuck
* feat(logging): Log email template header if avalible * feat(logging): Add flow logging and unit tests * feat(logging): Remove flowEvent logging * feat(logging): Add logging of bounce type * feat(logging): Fix busted test case
1 parent 1fc79a6 commit cccd899

File tree

2 files changed

+96
-3
lines changed

2 files changed

+96
-3
lines changed

lib/bounces.js

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,23 @@ module.exports = function (log, error) {
4949
}
5050
}
5151

52+
function getHeaderValue(headerName, message){
53+
var value = ''
54+
if (message.mail && message.mail.headers) {
55+
message.mail.headers.some(function (header) {
56+
if (header.name === headerName) {
57+
value = header.value
58+
return true
59+
}
60+
61+
return false
62+
})
63+
}
64+
65+
return value
66+
}
67+
68+
5269
function handleBounce(message) {
5370
var recipients = []
5471
if (message.bounce && message.bounce.bounceType === 'Permanent') {
@@ -57,17 +74,43 @@ module.exports = function (log, error) {
5774
else if (message.complaint && message.complaint.complaintFeedbackType === 'abuse') {
5875
recipients = message.complaint.complainedRecipients
5976
}
77+
78+
// SES can now send custom headers if enabled on topic.
79+
// Headers are stored as an array of name/value pairs.
80+
// Log the `X-Template-Name` header to help track the email template that bounced.
81+
// Ref: http://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-contents.html
82+
var templateName = getHeaderValue('X-Template-Name', message)
83+
6084
return P.each(recipients, function (recipient) {
85+
6186
var email = recipient.emailAddress
62-
log.info({
87+
var logData = {
6388
op: 'handleBounce',
6489
action: recipient.action,
6590
email: email,
6691
bounce: !!message.bounce,
6792
diagnosticCode: recipient.diagnosticCode,
6893
status: recipient.status
69-
})
94+
}
95+
96+
// Template name corresponds directly with the email template that was used
97+
if(templateName) {
98+
logData.template = templateName
99+
}
100+
101+
// Log the type of bounce that occurred
102+
// Ref: http://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-contents.html#bounce-types
103+
if (message.bounce && message.bounce.bounceType) {
104+
logData.bounceType = message.bounce.bounceType
105+
106+
if (message.bounce && message.bounce.bounceSubType) {
107+
logData.bounceSubType = message.bounce.bounceSubType
108+
}
109+
}
110+
111+
log.info(logData)
70112
log.increment('account.email_bounced')
113+
71114
return findEmailRecord(email)
72115
.then(
73116
deleteAccountIfUnverified,

test/local/bounce_tests.js

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ test(
6565
t.equal(mockDB.deleteAccount.callCount, 2)
6666
t.equal(mockDB.emailRecord.args[0][0], 'test@example.com')
6767
t.equal(mockDB.emailRecord.args[1][0], 'foobar@example.com')
68-
t.equal(mockLog.messages.length, 6)
68+
t.equal(mockLog.messages.length, 6, 'messages logged')
6969
t.equal(mockLog.messages[1].level, 'increment')
7070
t.equal(mockLog.messages[1].args[0], 'account.email_bounced')
7171
t.equal(mockLog.messages[5].level, 'info')
@@ -271,3 +271,53 @@ test(
271271
})
272272
}
273273
)
274+
275+
test(
276+
'can log email template name and bounceType',
277+
function (t) {
278+
var mockLog = spyLog()
279+
var mockDB = {
280+
emailRecord: sinon.spy(function (email) {
281+
return P.resolve({
282+
uid: '123456',
283+
email: email,
284+
emailVerified: false
285+
})
286+
}),
287+
deleteAccount: sinon.spy(function () {
288+
return P.resolve({ })
289+
})
290+
}
291+
var mockMsg = mockMessage({
292+
bounce: {
293+
bounceType: 'Permanent',
294+
bounceSubType: 'General',
295+
bouncedRecipients: [
296+
{emailAddress: 'test@example.com'}
297+
]
298+
},
299+
mail: {
300+
headers: [
301+
{
302+
name: 'X-Template-Name',
303+
value: 'verifyLoginEmail'
304+
}
305+
]
306+
}
307+
})
308+
309+
return mockedBounces(mockLog, mockDB).handleBounce(mockMsg).then(function () {
310+
t.equal(mockDB.emailRecord.callCount, 1)
311+
t.equal(mockDB.emailRecord.args[0][0], 'test@example.com')
312+
t.equal(mockDB.deleteAccount.callCount, 1)
313+
t.equal(mockDB.deleteAccount.args[0][0].email, 'test@example.com')
314+
t.equal(mockLog.messages.length, 3)
315+
t.equal(mockLog.messages[0].args[0].op, 'handleBounce')
316+
t.equal(mockLog.messages[0].args[0].email, 'test@example.com')
317+
t.equal(mockLog.messages[0].args[0].template, 'verifyLoginEmail')
318+
t.equal(mockLog.messages[0].args[0].bounceType, 'Permanent')
319+
t.equal(mockLog.messages[0].args[0].bounceSubType, 'General')
320+
t.equal(mockLog.messages[1].args[0], 'account.email_bounced')
321+
})
322+
}
323+
)

0 commit comments

Comments
 (0)