mandrill_mailer 0.4.8 → 0.4.9

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NGRiMzhmYWE5ODUwOWQzZjIxODI4M2RlOWFkMGUzN2NlOTQ3N2JjMw==
4
+ ZjFiMmQwMDkwY2Y2MmEyOWQyNjIwNjZlNGEwZDk3ZGI3YTE4NTZiMw==
5
5
  data.tar.gz: !binary |-
6
- NjNjZmZkOWY1OWI3ZTUxN2IzMTBiOTg1ZDU4ZTk3ZDc1NzEwZTljMQ==
6
+ YTIxMzNmNjllMDkwN2E1NDhhMTAzMTM5YjJhMjFhYTAzNDJiNGUxYQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MGQ1MTgwNjk5NjAwZTEzZmEzNWE5MjQwM2QzYzg1Mjk5ODk3MGExNmJkYTRh
10
- ZjNhNGQ5NjI3ZDI5NjQwMmNkNWU5ZWIwYWI2ZDNjZTZlNjU5Nzg0NzEwMjdj
11
- Nzc3OWRhNDY4NmYxOTcwOTZiN2ZjNmI0YzU3Y2QyNzMxNWRmYzU=
9
+ YWNjOTFlZmIzNmU0MWVkZmIyMzU0YmZmNmI1NzlmZWUyZjM0ZGEyNWJlNzY1
10
+ NzBiMGY5ZDFkZjFiNzIwNDAxMmJjODEwOTc1N2FlYmYwMWI0Njc2NDM1NmRh
11
+ ZWYxZjBiYTllZWFhZDk4YzU1YWQ5YzIxNWZkNTAxNzIwZWYyOTk=
12
12
  data.tar.gz: !binary |-
13
- ZmVmYWY0MGFkM2Y1N2JjZWVlNTBhOGYyYjQzOTA5MzIyYjQwZjYyZmQ3MDQ4
14
- MzI3NmE0Yjc1OTBhMjgxYTFhYWRlY2UwMGZjNmRmMzNmYTc5MDU2ZmFjNzZk
15
- MTVkZmIxODM1YjljZmM0ZjM1NGMwYTk5OGZiZmFmMGFiODlkYWI=
13
+ OGIwMDk1NWE5OTNkN2JjYTZhZTZhNGY4ZWExNjUwODFmZDU3MjM5Nzc0OWQx
14
+ YWE2YWVmZWRjZDMwNDU0NDYyY2RkMzcyODVmOTllYmQyNmUzODU5ZTRkZGFh
15
+ MmQ3Zjg3MGNhYzI0MDk1MzY5YzNmNjY1NTgyZTYwN2JmNTU2Mjc=
@@ -1,3 +1,6 @@
1
+ # 0.4.9
2
+ - [FEATURE] Added support for the Mandrill Messages api by adding a MandrillMailer::Messenger class. Thanks @arthurtalkgoal
3
+
1
4
  # 0.4.8
2
5
  - [IMPROVEMENT] Add a to= setter to the template mailer
3
6
 
data/README.md CHANGED
@@ -156,6 +156,43 @@ end
156
156
 
157
157
  * `:send_at` - When this message should be sent
158
158
 
159
+ ## Sending a message without template
160
+ Sending a message without template is similar to sending a template one:
161
+
162
+ ```ruby
163
+ class InvitationMailer < MandrillMailer::MessageMailer
164
+ default from: 'support@example.com'
165
+
166
+ def invite(invitation)
167
+ # in this example `invitation.invitees` is an Array
168
+ invitees = invitation.invitees.map { |invitee| { email: invitee.email, name: invitee.name } }
169
+
170
+ # no need to set up tempalte and template_content attributes, set up the html and text directly
171
+ mandrill_mail subject: I18n.t('invitation_mailer.invite.subject'),
172
+ to: invitees,
173
+ # to: invitation.email,
174
+ # to: { email: invitation.email, name: 'Honored Guest' },
175
+ text: "Example text content",
176
+ html: "<p>Example HTML content</p>",
177
+ view_content_link: "http://www.nba.com",
178
+ vars: {
179
+ 'OWNER_NAME' => invitation.owner_name,
180
+ 'PROJECT_NAME' => invitation.project_name
181
+ },
182
+ important: true,
183
+ inline_css: true,
184
+ recipient_vars: invitation.invitees.map do |invitee| # invitation.invitees is an Array
185
+ { invitee.email =>
186
+ {
187
+ 'INVITEE_NAME' => invitee.name,
188
+ 'INVITATION_URL' => new_invitation_url(invitee.email, secret: invitee.secret_code)
189
+ }
190
+ }
191
+ end
192
+ end
193
+ end
194
+ ```
195
+
159
196
  ## Sending an email
160
197
 
161
198
  You can send the email by using the familiar syntax:
@@ -2,6 +2,7 @@ require 'action_view'
2
2
  require 'mandrill_mailer/railtie'
3
3
  require 'mandrill_mailer/mock'
4
4
  require 'mandrill_mailer/template_mailer'
5
+ require 'mandrill_mailer/message_mailer'
5
6
  require 'mandrill_mailer/version'
6
7
 
7
8
  module MandrillMailer
@@ -0,0 +1,367 @@
1
+ # MandrilMailer class for sending transactional emails through mandril.
2
+ # Only template based emails are supported at this time.
3
+
4
+ # Example usage:
5
+
6
+ # class InvitationMailer < MandrillMailer::TemplateMailer
7
+ # default from: 'support@codeschool.com'
8
+
9
+ # def invite(invitation)
10
+ # invitees = invitation.invitees.map { |invitee| { email: invitee.email, name: invitee.name } }
11
+ #
12
+ # mandrill_mail template: 'Group Invite',
13
+ # subject: I18n.t('invitation_mailer.invite.subject'),
14
+ # to: invitees,
15
+ # # to: invitation.email
16
+ # # to: { email: invitation.email, name: invitation.recipient_name }
17
+ # vars: {
18
+ # 'OWNER_NAME' => invitation.owner_name,
19
+ # 'PROJECT_NAME' => invitation.project_name
20
+ # },
21
+ # recipient_vars: invitation.invitees.map do |invitee| # invitation.invitees is an Array
22
+ # { invitee.email =>
23
+ # {
24
+ # 'INVITEE_NAME' => invitee.name,
25
+ # 'INVITATION_URL' => new_invitation_url(invitee.email, secret: invitee.secret_code)
26
+ # }
27
+ # }
28
+ # end,
29
+ # template_content: {},
30
+ # attachments: [{file: File.read(File.expand_path('assets/some_image.png')), filename: 'My Image.png', mimetype: 'image/png'}],
31
+ # important: true,
32
+ # inline_css: true
33
+ # end
34
+ # end
35
+
36
+ # #default:
37
+ # :from - set the default from email address for the mailer
38
+
39
+ # .mandrill_mail
40
+ # :template(required) - Template name from within Mandrill
41
+
42
+ # :subject(required) - Subject of the email
43
+
44
+ # :to(required) - Accepts an email String, a Hash with :name and :email keys
45
+ # or an Array of Hashes with :name and :email keys
46
+ # examples:
47
+ # 1)
48
+ # 'example@domain.com`
49
+ # 2)
50
+ # { email: 'someone@email.com', name: 'Bob Bertly' }
51
+ # 3)
52
+ # [{ email: 'someone@email.com', name: 'Bob Bertly' },
53
+ # { email: 'other@email.com', name: 'Claire Nayo' }]
54
+ #
55
+
56
+ # :vars - A Hash of merge tags made available to the email. Use them in the
57
+ # email by wrapping them in '*||*' vars: {'OWNER_NAME' => 'Suzy'} is used
58
+ # by doing: *|OWNER_NAME|* in the email template within Mandrill
59
+ #
60
+ # :recipient_vars - Similar to :vars, this is a Hash of merge tags specific to a particular recipient.
61
+ # Use this if you are sending batch transactions and hence need to send multiple emails at one go.
62
+ # ex. [{'someone@email.com' => {'INVITEE_NAME' => 'Roger'}}, {'another@email.com' => {'INVITEE_NAME' => 'Tommy'}}]
63
+
64
+ # :template_content - A Hash of values and content for Mandrill editable content blocks.
65
+ # In MailChimp templates there are editable regions with 'mc:edit' attributes that look
66
+ # a little like: '<div mc:edit="header">My email content</div>' You can insert content directly into
67
+ # these fields by passing a Hash {'header' => 'my email content'}
68
+
69
+ # :attachments - An array of file objects with the following keys:
70
+ # file: This is the actual file, it will be converted to byte data in the mailer
71
+ # filename: The name of the file
72
+ # mimetype: This is the mimetype of the file. Ex. png = image/png, pdf = application/pdf, txt = text/plain etc
73
+
74
+ # :images - An array of embedded images to add to the message:
75
+ # file: This is the actual file, it will be converted to byte data in the mailer
76
+ # filename: The Content ID of the image - use <img src="cid:THIS_VALUE"> to reference the image in your HTML content
77
+ # mimetype: The MIME type of the image - must start with "image/"
78
+
79
+ # :headers - Extra headers to add to the message (currently only Reply-To and X-* headers are allowed) {"...": "..."}
80
+
81
+ # :bcc - Add an email to bcc to
82
+
83
+ # :tags - Array of Strings to tag the message with. Stats are
84
+ # accumulated using tags, though we only store the first 100 we see,
85
+ # so this should not be unique or change frequently. Tags should be
86
+ # 50 characters or less. Any tags starting with an underscore are
87
+ # reserved for internal use and will cause errors.
88
+
89
+ # :google_analytics_domains - Array of Strings indicating for which any
90
+ # matching URLs will automatically have Google Analytics parameters appended
91
+ # to their query string automatically.
92
+
93
+ # :google_analytics_campaign - String indicating the value to set for
94
+ # the utm_campaign tracking parameter. If this isn't provided the email's
95
+ # from address will be used instead.
96
+
97
+ # :inline_css - whether or not to automatically inline all CSS styles provided in the
98
+ # message HTML - only for HTML documents less than 256KB in size
99
+
100
+ # :important - whether or not this message is important, and should be delivered ahead of non-important messages
101
+ require 'base64'
102
+
103
+ module MandrillMailer
104
+ class CoreMailer
105
+ # include Rails.application.routes.url_helpers
106
+ include ActionView::Helpers::NumberHelper
107
+
108
+ class InvalidEmail < StandardError; end
109
+ class InvalidMailerMethod < StandardError; end
110
+ class InvalidInterceptorParams < StandardError; end
111
+
112
+ # Public: Other information on the message to send
113
+ attr_accessor :message
114
+
115
+ # Public: Enable background sending mode
116
+ attr_accessor :async
117
+
118
+ # Public: Name of the dedicated IP pool that should be used to send the message
119
+ attr_accessor :ip_pool
120
+
121
+ # Public: When message should be sent
122
+ attr_accessor :send_at
123
+
124
+ # Public: Defaults for the mailer. Currently the only option is from:
125
+ #
126
+ # options - The Hash options used to refine the selection (default: {}):
127
+ # :from - Default from email address
128
+ #
129
+ # Examples
130
+ #
131
+ # default from: 'foo@bar.com'
132
+ #
133
+ # Returns options
134
+ def self.defaults
135
+ @defaults || super_defaults
136
+ end
137
+
138
+ def self.super_defaults
139
+ superclass.defaults if superclass.respond_to?(:defaults)
140
+ end
141
+
142
+ def self.default(args)
143
+ @defaults ||= {}
144
+ @defaults[:from] ||= 'example@email.com'
145
+ @defaults.merge!(args)
146
+ end
147
+
148
+ class << self
149
+ attr_writer :defaults
150
+ end
151
+
152
+ # Public: setup a way to test mailer methods
153
+ #
154
+ # mailer_method - Name of the mailer method the test setup is for
155
+ #
156
+ # block - Block of code to execute to perform the test. The mailer
157
+ # and options are passed to the block. The options have to
158
+ # contain at least the :email to send the test to.
159
+ #
160
+ # Examples
161
+ #
162
+ # test_setup_for :invite do |mailer, options|
163
+ # invitation = OpenStruct.new({
164
+ # email: options[:email],
165
+ # owner_name: 'foobar',
166
+ # secret: rand(9000000..1000000).to_s
167
+ # })
168
+ # mailer.invite(invitation).deliver
169
+ # end
170
+ #
171
+ # Returns the duplicated String.
172
+ def self.test_setup_for(mailer_method, &block)
173
+ @mailer_methods ||= {}
174
+ @mailer_methods[mailer_method] = block
175
+ end
176
+
177
+ # Public: Executes a test email
178
+ #
179
+ # mailer_method - Method to execute
180
+ #
181
+ # options - The Hash options used to refine the selection (default: {}):
182
+ # :email - The email to send the test to.
183
+ #
184
+ # Examples
185
+ #
186
+ # InvitationMailer.test(:invite, email: 'benny@envylabs.com')
187
+ #
188
+ # Returns the duplicated String.
189
+ def self.test(mailer_method, options={})
190
+ unless options[:email]
191
+ raise InvalidEmail.new 'Please specify a :email option(email to send the test to)'
192
+ end
193
+
194
+ if @mailer_methods[mailer_method]
195
+ @mailer_methods[mailer_method].call(self.new, options)
196
+ else
197
+ raise InvalidMailerMethod.new "The mailer method: #{mailer_method} does not have test setup"
198
+ end
199
+
200
+ end
201
+
202
+ # Public: Triggers the stored Mandrill params to be sent to the Mandrill api
203
+ def deliver
204
+ mesg = "#{self.class.name}#deliver() is not implemented."
205
+ raise NotImplementedError.new(mesg)
206
+ end
207
+
208
+ # Public: Build the hash needed to send to the mandrill api
209
+ #
210
+ # args - The Hash options used to refine the selection:
211
+
212
+ # Examples
213
+ #
214
+ # mandrill_mail template: 'Group Invite',
215
+ # subject: I18n.t('invitation_mailer.invite.subject'),
216
+ # to: invitation.email,
217
+ # vars: {
218
+ # 'OWNER_NAME' => invitation.owner_name,
219
+ # 'INVITATION_URL' => new_invitation_url(email: invitation.email, secret: invitation.secret)
220
+ # }
221
+ #
222
+ # Returns the the mandrill mailer class (this is so you can chain #deliver like a normal mailer)
223
+ def mandrill_mail(args)
224
+ mesg = "#{self.class.name}#mandrill_mail() is not implemented."
225
+ raise NotImplementedError.new(mesg)
226
+ end
227
+
228
+ # Public: Data hash (deprecated)
229
+ def data
230
+ mesg = "#{self.class.name}#data() is not implemented."
231
+ raise NotImplementedError.new(mesg)
232
+ end
233
+
234
+ def check_required_options
235
+ mesg = "#{self.class.name}#check_required_options() is not implemented."
236
+ raise NotImplementedError.new(mesg)
237
+ end
238
+
239
+ def from
240
+ self.message && self.message['from_email']
241
+ end
242
+
243
+ def to
244
+ self.message && self.message['to']
245
+ end
246
+
247
+ def to=(values)
248
+ self.message && self.message['to'] = format_to_params(values)
249
+ end
250
+
251
+ def bcc
252
+ self.message && self.message['bcc_address']
253
+ end
254
+
255
+ protected
256
+
257
+ def mandrill_attachment_args(args)
258
+ return unless args
259
+ args.map do |attachment|
260
+ attachment.symbolize_keys!
261
+ type = attachment[:mimetype]
262
+ name = attachment[:filename]
263
+ file = attachment[:file]
264
+ {"type" => type, "name" => name, "content" => Base64.encode64(file)}
265
+ end
266
+ end
267
+
268
+ def mandrill_images_args(args)
269
+ return unless args
270
+ args.map do |attachment|
271
+ attachment.symbolize_keys!
272
+ type = attachment[:mimetype]
273
+ name = attachment[:filename]
274
+ file = attachment[:file]
275
+ {"type" => type, "name" => name, "content" => Base64.encode64(file)}
276
+ end
277
+ end
278
+
279
+ # Makes this class act as a singleton without it actually being a singleton
280
+ # This keeps the syntax the same as the orginal mailers so we can swap quickly if something
281
+ # goes wrong.
282
+ def self.method_missing(method, *args)
283
+ return super unless respond_to?(method)
284
+ new.method(method).call(*args)
285
+ end
286
+
287
+ def self.respond_to?(method, include_private = false)
288
+ super || instance_methods.include?(method.to_sym)
289
+ end
290
+
291
+ # Proxy route helpers to rails if Rails exists. Doing routes this way
292
+ # makes it so this gem doesn't need to be a rails engine
293
+ def method_missing(method, *args)
294
+ return super unless defined?(Rails) && Rails.application.routes.url_helpers.respond_to?(method)
295
+ # Check to see if one of the args is an open struct. If it is, we'll assume it's the
296
+ # test stub and try to call a path or url attribute.
297
+ if args.any? {|arg| arg.kind_of?(MandrillMailer::Mock)}
298
+ # take the first OpenStruct found in args and look for .url or.path
299
+ args.each do |arg|
300
+ if arg.kind_of?(MandrillMailer::Mock)
301
+ break arg.url || arg.path
302
+ end
303
+ end
304
+ else
305
+ options = args.extract_options!.merge({host: MandrillMailer.config.default_url_options[:host], protocol: MandrillMailer.config.default_url_options[:protocol]})
306
+ args << options
307
+ Rails.application.routes.url_helpers.method(method).call(*args)
308
+ end
309
+ end
310
+
311
+ def image_path(image)
312
+ if defined? Rails
313
+ ActionController::Base.helpers.asset_path(image)
314
+ else
315
+ method_missing(:image_path, image)
316
+ end
317
+ end
318
+
319
+ def image_url(image)
320
+ "#{root_url}#{image_path(image).split('/').reject!(&:empty?).join('/')}"
321
+ end
322
+
323
+ # convert a normal hash into the format mandrill needs
324
+ def mandrill_args(args)
325
+ return [] unless args
326
+ args.map do |k,v|
327
+ {'name' => k, 'content' => v}
328
+ end
329
+ end
330
+
331
+ def mandrill_rcpt_args(args)
332
+ return [] unless args
333
+ args.map do |item|
334
+ rcpt = item.keys[0]
335
+ {'rcpt' => rcpt, 'vars' => mandrill_args(item.fetch(rcpt))}
336
+ end
337
+ end
338
+
339
+ # ensure only true or false is returned given arg
340
+ def format_boolean(arg)
341
+ arg ? true : false
342
+ end
343
+
344
+ # handle if to params is an array of either hashes or strings or the single string
345
+ def format_to_params(to_params)
346
+ if to_params.kind_of? Array
347
+ to_params.map do |p|
348
+ to_params_item(p)
349
+ end
350
+ else
351
+ [to_params_item(to_params)]
352
+ end
353
+ end
354
+
355
+ # single to params item
356
+ def to_params_item(item)
357
+ return {"email" => item, "name" => item} unless item.kind_of? Hash
358
+ item
359
+ end
360
+
361
+ def api_key
362
+ MandrillMailer.config.api_key
363
+ end
364
+
365
+
366
+ end
367
+ end