mail_plugger 1.0.0.beta1

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.
Binary file
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mail_plugger/error'
4
+ require 'mail_plugger/mail_helper'
5
+ require 'mail_plugger/delivery_method'
6
+ # If we are using this gem outside of Rails then do not load this code.
7
+ require 'mail_plugger/railtie' if defined?(Rails)
8
+ require 'mail_plugger/version'
9
+
10
+ module MailPlugger
11
+ class << self
12
+ attr_reader :delivery_options, :delivery_settings, :client
13
+
14
+ # Plug in defined API(s) class.
15
+ #
16
+ # @param [String] delivery_system the name of the API
17
+ #
18
+ # @example using Rails config/initializers/mail_plugger.rb
19
+ #
20
+ # The defined API class should have an 'initializer' and a 'deliver' method.
21
+ # class DefinedApiClientClass
22
+ # def initialize(options = {}) # required
23
+ # @settings = { api_key: ENV['API_KEY'] }
24
+ # @massage_to = options[:to]
25
+ # @message_from = options[:from]
26
+ # @message_subject = options[:subject]
27
+ # @message_body_text = options[:text_part]
28
+ # @message_body_html = options[:html_part]
29
+ # end
30
+ #
31
+ # def deliver # required
32
+ # API.new(@settings).client.post(generate_mail_hash)
33
+ # end
34
+ #
35
+ # private
36
+ #
37
+ # def generate_mail_hash
38
+ # {
39
+ # to: generate_recipients,
40
+ # from: {
41
+ # email: @message_from
42
+ # },
43
+ # subject: @message_subject,
44
+ # content: [
45
+ # {
46
+ # type: 'text/plain',
47
+ # value: @message_body_text
48
+ # },
49
+ # {
50
+ # type: 'text/html',
51
+ # value: @message_body_html
52
+ # }
53
+ # ]
54
+ # }
55
+ # end
56
+ #
57
+ # def generate_recipients
58
+ # @massage_to.map do |to|
59
+ # {
60
+ # email: to
61
+ # }
62
+ # end
63
+ # end
64
+ # end
65
+ #
66
+ # MailPlugger.plug_in('definedapi') do |api|
67
+ # # It will search these options in the Mail::Message object
68
+ # api.delivery_options = [:to, :from, :subject, :text_part, :html_part]
69
+ #
70
+ # api.client = DefinedApiClientClass
71
+ # end
72
+ #
73
+ def plug_in(delivery_system)
74
+ if delivery_system.nil? || delivery_system.strip.empty?
75
+ raise Error::WrongDeliverySystem, 'Delivery system is nil or empty. ' \
76
+ 'You should provide correct MailPlugger.plug_in parameter'
77
+ end
78
+
79
+ @delivery_system = delivery_system
80
+
81
+ yield self
82
+ rescue NoMethodError => e
83
+ raise Error::WrongPlugInOption, e.message
84
+ end
85
+
86
+ # Define 'delivery_options' and 'client' setter methods. These methods are
87
+ # generating a hash where the key is the 'delivery_system'. This let us to
88
+ # set/use more than one API.
89
+ %w[delivery_options delivery_settings client].each do |method|
90
+ define_method "#{method}=" do |value|
91
+ variable = instance_variable_get("@#{method}")
92
+ variable = instance_variable_set("@#{method}", {}) if variable.nil?
93
+ variable[@delivery_system] = value
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MailPlugger
4
+ class DeliveryMethod
5
+ include MailHelper
6
+
7
+ # Initialize delivery method attributes. If we are using MailPlugger.plug_in
8
+ # method, then these attributes can be nil, if not then we should set these
9
+ # attributes.
10
+ #
11
+ # @param [Hash] options with the credentials
12
+ def initialize(options = {})
13
+ @delivery_options = options[:delivery_options] ||
14
+ MailPlugger.delivery_options
15
+
16
+ @client = options[:client] || MailPlugger.client
17
+
18
+ @default_delivery_system = options[:default_delivery_system] ||
19
+ default_delivery_system_get
20
+
21
+ @delivery_settings = options[:delivery_settings] ||
22
+ MailPlugger.delivery_settings
23
+
24
+ @message = nil
25
+ end
26
+
27
+ # Send message with the given client if the message parameter is a
28
+ # Mail::Message object. Before doing that extract those information from the
29
+ # Mail::Message object which was provided in the 'delivery_options'. After
30
+ # that it generates a hash with these data and sends the message with the
31
+ # provided client class which has a 'deliver' method.
32
+ #
33
+ # @param [Mail::Message] message what we would like to send
34
+ def deliver!(message)
35
+ unless message.is_a?(Mail::Message)
36
+ raise Error::WrongParameter,
37
+ 'The given parameter is not a Mail::Message'
38
+ end
39
+
40
+ @message = message
41
+
42
+ client.new(delivery_data).deliver
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MailPlugger
4
+ class Error < StandardError
5
+ # Specific error class for errors if client is not given or has a wrong type
6
+ class WrongApiClient < Error; end
7
+
8
+ # Specific error class for errors if delivery options is not given or
9
+ # has a wrong type
10
+ class WrongDeliveryOptions < Error; end
11
+
12
+ # Specific error class for errors if delivery settings has a wrong type
13
+ class WrongDeliverySettings < Error; end
14
+
15
+ # Specific error class for errors if delivery system is not given
16
+ class WrongDeliverySystem < Error; end
17
+
18
+ # Specific error class for errors if parameter is not given
19
+ class WrongParameter < Error; end
20
+
21
+ # Specific error class for errors if tries to add undelclared option
22
+ # in plug_in block
23
+ class WrongPlugInOption < Error; end
24
+ end
25
+ end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+
5
+ module MailPlugger
6
+ module MailHelper
7
+ # Check the version of a gem.
8
+ #
9
+ # @param [String] gem_name the name of the gem
10
+ # @param [String] version the satisfied version of the gem
11
+ #
12
+ # @return [Boolean] true/false
13
+ def check_version_of(gem_name, version)
14
+ requirement = Gem::Requirement.new(version)
15
+ current_version = Gem.loaded_specs[gem_name].version
16
+
17
+ requirement.satisfied_by?(current_version)
18
+ end
19
+
20
+ # Extract 'client'. If it's a hash then it'll return the right
21
+ # client belongs to the delivery system. If it's not a hash it'll return
22
+ # the given value. But if the value doesn't a class it'll raise an error.
23
+ #
24
+ # @return [Class] the defined API class
25
+ def client
26
+ api_client = option_value_from(@client)
27
+
28
+ unless api_client.is_a?(Class)
29
+ raise Error::WrongApiClient, '"client" does not a Class'
30
+ end
31
+ unless api_client.method_defined?(:deliver)
32
+ raise Error::WrongApiClient, '"client" does not have "deliver" method'
33
+ end
34
+
35
+ api_client
36
+ end
37
+
38
+ # Collects data from Mail::Message object.
39
+ #
40
+ # @return [Hash] the data which was defined in 'delivery_options'
41
+ def delivery_data
42
+ data = {}
43
+
44
+ delivery_options.each do |option|
45
+ data[option] =
46
+ case option
47
+ when :from, :to, :cc, :bcc, :subject
48
+ @message.public_send(option)
49
+ when :attachments
50
+ extract_attachments
51
+ when :body, :html_part, :text_part
52
+ @message.public_send(option)&.decoded
53
+ else
54
+ message_field_value_from(@message[option.to_s])
55
+ end
56
+ end
57
+
58
+ data
59
+ end
60
+
61
+ # Tries to set up a default delivery system, if the 'delivery_system'
62
+ # wasn't defined in the Mail::Message object and 'delivery_options' and/or
63
+ # 'client' is a hash. Which means the MailPlugger.plugin method was used,
64
+ # probably.
65
+ #
66
+ # @return [Stirng] the first key of the 'delivery_options' or 'client'
67
+ def default_delivery_system_get
68
+ if @delivery_options.is_a?(Hash)
69
+ @delivery_options
70
+ elsif @client.is_a?(Hash)
71
+ @client
72
+ end&.keys&.first
73
+ end
74
+
75
+ # Extract 'delivery_options'. If it's a hash then it'll return the right
76
+ # options belongs to the delivery system. If it's not a hash it'll return
77
+ # the given value. But if the value doesn't an array it'll raise an error.
78
+ #
79
+ # @return [Array] the options it'll collect from the Mail::Message object
80
+ def delivery_options
81
+ options = option_value_from(@delivery_options)
82
+
83
+ unless options.is_a?(Array)
84
+ raise Error::WrongDeliveryOptions,
85
+ '"delivery_options" does not an Array'
86
+ end
87
+
88
+ options
89
+ end
90
+
91
+ # Extract 'delivery_system' from the Mail::Message object or if it's not
92
+ # defined then use the default one. If it's still nil and one of the
93
+ # 'delivery_options' or 'client' is a hash then raise error.
94
+ #
95
+ # @return [String] with the name of the delivery system
96
+ def delivery_system
97
+ @delivery_system ||=
98
+ (@message && message_field_value_from(@message['delivery_system'])) ||
99
+ @default_delivery_system
100
+
101
+ if @delivery_system.nil? &&
102
+ (@delivery_options.is_a?(Hash) || @client.is_a?(Hash))
103
+ raise Error::WrongDeliverySystem,
104
+ '"delivery_system" was not defined as a Mail::Message parameter'
105
+ end
106
+
107
+ @delivery_system
108
+ end
109
+
110
+ # Extract attachments.
111
+ #
112
+ # @return [Array] with extracted attachment hashes
113
+ def extract_attachments
114
+ @message.attachments&.map do |attachment|
115
+ hash =
116
+ if attachment.inline?
117
+ { cid: attachment.cid }
118
+ else
119
+ { filename: attachment.filename }
120
+ end
121
+
122
+ hash.merge(
123
+ type: attachment.mime_type,
124
+ content: Base64.encode64(attachment.decoded)
125
+ )
126
+ end
127
+ end
128
+
129
+ # How to Extract the (uparsed) value of the mail message fields.
130
+ #
131
+ # @return [String] version dependent method call
132
+ def mail_field_value
133
+ @mail_field_value ||=
134
+ if check_version_of('mail', '> 2.7.0')
135
+ %w[unparsed_value]
136
+ elsif check_version_of('mail', '= 2.7.0')
137
+ %w[instance_variable_get @unparsed_value]
138
+ elsif check_version_of('mail', '< 2.7.0')
139
+ %w[instance_variable_get @value]
140
+ end
141
+ end
142
+
143
+ # Extract the (unparsed) value of the mail message fields.
144
+ #
145
+ # @param [Mail::Field] message_field
146
+ #
147
+ # @return [String/Boolean/Hash] with the field (unparsed) value
148
+ def message_field_value_from(message_field)
149
+ return if message_field.nil?
150
+
151
+ message_field.public_send(*mail_field_value)
152
+ end
153
+
154
+ # Extract the value from the given options.
155
+ #
156
+ # @param [Hash/Array/Class] option
157
+ #
158
+ # @return [Hash/Array/Class] with the option value
159
+ def option_value_from(option)
160
+ if option.is_a?(Hash) && option[delivery_system]
161
+ option[delivery_system]
162
+ else
163
+ option
164
+ end
165
+ end
166
+
167
+ # Extract 'settings'. If it's a hash then it'll return the right
168
+ # settings belongs to the delivery system. If it's not a hash it'll return
169
+ # the given value. But if the value doesn't a hash it'll raise an error.
170
+ #
171
+ # @return [Hash] settings for Mail delivery_method
172
+ def settings
173
+ @settings ||= option_value_from(@delivery_settings)
174
+
175
+ return {} if @settings.nil?
176
+
177
+ unless @settings.is_a?(Hash)
178
+ raise Error::WrongDeliverySettings,
179
+ '"delivery_settings" does not a Hash'
180
+ end
181
+
182
+ @settings
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MailPlugger
4
+ class Railtie < Rails::Railtie
5
+ initializer 'mail_plugger.add_delivery_method' do
6
+ ActiveSupport.on_load :action_mailer do
7
+ ActionMailer::Base.add_delivery_method(
8
+ :mail_plugger,
9
+ MailPlugger::DeliveryMethod
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MailPlugger
4
+ VERSION = '1.0.0.beta1'
5
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/mail_plugger/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'mail_plugger'
7
+ spec.version = MailPlugger::VERSION
8
+ spec.authors = ['Norbert Szivós']
9
+ spec.email = ['sysqa@yahoo.com']
10
+
11
+ spec.summary = 'Plug in the required mailer API(s) with MailPlugger.'
12
+ spec.description = 'Delivery Method to send emails via the defined ' \
13
+ 'API(s), e.g. for Rails ActionMailer.'
14
+ spec.homepage = 'https://github.com/norbertszivos/mail_plugger'
15
+ spec.license = 'MIT'
16
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
17
+
18
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
19
+
20
+ spec.metadata['homepage_uri'] = spec.homepage
21
+ spec.metadata['source_code_uri'] =
22
+ 'https://github.com/norbertszivos/mail_plugger'
23
+ spec.metadata['changelog_uri'] =
24
+ 'https://github.com/norbertszivos/mail_plugger/CHANGELOG.md'
25
+
26
+ # Specify which files should be added to the gem when it is released.
27
+ # The `git ls-files -z` loads the files in the RubyGem
28
+ # that have been added into git.
29
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
30
+ `git ls-files -z`.split("\x0").reject do |f|
31
+ f.match(%r{^(test|spec|features)/})
32
+ end
33
+ end
34
+ spec.bindir = 'exe'
35
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
+ spec.require_paths = ['lib']
37
+
38
+ spec.add_dependency 'mail', '~> 2.5'
39
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mail_plugger
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.beta1
5
+ platform: ruby
6
+ authors:
7
+ - Norbert Szivós
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-01-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mail
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.5'
27
+ description: Delivery Method to send emails via the defined API(s), e.g. for Rails
28
+ ActionMailer.
29
+ email:
30
+ - sysqa@yahoo.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
36
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
37
+ - ".gitignore"
38
+ - ".rspec"
39
+ - ".rubocop.yml"
40
+ - ".travis.yml"
41
+ - Appraisals
42
+ - CHANGELOG.md
43
+ - CODE_OF_CONDUCT.md
44
+ - CONTRIBUTING.md
45
+ - Gemfile
46
+ - Gemfile.lock
47
+ - LICENSE.txt
48
+ - README.md
49
+ - Rakefile
50
+ - bin/console
51
+ - bin/setup
52
+ - docs/usage_in_ruby_on_rails.md
53
+ - docs/usage_in_script_or_console.md
54
+ - gemfiles/.bundle/config
55
+ - gemfiles/mail_2.6.gemfile
56
+ - gemfiles/mail_2.6.gemfile.lock
57
+ - gemfiles/mail_2.7.0.gemfile
58
+ - gemfiles/mail_2.7.0.gemfile.lock
59
+ - gemfiles/mail_2.7.gemfile
60
+ - gemfiles/mail_2.7.gemfile.lock
61
+ - images/mail_plugger.png
62
+ - lib/mail_plugger.rb
63
+ - lib/mail_plugger/delivery_method.rb
64
+ - lib/mail_plugger/error.rb
65
+ - lib/mail_plugger/mail_helper.rb
66
+ - lib/mail_plugger/railtie.rb
67
+ - lib/mail_plugger/version.rb
68
+ - mail_plugger.gemspec
69
+ homepage: https://github.com/norbertszivos/mail_plugger
70
+ licenses:
71
+ - MIT
72
+ metadata:
73
+ homepage_uri: https://github.com/norbertszivos/mail_plugger
74
+ source_code_uri: https://github.com/norbertszivos/mail_plugger
75
+ changelog_uri: https://github.com/norbertszivos/mail_plugger/CHANGELOG.md
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 2.5.0
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.3.1
90
+ requirements: []
91
+ rubygems_version: 3.2.3
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Plug in the required mailer API(s) with MailPlugger.
95
+ test_files: []