sisimai 5.4.1-java → 5.5.0-java

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.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codecovio.yml +1 -1
  3. data/.github/workflows/rake-test.yml +1 -1
  4. data/ChangeLog.md +35 -0
  5. data/Makefile +2 -4
  6. data/README-JA.md +23 -20
  7. data/README.md +23 -20
  8. data/lib/sisimai/address.rb +92 -44
  9. data/lib/sisimai/arf.rb +7 -8
  10. data/lib/sisimai/datetime.rb +2 -2
  11. data/lib/sisimai/fact/json.rb +1 -2
  12. data/lib/sisimai/fact/yaml.rb +1 -2
  13. data/lib/sisimai/fact.rb +60 -35
  14. data/lib/sisimai/lda.rb +2 -2
  15. data/lib/sisimai/lhost/activehunter.rb +4 -5
  16. data/lib/sisimai/lhost/amazonses.rb +3 -4
  17. data/lib/sisimai/lhost/apachejames.rb +2 -2
  18. data/lib/sisimai/lhost/biglobe.rb +6 -6
  19. data/lib/sisimai/lhost/courier.rb +7 -7
  20. data/lib/sisimai/lhost/domino.rb +6 -6
  21. data/lib/sisimai/lhost/dragonfly.rb +5 -5
  22. data/lib/sisimai/lhost/einsundeins.rb +4 -4
  23. data/lib/sisimai/lhost/exchange2003.rb +7 -7
  24. data/lib/sisimai/lhost/exchange2007.rb +3 -3
  25. data/lib/sisimai/lhost/exim.rb +7 -7
  26. data/lib/sisimai/lhost/ezweb.rb +3 -2
  27. data/lib/sisimai/lhost/fml.rb +9 -9
  28. data/lib/sisimai/lhost/gmail.rb +9 -9
  29. data/lib/sisimai/lhost/gmx.rb +3 -3
  30. data/lib/sisimai/lhost/googlegroups.rb +6 -7
  31. data/lib/sisimai/lhost/googleworkspace.rb +5 -6
  32. data/lib/sisimai/lhost/imailserver.rb +4 -4
  33. data/lib/sisimai/lhost/kddi.rb +4 -4
  34. data/lib/sisimai/lhost/mailfoundry.rb +3 -3
  35. data/lib/sisimai/lhost/{mailmarshalsmtp.rb → mailmarshal.rb} +5 -5
  36. data/lib/sisimai/lhost/messagingserver.rb +8 -8
  37. data/lib/sisimai/lhost/mfilter.rb +8 -4
  38. data/lib/sisimai/lhost/mimecast.rb +105 -0
  39. data/lib/sisimai/lhost/notes.rb +5 -5
  40. data/lib/sisimai/lhost/opensmtpd.rb +5 -5
  41. data/lib/sisimai/lhost/postfix.rb +38 -32
  42. data/lib/sisimai/lhost/qmail.rb +6 -6
  43. data/lib/sisimai/lhost/sendmail.rb +13 -13
  44. data/lib/sisimai/lhost/{interscanmss.rb → trendmicro.rb} +8 -9
  45. data/lib/sisimai/lhost/v5sendmail.rb +7 -7
  46. data/lib/sisimai/lhost/verizon.rb +3 -3
  47. data/lib/sisimai/lhost/x1.rb +7 -4
  48. data/lib/sisimai/lhost/x2.rb +40 -12
  49. data/lib/sisimai/lhost/x3.rb +3 -3
  50. data/lib/sisimai/lhost/x6.rb +2 -2
  51. data/lib/sisimai/lhost/zoho.rb +5 -5
  52. data/lib/sisimai/lhost.rb +18 -17
  53. data/lib/sisimai/mail/maildir.rb +4 -4
  54. data/lib/sisimai/mail/mbox.rb +4 -4
  55. data/lib/sisimai/mail/memory.rb +1 -1
  56. data/lib/sisimai/mail/stdin.rb +2 -2
  57. data/lib/sisimai/message.rb +34 -34
  58. data/lib/sisimai/order.rb +5 -4
  59. data/lib/sisimai/reason/authfailure.rb +1 -1
  60. data/lib/sisimai/reason/badreputation.rb +1 -1
  61. data/lib/sisimai/reason/blocked.rb +2 -1
  62. data/lib/sisimai/reason/contenterror.rb +1 -2
  63. data/lib/sisimai/reason/exceedlimit.rb +1 -1
  64. data/lib/sisimai/reason/expired.rb +1 -1
  65. data/lib/sisimai/reason/failedstarttls.rb +1 -1
  66. data/lib/sisimai/reason/filtered.rb +1 -1
  67. data/lib/sisimai/reason/hasmoved.rb +1 -1
  68. data/lib/sisimai/reason/hostunknown.rb +2 -2
  69. data/lib/sisimai/reason/mailboxfull.rb +1 -1
  70. data/lib/sisimai/reason/mailererror.rb +1 -1
  71. data/lib/sisimai/reason/mesgtoobig.rb +1 -1
  72. data/lib/sisimai/reason/networkerror.rb +1 -1
  73. data/lib/sisimai/reason/norelaying.rb +2 -2
  74. data/lib/sisimai/reason/notaccept.rb +2 -3
  75. data/lib/sisimai/reason/notcompliantrfc.rb +1 -1
  76. data/lib/sisimai/reason/policyviolation.rb +2 -4
  77. data/lib/sisimai/reason/rejected.rb +5 -3
  78. data/lib/sisimai/reason/requireptr.rb +1 -1
  79. data/lib/sisimai/reason/securityerror.rb +1 -1
  80. data/lib/sisimai/reason/spamdetected.rb +1 -1
  81. data/lib/sisimai/reason/speeding.rb +1 -1
  82. data/lib/sisimai/reason/suspend.rb +2 -1
  83. data/lib/sisimai/reason/systemerror.rb +1 -1
  84. data/lib/sisimai/reason/systemfull.rb +1 -1
  85. data/lib/sisimai/reason/toomanyconn.rb +1 -1
  86. data/lib/sisimai/reason/userunknown.rb +4 -3
  87. data/lib/sisimai/reason/vacation.rb +1 -1
  88. data/lib/sisimai/reason/virusdetected.rb +1 -1
  89. data/lib/sisimai/reason.rb +12 -12
  90. data/lib/sisimai/rfc1123.rb +58 -18
  91. data/lib/sisimai/rfc1894.rb +6 -8
  92. data/lib/sisimai/rfc2045.rb +25 -13
  93. data/lib/sisimai/rfc3464/thirdparty.rb +2 -3
  94. data/lib/sisimai/rfc3464.rb +6 -6
  95. data/lib/sisimai/rfc3834.rb +18 -8
  96. data/lib/sisimai/rfc5322.rb +9 -9
  97. data/lib/sisimai/rfc791.rb +2 -2
  98. data/lib/sisimai/rhost/aol.rb +4 -1
  99. data/lib/sisimai/rhost/apple.rb +11 -7
  100. data/lib/sisimai/rhost/cox.rb +9 -5
  101. data/lib/sisimai/rhost/facebook.rb +9 -3
  102. data/lib/sisimai/rhost/franceptt.rb +86 -37
  103. data/lib/sisimai/rhost/godaddy.rb +10 -1
  104. data/lib/sisimai/rhost/google.rb +6 -6
  105. data/lib/sisimai/rhost/gsuite.rb +1 -1
  106. data/lib/sisimai/rhost/kddi.rb +1 -1
  107. data/lib/sisimai/rhost/messagelabs.rb +160 -2
  108. data/lib/sisimai/rhost/microsoft.rb +77 -26
  109. data/lib/sisimai/rhost/mimecast.rb +30 -21
  110. data/lib/sisimai/rhost/nttdocomo.rb +69 -89
  111. data/lib/sisimai/rhost/outlook.rb +1 -1
  112. data/lib/sisimai/rhost/spectrum.rb +1 -1
  113. data/lib/sisimai/rhost/tencent.rb +5 -4
  114. data/lib/sisimai/rhost/yahooinc.rb +2 -2
  115. data/lib/sisimai/rhost/zoho.rb +72 -0
  116. data/lib/sisimai/rhost.rb +4 -3
  117. data/lib/sisimai/smtp/command.rb +2 -2
  118. data/lib/sisimai/smtp/reply.rb +11 -4
  119. data/lib/sisimai/smtp/status.rb +17 -8
  120. data/lib/sisimai/smtp/transcript.rb +3 -3
  121. data/lib/sisimai/string.rb +6 -10
  122. data/lib/sisimai/version.rb +1 -1
  123. data/lib/sisimai.rb +1 -1
  124. data/set-of-emails/maildir/bsd/lhost-exim-56.eml +40 -40
  125. data/set-of-emails/maildir/bsd/lhost-mfilter-05.eml +41 -0
  126. data/set-of-emails/maildir/bsd/lhost-mimecast-01.eml +46 -0
  127. data/set-of-emails/maildir/bsd/lhost-mimecast-02.eml +59 -0
  128. data/set-of-emails/maildir/bsd/lhost-postfix-79.eml +81 -0
  129. data/set-of-emails/maildir/bsd/lhost-postfix-80.eml +84 -0
  130. data/set-of-emails/maildir/bsd/lhost-x1-03.eml +26 -0
  131. data/set-of-emails/maildir/bsd/lhost-x1-04.eml +45 -0
  132. data/set-of-emails/maildir/bsd/lhost-x2-07.eml +30 -0
  133. data/set-of-emails/maildir/bsd/rfc3464-66.eml +170 -0
  134. data/set-of-emails/maildir/bsd/rfc3834-06.eml +59 -0
  135. data/set-of-emails/maildir/bsd/rhost-zoho-01.eml +88 -0
  136. data/set-of-emails/maildir/bsd/rhost-zoho-02.eml +86 -0
  137. data/set-of-emails/maildir/bsd/rhost-zoho-03.eml +87 -0
  138. data/set-of-emails/maildir/bsd/rhost-zoho-04.eml +86 -0
  139. data/set-of-emails/maildir/not/rb-issue-368-bug.eml +39 -0
  140. data/sisimai-java.gemspec +1 -1
  141. data/sisimai.gemspec +1 -1
  142. metadata +26 -9
  143. /data/set-of-emails/maildir/bsd/{lhost-mailmarshalsmtp-02.eml → lhost-mailmarshal-02.eml} +0 -0
  144. /data/set-of-emails/maildir/bsd/{lhost-interscanmss-01.eml → lhost-trendmicro-01.eml} +0 -0
  145. /data/set-of-emails/maildir/bsd/{lhost-interscanmss-02.eml → lhost-trendmicro-02.eml} +0 -0
  146. /data/set-of-emails/maildir/bsd/{lhost-interscanmss-03.eml → lhost-trendmicro-03.eml} +0 -0
@@ -28,6 +28,9 @@ module Sisimai
28
28
  )
29
29
  [ ]*(.+)\z
30
30
  }x.freeze
31
+ Suspending = [
32
+ ["this email inbox", " is no longer in use."],
33
+ ].freeze
31
34
 
32
35
  # Detect auto reply message as RFC3834
33
36
  # @param [Hash] mhead Message headers of a bounce email
@@ -41,15 +44,14 @@ module Sisimai
41
44
 
42
45
  LowerLabel.each do |e|
43
46
  # Set lower-cased value of each header related to auto-response
44
- next unless mhead.has_key?(e)
47
+ next if mhead.has_key?(e) == false
45
48
  lower[e] = mhead[e].downcase
46
49
  end
47
50
 
48
51
  # DETECT_EXCLUSION_MESSAGE
49
52
  DoNotParse.each_key do |e|
50
53
  # Exclude message from root@
51
- next unless lower[e]
52
- next unless DoNotParse[e].any? { |a| lower[e].include?(a) }
54
+ next if lower[e].nil? || DoNotParse[e].none? { |a| lower[e].include?(a) }
53
55
  leave = 1
54
56
  break
55
57
  end
@@ -58,8 +60,7 @@ module Sisimai
58
60
  # DETECT_AUTO_REPLY_MESSAGE0
59
61
  AutoReply0.each_key do |e|
60
62
  # RFC3834 Auto-Submitted and other headers
61
- next unless lower[e]
62
- next unless AutoReply0[e].any? { |a| lower[e].include?(a) }
63
+ next if lower[e].nil? || AutoReply0[e].none? { |a| lower[e].include?(a) }
63
64
  match += 1
64
65
  break
65
66
  end
@@ -78,7 +79,7 @@ module Sisimai
78
79
  # RECIPIENT_ADDRESS
79
80
  %w[from return-path].each do |e|
80
81
  # Try to get the address of the recipient
81
- next unless mhead[e]
82
+ next if mhead[e].nil?
82
83
  v['recipient'] = mhead[e]
83
84
  break
84
85
  end
@@ -88,12 +89,12 @@ module Sisimai
88
89
  v['recipient'] = Sisimai::Address.s3s4(v['recipient'])
89
90
  recipients += 1
90
91
  end
91
- return nil unless recipients > 0
92
+ return nil if recipients == 0
92
93
 
93
94
  if mhead['content-type']
94
95
  # Get the boundary string and set regular expression for matching with the boundary string.
95
96
  q = Sisimai::RFC2045.boundary(mhead['content-type'], 0) || ''
96
- MarkingsOf[:boundary] = q unless q.empty?
97
+ MarkingsOf[:boundary] = q if q.empty? == false
97
98
  end
98
99
 
99
100
  # MESSAGE_BODY: Get the vacation message
@@ -117,6 +118,15 @@ module Sisimai
117
118
  v['diagnosis'] ||= mhead['subject']
118
119
  v['diagnosis'] = Sisimai::String.sweep(v['diagnosis'])
119
120
  v['reason'] = 'vacation'
121
+
122
+ cv = v['diagnosis'].downcase
123
+ Suspending.each do |e|
124
+ # Check that the auto-replied message indicates the "Suspend" reason or not.
125
+ next unless Sisimai::String.aligned(cv, e)
126
+ v['reason'] = 'suspend'
127
+ break
128
+ end
129
+
120
130
  v['date'] = mhead['date']
121
131
  v['status'] = ''
122
132
 
@@ -36,7 +36,7 @@ module Sisimai
36
36
  # @param [String] argv1 Received header
37
37
  # @return [Array] Received header as a structured data
38
38
  def received(argv1)
39
- return [] unless argv1.is_a?(::String)
39
+ return [] if argv1.is_a?(::String) == false
40
40
  return [] if argv1.include?(' invoked by uid') || argv1.include?(' invoked from network')
41
41
 
42
42
  # - https://datatracker.ietf.org/doc/html/rfc5322
@@ -63,14 +63,14 @@ module Sisimai
63
63
  recvd.each do |e|
64
64
  # Look up each label defined in "label" from Received header
65
65
  index += 1
66
- break unless index < range; f = e.downcase
67
- next unless label.any? { |a| f == a }
66
+ break if index >= range; f = e.downcase
67
+ next if label.none? { |a| f == a }
68
68
  token[f] = recvd[index + 1] || next
69
69
  token[f] = token[f].downcase.delete('();')
70
70
 
71
- next unless f == 'from'
72
- break unless index + 2 < range
73
- next unless recvd[index + 2].start_with?('(')
71
+ next if f != 'from'
72
+ break if index + 2 >= range
73
+ next if recvd[index + 2].start_with?('(') == false
74
74
 
75
75
  # Get and keep a hostname in the comment as follows:
76
76
  # from mx1.example.com (c213502.kyoto.example.ne.jp [192.0.2.135]) by mx.example.jp (V8/cf)
@@ -90,7 +90,7 @@ module Sisimai
90
90
 
91
91
  # The 2nd element after the current element is a continuation of the current element.
92
92
  # such as "(c213502.kyoto.example.ne.jp", "[192.0.2.135])"
93
- break unless index + 3 < range
93
+ break if index + 3 >= range
94
94
  other << recvd[index + 3].delete('();')
95
95
  end
96
96
 
@@ -173,7 +173,7 @@ module Sisimai
173
173
 
174
174
  cutby.each do |e|
175
175
  # Find a boundary string(2nd argument) from the 1st argument
176
- positionor = email.index(e); next unless positionor
176
+ positionor = email.index(e); next if positionor.nil?
177
177
  boundaryor = e
178
178
  break
179
179
  end
@@ -200,7 +200,7 @@ module Sisimai
200
200
  # Remove text after the first blank line: \n\n when "keeps" is false
201
201
  latterpart = latterpart[0, latterpart.index("\n\n")] if latterpart.include?("\n\n")
202
202
  end
203
- latterpart << "\n" unless latterpart.end_with?("\n")
203
+ latterpart << "\n" if latterpart.end_with?("\n") == false
204
204
  end
205
205
 
206
206
  return [formerpart, latterpart]
@@ -31,13 +31,13 @@ module Sisimai
31
31
  ipv4a = []
32
32
  %w|( ) [ ] ,|.each do |e|
33
33
  # Rewrite: "mx.example.jp[192.0.2.1]" => "mx.example.jp 192.0.2.1"
34
- p0 = given.index(e); next unless p0
34
+ p0 = given.index(e); next if p0.nil?
35
35
  given[p0, 1] = ' '
36
36
  end
37
37
 
38
38
  given.split(' ').each do |e|
39
39
  # Find string including an IPv4 address
40
- next unless e.index('.') # IPv4 address must include "." character
40
+ next if e.index('.').nil? # IPv4 address must include "." character
41
41
 
42
42
  lx = e.size; next if lx < 7 || lx > 17 # 0.0.0.0 = 7, [255.255.255.255] = 17
43
43
  cu = 0 # Cursor for seeking each octet of an IPv4 address
@@ -14,6 +14,9 @@ module Sisimai
14
14
  # @param [Sisimai::Fact] argvs Decoded email object
15
15
  # @return [String] The bounce reason for Aol
16
16
  # @since v5.2.0
17
+ # @see
18
+ # - Y!Sender Hub/SMTP Error Codes: https://senders.yahooinc.com/smtp-error-codes/
19
+ # - The MX record of Aol points "mx-aol.mail.gm0.yahoodns.net".
17
20
  def find(argvs)
18
21
  return "" if argvs["diagnosticcode"].empty?
19
22
  issuedcode = argvs["diagnosticcode"]
@@ -21,7 +24,7 @@ module Sisimai
21
24
 
22
25
  MessagesOf.each_key do |e|
23
26
  # Try to match the error message with message patterns defined in $MessagesOf
24
- next unless MessagesOf[e].any? { |a| issuedcode.include?(a) }
27
+ next if MessagesOf[e].none? { |a| issuedcode.include?(a) }
25
28
  reasontext = e
26
29
  break
27
30
  end
@@ -53,10 +53,14 @@ module Sisimai
53
53
  # Try again later - https://support.apple.com/en-us/HT204137
54
54
  'due to excessive volume',
55
55
  ],
56
+ 'suspend' => [
57
+ # - https://support.apple.com/guide/icloud/stop-using-or-reactivate-addresses-mm3adb030cbf/icloud
58
+ # - 550 5.1.1 <****@icloud.com>: inactive email address (in reply to RCPT TO command)
59
+ "inactive email address",
60
+ ],
56
61
  'userunknown' => [
57
62
  # - 550 5.1.1 <****@icloud.com>: inactive email address (in reply to RCPT TO command)
58
63
  # - 550 5.1.1 unknown or illegal alias: ****@icloud.com
59
- 'inactive email address',
60
64
  'user does not exist',
61
65
  'unknown or illegal alias',
62
66
  ],
@@ -65,20 +69,20 @@ module Sisimai
65
69
  # Detect bounce reason from Apple iCloud Mail
66
70
  # @param [Sisimai::Fact] argvs Decoded email object
67
71
  # @return [String] The bounce reason for Apple
68
- # @see https://support.apple.com/en-us/102322
69
- # https://www.postmastery.com/icloud-postmastery-page/
70
- # https://smtpfieldmanual.com/provider/apple
72
+ # @see
73
+ # - Postmaster information for iCloud Mail: https://support.apple.com/en-us/102322
74
+ # - https://www.postmastery.com/icloud-postmastery-page/
75
+ # - https://smtpfieldmanual.com/provider/apple
71
76
  # @since v5.1.0
72
77
  def find(argvs)
73
- return '' unless argvs
74
- return '' unless argvs['diagnosticcode'].size > 0
78
+ return '' if argvs.nil? || argvs['diagnosticcode'].size == 0
75
79
 
76
80
  issuedcode = argvs['diagnosticcode'].downcase
77
81
  reasontext = ''
78
82
 
79
83
  MessagesOf.each_key do |e|
80
84
  MessagesOf[e].each do |f|
81
- next unless issuedcode.include?(f)
85
+ next if issuedcode.include?(f) == false
82
86
  reasontext = e
83
87
  break
84
88
  end
@@ -61,7 +61,7 @@ module Sisimai
61
61
  'IPBL0101' => 'blocked', # The sending IP is in the Spamhaus Zen and Invaluement ivmSIP DNSBLs.
62
62
  'IPBL0110' => 'blocked', # The sending IP is in the Return Path and Invaluement ivmSIP DNSBLs.
63
63
  'IPBL0111' => 'blocked', # The sending IP is in the Spamhaus Zen, Return Path and Invaluement ivmSIP DNSBLs.
64
- 'IPBL1000' => 'blocked', # The sending IP address is listed on a CSI blacklist. You can check your status on the CSI website.
64
+ 'IPBL1000' => 'blocked', # The sending IP address is listed on a CSI blacklist.
65
65
  'IPBL1001' => 'blocked', # The sending IP is listed in the Cloudmark CSI and Spamhaus Zen DNSBLs.
66
66
  'IPBL1010' => 'blocked', # The sending IP is listed in the Cloudmark CSI and Return Path DNSBLs.
67
67
  'IPBL1011' => 'blocked', # The sending IP is in the Cloudmark CSI, Spamhaus Zen and Return Path DNSBLs.
@@ -69,12 +69,12 @@ module Sisimai
69
69
  'IPBL1101' => 'blocked', # The sending IP is in the Cloudmark CSI, Spamhaus Zen and Invaluement IVMsip DNSBLs.
70
70
  'IPBL1110' => 'blocked', # The sending IP is in the Cloudmark CSI, Return Path and Invaluement ivmSIP DNSBLs.
71
71
  'IPBL1111' => 'blocked', # The sending IP is in the Cloudmark CSI, Spamhaus Zen, Return Path and Invaluement ivmSIP DNSBLs.
72
- 'IPBL00001' => 'blocked', # The sending IP address is listed on a Spamhaus blacklist. Check your status at Spamhaus.
72
+ 'IPBL00001' => 'blocked', # The sending IP address is listed on a Spamhaus blacklist.
73
73
 
74
74
  'URLBL011' => 'spamdetected', # A URL within the body of the message was found on blocklists SURBL and Spamhaus DBL.
75
75
  'URLBL101' => 'spamdetected', # A URL within the body of the message was found on blocklists SURBL and ivmURI.
76
76
  'URLBL110' => 'spamdetected', # A URL within the body of the message was found on blocklists Spamhaus DBL and ivmURI.
77
- 'URLBL1001' => 'spamdetected', # The URL is listed on a Spamhaus blacklist. Check your status at Spamhaus.
77
+ 'URLBL1001' => 'spamdetected', # The URL is listed on a Spamhaus blacklist.
78
78
  }.freeze
79
79
  MessagesOf = {
80
80
  'blocked' => [
@@ -82,6 +82,8 @@ module Sisimai
82
82
  # a three-hour block of the client's IP address.
83
83
  # - The sending IP address has exceeded the threshold of invalid recipients and has
84
84
  # been blocked.
85
+ # - Cox enforces various rate limits to protect our platform. The sending IP address
86
+ # has exceeded one of these rate limits and has been temporarily blocked.
85
87
  'cox too many bad commands from',
86
88
  'too many invalid recipients',
87
89
  ],
@@ -127,7 +129,9 @@ module Sisimai
127
129
  # Detect bounce reason from https://cox.com/
128
130
  # @param [Sisimai::Fact] argvs Decoded email object
129
131
  # @return [String, Nil] The bounce reason at Cox
130
- # @see https://www.cox.com/residential/support/email-error-codes.html
132
+ # @see
133
+ # - Email Error Codes: https://www.cox.com/business/support/email-error-codes.html
134
+ # - Feedback Loop Service https://www.cox.com/business/support/feedback-loop-service.html
131
135
  # @since v4.25.8
132
136
  def find(argvs)
133
137
  return "" if argvs["diagnosticcode"].empty?
@@ -145,7 +149,7 @@ module Sisimai
145
149
  # The error code was not found in ErrorCodes
146
150
  MessagesOf.each_key do |e|
147
151
  # Try to find with each error message defined in MessagesOf
148
- next unless MessagesOf[e].any? { |a| issuedcode.include?(a) }
152
+ next if MessagesOf[e].none? { |a| issuedcode.include?(a) }
149
153
  reasontext = e
150
154
  break
151
155
  end
@@ -27,6 +27,9 @@ module Sisimai
27
27
  "RCP-P2", # The attempted recipient's preferences prevent messages from being delivered.
28
28
  "RCP-P3", # The attempted recipient's privacy settings blocked the delivery.
29
29
  ],
30
+ "mailboxfull" => [
31
+ "INT-P7", # The attempted recipient has exceeded their storage quota.
32
+ ],
30
33
  "mesgtoobig" => [
31
34
  "MSG-P1", # The message exceeds Facebook's maximum allowed size.
32
35
  "INT-P2", # The message exceeds Facebook's maximum allowed size.
@@ -34,6 +37,9 @@ module Sisimai
34
37
  "notcompliantrfc" => [
35
38
  "MSG-P3", # The message contains multiple instances of a header field that can only be present once.
36
39
  ],
40
+ "policyviolation" => [
41
+ "POL-P8", # The message does not comply with Facebook's abuse policies and will not be accepted.
42
+ ],
37
43
  "rejected" => [
38
44
  "DNS-P1", # Your SMTP MAIL FROM domain does not exist.
39
45
  "DNS-P2", # Your SMTP MAIL FROM domain does not have an MX record.
@@ -45,13 +51,13 @@ module Sisimai
45
51
  ],
46
52
  "spamdetected" => [
47
53
  "POL-P6", # The message contains a url that has been blocked by Facebook.
48
- "POL-P7", # The message does not comply with Facebook's abuse policies and will not be accepted.
49
54
  ],
50
55
  "suspend" => [
51
56
  "RCP-T4", # The attempted recipient address is currently deactivated. The user may or may not reactivate it.
52
57
  ],
53
58
  "systemerror" => [
54
- "RCP-T1", # The attempted recipient address is not currently available due to an internal system issue. This is a temporary condition.
59
+ "RCP-T1", # The attempted recipient address is not currently available due to an internal system issue.
60
+ "INT-Tx", # These codes indicate a temporary issue internal to Facebook's system.
55
61
  ],
56
62
  "toomanyconn" => [
57
63
  "CON-T1", # Facebook's mail server currently has too many connections open to allow another one.
@@ -85,7 +91,7 @@ module Sisimai
85
91
 
86
92
  ErrorCodes.each_key do |e|
87
93
  # The key is a bounce reason name
88
- next unless ErrorCodes[e].any? { |a| errorlabel == a }
94
+ next if ErrorCodes[e].none? { |a| errorlabel == a }
89
95
  reasontext = e
90
96
  break
91
97
  end
@@ -6,6 +6,12 @@ module Sisimai
6
6
  module FrancePTT
7
7
  class << self
8
8
  ErrorCodes = {
9
+ # - Your sending IP is listed on Abusix RBL
10
+ # Please visit: https://lookup.abusix.com/search?q=$IP
11
+ "100" => 'blocked',
12
+
13
+ # - Your sending IP is listed by SpamHaus RBL
14
+ # Please visit: https://check.spamhaus.org/listed/?searchterm=$IP
9
15
  # - 550 5.7.1 Service unavailable; client [192.0.2.1] blocked using Spamhaus
10
16
  # Les emails envoyes vers la messagerie Laposte.net ont ete bloques par nos services.
11
17
  # Afin de regulariser votre situation, nous vous invitons a cliquer sur le lien ci-dessous
@@ -15,6 +21,8 @@ module Sisimai
15
21
  # https://www.spamhaus.org/lookup/ LPNAAA_101 (in reply to RCPT TO command))
16
22
  '101' => 'blocked',
17
23
 
24
+ # - Your sending IP is listed by Cloudmark RBL
25
+ # Please visit: https://csi.cloudmark.com/reset-request/?ip=$IP#
18
26
  # - 550 mwinf5c04 ME Adresse IP source bloquee pour incident de spam.
19
27
  # - Client host blocked for spamming issues. OFR006_102 Ref http://csi.cloudmark.com ...
20
28
  # - 550 5.5.0 Les emails envoyes vers la messagerie Laposte.net ont ete bloques par nos
@@ -25,6 +33,9 @@ module Sisimai
25
33
  # https://senderscore.org/blacklistlookup/ LPN007_102
26
34
  '102' => 'blocked',
27
35
 
36
+ # - Your sending IP has been blacklisted by Orange
37
+ # Please contact Orange by using our contact form and select option
38
+ # "Un problème d'envoi d'emails vers les adresses Orange ou Wanadoo (deliverability issue)"
28
39
  # - 550 mwinf5c10 ME Service refuse. Veuillez essayer plus tard.
29
40
  # - Service refused, please try later. OFR006_103 192.0.2.1 [103]
30
41
  '103' => 'blocked',
@@ -34,31 +45,45 @@ module Sisimai
34
45
  # - Too many connections, slow down. LPN105_104
35
46
  '104' => 'toomanyconn',
36
47
 
37
- '105' => nil, # Veuillez essayer plus tard.
38
- '107' => nil, # Service refused, please try later. LPN006_107
39
- '108' => nil, # service refused, please try later. LPN001_108
40
- '109' => nil, # Veuillez essayer plus tard. LPN003_109
41
- '201' => nil, # Veuillez essayer plus tard. OFR004_201
42
-
43
- # - 550 5.7.0 Code d'authentification invalide OFR_305
44
- '305' => 'securityerror',
45
-
46
- # - 550 5.5.0 SPF: *** is not allowed to send mail. LPN004_401
47
- '401' => 'authfailure',
48
-
49
- # - 550 5.5.0 Authentification requise. Authentication Required. LPN105_402
50
- '402' => 'securityerror',
51
-
52
- # - 5.0.1 Emetteur invalide. Invalid Sender.
53
- '403' => 'rejected',
54
-
48
+ # - Your IP address is missing a DNS PTR record, it also called a rDNS (reverse DNS)
49
+ # Please set up a valid DNS PTR record for your IP address that point to your domain,
50
+ # It's important that the sending IP address must match the IP address of the hostname
51
+ # defined in the PTR record
52
+ # - Service refused, please try later. LPN006_107
53
+ "107" => 'requireptr',
54
+
55
+ # - You are sending too many messages per SMTP connection
56
+ # Please reduce the number of messages per connection, recommended value is 100
57
+ # messages per connections
58
+ # - Veuillez essayer plus tard. LPN003_109
59
+ "109" => 'toomanyconn',
60
+
61
+ # - Invalid HELO/EHLO
62
+ # Please set up a valid HELO/EHLO, it must be fully qualified domain name (FQDN) and
63
+ # should resolve (DNS record needed). E.g.: "mail.yourdomain.com"
64
+ # - Veuillez essayer plus tard. OFR004_201
65
+ "201" => 'blocked',
66
+ "20X" => 'blocked',
67
+
68
+ # - Sender's Domain name SPF Error
69
+ # Please verify your mail from domain name DNS/TXT configuration for your SPF
70
+ # configuration. Please visit https://mxtoolbox.com/supertool3?action=spf:$YOUR_DOMAIN
71
+ # to check your domain. (replace $YOUR_DOMAIN by your sender domain name)
72
+ # Please note:
73
+ # If you have changed your DNS record recently, please let DNS caches expire (TTL)
74
+ "39X" => 'authfailure',
75
+
76
+ # - Sender's Domain DNS Error
77
+ # Please verify your mail from domain name DNS configuration. Your domain name must
78
+ # have valid A or MX records. You can check your DNS configuration on MxToolBox
79
+ # Please note:
80
+ # If you have changed your DNS record recently, please let DNS caches expire (TTL)
55
81
  # - 5.0.1 Emetteur invalide. Invalid Sender. LPN105_405
56
82
  # - 501 5.1.0 Emetteur invalide. Invalid Sender. OFR004_405 [405] (in reply to MAIL FROM command))
57
83
  '405' => 'rejected',
58
84
 
59
- # Emetteur invalide. Invalid Sender. OFR_415
60
- '415' => 'rejected',
61
-
85
+ # - User doesn't exist here
86
+ # Please remove this email address from your distribution list, it does not exist
62
87
  # - 550 5.1.1 Adresse d au moins un destinataire invalide.
63
88
  # - Invalid recipient. LPN416 (in reply to RCPT TO command)
64
89
  # - Invalid recipient. OFR_416 [416] (in reply to RCPT TO command)
@@ -68,17 +93,15 @@ module Sisimai
68
93
  # - Recipient overquota. OFR_417 [417] (in reply to RCPT TO command))
69
94
  '417' => 'mailboxfull',
70
95
 
71
- # - Adresse d au moins un destinataire invalide
72
-
73
96
  # - 550 5.5.0 Boite du destinataire archivee.
74
97
  # - Archived recipient. LPN007_420 (in reply to RCPT TO command)
75
98
  '420' => 'suspend',
76
99
 
77
- # - 5.5.3 Mail from not owned by user. LPN105_421.
78
- '421' => 'rejected',
79
-
80
- '423' => nil, # Service refused, please try later. LPN105_423
81
- '424' => nil, # Veuillez essayer plus tard. LPN105_424
100
+ # - Your sender domain name has been blacklisted
101
+ # Your sender domain name has been blacklisted by Abusix OR SpamHaus, Please visit:
102
+ # - https://lookup.abusix.com/search?q=$YOUR_DOMAIN
103
+ # - https://check.spamhaus.org/listed/?searchterm=$YOUR_DOMAIN
104
+ "425" => 'rejected',
82
105
 
83
106
  # - 550 5.5.0 Le compte du destinataire est bloque. The recipient account isblocked.
84
107
  # LPN007_426 (in reply to RCPT TO command)
@@ -90,6 +113,9 @@ module Sisimai
90
113
  # LPN007_505 (in reply to end of DATA command)
91
114
  '505' => 'systemerror',
92
115
 
116
+ # - Your message has been blocked by Orange, suspected spam
117
+ # Please contact Orange by using our contact form and select option
118
+ # "Un problème d'envoi d'emails vers les adresses Orange ou Wanadoo (deliverability issue)"
93
119
  # - Mail rejete. Mail rejected. OFR_506 [506]
94
120
  '506' => 'spamdetected',
95
121
 
@@ -97,21 +123,43 @@ module Sisimai
97
123
  # LPN005_510 (in reply to end of DATA command)
98
124
  '510' => 'blocked',
99
125
 
100
- '513' => nil, # Mail rejete. Mail rejected. OUK_513
101
-
102
- # - Taille limite du message atteinte
103
- '514' => 'mesgtoobig',
126
+ # - DMARC authentication failed, message rejected as defined by your DMARC policy
127
+ # Please check your SPF/DKIM/DMARC configuration. Please visit MxToolBox DMARC to
128
+ # check your domain configuration
129
+ "515" => 'authfailure',
104
130
 
105
131
  # - 571 5.7.1 Message refused, DMARC verification Failed.
106
132
  # - Message refuse, verification DMARC en echec LPN007_517
107
133
  '517' => 'authfailure',
108
134
 
109
- # - 554 5.7.1 Client host rejected LPN000_630
110
- '630' => 'policyviolation',
135
+ # - The sending IP address is not authorized to send messages for your domain as defined
136
+ # in the sender's Domain name SPF configuration (DNS/TXT)
137
+ # Please verify your mail from domain name DNS/TXT configuration for your SPF configuration.
138
+ # Please visit https://mxtoolbox.com/supertool3?action=spf:$YOUR_DOMAIN to check your
139
+ # domain. (replace $YOUR_DOMAIN by your sender domain name)
140
+ "519" => 'authfailure',
111
141
 
142
+ # - Due to bad behavior you have been rate limited, please try again later
143
+ # Due to inappropriate behavior, you have been rate limited. Please check what you
144
+ # are trying to send
112
145
  # - 421 mwinf5c77 ME Service refuse. Veuillez essayer plus tard. Service refused, please try
113
146
  # later. OFR_999 [999]
114
- '999' => 'blocked',
147
+ "99X" => 'toomanyconn',
148
+
149
+ # Other undocumented or old error codes
150
+ "105" => "", # Veuillez essayer plus tard.
151
+ "108" => "", # service refused, please try later. LPN001_108
152
+ "305" => "securityerror", # 550 5.7.0 Code d'authentification invalide OFR_305
153
+ "401" => "authfailure", # 550 5.5.0 SPF: *** is not allowed to send mail. LPN004_401
154
+ "402" => "securityerror", # 550 5.5.0 Authentification requise. Authentication Required. LPN105_402
155
+ "403" => "rejected", # 5.0.1 Emetteur invalide. Invalid Sender.
156
+ "415" => "rejected", # Emetteur invalide. Invalid Sender. OFR_415
157
+ "421" => "rejected", # 5.5.3 Mail from not owned by user. LPN105_421.
158
+ "423" => "", # Service refused, please try later. LPN105_423
159
+ "424" => "", # Veuillez essayer plus tard. LPN105_424
160
+ "513" => "", # Mail rejete. Mail rejected. OUK_513
161
+ "514" => "messagetoobig", # Taille limite du message atteinte
162
+ "630" => "policyviolation", # 554 5.7.1 Client host rejected LPN000_630
115
163
  }.freeze
116
164
  MessagesOf = {
117
165
  'authfailure' => [
@@ -135,14 +183,15 @@ module Sisimai
135
183
  if cv = issuedcode.match(/\b(LPN|LPNAAA|OFR|OUK)(_[0-9]{3}|[0-9]{3}[-_][0-9]{3})\b/i)
136
184
  # OUK_513, LPN105-104, OFR102-104, ofr_506
137
185
  v = sprintf("%03d", (cv[1] + cv[2])[-3, 3])
138
- reasontext = ErrorCodes[v] || 'undefined'
186
+ x = v.clone; x[-1] = "X"
187
+ reasontext = ErrorCodes[v] || ErrorCodes[x] || ''
139
188
  end
140
189
  return reasontext if reasontext.size > 0
141
190
 
142
191
  issuedcode = issuedcode.downcase
143
192
  MessagesOf.each_key do |e|
144
193
  MessagesOf[e].each do |f|
145
- next unless issuedcode.include?(f)
194
+ next if issuedcode.include?(f) == false
146
195
  reasontext = e
147
196
  break
148
197
  end
@@ -188,6 +188,15 @@ module Sisimai
188
188
  # other. They need to correct their forwarding settings.
189
189
  'message is looping',
190
190
  ],
191
+ 'toomanyconn' => [
192
+ # - 550 5.7.232 Your message can't be sent because your trial tenant has exceeded
193
+ # its daily limit for sending email to external recipients (tenant external
194
+ # recipient rate limit)
195
+ # - 550 5.7.233 - Your message can't be sent because your tenant exceeded its daily
196
+ # limit for sending email to external recipients (tenant external recipient rate
197
+ # limit)
198
+ "exceeded its daily limit",
199
+ ],
191
200
  'userunknown' => [
192
201
  # - 550 Recipient not found
193
202
  # - The recipient is not a valid email address.
@@ -218,7 +227,7 @@ module Sisimai
218
227
  issuedcode = issuedcode.downcase
219
228
  MessagesOf.each_key do |e|
220
229
  MessagesOf[e].each do |f|
221
- next unless issuedcode.include?(f)
230
+ next if issuedcode.include?(f) == false
222
231
  reasontext = e
223
232
  break
224
233
  end
@@ -527,8 +527,8 @@ module Sisimai
527
527
  # @see https://support.google.com/a/answer/3726730?hl=en
528
528
  def find(argvs)
529
529
  return "" if argvs["diagnosticcode"].empty?
530
- return '' unless Sisimai::SMTP::Reply.test(argvs['replycode'])
531
- return '' unless Sisimai::SMTP::Status.test(argvs['deliverystatus'])
530
+ return '' if Sisimai::SMTP::Reply.test(argvs['replycode']) == false
531
+ return '' if Sisimai::SMTP::Status.test(argvs['deliverystatus']) == false
532
532
 
533
533
  statuscode = argvs['deliverystatus'][2,6]
534
534
  esmtpreply = argvs['replycode'][1,2]
@@ -539,13 +539,13 @@ module Sisimai
539
539
  # Each key is a reason name
540
540
  MessagesOf[e].each do |f|
541
541
  # Try to match an SMTP reply code, a D.S.N, and an error message
542
- next unless issuedcode.include?(f[2])
543
- next unless f[0].end_with?(esmtpreply)
544
- next unless f[1].end_with?(statuscode)
542
+ next if issuedcode.include?(f[2]) == false
543
+ next if f[0].end_with?(esmtpreply) == false
544
+ next if f[1].end_with?(statuscode) == false
545
545
  reasontext = e
546
546
  break
547
547
  end
548
- break unless reasontext.empty?
548
+ break if reasontext.empty? == false
549
549
  end
550
550
 
551
551
  return reasontext
@@ -24,7 +24,7 @@ module Sisimai
24
24
 
25
25
  MessagesOf.each_key do |e|
26
26
  # Try to match the error message with message patterns defined in $MessagesOf
27
- next unless MessagesOf[e].any? { |a| argvs["diagnosticcode"].include?(a) }
27
+ next if MessagesOf[e].none? { |a| argvs["diagnosticcode"].include?(a) }
28
28
  next if e == "networkerror" && (statuscode == "5" || esmtpreply == "5")
29
29
  next if e == "hostunknown" && (statuscode == "4" || statuscode == "")
30
30
  next if e == "hostunknown" && (esmtpreply == "4" || esmtpreply == "")
@@ -21,7 +21,7 @@ module Sisimai
21
21
 
22
22
  MessagesOf.each_key do |e|
23
23
  # Try to match the error message with message patterns defined in $MessagesOf
24
- next unless issuedcode.include?(MessagesOf[e])
24
+ next if issuedcode.include?(MessagesOf[e]) == false
25
25
  reasontext = e
26
26
  break
27
27
  end