snails 0.4.2 → 0.5.0
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.
- checksums.yaml +4 -4
- data/lib/snails/mailer.rb +127 -26
- data/snails.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 06b4aea8ffe430adc00748ea5f48ace43cd79fdf26cebb02da08b31ea88765ac
|
|
4
|
+
data.tar.gz: 9c856ce125123fe7d3423b362ea948dba6b41038490dea3b0158084ecf2d6b35
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ddff99a5c53edfb7a897b2c3015cbf883e1db67124df89d5c9cbe7058798cdc644f3954d575b6381ef017c458fa908df40bb14e825bb2ce174810f26844c4e24
|
|
7
|
+
data.tar.gz: ed3065454f356aaf82e325ae2e46bccafc8c93f39de9ccf99f7079b43bfab913231f4abfd355e437444e7d9d7268532e072c9b8447c782cd09f7079227fa83a1
|
data/lib/snails/mailer.rb
CHANGED
|
@@ -12,32 +12,40 @@ module Snails
|
|
|
12
12
|
|
|
13
13
|
@queue = :emails
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
# class Bounce < StandardError; end
|
|
16
|
+
# class SoftBounce < Bounce; end
|
|
17
|
+
# class HardBounce < Bounce; end
|
|
18
|
+
|
|
19
|
+
def self.backends
|
|
20
|
+
{
|
|
21
|
+
'test_backend' => 'Snails::Mailer::TestBackend',
|
|
22
|
+
'smtp' => 'Snails::Mailer::TuktukBackend',
|
|
23
|
+
'mailgun' => 'Snails::Mailer::MailgunBackend'
|
|
24
|
+
}
|
|
25
|
+
end
|
|
17
26
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
mail_config.delete(:dkim)
|
|
23
|
-
end
|
|
27
|
+
def self.init_backend(backend_name, opts = {})
|
|
28
|
+
backend_name = backend_name.presence || 'test_backend'
|
|
29
|
+
backends[backend_name].constantize.new(opts)
|
|
30
|
+
end
|
|
24
31
|
|
|
25
|
-
|
|
26
|
-
@debug = mail_config[:debug]
|
|
32
|
+
def initialize(opts)
|
|
27
33
|
@from_email = opts[:from] or raise ":from required"
|
|
28
34
|
@base_subject = opts[:base_subject] || ''
|
|
29
35
|
@views = opts[:views] || Snails.root.join('lib', 'views')
|
|
30
36
|
@logfile = opts[:logfile] # || Snails.root.join('log', 'mailer.log')
|
|
37
|
+
|
|
38
|
+
@backend = self.class.init_backend(opts[:backend_name], opts[:backend_options])
|
|
31
39
|
end
|
|
32
40
|
|
|
33
41
|
def email(name, &block)
|
|
34
42
|
define_singleton_method(name) do |*args|
|
|
35
|
-
instance_exec(*args, &block)
|
|
43
|
+
instance_exec(*args, &block)
|
|
36
44
|
end
|
|
37
45
|
end
|
|
38
46
|
|
|
39
47
|
def helpers(&block)
|
|
40
|
-
instance_eval(&block)
|
|
48
|
+
instance_eval(&block)
|
|
41
49
|
end
|
|
42
50
|
|
|
43
51
|
def perform(method, *args)
|
|
@@ -81,50 +89,143 @@ A <%= @exception.class %> occurred in <%= @url %>:
|
|
|
81
89
|
|
|
82
90
|
private
|
|
83
91
|
|
|
84
|
-
def render(
|
|
85
|
-
|
|
92
|
+
def render(view_path, layout_path = nil)
|
|
93
|
+
view = File.read(File.join(@views, "#{view_path}.erb"))
|
|
94
|
+
if layout_path
|
|
95
|
+
layout = File.read(File.join(@views, "#{layout_path}.erb"))
|
|
96
|
+
render_erb(layout) { render_erb(view) }
|
|
97
|
+
else
|
|
98
|
+
render_erb(view)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def render_erb(template)
|
|
86
103
|
ERB.new(template).result(binding)
|
|
87
104
|
end
|
|
88
105
|
|
|
89
106
|
def partial(name)
|
|
90
107
|
partial_name = name.to_s["/"] ? name.to_s.reverse.sub("/", "_/").reverse : "_#{name}"
|
|
91
|
-
render
|
|
108
|
+
render(partial_name)
|
|
92
109
|
end
|
|
93
110
|
|
|
94
111
|
def logger
|
|
95
112
|
@logger ||= @logfile ? Logger.new(@logfile) : Snails.logger
|
|
96
113
|
end
|
|
97
114
|
|
|
98
|
-
def send_email(from:
|
|
115
|
+
def send_email(from: @from_email, to:, subject:, body: nil, template: nil, layout: nil, html_body: nil, html_template: nil, html_layout: nil, message_id: nil, attachments: nil, return_path: nil, list_unsubscribe: nil)
|
|
99
116
|
raise "No recipient given for mail: #{subject}!" if to.blank?
|
|
100
117
|
|
|
101
118
|
message = {
|
|
102
119
|
to: to,
|
|
103
|
-
from: from
|
|
104
|
-
subject: @base_subject + subject
|
|
120
|
+
from: from,
|
|
121
|
+
subject: @base_subject + subject
|
|
105
122
|
}
|
|
106
123
|
|
|
124
|
+
raise "Blank from" if message[:from].blank?
|
|
125
|
+
raise "Blank to" if message[:to].blank?
|
|
126
|
+
|
|
107
127
|
if body or template
|
|
108
|
-
message[:body] = template ? render(template) : body
|
|
128
|
+
message[:body] = template ? render(template, layout) : body
|
|
109
129
|
end
|
|
110
130
|
|
|
111
131
|
if html_body or html_template
|
|
112
|
-
message[:html_body] = html_template ? render(html_template) : html_body
|
|
132
|
+
message[:html_body] = html_template ? render(html_template, html_layout) : html_body
|
|
113
133
|
end
|
|
114
134
|
|
|
135
|
+
message[:attachments] = attachments if attachments
|
|
115
136
|
message[:message_id] = message_id if message_id
|
|
116
137
|
message[:return_path] = return_path if return_path
|
|
117
138
|
message[:list_unsubscribe] = list_unsubscribe if list_unsubscribe
|
|
118
139
|
|
|
119
|
-
logger.info "[#{to}] Delivering: #{subject}"
|
|
120
|
-
|
|
121
|
-
|
|
140
|
+
logger.info "[#{to}] Delivering: #{subject}"
|
|
141
|
+
@backend.deliver(message)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
alias_method :deliver, :send_email
|
|
145
|
+
|
|
146
|
+
class Backend
|
|
147
|
+
def deliver(email, options = {})
|
|
148
|
+
raise "Please redefine in subclass"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def deliver_many(emails, options = {})
|
|
152
|
+
emails.map { |e| deliver(e, options) }
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
class TestBackend < Backend
|
|
157
|
+
def initialize(opts = {})
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def deliver(email, options = {})
|
|
161
|
+
puts "Deliverying single: #{email[:to]}"
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def deliver_many(emails, options = {})
|
|
165
|
+
puts "Deliverying many: #{emails.count}"
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
class TuktukBackend < Backend
|
|
170
|
+
def initialize(config = {})
|
|
171
|
+
@debug = config[:debug]
|
|
172
|
+
|
|
173
|
+
puts "-- #{config.inspect}"
|
|
174
|
+
|
|
175
|
+
if key = config.dig(:dkim, :private_key) and File.exist?(key)
|
|
176
|
+
config[:dkim][:private_key] = IO.read(key)
|
|
177
|
+
elsif config[:dkim]
|
|
178
|
+
puts "Private key for DKIM not found! Disabling..."
|
|
179
|
+
config.delete(:dkim)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
Tuktuk.options = config
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def deliver(email, options = {})
|
|
186
|
+
debug = @debug.nil? ? !Snails.env.production? : @debug # if debug isn't set, determine based on env
|
|
187
|
+
resp, email = Tuktuk.deliver(email, debug: debug)
|
|
188
|
+
|
|
189
|
+
if resp.is_a?(Tuktuk::Bounce)
|
|
190
|
+
logger.info "[#{to}] Email bounced! [#{resp.code}] #{resp.message}"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
return resp, email
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def deliver_many(emails, options = {})
|
|
197
|
+
Tuktuk.deliver_many(emails, options)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
class MailgunBackend < Backend
|
|
202
|
+
|
|
203
|
+
def initialize(api_key:, domain_name:)
|
|
204
|
+
@key = api_key
|
|
205
|
+
@url = "https://api.mailgun.net/v3/#{domain_name}/messages"
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def deliver(email, options = {})
|
|
209
|
+
raise "No body!" if email[:body].nil?
|
|
210
|
+
|
|
211
|
+
data = {
|
|
212
|
+
from: email[:from],
|
|
213
|
+
to: email[:to],
|
|
214
|
+
subject: email[:subject],
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
data[:text] = email[:body] if email[:body]
|
|
218
|
+
data[:html] = email[:html_body] if email[:html_body]
|
|
219
|
+
|
|
220
|
+
if data[:text].blank? && data[:html].blank?
|
|
221
|
+
raise ArgumentError, "Either text or html required"
|
|
222
|
+
end
|
|
122
223
|
|
|
123
|
-
|
|
124
|
-
|
|
224
|
+
opts = { username: 'api', password: @key }
|
|
225
|
+
resp = Dagger.post(@url, data, opts)
|
|
226
|
+
resp.ok? ? [resp.data, data[:to]] : nil
|
|
125
227
|
end
|
|
126
228
|
|
|
127
|
-
return resp, email
|
|
128
229
|
end
|
|
129
230
|
|
|
130
231
|
end
|
data/snails.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: snails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tomás Pollak
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-10-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|