email-bounce-parser 1.0.17 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/lib/parser.js +37 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ console.log(result);
|
|
|
53
53
|
// email: {
|
|
54
54
|
// body: "This is the mail system at host mailer.acme.email [...] (in reply to RCPT TO command)",
|
|
55
55
|
// intro: "This is the mail system at host mailer.acme.email [...] The mail system",
|
|
56
|
-
// error: "<
|
|
56
|
+
// error: "<john@yipee.com>: host smtp.secureserver.net[92.240.81.0] said: [...] (in reply to RCPT TO command)"
|
|
57
57
|
// },
|
|
58
58
|
//
|
|
59
59
|
// data: {
|
|
@@ -62,7 +62,7 @@ console.log(result);
|
|
|
62
62
|
// basic: "550",
|
|
63
63
|
// enhanced: "5.1.1"
|
|
64
64
|
// },
|
|
65
|
-
// label: "<
|
|
65
|
+
// label: "<john@yipee.com> Recipient not found.",
|
|
66
66
|
//
|
|
67
67
|
// type: "action_not_taken",
|
|
68
68
|
//
|
|
@@ -76,6 +76,8 @@ console.log(result);
|
|
|
76
76
|
// }
|
|
77
77
|
// },
|
|
78
78
|
//
|
|
79
|
+
// recipient: "john@yipee.com",
|
|
80
|
+
//
|
|
79
81
|
// server: {
|
|
80
82
|
// hostname: "smtp.secureserver.net",
|
|
81
83
|
// ip: "92.240.81.0",
|
package/lib/parser.js
CHANGED
|
@@ -82,16 +82,16 @@ var REGEXES = {
|
|
|
82
82
|
],
|
|
83
83
|
|
|
84
84
|
error : [
|
|
85
|
-
/said\: (\d{3}(?:[\s\-]\d\.\d\.\d
|
|
86
|
-
/said\: (\d{3}(?:[\s\-]\d\.\d\.\d
|
|
87
|
-
/(\d{3}\-\'\d\.\d\.\d
|
|
88
|
-
/LMTP error after .+?\:\<.+?\>\: (\d{3}(?:[\s\-]\d\.\d\.\d
|
|
89
|
-
/remote server returned \'(\d{3}(?:[\s\-]\d\.\d\.\d
|
|
90
|
-
/The response from the remote server was:\s(\d{3}(?:[\s\-]\d\.\d\.\d
|
|
91
|
-
/refused to talk to me\: (\d{3}(?:[\s\-]\d\.\d\.\d
|
|
92
|
-
/(?:error|reason)\:\s*?(\d{3}(?:[\s\-]\d\.\d\.\d
|
|
93
|
-
/(\d{3}[\s\-]\d\.\d\.\d
|
|
94
|
-
/(\d{3}\-\'\d\.\d\.\d
|
|
85
|
+
/said\: (\d{3}(?:[\s\-]\d\.\d\.\d{1,3})?) (.+) \(in reply to/,
|
|
86
|
+
/said\: (\d{3}(?:[\s\-]\d\.\d\.\d{1,3})?)-(.+)/,
|
|
87
|
+
/(\d{3}\-\'\d\.\d\.\d{1,3}) (.+)/,
|
|
88
|
+
/LMTP error after .+?\:\<.+?\>\: (\d{3}(?:[\s\-]\d\.\d\.\d{1,3})?) <.+?\>(.+)$/m,
|
|
89
|
+
/remote server returned \'(\d{3}(?:[\s\-]\d\.\d\.\d{1,3})?) (.+)\'/i,
|
|
90
|
+
/The response from the remote server was:\s(\d{3}(?:[\s\-]\d\.\d\.\d{1,3})?) (.+)/,
|
|
91
|
+
/refused to talk to me\: (\d{3}(?:[\s\-]\d\.\d\.\d{1,3})?) (.+)/,
|
|
92
|
+
/(?:error|reason)\:\s*?(\d{3}(?:[\s\-]\d\.\d\.\d{1,3})?) (.+)/i,
|
|
93
|
+
/(\d{3}[\s\-]\d\.\d\.\d{1,3})/,
|
|
94
|
+
/(\d{3}\-\'\d\.\d\.\d{1,3})/
|
|
95
95
|
],
|
|
96
96
|
|
|
97
97
|
error_lax : [
|
|
@@ -110,12 +110,13 @@ var REGEXES = {
|
|
|
110
110
|
|
|
111
111
|
recipient : [
|
|
112
112
|
/the following addresses had permanent fatal errors (?:.*?)\s\<(.+?)\>/i,
|
|
113
|
+
/there was a temporary problem delivering your message to (.+?). Gmail will retry/i,
|
|
113
114
|
/the following message to \<(.+?)\> was undeliverable/i,
|
|
114
115
|
/to the following addresses:\s*(.+)/i,
|
|
115
|
-
/^\<(.+?)\>:/m,
|
|
116
|
-
/^(.+?)\s?\n?\s*[\[|<]mailto\:(.+?)[\]|>]/mi, // "john@acme.com<mailto:john@acme.com>"
|
|
117
116
|
/^your message wasn't delivered to (.+?)\s/mi, // "Your message wasn't delivered to john@acme.com"
|
|
118
117
|
/^your message to (.+?) couldn\'t/mi, // "Your message to john@acme.com couldn't"
|
|
118
|
+
/^(.+?)\s?(?:\s\(.*?\))?\n?\s*[\[|<]mailto\:(.+?)[\]|>]/mi, // "john@acme.com<mailto:john@acme.com>" or "john@acme.com[mailto:john@acme.com]" or "john@acme.com (john@acme.com)<mailto:john@acme.com>"
|
|
119
|
+
/^\<(.+?)\>:/m,
|
|
119
120
|
/\<(.+?)\> \(expanded from \<.+?\>\)\:/, // "<john@acme.com> (expanded from <john@digiflex.com>): "
|
|
120
121
|
/\<(.+?)\>:/ // "<john@acme.com>:"
|
|
121
122
|
],
|
|
@@ -135,7 +136,7 @@ var REGEXES = {
|
|
|
135
136
|
|
|
136
137
|
enhanced_types_server_unknown : [
|
|
137
138
|
/(does not accept mail)/i,
|
|
138
|
-
/(domain name not
|
|
139
|
+
/(domain (?:name\s+)?(?:\S+\s)?(?:not found|does not exist))/i, // "domain does not exist" or "domain name does not exist" or "domain acme.com does not exist" or "domain name acme.com does not exist"
|
|
139
140
|
/(no route to host)/i
|
|
140
141
|
],
|
|
141
142
|
|
|
@@ -147,9 +148,13 @@ var REGEXES = {
|
|
|
147
148
|
/(out of storage|(?:mailbox (?:is )?full)|(?:user (?:is )?over quota))/i // "user is over quota" (iCloud)
|
|
148
149
|
],
|
|
149
150
|
|
|
151
|
+
enhanced_types_reputation : [
|
|
152
|
+
/(rate limited due to IP reputation)/i
|
|
153
|
+
],
|
|
154
|
+
|
|
150
155
|
error_code : [
|
|
151
|
-
/(\d{3})[\s\-](\d\.\d\.\d
|
|
152
|
-
/(\d{3})\-\'(\d\.\d\.\d
|
|
156
|
+
/(\d{3})[\s\-](\d\.\d\.\d{1,3})/, // "550 5.4.1" or "550-5.4.1" or "550-5.4.11" or "550-5.4.110"
|
|
157
|
+
/(\d{3})\-\'(\d\.\d\.\d{1,3})/, // "550-'5.4.1" or "550-'5.4.11" or "550-'5.4.110"
|
|
153
158
|
/(\d{3})/ // "550"
|
|
154
159
|
]
|
|
155
160
|
};
|
|
@@ -299,21 +304,22 @@ class Parser {
|
|
|
299
304
|
_permanent = true;
|
|
300
305
|
}
|
|
301
306
|
|
|
302
|
-
// Make sure the bounce is actually permanent
|
|
303
|
-
if (_permanent === true) {
|
|
304
|
-
var _match = this.__regexes.temporary_safe.match(str);
|
|
305
|
-
|
|
306
|
-
if (_match && _match.length > 1) {
|
|
307
|
-
_temporary = true;
|
|
308
|
-
_permanent = false;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
307
|
if (_code.basic) {
|
|
313
308
|
_type = ERROR_CODES_TYPES[_code.basic] || null
|
|
314
309
|
}
|
|
315
310
|
}
|
|
316
311
|
|
|
312
|
+
// In cases where the bounce is detected as permanent, or the \
|
|
313
|
+
// temporary / permanent status is still unclear, run additional detection
|
|
314
|
+
if (_permanent === true || (_temporary === false && _permanent === false)) {
|
|
315
|
+
var _match = this.__regexes.temporary_safe.match(str);
|
|
316
|
+
|
|
317
|
+
if (_match && _match.length > 1) {
|
|
318
|
+
_temporary = true;
|
|
319
|
+
_permanent = false;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
317
323
|
// No label detected? Probably because there's no error code
|
|
318
324
|
if (!_label) {
|
|
319
325
|
// Attempt a lax check
|
|
@@ -409,6 +415,12 @@ class Parser {
|
|
|
409
415
|
_type = "mailbox_full";
|
|
410
416
|
}
|
|
411
417
|
|
|
418
|
+
_match = loopRegexes(this.__regexes.enhanced_types_reputation, str);
|
|
419
|
+
|
|
420
|
+
if (!_type && _match && _match.length > 1) {
|
|
421
|
+
_type = "reputation";
|
|
422
|
+
}
|
|
423
|
+
|
|
412
424
|
// Detect enhanced-type from enhanced error code
|
|
413
425
|
// Notice: this is done as a last resort, as sometimes enhanced code \
|
|
414
426
|
// doesn't clearly convey the actual error
|