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 +8 -8
- data/CHANGELOG.md +3 -0
- data/README.md +37 -0
- data/lib/mandrill_mailer.rb +1 -0
- data/lib/mandrill_mailer/core_mailer.rb +367 -0
- data/lib/mandrill_mailer/message_mailer.rb +212 -0
- data/lib/mandrill_mailer/template_mailer.rb +10 -233
- data/lib/mandrill_mailer/version.rb +1 -1
- data/spec/message_mailer_spec.rb +148 -0
- data/spec/template_mailer_spec.rb +65 -27
- metadata +6 -2
@@ -0,0 +1,212 @@
|
|
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::MessageMailer
|
7
|
+
# default from: 'support@codeschool.com'
|
8
|
+
|
9
|
+
# def invite(invitation)
|
10
|
+
# invitees = invitation.invitees.map { |invitee| { email: invitee.email, name: invitee.name } }
|
11
|
+
# mandrill_mail html: "<p>Example HTML content</p>",
|
12
|
+
# text: "Example text content",
|
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
|
+
# attachments: [{file: File.read(File.expand_path('assets/some_image.png')), filename: 'My Image.png', mimetype: 'image/png'}],
|
30
|
+
# important: true,
|
31
|
+
# inline_css: true
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
|
35
|
+
# #default:
|
36
|
+
# :from - set the default from email address for the mailer
|
37
|
+
|
38
|
+
# .mandrill_mail
|
39
|
+
# :html(required) - HTML codes for the Message
|
40
|
+
# :text - Text for the Message
|
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
|
+
# :attachments - An array of file objects with the following keys:
|
65
|
+
# file: This is the actual file, it will be converted to byte data in the mailer
|
66
|
+
# filename: The name of the file
|
67
|
+
# mimetype: This is the mimetype of the file. Ex. png = image/png, pdf = application/pdf, txt = text/plain etc
|
68
|
+
|
69
|
+
# :images - An array of embedded images to add to the message:
|
70
|
+
# file: This is the actual file, it will be converted to byte data in the mailer
|
71
|
+
# filename: The Content ID of the image - use <img src="cid:THIS_VALUE"> to reference the image in your HTML content
|
72
|
+
# mimetype: The MIME type of the image - must start with "image/"
|
73
|
+
|
74
|
+
# :headers - Extra headers to add to the message (currently only Reply-To and X-* headers are allowed) {"...": "..."}
|
75
|
+
|
76
|
+
# :bcc - Add an email to bcc to
|
77
|
+
|
78
|
+
# :tags - Array of Strings to tag the message with. Stats are
|
79
|
+
# accumulated using tags, though we only store the first 100 we see,
|
80
|
+
# so this should not be unique or change frequently. Tags should be
|
81
|
+
# 50 characters or less. Any tags starting with an underscore are
|
82
|
+
# reserved for internal use and will cause errors.
|
83
|
+
|
84
|
+
# :google_analytics_domains - Array of Strings indicating for which any
|
85
|
+
# matching URLs will automatically have Google Analytics parameters appended
|
86
|
+
# to their query string automatically.
|
87
|
+
|
88
|
+
# :google_analytics_campaign - String indicating the value to set for
|
89
|
+
# the utm_campaign tracking parameter. If this isn't provided the email's
|
90
|
+
# from address will be used instead.
|
91
|
+
|
92
|
+
# :inline_css - whether or not to automatically inline all CSS styles provided in the
|
93
|
+
# message HTML - only for HTML documents less than 256KB in size
|
94
|
+
|
95
|
+
# :important - whether or not this message is important, and should be delivered ahead of non-important messages
|
96
|
+
require 'base64'
|
97
|
+
require 'mandrill_mailer/core_mailer'
|
98
|
+
|
99
|
+
module MandrillMailer
|
100
|
+
class MessageMailer < MandrillMailer::CoreMailer
|
101
|
+
# Public: The name of the template to use
|
102
|
+
attr_accessor :html
|
103
|
+
|
104
|
+
# Public: Template content
|
105
|
+
attr_accessor :text
|
106
|
+
|
107
|
+
# Public: Triggers the stored Mandrill params to be sent to the Mandrill api
|
108
|
+
def deliver
|
109
|
+
mandrill = Mandrill::API.new(api_key)
|
110
|
+
check_required_options(message)
|
111
|
+
mandrill.messages.send(message, async, ip_pool, send_at)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Public: Build the hash needed to send to the mandrill api
|
115
|
+
#
|
116
|
+
# args - The Hash options used to refine the selection:
|
117
|
+
# :template - Template name in Mandrill
|
118
|
+
# :subject - Subject of the email
|
119
|
+
# :to - Email to send the mandrill email to
|
120
|
+
# :vars - Global merge vars used in the email for dynamic data
|
121
|
+
# :recipient_vars - Merge vars used in the email for recipient-specific dynamic data
|
122
|
+
# :bcc - bcc email for the mandrill email
|
123
|
+
# :tags - Tags for the email
|
124
|
+
# :google_analytics_domains - Google analytics domains
|
125
|
+
# :google_analytics_campaign - Google analytics campaign
|
126
|
+
# :inline_css - whether or not to automatically inline all CSS styles provided in the message HTML
|
127
|
+
# :important - whether or not this message is important
|
128
|
+
# :async - whether or not this message should be sent asynchronously
|
129
|
+
# :ip_pool - name of the dedicated IP pool that should be used to send the message
|
130
|
+
# :send_at - when this message should be sent
|
131
|
+
#
|
132
|
+
# Examples
|
133
|
+
#
|
134
|
+
# mandrill_mail template: 'Group Invite',
|
135
|
+
# subject: I18n.t('invitation_mailer.invite.subject'),
|
136
|
+
# to: invitation.email,
|
137
|
+
# vars: {
|
138
|
+
# 'OWNER_NAME' => invitation.owner_name,
|
139
|
+
# 'INVITATION_URL' => new_invitation_url(email: invitation.email, secret: invitation.secret)
|
140
|
+
# }
|
141
|
+
#
|
142
|
+
# Returns the the mandrill mailer class (this is so you can chain #deliver like a normal mailer)
|
143
|
+
def mandrill_mail(args)
|
144
|
+
# format the :to param to what Mandrill expects if a string or array is passed
|
145
|
+
args[:to] = format_to_params(args[:to])
|
146
|
+
|
147
|
+
self.async = args.delete(:async)
|
148
|
+
self.ip_pool = args.delete(:ip_pool)
|
149
|
+
if args.has_key?(:send_at)
|
150
|
+
self.send_at = args.delete(:send_at).getutc.strftime('%Y-%m-%d %H:%M:%S')
|
151
|
+
end
|
152
|
+
|
153
|
+
# Construct message hash
|
154
|
+
self.message = {
|
155
|
+
"text" => args[:text],
|
156
|
+
"html" => args[:html],
|
157
|
+
"view_content_link" => args[:view_content_link],
|
158
|
+
"subject" => args[:subject],
|
159
|
+
"from_email" => args[:from] || self.class.defaults[:from],
|
160
|
+
"from_name" => args[:from_name] || self.class.defaults[:from_name] || self.class.defaults[:from],
|
161
|
+
"to" => args[:to],
|
162
|
+
"headers" => args[:headers],
|
163
|
+
"important" => args[:important],
|
164
|
+
"track_opens" => args.fetch(:track_opens, true),
|
165
|
+
"track_clicks" => args.fetch(:track_clicks, true),
|
166
|
+
"auto_text" => true,
|
167
|
+
"inline_css" => args[:inline_css],
|
168
|
+
"url_strip_qs" => args.fetch(:url_strip_qs, true),
|
169
|
+
"preserve_recipients" => args[:preserve_recipients],
|
170
|
+
"bcc_address" => args[:bcc],
|
171
|
+
"global_merge_vars" => mandrill_args(args[:vars]),
|
172
|
+
"merge_vars" => mandrill_rcpt_args(args[:recipient_vars]),
|
173
|
+
"tags" => args[:tags],
|
174
|
+
"subaccount" => args[:subaccount],
|
175
|
+
"google_analytics_domains" => args[:google_analytics_domains],
|
176
|
+
"google_analytics_campaign" => args[:google_analytics_campaign],
|
177
|
+
"metadata" => args[:metadata],
|
178
|
+
"attachments" => mandrill_attachment_args(args[:attachments]),
|
179
|
+
"images" => mandrill_images_args(args[:images])
|
180
|
+
}
|
181
|
+
|
182
|
+
unless MandrillMailer.config.interceptor_params.nil?
|
183
|
+
unless MandrillMailer.config.interceptor_params.is_a?(Hash)
|
184
|
+
raise InvalidInterceptorParams.new "The interceptor_params config must be a Hash"
|
185
|
+
end
|
186
|
+
self.message.merge!(MandrillMailer.config.interceptor_params.stringify_keys)
|
187
|
+
end
|
188
|
+
|
189
|
+
# return self so we can chain deliver after the method call, like a normal mailer.
|
190
|
+
return self
|
191
|
+
end
|
192
|
+
|
193
|
+
# Public: Data hash (deprecated)
|
194
|
+
def data
|
195
|
+
{
|
196
|
+
"key" => api_key,
|
197
|
+
"message" => message,
|
198
|
+
"async" => async,
|
199
|
+
"ip_pool" => ip_pool,
|
200
|
+
"send_at" => send_at
|
201
|
+
}
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
def check_required_options(options)
|
206
|
+
names = ['text', 'html', 'from', 'subject', 'to']
|
207
|
+
names.each do |name|
|
208
|
+
warn("Mandrill Mailer Warn: missing required option: #{name}") unless options.has_key?(name)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
@@ -99,93 +99,10 @@
|
|
99
99
|
|
100
100
|
# :important - whether or not this message is important, and should be delivered ahead of non-important messages
|
101
101
|
require 'base64'
|
102
|
+
require 'mandrill_mailer/core_mailer'
|
102
103
|
|
103
104
|
module MandrillMailer
|
104
|
-
class TemplateMailer
|
105
|
-
# include Rails.application.routes.url_helpers
|
106
|
-
include ActionView::Helpers::NumberHelper
|
107
|
-
|
108
|
-
|
109
|
-
class InvalidEmail < StandardError; end
|
110
|
-
class InvalidMailerMethod < StandardError; end
|
111
|
-
class InvalidInterceptorParams < StandardError; end
|
112
|
-
|
113
|
-
# Public: Defaults for the mailer. Currently the only option is from:
|
114
|
-
#
|
115
|
-
# options - The Hash options used to refine the selection (default: {}):
|
116
|
-
# :from - Default from email address
|
117
|
-
#
|
118
|
-
# Examples
|
119
|
-
#
|
120
|
-
# default from: 'foo@bar.com'
|
121
|
-
#
|
122
|
-
# Returns options
|
123
|
-
def self.defaults
|
124
|
-
@defaults || super_defaults
|
125
|
-
end
|
126
|
-
|
127
|
-
def self.super_defaults
|
128
|
-
superclass.defaults if superclass.respond_to?(:defaults)
|
129
|
-
end
|
130
|
-
|
131
|
-
def self.default(args)
|
132
|
-
@defaults ||= {}
|
133
|
-
@defaults[:from] ||= 'example@email.com'
|
134
|
-
@defaults.merge!(args)
|
135
|
-
end
|
136
|
-
class << self
|
137
|
-
attr_writer :defaults
|
138
|
-
end
|
139
|
-
|
140
|
-
# Public: setup a way to test mailer methods
|
141
|
-
#
|
142
|
-
# mailer_method - Name of the mailer method the test setup is for
|
143
|
-
#
|
144
|
-
# block - Block of code to execute to perform the test. The mailer
|
145
|
-
# and options are passed to the block. The options have to
|
146
|
-
# contain at least the :email to send the test to.
|
147
|
-
#
|
148
|
-
# Examples
|
149
|
-
#
|
150
|
-
# test_setup_for :invite do |mailer, options|
|
151
|
-
# invitation = OpenStruct.new({
|
152
|
-
# email: options[:email],
|
153
|
-
# owner_name: 'foobar',
|
154
|
-
# secret: rand(9000000..1000000).to_s
|
155
|
-
# })
|
156
|
-
# mailer.invite(invitation).deliver
|
157
|
-
# end
|
158
|
-
#
|
159
|
-
# Returns the duplicated String.
|
160
|
-
def self.test_setup_for(mailer_method, &block)
|
161
|
-
@mailer_methods ||= {}
|
162
|
-
@mailer_methods[mailer_method] = block
|
163
|
-
end
|
164
|
-
|
165
|
-
# Public: Executes a test email
|
166
|
-
#
|
167
|
-
# mailer_method - Method to execute
|
168
|
-
#
|
169
|
-
# options - The Hash options used to refine the selection (default: {}):
|
170
|
-
# :email - The email to send the test to.
|
171
|
-
#
|
172
|
-
# Examples
|
173
|
-
#
|
174
|
-
# InvitationMailer.test(:invite, email: 'benny@envylabs.com')
|
175
|
-
#
|
176
|
-
# Returns the duplicated String.
|
177
|
-
def self.test(mailer_method, options={})
|
178
|
-
unless options[:email]
|
179
|
-
raise InvalidEmail.new 'Please specify a :email option(email to send the test to)'
|
180
|
-
end
|
181
|
-
|
182
|
-
if @mailer_methods[mailer_method]
|
183
|
-
@mailer_methods[mailer_method].call(self.new, options)
|
184
|
-
else
|
185
|
-
raise InvalidMailerMethod.new "The mailer method: #{mailer_method} does not have test setup"
|
186
|
-
end
|
187
|
-
|
188
|
-
end
|
105
|
+
class TemplateMailer < MandrillMailer::CoreMailer
|
189
106
|
|
190
107
|
# Public: The name of the template to use
|
191
108
|
attr_accessor :template_name
|
@@ -193,31 +110,10 @@ module MandrillMailer
|
|
193
110
|
# Public: Template content
|
194
111
|
attr_accessor :template_content
|
195
112
|
|
196
|
-
# Public:
|
197
|
-
attr_accessor :message
|
198
|
-
|
199
|
-
# Public: Enable background sending mode
|
200
|
-
attr_accessor :async
|
201
|
-
|
202
|
-
# Public: Name of the dedicated IP pool that should be used to send the message
|
203
|
-
attr_accessor :ip_pool
|
204
|
-
|
205
|
-
# Public: When message should be sent
|
206
|
-
attr_accessor :send_at
|
207
|
-
|
208
|
-
# Public: Triggers the stored Mandril params to be sent to the Mandrill api
|
209
|
-
#
|
210
|
-
# text - The String to be duplicated.
|
211
|
-
# count - The Integer number of times to duplicate the text.
|
212
|
-
#
|
213
|
-
# Examples
|
214
|
-
#
|
215
|
-
# multiplex('Tom', 4)
|
216
|
-
# # => 'TomTomTomTom'
|
217
|
-
#
|
218
|
-
# Returns the duplicated String.
|
113
|
+
# Public: Triggers the stored Mandrill params to be sent to the Mandrill api
|
219
114
|
def deliver
|
220
115
|
mandrill = Mandrill::API.new(api_key)
|
116
|
+
check_required_options(message)
|
221
117
|
mandrill.messages.send_template(template_name, template_content, message, async, ip_pool, send_at)
|
222
118
|
end
|
223
119
|
|
@@ -263,9 +159,9 @@ module MandrillMailer
|
|
263
159
|
|
264
160
|
# Set the template content
|
265
161
|
self.template_content = mandrill_args(args.delete(:template_content))
|
266
|
-
|
267
162
|
self.async = args.delete(:async)
|
268
163
|
self.ip_pool = args.delete(:ip_pool)
|
164
|
+
|
269
165
|
if args.has_key?(:send_at)
|
270
166
|
self.send_at = args.delete(:send_at).getutc.strftime('%Y-%m-%d %H:%M:%S')
|
271
167
|
end
|
@@ -295,7 +191,6 @@ module MandrillMailer
|
|
295
191
|
"attachments" => mandrill_attachment_args(args[:attachments]),
|
296
192
|
"images" => mandrill_images_args(args[:images])
|
297
193
|
}
|
298
|
-
|
299
194
|
unless MandrillMailer.config.interceptor_params.nil?
|
300
195
|
unless MandrillMailer.config.interceptor_params.is_a?(Hash)
|
301
196
|
raise InvalidInterceptorParams.new "The interceptor_params config must be a Hash"
|
@@ -320,130 +215,12 @@ module MandrillMailer
|
|
320
215
|
}
|
321
216
|
end
|
322
217
|
|
323
|
-
def
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
self.message && self.message['to']
|
329
|
-
end
|
330
|
-
|
331
|
-
def to=(values)
|
332
|
-
self.message && self.message['to'] = format_to_params(values)
|
333
|
-
end
|
334
|
-
|
335
|
-
def bcc
|
336
|
-
self.message && self.message['bcc_address']
|
337
|
-
end
|
338
|
-
|
339
|
-
protected
|
340
|
-
|
341
|
-
def mandrill_attachment_args(args)
|
342
|
-
return unless args
|
343
|
-
args.map do |attachment|
|
344
|
-
attachment.symbolize_keys!
|
345
|
-
type = attachment[:mimetype]
|
346
|
-
name = attachment[:filename]
|
347
|
-
file = attachment[:file]
|
348
|
-
{"type" => type, "name" => name, "content" => Base64.encode64(file)}
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
|
-
def mandrill_images_args(args)
|
353
|
-
return unless args
|
354
|
-
args.map do |attachment|
|
355
|
-
attachment.symbolize_keys!
|
356
|
-
type = attachment[:mimetype]
|
357
|
-
name = attachment[:filename]
|
358
|
-
file = attachment[:file]
|
359
|
-
{"type" => type, "name" => name, "content" => Base64.encode64(file)}
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
# Makes this class act as a singleton without it actually being a singleton
|
364
|
-
# This keeps the syntax the same as the orginal mailers so we can swap quickly if something
|
365
|
-
# goes wrong.
|
366
|
-
def self.method_missing(method, *args)
|
367
|
-
return super unless respond_to?(method)
|
368
|
-
new.method(method).call(*args)
|
369
|
-
end
|
370
|
-
|
371
|
-
def self.respond_to?(method, include_private = false)
|
372
|
-
super || instance_methods.include?(method.to_sym)
|
373
|
-
end
|
374
|
-
|
375
|
-
# Proxy route helpers to rails if Rails exists. Doing routes this way
|
376
|
-
# makes it so this gem doesn't need to be a rails engine
|
377
|
-
def method_missing(method, *args)
|
378
|
-
return super unless defined?(Rails) && Rails.application.routes.url_helpers.respond_to?(method)
|
379
|
-
# Check to see if one of the args is an open struct. If it is, we'll assume it's the
|
380
|
-
# test stub and try to call a path or url attribute.
|
381
|
-
if args.any? {|arg| arg.kind_of?(MandrillMailer::Mock)}
|
382
|
-
# take the first OpenStruct found in args and look for .url or.path
|
383
|
-
args.each do |arg|
|
384
|
-
if arg.kind_of?(MandrillMailer::Mock)
|
385
|
-
break arg.url || arg.path
|
386
|
-
end
|
387
|
-
end
|
388
|
-
else
|
389
|
-
options = args.extract_options!.merge({host: MandrillMailer.config.default_url_options[:host], protocol: MandrillMailer.config.default_url_options[:protocol]})
|
390
|
-
args << options
|
391
|
-
Rails.application.routes.url_helpers.method(method).call(*args)
|
392
|
-
end
|
393
|
-
end
|
394
|
-
|
395
|
-
def image_path(image)
|
396
|
-
if defined? Rails
|
397
|
-
ActionController::Base.helpers.asset_path(image)
|
398
|
-
else
|
399
|
-
method_missing(:image_path, image)
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
def image_url(image)
|
404
|
-
"#{root_url}#{image_path(image).split('/').reject!(&:empty?).join('/')}"
|
405
|
-
end
|
406
|
-
|
407
|
-
# convert a normal hash into the format mandrill needs
|
408
|
-
def mandrill_args(args)
|
409
|
-
return [] unless args
|
410
|
-
args.map do |k,v|
|
411
|
-
{'name' => k, 'content' => v}
|
412
|
-
end
|
413
|
-
end
|
414
|
-
|
415
|
-
def mandrill_rcpt_args(args)
|
416
|
-
return [] unless args
|
417
|
-
args.map do |item|
|
418
|
-
rcpt = item.keys[0]
|
419
|
-
{'rcpt' => rcpt, 'vars' => mandrill_args(item.fetch(rcpt))}
|
218
|
+
def check_required_options(options)
|
219
|
+
names = ['to', 'from', 'subject']
|
220
|
+
|
221
|
+
names.each do |name|
|
222
|
+
warn("Mandrill Mailer Warn: missing required option: #{name}") unless options.has_key?(name)
|
420
223
|
end
|
421
224
|
end
|
422
|
-
|
423
|
-
# ensure only true or false is returned given arg
|
424
|
-
def format_boolean(arg)
|
425
|
-
arg ? true : false
|
426
|
-
end
|
427
|
-
|
428
|
-
# handle if to params is an array of either hashes or strings or the single string
|
429
|
-
def format_to_params(to_params)
|
430
|
-
if to_params.kind_of? Array
|
431
|
-
to_params.map do |p|
|
432
|
-
to_params_item(p)
|
433
|
-
end
|
434
|
-
else
|
435
|
-
[to_params_item(to_params)]
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
|
-
# single to params item
|
440
|
-
def to_params_item(item)
|
441
|
-
return {"email" => item, "name" => item} unless item.kind_of? Hash
|
442
|
-
item
|
443
|
-
end
|
444
|
-
|
445
|
-
def api_key
|
446
|
-
MandrillMailer.config.api_key
|
447
|
-
end
|
448
225
|
end
|
449
226
|
end
|