Class: MultiMail::Receiver::Cloudmailin

Inherits:
Object
  • Object
show all
Includes:
Base
Defined in:
lib/multi_mail/cloudmailin/receiver.rb

Overview

Cloudmailin's incoming email receiver.

Cloudmailin recommends using basic authentication over HTTPS to ensure that a request originates from Cloudmailin.

Instance Method Summary collapse

Methods included from Base

included, #process, #valid?

Constructor Details

#initialize(options = {}) ⇒ Cloudmailin

Initializes a Cloudmailin incoming email receiver.

Parameters:

  • options (Hash) (defaults to: {})

    required and optional arguments

Options Hash (options):

  • :http_post_format (String)

    "multipart", "json" or "raw"

  • :attachment_store (Boolean)

    whether attachments have been sent to an attachment store



20
21
22
23
24
# File 'lib/multi_mail/cloudmailin/receiver.rb', line 20

def initialize(options = {})
  super
  @http_post_format = options[:http_post_format]
  @attachment_store = options[:attachment_store]
end

Instance Method Details

#spam?(message) ⇒ Boolean

Returns whether the message is spam.

Parameters:

Returns:

  • (Boolean)

    whether the message is spam



106
107
108
# File 'lib/multi_mail/cloudmailin/receiver.rb', line 106

def spam?(message)
  message.spf_result == 'fail'
end

#transform(params) ⇒ Array<MultiMail::Message::Cloudmailin>

Returns messages.



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
# File 'lib/multi_mail/cloudmailin/receiver.rb', line 31

def transform(params)
  case @http_post_format
  when 'raw', '', nil
    message = self.class.condense(MultiMail::Message::Cloudmailin.new(Mail.new(params['message'])))

    # Extra Cloudmailin parameters.
    message.spf_result = params['envelope']['spf']['result']

    if @attachment_store
      params['attachments'].each do |_,attachment|
        message.add_file(:filename => attachment['file_name'], :content => Faraday.get(attachment['url']).body)
      end
    end

    # Discard rest of `envelope`: `from`, `to`, `recipients`,
    # `helo_domain` and `remote_ip`.
    [message]
  when 'multipart', 'json'
    # Mail changes `self`.
    headers = self.class.multimap(params['headers'])
    http_post_format = @http_post_format
    attachment_store = @attachment_store
    this = self

    message = MultiMail::Message::Cloudmailin.new do
      headers headers

      text_part do
        body params['plain']
      end

      if params.key?('html')
        html_part do
          content_type 'text/html; charset=UTF-8'
          body params['html']
        end
      end

      if params.key?('attachments')
        # Using something like lazy.rb will not prevent the HTTP request,
        # because the Mail gem must be able to call #valid_encoding? on
        # the attachment body (in Ruby 1.9).
        if http_post_format == 'json'
          params['attachments'].each do |attachment|
            if attachment_store
              add_file(:filename => attachment['file_name'], :content => Faraday.get(attachment['url']).body)
            else
              add_file(:filename => attachment['file_name'], :content => Base64.decode64(attachment['content']))
            end
          end
        else
          params['attachments'].each do |_,attachment|
            if attachment_store
              add_file(:filename => attachment['file_name'], :content => Faraday.get(attachment['url']).body)
            else
              add_file(this.class.add_file_arguments(attachment))
            end
          end
        end
      end
    end

    # Extra Cloudmailin parameters. The multipart format uses CRLF whereas
    # the JSON format uses LF. Normalize to LF.
    message.reply_plain = params['reply_plain'].gsub("\r\n", "\n")
    message.spf_result  = params['envelope']['spf']['result']

    [message]
  else
    raise ArgumentError, "Can't handle Cloudmailin #{@http_post_format} HTTP POST format"
  end
end