sisimai 5.0.3 → 5.2.0
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.
- checksums.yaml +4 -4
- data/.github/workflows/codecovio.yml +3 -1
- data/.github/workflows/rake-test.yml +7 -3
- data/ChangeLog.md +136 -0
- data/Makefile +4 -2
- data/README-JA.md +32 -22
- data/README.md +31 -21
- data/lib/sisimai/arf.rb +124 -213
- data/lib/sisimai/fact/json.rb +2 -2
- data/lib/sisimai/fact/yaml.rb +2 -2
- data/lib/sisimai/fact.rb +208 -173
- data/lib/sisimai/lda.rb +98 -0
- data/lib/sisimai/lhost/activehunter.rb +5 -4
- data/lib/sisimai/lhost/amazonses.rb +189 -305
- data/lib/sisimai/lhost/apachejames.rb +52 -55
- data/lib/sisimai/lhost/biglobe.rb +5 -6
- data/lib/sisimai/lhost/courier.rb +14 -12
- data/lib/sisimai/lhost/domino.rb +29 -29
- data/lib/sisimai/lhost/dragonfly.rb +113 -0
- data/lib/sisimai/lhost/einsundeins.rb +7 -8
- data/lib/sisimai/lhost/exchange2003.rb +10 -11
- data/lib/sisimai/lhost/exchange2007.rb +115 -104
- data/lib/sisimai/lhost/exim.rb +236 -246
- data/lib/sisimai/lhost/ezweb.rb +47 -55
- data/lib/sisimai/lhost/fml.rb +6 -7
- data/lib/sisimai/lhost/gmail.rb +36 -32
- data/lib/sisimai/lhost/gmx.rb +8 -20
- data/lib/sisimai/lhost/googlegroups.rb +13 -12
- data/lib/sisimai/lhost/googleworkspace.rb +94 -0
- data/lib/sisimai/lhost/imailserver.rb +11 -19
- data/lib/sisimai/lhost/interscanmss.rb +6 -5
- data/lib/sisimai/lhost/kddi.rb +7 -8
- data/lib/sisimai/lhost/mailfoundry.rb +6 -9
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +6 -6
- data/lib/sisimai/lhost/messagingserver.rb +19 -17
- data/lib/sisimai/lhost/mfilter.rb +8 -7
- data/lib/sisimai/lhost/notes.rb +6 -8
- data/lib/sisimai/lhost/opensmtpd.rb +11 -9
- data/lib/sisimai/lhost/postfix.rb +29 -31
- data/lib/sisimai/lhost/qmail.rb +136 -112
- data/lib/sisimai/lhost/sendmail.rb +23 -22
- data/lib/sisimai/lhost/v5sendmail.rb +93 -64
- data/lib/sisimai/lhost/verizon.rb +6 -6
- data/lib/sisimai/lhost/x1.rb +4 -4
- data/lib/sisimai/lhost/x2.rb +4 -5
- data/lib/sisimai/lhost/x3.rb +5 -5
- data/lib/sisimai/lhost/x6.rb +4 -4
- data/lib/sisimai/lhost/zoho.rb +6 -6
- data/lib/sisimai/lhost.rb +21 -24
- data/lib/sisimai/mail/maildir.rb +1 -1
- data/lib/sisimai/mail/stdin.rb +1 -1
- data/lib/sisimai/message.rb +100 -153
- data/lib/sisimai/order.rb +22 -77
- data/lib/sisimai/reason/authfailure.rb +1 -4
- data/lib/sisimai/reason/badreputation.rb +3 -3
- data/lib/sisimai/reason/blocked.rb +7 -10
- data/lib/sisimai/reason/contenterror.rb +7 -1
- data/lib/sisimai/reason/exceedlimit.rb +1 -4
- data/lib/sisimai/reason/failedstarttls.rb +42 -0
- data/lib/sisimai/reason/filtered.rb +5 -4
- data/lib/sisimai/reason/hasmoved.rb +1 -2
- data/lib/sisimai/reason/hostunknown.rb +3 -3
- data/lib/sisimai/reason/mailboxfull.rb +2 -4
- data/lib/sisimai/reason/mailererror.rb +1 -2
- data/lib/sisimai/reason/mesgtoobig.rb +2 -4
- data/lib/sisimai/reason/norelaying.rb +3 -3
- data/lib/sisimai/reason/notaccept.rb +2 -3
- data/lib/sisimai/reason/notcompliantrfc.rb +10 -4
- data/lib/sisimai/reason/rejected.rb +2 -1
- data/lib/sisimai/reason/requireptr.rb +2 -2
- data/lib/sisimai/reason/securityerror.rb +1 -3
- data/lib/sisimai/reason/spamdetected.rb +6 -8
- data/lib/sisimai/reason/speeding.rb +1 -2
- data/lib/sisimai/reason/suppressed.rb +36 -0
- data/lib/sisimai/reason/suspend.rb +1 -3
- data/lib/sisimai/reason/systemerror.rb +5 -0
- data/lib/sisimai/reason/toomanyconn.rb +1 -2
- data/lib/sisimai/reason/userunknown.rb +1 -1
- data/lib/sisimai/reason/virusdetected.rb +5 -6
- data/lib/sisimai/reason.rb +82 -78
- data/lib/sisimai/rfc1123.rb +152 -0
- data/lib/sisimai/rfc1894.rb +102 -62
- data/lib/sisimai/rfc2045.rb +2 -1
- data/lib/sisimai/rfc3464/thirdparty.rb +102 -0
- data/lib/sisimai/rfc3464.rb +224 -345
- data/lib/sisimai/rfc3834.rb +3 -3
- data/lib/sisimai/rfc5322.rb +7 -17
- data/lib/sisimai/rfc791.rb +69 -0
- data/lib/sisimai/rhost/aol.rb +36 -0
- data/lib/sisimai/rhost/apple.rb +95 -0
- data/lib/sisimai/rhost/cox.rb +84 -34
- data/lib/sisimai/rhost/facebook.rb +100 -0
- data/lib/sisimai/rhost/franceptt.rb +87 -83
- data/lib/sisimai/rhost/godaddy.rb +208 -45
- data/lib/sisimai/rhost/google.rb +22 -22
- data/lib/sisimai/rhost/gsuite.rb +42 -0
- data/lib/sisimai/rhost/iua.rb +5 -5
- data/lib/sisimai/rhost/kddi.rb +9 -7
- data/lib/sisimai/rhost/messagelabs.rb +37 -0
- data/lib/sisimai/rhost/microsoft.rb +60 -54
- data/lib/sisimai/rhost/mimecast.rb +44 -31
- data/lib/sisimai/rhost/nttdocomo.rb +5 -4
- data/lib/sisimai/rhost/outlook.rb +36 -0
- data/lib/sisimai/rhost/spectrum.rb +102 -41
- data/lib/sisimai/rhost/tencent.rb +48 -26
- data/lib/sisimai/rhost/yahooinc.rb +111 -0
- data/lib/sisimai/rhost.rb +65 -42
- data/lib/sisimai/smtp/command.rb +31 -21
- data/lib/sisimai/smtp/failure.rb +103 -0
- data/lib/sisimai/smtp/reply.rb +29 -24
- data/lib/sisimai/smtp/status.rb +36 -19
- data/lib/sisimai/smtp/transcript.rb +18 -18
- data/lib/sisimai/string.rb +0 -46
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +0 -6
- data/set-of-emails/maildir/bsd/lhost-dragonfly-01.eml +36 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-02.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-03.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-04.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-05.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-06.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-07.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-08.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-09.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-10.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-11.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-12.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-13.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-14.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-15.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-16.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-17.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-18.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-19.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-20.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-21.eml +33 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-22.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-23.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-24.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-25.eml +33 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-26.eml +33 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-27.eml +47 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-28.eml +47 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-29.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-dragonfly-30.eml +32 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-10.eml +58 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-11.eml +58 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-12.eml +62 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-13.eml +62 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-14.eml +58 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-15.eml +63 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-16.eml +62 -0
- data/set-of-emails/maildir/bsd/lhost-opensmtpd-17.eml +63 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-30.eml +81 -81
- data/set-of-emails/maildir/bsd/lhost-qmail-11.eml +29 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-12.eml +29 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-13.eml +29 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-14.eml +34 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-15.eml +30 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-16.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-17.eml +38 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-18.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-19.eml +31 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-20.eml +46 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-21.eml +41 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-22.eml +42 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-23.eml +43 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-24.eml +43 -0
- data/set-of-emails/maildir/bsd/lhost-qmail-25.eml +54 -0
- data/set-of-emails/maildir/bsd/{lhost-aol-03.eml → rhost-aol-03.eml} +1264 -1264
- data/set-of-emails/maildir/bsd/{lhost-aol-04.eml → rhost-aol-04.eml} +1260 -1260
- data/set-of-emails/maildir/bsd/{lhost-aol-05.eml → rhost-aol-05.eml} +105 -105
- data/set-of-emails/maildir/bsd/{lhost-aol-06.eml → rhost-aol-06.eml} +105 -105
- data/set-of-emails/maildir/bsd/rhost-apple-01.eml +79 -0
- data/set-of-emails/maildir/bsd/rhost-apple-02.eml +81 -0
- data/set-of-emails/maildir/bsd/rhost-apple-03.eml +75 -0
- data/set-of-emails/maildir/bsd/rhost-apple-04.eml +74 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-01.eml +189 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-02.eml +180 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-03.eml +251 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-04.eml +211 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-05.eml +226 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-06.eml +257 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-07.eml +289 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-08.eml +231 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-09.eml +231 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-10.eml +254 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-11.eml +228 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-12.eml +271 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-13.eml +261 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-14.eml +273 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-15.eml +229 -0
- data/set-of-emails/maildir/bsd/{lhost-messagelabs-01.eml → rhost-messagelabs-01.eml} +93 -93
- data/set-of-emails/maildir/bsd/rhost-outlook-01.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-02.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-03.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-04.eml +79 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-06.eml +75 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-07.eml +70 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-08.eml +70 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-09.eml +56 -0
- data/set-of-emails/maildir/bsd/rhost-yahooinc-01.eml +80 -0
- data/set-of-emails/maildir/bsd/rhost-yahooinc-02.eml +83 -0
- data/set-of-emails/maildir/bsd/rhost-yahooinc-03.eml +125 -0
- data/set-of-emails/maildir/tmp/arf-22.eml +49 -0
- data/set-of-emails/maildir/tmp/arf-23.eml +49 -0
- data/set-of-emails/maildir/tmp/arf-24.eml +50 -0
- data/set-of-emails/maildir/tmp/lhost-exim-07.eml +28 -0
- metadata +136 -56
- data/lib/sisimai/lhost/amavis.rb +0 -163
- data/lib/sisimai/lhost/amazonworkmail.rb +0 -127
- data/lib/sisimai/lhost/aol.rb +0 -125
- data/lib/sisimai/lhost/barracuda.rb +0 -92
- data/lib/sisimai/lhost/bigfoot.rb +0 -125
- data/lib/sisimai/lhost/facebook.rb +0 -188
- data/lib/sisimai/lhost/gsuite.rb +0 -194
- data/lib/sisimai/lhost/mailru.rb +0 -214
- data/lib/sisimai/lhost/mcafee.rb +0 -109
- data/lib/sisimai/lhost/messagelabs.rb +0 -119
- data/lib/sisimai/lhost/mxlogic.rb +0 -198
- data/lib/sisimai/lhost/office365.rb +0 -252
- data/lib/sisimai/lhost/outlook.rb +0 -129
- data/lib/sisimai/lhost/powermta.rb +0 -118
- data/lib/sisimai/lhost/receivingses.rb +0 -126
- data/lib/sisimai/lhost/sendgrid.rb +0 -150
- data/lib/sisimai/lhost/surfcontrol.rb +0 -105
- data/lib/sisimai/lhost/x4.rb +0 -269
- data/lib/sisimai/lhost/x5.rb +0 -112
- data/lib/sisimai/lhost/yahoo.rb +0 -102
- data/lib/sisimai/lhost/yandex.rb +0 -118
- data/lib/sisimai/mda.rb +0 -121
- data/lib/sisimai/smtp/error.rb +0 -119
- /data/set-of-emails/maildir/bsd/{lhost-googlegroups-15.eml → lhost-googleworkspace-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-x4-08.eml → lhost-x2-06.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-01.eml → rfc3464-51.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-03.eml → rfc3464-52.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-04.eml → rfc3464-53.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-05.eml → rfc3464-54.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-06.eml → rfc3464-55.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-07.eml → rfc3464-56.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-08.eml → rfc3464-57.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-09.eml → rfc3464-58.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-10.eml → rfc3464-59.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-11.eml → rfc3464-60.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-12.eml → rfc3464-61.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-13.eml → rfc3464-62.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-14.eml → rfc3464-63.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-15.eml → rfc3464-64.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-02.eml → rfc3464-65.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-aol-01.eml → rhost-aol-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-aol-02.eml → rhost-aol-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-facebook-03.eml → rhost-facebook-03.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-facebook-04.eml → rhost-facebook-04.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-messagelabs-02.eml → rhost-messagelabs-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-messagelabs-03.eml → rhost-messagelabs-03.eml} +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-37.eml +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-38.eml +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-39.eml +0 -0
data/lib/sisimai/lhost/ezweb.rb
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::EZweb
|
3
|
-
# called from only Sisimai::Message.
|
2
|
+
# Sisimai::Lhost::EZweb decodes a bounce email which created by au EZweb https://www.au.com/mobile/.
|
3
|
+
# Methods in the module are called from only Sisimai::Message.
|
4
4
|
module EZweb
|
5
5
|
class << self
|
6
6
|
require 'sisimai/lhost'
|
7
7
|
|
8
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
9
|
-
Boundaries = [
|
10
|
-
|
11
|
-
|
9
|
+
Boundaries = ["--------------------------------------------------", "Content-Type: message/rfc822"].freeze
|
10
|
+
StartingOf = { message: ['The user(s) ', 'Your message ', 'Each of the following', '<'] }.freeze
|
11
|
+
Messagesof = {
|
12
12
|
# notaccept: ['The following recipients did not receive this message:'],
|
13
|
+
'expired' => [
|
14
|
+
# Your message was not delivered within 0 days and 1 hours.
|
15
|
+
# Remote host is not responding.
|
16
|
+
'Your message was not delivered within ',
|
17
|
+
],
|
13
18
|
'mailboxfull' => ['The user(s) account is temporarily over quota'],
|
19
|
+
'onhold' => ['Each of the following recipients was rejected by a remote mail server'],
|
14
20
|
'suspend' => [
|
15
21
|
# http://www.naruhodo-au.kddi.com/qa3429203.html
|
16
22
|
# The recipient may be unpaid user...?
|
17
23
|
'The user(s) account is disabled.',
|
18
24
|
'The user(s) account is temporarily limited.',
|
19
25
|
],
|
20
|
-
'expired' => [
|
21
|
-
# Your message was not delivered within 0 days and 1 hours.
|
22
|
-
# Remote host is not responding.
|
23
|
-
'Your message was not delivered within ',
|
24
|
-
],
|
25
|
-
'onhold' => ['Each of the following recipients was rejected by a remote mail server'],
|
26
26
|
}.freeze
|
27
27
|
|
28
|
-
#
|
28
|
+
# @abstract Decodes the bounce message from au EZweb
|
29
29
|
# @param [Hash] mhead Message headers of a bounce email
|
30
30
|
# @param [String] mbody Message body of a bounce email
|
31
31
|
# @return [Hash] Bounce data list and message/rfc822 part
|
32
|
-
# @return [Nil] it failed to
|
32
|
+
# @return [Nil] it failed to decode or the arguments are missing
|
33
33
|
def inquire(mhead, mbody)
|
34
34
|
match = 0
|
35
35
|
match += 1 if mhead['from'].include?('Postmaster@ezweb.ne.jp')
|
@@ -48,7 +48,7 @@ module Sisimai::Lhost
|
|
48
48
|
bodyslices = emailparts[0].split("\n")
|
49
49
|
readcursor = 0 # (Integer) Points the current cursor position
|
50
50
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
51
|
-
|
51
|
+
substrings = []; Messagesof.each_value { |a| substrings << a }; substrings.flatten!
|
52
52
|
v = nil
|
53
53
|
|
54
54
|
while e = bodyslices.shift do
|
@@ -56,7 +56,7 @@ module Sisimai::Lhost
|
|
56
56
|
# line of the beginning of the original message.
|
57
57
|
if readcursor == 0
|
58
58
|
# Beginning of the bounce message or delivery status part
|
59
|
-
readcursor |= Indicators[:deliverystatus] if
|
59
|
+
readcursor |= Indicators[:deliverystatus] if StartingOf[:message].any? { |a| e.include?(a) }
|
60
60
|
end
|
61
61
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
62
62
|
next if e.empty?
|
@@ -79,81 +79,73 @@ module Sisimai::Lhost
|
|
79
79
|
p1 = e.index('<') || -1
|
80
80
|
p2 = e.index('>') || -1
|
81
81
|
|
82
|
-
if v[
|
82
|
+
if v["recipient"] != ""
|
83
83
|
# There are multiple recipient addresses in the message body.
|
84
84
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
85
85
|
v = dscontents[-1]
|
86
86
|
end
|
87
|
-
v[
|
87
|
+
v["recipient"] = Sisimai::Address.s3s4(e[p1, p2 - p1])
|
88
|
+
v["diagnosis"] << " " << e
|
88
89
|
recipients += 1
|
89
90
|
|
90
|
-
elsif
|
91
|
+
elsif Sisimai::RFC1894.match(e) > 0
|
91
92
|
# "e" matched with any field defined in RFC3464
|
92
93
|
next unless o = Sisimai::RFC1894.field(e)
|
93
94
|
next unless fieldtable[o[0]]
|
94
95
|
v[fieldtable[o[0]]] = o[2]
|
95
96
|
|
96
97
|
else
|
97
|
-
#
|
98
|
+
# Other error messages
|
98
99
|
next if Sisimai::String.is_8bit(e)
|
99
|
-
if e.include?(
|
100
|
+
if e.include?(" >>> ")
|
100
101
|
# >>> RCPT TO:<******@ezweb.ne.jp>
|
101
|
-
v[
|
102
|
+
v["command"] = Sisimai::SMTP::Command.find(e)
|
103
|
+
v["diagnosis"] << " " << e
|
104
|
+
|
105
|
+
elsif e.include?(" <<< ")
|
106
|
+
# <<< 550 ...
|
107
|
+
v["diagnosis"] << " " << e
|
108
|
+
|
102
109
|
else
|
103
110
|
# Check error message
|
104
|
-
|
111
|
+
isincluded = false
|
112
|
+
if substrings.any? { |a| e.include?(a) }
|
105
113
|
# Check with regular expressions of each error
|
106
|
-
v[
|
107
|
-
|
108
|
-
else
|
109
|
-
# >>> 550
|
110
|
-
v['alterrors'] ||= ''
|
111
|
-
v['alterrors'] << ' ' << e
|
114
|
+
v["diagnosis"] << " " << e
|
115
|
+
isincluded = true
|
112
116
|
end
|
117
|
+
v["diagnosis"] << " " << e if isincluded
|
113
118
|
end
|
114
119
|
end
|
115
120
|
end
|
116
121
|
return nil unless recipients > 0
|
117
122
|
|
118
123
|
dscontents.each do |e|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
if e['diagnosis'].start_with?('-') || e['diagnosis'].end_with?('__')
|
123
|
-
# Override the value of diagnostic code message
|
124
|
-
e['diagnosis'] = e['alterrors'] unless e['alterrors'].empty?
|
125
|
-
end
|
126
|
-
e.delete('alterrors')
|
127
|
-
end
|
128
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
|
124
|
+
# Check each value of DeliveryMatter{}, try to detect the bounce reason.
|
125
|
+
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
126
|
+
e["command"] = Sisimai::SMTP::Command.find(e["diagnosis"]) if e["command"].empty?
|
129
127
|
|
130
128
|
if mhead['x-spasign'].to_s == 'NG'
|
131
129
|
# Content-Type: text/plain; ..., X-SPASIGN: NG (spamghetti, au by EZweb)
|
132
130
|
# Filtered recipient returns message that include 'X-SPASIGN' header
|
133
131
|
e['reason'] = 'filtered'
|
134
132
|
else
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
# Check each error message pattern
|
145
|
-
next unless e['diagnosis'].include?(rr)
|
146
|
-
e['reason'] = r
|
147
|
-
throw :SESSION
|
148
|
-
end
|
133
|
+
# There is no X-SPASIGN header or the value of the header is not "NG"
|
134
|
+
catch :FINDREASON do
|
135
|
+
Messagesof.each_key do |r|
|
136
|
+
# Try to match with each session error message
|
137
|
+
Messagesof[r].each do |f|
|
138
|
+
# Check each error message pattern
|
139
|
+
next unless e['diagnosis'].include?(f)
|
140
|
+
e['reason'] = r
|
141
|
+
throw :FINDREASON
|
149
142
|
end
|
150
143
|
end
|
151
|
-
|
152
144
|
end
|
153
145
|
end
|
154
|
-
next if e['reason']
|
146
|
+
next if e['reason'] != ""
|
155
147
|
next if e['recipient'].end_with?('@ezweb.ne.jp', '@au.com')
|
156
|
-
e[
|
148
|
+
e["reason"] = "userunknown" if e["diagnosis"].start_with?("<")
|
157
149
|
end
|
158
150
|
|
159
151
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
data/lib/sisimai/lhost/fml.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::FML
|
3
|
-
# from only Sisimai::Message.
|
2
|
+
# Sisimai::Lhost::FML decodes a bounce email which created by fml mailing list server/manager
|
3
|
+
# https://www.fml.org/. Methods in the module are called from only Sisimai::Message.
|
4
4
|
module FML
|
5
5
|
class << self
|
6
6
|
require 'sisimai/lhost'
|
@@ -38,11 +38,11 @@ module Sisimai::Lhost
|
|
38
38
|
'securityerror' => ['Security alert:'],
|
39
39
|
}.freeze
|
40
40
|
|
41
|
-
#
|
41
|
+
# @abstract Decodes the bounce message from fml mailling list server/manager
|
42
42
|
# @param [Hash] mhead Message headers of a bounce email
|
43
43
|
# @param [String] mbody Message body of a bounce email
|
44
44
|
# @return [Hash] Bounce data list and message/rfc822 part
|
45
|
-
# @return [Nil] it failed to
|
45
|
+
# @return [Nil] it failed to decode or the arguments are missing
|
46
46
|
# @since v4.22.3
|
47
47
|
def inquire(mhead, mbody)
|
48
48
|
return nil unless mhead['x-mlserver']
|
@@ -68,7 +68,7 @@ module Sisimai::Lhost
|
|
68
68
|
p2 = e.rindex('>') || -1
|
69
69
|
if p1 > 0 && p2 > 0
|
70
70
|
# You are not a member of this mailing list <neko-nyaan@example.org>.
|
71
|
-
if v[
|
71
|
+
if v["recipient"] != ""
|
72
72
|
# There are multiple recipient addresses in the message body.
|
73
73
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
74
74
|
v = dscontents[-1]
|
@@ -79,7 +79,6 @@ module Sisimai::Lhost
|
|
79
79
|
else
|
80
80
|
# If you know the general guide of this list, please send mail with
|
81
81
|
# the mail body
|
82
|
-
v['diagnosis'] ||= ''
|
83
82
|
v['diagnosis'] << e
|
84
83
|
end
|
85
84
|
end
|
@@ -98,7 +97,7 @@ module Sisimai::Lhost
|
|
98
97
|
# Error messages in the message body did not matched
|
99
98
|
ErrorTitle.each_key do |f|
|
100
99
|
# Try to match with the Subject string
|
101
|
-
next unless
|
100
|
+
next unless ErrorTitle[f].any? { |a| mhead["subject"].include?(a) }
|
102
101
|
e['reason'] = f
|
103
102
|
break
|
104
103
|
end
|
data/lib/sisimai/lhost/gmail.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::Gmail
|
3
|
-
# called from only Sisimai::Message.
|
2
|
+
# Sisimai::Lhost::Gmail decodes a bounce email which created by Gmail https://mail.google.com/.
|
3
|
+
# Methods in the module are called from only Sisimai::Message.
|
4
4
|
module Gmail
|
5
5
|
class << self
|
6
6
|
require 'sisimai/lhost'
|
@@ -28,7 +28,7 @@ module Sisimai::Lhost
|
|
28
28
|
# We recommend contacting the other email provider for further information about the
|
29
29
|
# cause of this error. The error that the other server returned was:
|
30
30
|
# 500 Remote server does not support TLS (state 6).
|
31
|
-
'6' => { 'command' => 'MAIL', 'reason' => '
|
31
|
+
'6' => { 'command' => 'MAIL', 'reason' => 'failedstarttls' },
|
32
32
|
|
33
33
|
# https://www.google.td/support/forum/p/gmail/thread?tid=08a60ebf5db24f7b&hl=en
|
34
34
|
# Technical details of permanent failure:
|
@@ -44,7 +44,7 @@ module Sisimai::Lhost
|
|
44
44
|
# We recommend contacting the other email provider for further information about the
|
45
45
|
# cause of this error. The error that the other server returned was:
|
46
46
|
# 454 454 TLS missing certificate: error:0200100D:system library:fopen:Permission denied (#4.3.0) (state 9).
|
47
|
-
'9' => { 'command' => 'AUTH', 'reason' => '
|
47
|
+
'9' => { 'command' => 'AUTH', 'reason' => 'failedstarttls' },
|
48
48
|
|
49
49
|
# https://www.google.com/support/forum/p/gmail/thread?tid=5cfab8c76ec88638&hl=en
|
50
50
|
# Technical details of permanent failure:
|
@@ -96,11 +96,11 @@ module Sisimai::Lhost
|
|
96
96
|
'18' => { 'command' => 'DATA', 'reason' => 'filtered' },
|
97
97
|
}.freeze
|
98
98
|
|
99
|
-
#
|
99
|
+
# @abstract Decodes the bounce message from Gmail
|
100
100
|
# @param [Hash] mhead Message headers of a bounce email
|
101
101
|
# @param [String] mbody Message body of a bounce email
|
102
102
|
# @return [Hash] Bounce data list and message/rfc822 part
|
103
|
-
# @return [Nil] it failed to
|
103
|
+
# @return [Nil] it failed to decode or the arguments are missing
|
104
104
|
def inquire(mhead, mbody)
|
105
105
|
# From: Mail Delivery Subsystem <mailer-daemon@googlemail.com>
|
106
106
|
# Received: from vw-in-f109.1e100.net [74.125.113.109] by ...
|
@@ -151,6 +151,7 @@ module Sisimai::Lhost
|
|
151
151
|
return nil unless mhead['from'].end_with?('<mailer-daemon@googlemail.com>')
|
152
152
|
return nil unless mhead['subject'].start_with?('Delivery Status Notification')
|
153
153
|
|
154
|
+
require 'sisimai/address'
|
154
155
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
155
156
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
156
157
|
bodyslices = emailparts[0].split("\n")
|
@@ -187,7 +188,7 @@ module Sisimai::Lhost
|
|
187
188
|
|
188
189
|
if e.start_with?(' ') && e.include?('@')
|
189
190
|
# kijitora@example.jp: 550 5.2.2 <kijitora@example>... Mailbox Full
|
190
|
-
if v[
|
191
|
+
if v["recipient"] != ""
|
191
192
|
# There are multiple recipient addresses in the message body.
|
192
193
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
193
194
|
v = dscontents[-1]
|
@@ -198,41 +199,44 @@ module Sisimai::Lhost
|
|
198
199
|
v['recipient'] = r
|
199
200
|
recipients += 1
|
200
201
|
else
|
201
|
-
v[
|
202
|
-
v['diagnosis'] << e + ' '
|
202
|
+
v["diagnosis"] << e << " "
|
203
203
|
end
|
204
204
|
end
|
205
205
|
return nil unless recipients > 0
|
206
206
|
|
207
|
+
require 'sisimai/string'
|
208
|
+
require 'sisimai/rfc1123'
|
207
209
|
dscontents.each do |e|
|
208
210
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
209
211
|
|
210
|
-
|
212
|
+
if Sisimai::String.aligned(e['diagnosis'], [' by ', '. [', ']. '])
|
211
213
|
# Get the value of remote host
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
ipv4addr = e['diagnosis'][p2 + 3, e['diagnosis'].rindex(']. ') - p2 - 3]
|
219
|
-
lastchar = hostname[-1, 1].upcase.ord
|
214
|
+
# Google tried to deliver your message, but it was rejected by the server for the recipient
|
215
|
+
# domain example.jp by mx.example.jp. [192.0.2.153].
|
216
|
+
p1 = e['diagnosis'].rindex(' by ') || -1
|
217
|
+
p2 = e['diagnosis'].rindex('. [' ) || -1
|
218
|
+
hostname = e['diagnosis'][p1 + 4, p2 - p1 - 4]
|
219
|
+
ipv4addr = e['diagnosis'][p2 + 3, e['diagnosis'].rindex(']. ') - p2 - 3]
|
220
220
|
|
221
|
-
|
222
|
-
|
223
|
-
end
|
221
|
+
e['rhost'] = hostname if Sisimai::RFC1123.is_internethost(hostname)
|
222
|
+
e['rhost'] = ipv4addr if e["rhost"].empty?
|
224
223
|
end
|
225
224
|
|
226
|
-
|
227
|
-
|
228
|
-
|
225
|
+
while true do
|
226
|
+
# Find "(state 18)" and pick "18" as a key of statetable
|
227
|
+
p1 = e['diagnosis'].rindex(' (state '); break unless p1
|
228
|
+
p2 = e['diagnosis'].rindex(')'); break unless p2
|
229
|
+
break if p1 > p2
|
230
|
+
cu = e['diagnosis'][p1 + 8, p2 - p1 - 8]
|
231
|
+
break if cu.empty?
|
232
|
+
break unless StateTable[cu]
|
233
|
+
e['reason'] = StateTable[cu]['reason']
|
234
|
+
e['command'] = StateTable[cu]['command']
|
235
|
+
break
|
236
|
+
end
|
229
237
|
|
230
|
-
if
|
231
|
-
#
|
232
|
-
e['reason'] = StateTable[statecode0]['reason']
|
233
|
-
e['command'] = StateTable[statecode0]['command']
|
234
|
-
else
|
235
|
-
# No state code
|
238
|
+
if e['reason'].empty?
|
239
|
+
# There is no no state code in the error message
|
236
240
|
MessagesOf.each_key do |r|
|
237
241
|
# Verify each regular expression of session errors
|
238
242
|
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
@@ -240,10 +244,10 @@ module Sisimai::Lhost
|
|
240
244
|
break
|
241
245
|
end
|
242
246
|
end
|
243
|
-
next
|
247
|
+
next if e['reason'].empty?
|
244
248
|
|
245
249
|
# Set pseudo status code
|
246
|
-
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
250
|
+
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
247
251
|
next if e['status'].size == 0 || e['status'].include?('.0')
|
248
252
|
e['reason'] = Sisimai::SMTP::Status.name(e['status']).to_s || ''
|
249
253
|
end
|
data/lib/sisimai/lhost/gmx.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::GMX
|
3
|
-
# from only Sisimai::Message.
|
2
|
+
# Sisimai::Lhost::GMX decodes a bounce email which created by GMX https://gmx.net/.
|
3
|
+
# Methods in the module are called from only Sisimai::Message.
|
4
4
|
module GMX
|
5
5
|
class << self
|
6
6
|
require 'sisimai/lhost'
|
@@ -10,11 +10,11 @@ module Sisimai::Lhost
|
|
10
10
|
StartingOf = { message: ['This message was created automatically by mail delivery software'] }.freeze
|
11
11
|
MessagesOf = { 'expired' => ['delivery retry timeout exceeded'] }.freeze
|
12
12
|
|
13
|
-
#
|
13
|
+
# @abstract Decodes the bounce message from GMX
|
14
14
|
# @param [Hash] mhead Message headers of a bounce email
|
15
15
|
# @param [String] mbody Message body of a bounce email
|
16
16
|
# @return [Hash] Bounce data list and message/rfc822 part
|
17
|
-
# @return [Nil] it failed to
|
17
|
+
# @return [Nil] it failed to decode or the arguments are missing
|
18
18
|
def inquire(mhead, mbody)
|
19
19
|
# Envelope-To: <kijitora@mail.example.com>
|
20
20
|
# X-GMX-Antispam: 0 (Mail was not recognized as spam); Detail=V3;
|
@@ -60,7 +60,7 @@ module Sisimai::Lhost
|
|
60
60
|
#
|
61
61
|
# Reason:
|
62
62
|
# delivery retry timeout exceeded
|
63
|
-
if v[
|
63
|
+
if v["recipient"] != ""
|
64
64
|
# There are multiple recipient addresses in the message body.
|
65
65
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
66
66
|
v = dscontents[-1]
|
@@ -76,21 +76,9 @@ module Sisimai::Lhost
|
|
76
76
|
# host: mx.example.jp
|
77
77
|
v['rhost'] = e[6, e.size]
|
78
78
|
else
|
79
|
-
# Get error
|
80
|
-
if
|
81
|
-
|
82
|
-
v['diagnosis'] ||= e
|
83
|
-
else
|
84
|
-
next if e.empty?
|
85
|
-
if e.start_with?('Reason:')
|
86
|
-
# Reason:
|
87
|
-
# delivery retry timeout exceeded
|
88
|
-
v['diagnosis'] = e
|
89
|
-
|
90
|
-
elsif v['diagnosis'] == 'Reason:'
|
91
|
-
v['diagnosis'] = e
|
92
|
-
end
|
93
|
-
end
|
79
|
+
# Get error messages
|
80
|
+
next if e.empty?
|
81
|
+
v['diagnosis'] += e + ' '
|
94
82
|
end
|
95
83
|
end
|
96
84
|
return nil unless recipients > 0
|
@@ -1,20 +1,19 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::GoogleGroups
|
3
|
-
# module are called from only Sisimai::Message.
|
2
|
+
# Sisimai::Lhost::GoogleGroups decodes a bounce email which created by Google Groups https://groups.google.com.
|
3
|
+
# Methods in the module are called from only Sisimai::Message.
|
4
4
|
module GoogleGroups
|
5
5
|
class << self
|
6
6
|
require 'sisimai/lhost'
|
7
|
+
Boundaries = ['----- Original message -----', 'Content-Type: message/rfc822'].freeze
|
7
8
|
|
8
|
-
|
9
|
-
Boundaries = ['----- Original message -----'].freeze
|
10
|
-
|
11
|
-
# Parse bounce messages from Google Groups
|
9
|
+
# @abstract Decodes the bounce message from Google Groups
|
12
10
|
# @param [Hash] mhead Message headers of a bounce email
|
13
11
|
# @param [String] mbody Message body of a bounce email
|
14
12
|
# @return [Hash] Bounce data list and message/rfc822 part
|
15
|
-
# @return [Nil] it failed to
|
13
|
+
# @return [Nil] it failed to decode or the arguments are missing
|
16
14
|
# @since v4.25.6
|
17
15
|
def inquire(mhead, mbody)
|
16
|
+
return nil unless mbody.include?("Google Groups")
|
18
17
|
return nil unless mhead['from'].end_with?('<mailer-daemon@googlemail.com>')
|
19
18
|
return nil unless mhead['subject'].start_with?('Delivery Status Notification')
|
20
19
|
return nil unless mhead['x-failed-recipients']
|
@@ -39,7 +38,6 @@ module Sisimai::Lhost
|
|
39
38
|
# Google Groups
|
40
39
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
41
40
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
42
|
-
recordwide = { 'rhost' => '', 'reason' => '', 'diagnosis' => '' }
|
43
41
|
recipients = 0
|
44
42
|
v = dscontents[-1]
|
45
43
|
|
@@ -49,15 +47,18 @@ module Sisimai::Lhost
|
|
49
47
|
# * This group may not be open to posting.
|
50
48
|
entiremesg = emailparts[0].split(/\n\n/, 5).slice(0, 4).join(' ').tr("\n", ' ');
|
51
49
|
receivedby = mhead['received'] || []
|
52
|
-
recordwide
|
53
|
-
|
54
|
-
|
50
|
+
recordwide = {
|
51
|
+
'diagnosis' => Sisimai::String.sweep(entiremesg),
|
52
|
+
'reason' => 'onhold',
|
53
|
+
'rhost' => Sisimai::RFC5322.received(receivedby[0])[1],
|
54
|
+
}
|
55
|
+
recordwide['reason'] = 'rejected' if emailparts[0].scan(/^[ ]?[*][ ]?/).size == 4
|
55
56
|
|
56
57
|
mhead['x-failed-recipients'].split(',').each do |e|
|
57
58
|
# X-Failed-Recipients: neko@example.jp, nyaan@example.org, ...
|
58
59
|
next unless Sisimai::Address.is_emailaddress(e)
|
59
60
|
|
60
|
-
if v[
|
61
|
+
if v["recipient"] != ""
|
61
62
|
# There are multiple recipient addresses in the message body.
|
62
63
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
63
64
|
v = dscontents[-1]
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Sisimai::Lhost
|
2
|
+
# Sisimai::Lhost::GoogleWorkspace decodes a bounce email which created by Google Workspace.
|
3
|
+
# Methods in the module are called only from Sisimai::Message.
|
4
|
+
module GoogleWorkspace
|
5
|
+
class << self
|
6
|
+
require 'sisimai/lhost'
|
7
|
+
require 'sisimai/string'
|
8
|
+
require 'sisimai/address'
|
9
|
+
|
10
|
+
Indicators = Sisimai::Lhost.INDICATORS
|
11
|
+
Boundaries = ["Content-Type: message/rfc822", "Content-Type: text/rfc822-headers"].freeze
|
12
|
+
StartingOf = {
|
13
|
+
message: ["** "],
|
14
|
+
error: ["The response was:", "The response from the remote server was:"],
|
15
|
+
}.freeze
|
16
|
+
MessagesOf = {
|
17
|
+
"userunknown" => ["because the address couldn't be found. Check for typos or unnecessary spaces and try again."],
|
18
|
+
"notaccept" => ["Null MX"],
|
19
|
+
"networkerror" => [" had no relevant answers.", " responded with code NXDOMAIN"],
|
20
|
+
}.freeze
|
21
|
+
|
22
|
+
# @abstract Decodes the bounce message from Google Workspace
|
23
|
+
# @param [Hash] mhead Message headers of a bounce email
|
24
|
+
# @param [String] mbody Message body of a bounce email
|
25
|
+
# @return [Hash] Bounce data list and message/rfc822 part
|
26
|
+
# @return [Nil] it failed to decode or the arguments are missing
|
27
|
+
# @see https://workspace.google.com/.
|
28
|
+
def inquire(mhead, mbody)
|
29
|
+
return nil if mbody.include?("\nDiagnostic-Code:")
|
30
|
+
return nil if mbody.include?("\nFinal-Recipient:")
|
31
|
+
return nil unless mhead["from"].include?('<mailer-daemon@googlemail.com>')
|
32
|
+
return nil unless mhead["subject"].include?("Delivery Status Notification")
|
33
|
+
|
34
|
+
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
35
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
36
|
+
bodyslices = emailparts[0].split("\n")
|
37
|
+
entiremesg = ""
|
38
|
+
readcursor = 0 # (Integer) Points the current cursor position
|
39
|
+
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
40
|
+
|
41
|
+
while e = bodyslices.shift do
|
42
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
43
|
+
# line of the beginning of the original message.
|
44
|
+
if readcursor == 0
|
45
|
+
# Beginning of the bounce message or message/delivery-status part
|
46
|
+
if e.start_with?(StartingOf[:message][0])
|
47
|
+
# ** Message not delivered **
|
48
|
+
readcursor |= Indicators[:deliverystatus]
|
49
|
+
entiremesg << e + " "
|
50
|
+
end
|
51
|
+
end
|
52
|
+
next if (readcursor & Indicators[:deliverystatus]) == 0
|
53
|
+
next if e.empty?
|
54
|
+
|
55
|
+
# ** Message not delivered **
|
56
|
+
# You're sending this from a different address or alias using the 'Send mail as' feature.
|
57
|
+
# The settings for your 'Send mail as' account are misconfigured or out of date. Check those settings and try resending.
|
58
|
+
# Learn more here: https://support.google.com/mail/?p=CustomFromDenied
|
59
|
+
# The response was:
|
60
|
+
# Unspecified Error (SENT_SECOND_EHLO): Smtp server does not advertise AUTH capability
|
61
|
+
next if e.start_with?("Content-Type: ")
|
62
|
+
entiremesg << e + " "
|
63
|
+
end
|
64
|
+
|
65
|
+
while recipients == 0 do
|
66
|
+
# Pick the recipient address from the value of To: header of the original message after
|
67
|
+
# Content-Type: message/rfc822 field
|
68
|
+
p0 = emailparts[1].index("\nTo:"); break unless p0
|
69
|
+
p1 = emailparts[1].index("\n", p0 + 2)
|
70
|
+
cv = Sisimai::Address.s3s4(emailparts[1][p0 + 4, p1 - p0])
|
71
|
+
dscontents[0]["recipient"] = cv
|
72
|
+
recipients += 1
|
73
|
+
end
|
74
|
+
return nil if recipients == 0
|
75
|
+
|
76
|
+
dscontents[0]["diagnosis"] = entiremesg
|
77
|
+
dscontents.each do |e|
|
78
|
+
# Tidy up the error message in e["diagnosis"], Try to detect the bounce reason.
|
79
|
+
e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"])
|
80
|
+
MessagesOf.each_key do |r|
|
81
|
+
# Guess an reason of the bounce
|
82
|
+
next unless MessagesOf[r].any? { |a| e["diagnosis"].include?(a) }
|
83
|
+
e["reason"] = r
|
84
|
+
break
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
return { "ds" => dscontents, "rfc822" => emailparts[1] }
|
89
|
+
end
|
90
|
+
def description; return "Google Workspace: https://workspace.google.com/"; end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module Sisimai::Lhost
|
2
|
-
# Sisimai::Lhost::IMailServer
|
2
|
+
# Sisimai::Lhost::IMailServer decodes a bounce email which created by Progress iMail Server
|
3
|
+
# https://community.progress.com/s/products/imailserver.
|
3
4
|
# Methods in the module are called from only Sisimai::Message.
|
4
5
|
module IMailServer
|
5
6
|
class << self
|
@@ -7,20 +8,20 @@ module Sisimai::Lhost
|
|
7
8
|
|
8
9
|
Boundaries = ['Original message follows.'].freeze
|
9
10
|
StartingOf = { error: ['Body of message generated response:'] }.freeze
|
10
|
-
|
11
|
+
MessagesOf = {
|
11
12
|
'hostunknown' => ['Unknown host'],
|
12
13
|
'userunknown' => ['Unknown user', 'Invalid final delivery userid'],
|
13
14
|
'mailboxfull' => ['User mailbox exceeds allowed size'],
|
14
15
|
'virusdetected' => ['Requested action not taken: virus detected'],
|
15
|
-
'
|
16
|
+
'spamdetected' => ['Blacklisted URL in message'],
|
16
17
|
'expired' => ['Delivery failed '],
|
17
18
|
}.freeze
|
18
19
|
|
19
|
-
#
|
20
|
+
# @abstract Decodes the bounce message from Progress iMail Server
|
20
21
|
# @param [Hash] mhead Message headers of a bounce email
|
21
22
|
# @param [String] mbody Message body of a bounce email
|
22
23
|
# @return [Hash] Bounce data list and message/rfc822 part
|
23
|
-
# @return [Nil] it failed to
|
24
|
+
# @return [Nil] it failed to decode or the arguments are missing
|
24
25
|
def inquire(mhead, mbody)
|
25
26
|
# X-Mailer: <SMTP32 v8.22>
|
26
27
|
match = 0
|
@@ -44,24 +45,15 @@ module Sisimai::Lhost
|
|
44
45
|
v = dscontents[-1]
|
45
46
|
|
46
47
|
p0 = e.index(': ') || -1
|
47
|
-
if p0 > 8 && Sisimai::String.aligned(e, [': ', '@'])
|
48
|
+
if (p0 > 8 && Sisimai::String.aligned(e, [': ', '@'])) || e.start_with?('undeliverable ')
|
48
49
|
# Unknown user: kijitora@example.com
|
49
|
-
if v['recipient']
|
50
|
-
# There are multiple recipient addresses in the message body.
|
51
|
-
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
52
|
-
v = dscontents[-1]
|
53
|
-
end
|
54
|
-
v['diagnosis'] = e
|
55
|
-
v['recipient'] = Sisimai::Address.s3s4(e[p0 + 2, e.size])
|
56
|
-
recipients += 1
|
57
|
-
|
58
|
-
elsif e.start_with?('undeliverable ')
|
59
50
|
# undeliverable to kijitora@example.com
|
60
|
-
if v[
|
51
|
+
if v["recipient"] != ""
|
61
52
|
# There are multiple recipient addresses in the message body.
|
62
53
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
63
54
|
v = dscontents[-1]
|
64
55
|
end
|
56
|
+
v['diagnosis'] = e
|
65
57
|
v['recipient'] = Sisimai::Address.s3s4(e)
|
66
58
|
recipients += 1
|
67
59
|
else
|
@@ -87,9 +79,9 @@ module Sisimai::Lhost
|
|
87
79
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
|
88
80
|
e['command'] = Sisimai::SMTP::Command.find(e['diagnosis'])
|
89
81
|
|
90
|
-
|
82
|
+
MessagesOf.each_key do |r|
|
91
83
|
# Verify each regular expression of session errors
|
92
|
-
next unless
|
84
|
+
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
93
85
|
e['reason'] = r
|
94
86
|
break
|
95
87
|
end
|