Module: Sisimai::Lhost::EinsUndEins
- Defined in:
- lib/sisimai/lhost/einsundeins.rb
Overview
Sisimai::Lhost::EinsUndEins decodes a bounce email which created by 1&1 www.1und1.de/. Methods in the module are called from only Sisimai::Message.
Constant Summary collapse
- Indicators =
Sisimai::Lhost.INDICATORS
- Boundaries =
['--- The header of the original message is following. ---'].freeze
- StartingOf =
{ message: ['This message was created automatically by mail delivery software'], error: ['For the following reason:'], }.freeze
Class Method Summary collapse
Class Method Details
.description ⇒ Object
104 |
# File 'lib/sisimai/lhost/einsundeins.rb', line 104 def description; return '1&1: https://www.1und1.de'; end |
.inquire(mhead, mbody) ⇒ Hash, Nil
This method is abstract.
Decode the bounce message from 1&1
20 21 22 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 |
# File 'lib/sisimai/lhost/einsundeins.rb', line 20 def inquire(mhead, mbody) return nil if mhead['from'].start_with?('"Mail Delivery System"') == false return nil if mhead['subject'] != 'Mail delivery failed: returning message to sender' 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 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 || e.empty? # The following address failed: # # general@example.eu # # For the following reason: # # Mail size limit exceeded. For explanation visit # http://postmaster.1and1.com/en/error-messages?ip=%1s v = dscontents[-1] if cv = e.match(/\A\s*([^ ]+[@][^ ]+?)[:]?\z/) # general@example.eu OR # the line begin with 4 space characters, end with ":" like " neko@example.eu:" if v["recipient"] != "" # There are multiple recipient addresses in the message body. dscontents << Sisimai::Lhost.DELIVERYSTATUS v = dscontents[-1] end v['recipient'] = Sisimai::Address.s3s4(e) recipients += 1 elsif e.start_with?(StartingOf[:error][0]) # For the following reason: v['diagnosis'] = e else if v['diagnosis'] # Get error message and append error message strings v['diagnosis'] += " #{e}" else # OR the following format: # neko@example.fr: # SMTP error from remote server for TEXT command, host: ... v['alterrors'] ||= '' v['alterrors'] += " #{e}" end end end return nil if recipients == 0 require 'sisimai/smtp/command' dscontents.each do |e| e['diagnosis'] = e['alterrors'] if e['diagnosis'].empty? e['command'] = Sisimai::SMTP::Command.find(e['diagnosis']) if Sisimai::String.aligned(e['diagnosis'], ['host: ', ' reason:']) # SMTP error from remote server for TEXT command, # host: smtp-in.orange.fr (193.252.22.65) # reason: 550 5.2.0 Mail rejete. Mail rejected. ofr_506 [506] p1 = e['diagnosis'].index('host: ') p2 = e['diagnosis'].index(' reason:') e['rhost'] = e['diagnosis'][p1 + 6, p2 - p1 - 6] e['command'] = 'DATA' if e['diagnosis'].include?('for TEXT command') e['spec'] = 'SMTP' if e['diagnosis'].include?('SMTP error') e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) else # For the following reason: e['diagnosis'][0, StartingOf[:error][0].size] = '' end end return {"ds" => dscontents, "rfc822" => emailparts[1]} end |