Module: Sisimai::Lhost::Notes
- Defined in:
- lib/sisimai/lhost/notes.rb
Overview
Sisimai::Lhost::Notes decodes a bounce email which created by HCL Notes (formerly IMB Notes Server (formerly Lotus Notes Server)). Methods in the module are called from only Sisimai::Message.
Constant Summary collapse
- Indicators =
Sisimai::Lhost.INDICATORS
- Boundaries =
['------- Returned Message --------'].freeze
- StartingOf =
{message: ['------- Failure Reasons ']}.freeze
- MessagesOf =
{ 'userunknown' => [ 'User not listed in public Name & Address Book', 'ディレクトリのリストにありません', ], }.freeze
Class Method Summary collapse
Class Method Details
.description ⇒ Object
117 |
# File 'lib/sisimai/lhost/notes.rb', line 117 def description; return 'Lotus Notes'; end |
.inquire(mhead, mbody) ⇒ Hash, Nil
This method is abstract.
Decodes the bounce messages from HCL Notes (Formerly IBM Notes (Formerly Lotus Notes))
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/sisimai/lhost/notes.rb', line 23 def inquire(mhead, mbody) return nil if mhead['subject'].start_with?('Undeliverable message') == false dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil emailparts = Sisimai::RFC5322.part(mbody, Boundaries) bodyslices = emailparts[0].split("\n") readcursor = 0 # (Integer) Points the current cursor position recipients = 0 # (Integer) The number of 'Final-Recipient' header characters = '' # (String) Character set name of the bounce mail removedmsg = 'MULTIBYTE CHARACTERS HAVE BEEN REMOVED' encodedmsg = '' if mhead['content-type'].include?('charset=') # Get character set name, Content-Type: text/plain; charset=ISO-2022-JP characters = mhead['content-type'][mhead['content-type'].index('charset=') + 8, mhead['content-type'].size].downcase end while e = bodyslices.shift do # Read error messages and delivery status lines from the head of the email to the previous # line of the beginning of the original message. if readcursor == 0 # Beginning of the bounce message or delivery status part readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0]) next end next if (readcursor & Indicators[:deliverystatus]) == 0 # ------- Failure Reasons -------- # # User not listed in public Name & Address Book # kijitora@notes.example.jp # # ------- Returned Message -------- v = dscontents[-1] if e.include?('@') && e.index(' ').nil? # kijitora@notes.example.jp if v["recipient"] != "" # There are multiple recipient addresses in the message body. dscontents << Sisimai::Lhost.DELIVERYSTATUS v = dscontents[-1] end v["recipient"] = e if v["recipient"].empty? recipients += 1 else next if e.empty? || e.start_with?('-') if e =~ /[^\x20-\x7e]/ # Error message is not ISO-8859-1 if characters.size > 0 # Try to convert string begin encodedmsg = e.encode('UTF-8', characters) rescue # Failed to convert encodedmsg = removedmsg end else # No character set in Content-Type header encodedmsg = removedmsg end v['diagnosis'] += encodedmsg else # Error message does not include multi-byte character v['diagnosis'] += e end end end if recipients == 0 # Fallback: Get the recpient address from RFC822 part p1 = emailparts[1].index("\nTo: ") || -1 p2 = emailparts[1].index("\n", p1 + 6) || -1 if p1 > 0 v['recipient'] = Sisimai::Address.s3s4(emailparts[1][p1 + 5, p2 - p1 - 5]) recipients += 1 if v['recipient'].empty? == false end end return nil if recipients == 0 dscontents.each do |e| e['diagnosis'] = e['diagnosis'].split.join(" ") e['recipient'] = Sisimai::Address.s3s4(e['recipient']) MessagesOf.each_key do |r| # Check each regular expression of Notes error messages next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) } e['reason'] = r e['status'] = Sisimai::SMTP::Status.code(r.to_s) || '' break end end return {"ds" => dscontents, "rfc822" => emailparts[1]} end |