mandrill_mailer 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ mandrill_mailer-0.0.1.gem
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # Mandrill Mailer gem
2
+ MandrilMailer class for sending transactional emails through mandril.
3
+ Only template based emails are supported at this time.
4
+
5
+ ## Usage
6
+ Add `gem 'mandrill_mailer'` to your Gemfile
7
+
8
+ Add this to your `mail.rb` in initializers:
9
+
10
+ ```
11
+ ActionMailer::Base.smtp_settings = {
12
+ :address => "smtp.mandrillapp.com",
13
+ :port => 587,
14
+ :user_name => ENV['MANDRILL_USERNAME'],
15
+ :password => ENV['MANDRILL_PASSWORD'],
16
+ :domain => 'heroku.com'
17
+ }
18
+ ActionMailer::Base.delivery_method = :smtp
19
+ MandrillMailer.api_key = ENV['MANDRILL_API_KEY']
20
+ ```
21
+
22
+ Don't forget to setup your ENV variables on your server
23
+
24
+ ## Creating a new mailer
25
+ Creating a new Mandrill Mailer is similar to a normal Rails mailer:
26
+
27
+ ```
28
+ class InvitationMailer < MandrillMailer
29
+ default from: 'support@example.com'
30
+
31
+ def invite(invitation)
32
+ mandrill_mail template: 'Group Invite',
33
+ subject: I18n.t('invitation_mailer.invite.subject'),
34
+ to: {email: invitation.email, name: 'Honored Guest'},
35
+ vars: {
36
+ 'OWNER_NAME' => invitation.owner_name,
37
+ 'INVITATION_URL' => new_invitation_url(email: invitation.email, secret: invitation.secret)
38
+ }
39
+ end
40
+ end
41
+ ```
42
+
43
+ * `#default:`
44
+ * `:from` - set the default from email address for the mailer
45
+
46
+ * `.mandrill_mail`
47
+ * `:template`(required) - Template name from within Mandrill
48
+
49
+ * `:subject`(required) - Subject of the email
50
+
51
+ * `:to`(required) - Accepts an email String, or hash with :name and :email keys
52
+ ex. `{email: 'someone@email.com', name: 'Bob Bertly'}`
53
+
54
+ * `:vars` - A Hash of merge tags made available to the email. Use them in the
55
+ email by wrapping them in `*||*` vars: {'OWNER_NAME' => 'Suzy'} is used
56
+ by doing: `*|OWNER_NAME|*` in the email template within Mandrill
57
+
58
+ * `:template_content` - A Hash of values and content for Mandrill editable content blocks.
59
+ In MailChimp templates there are editable regions with 'mc:edit' attributes that look
60
+ a little like: `<div mc:edit="header">My email content</div>` You can insert content directly into
61
+ these fields by passing a Hash `{'header' => 'my email content'}`
62
+
63
+ * `:headers` - Extra headers to add to the message (currently only Reply-To and X-* headers are allowed) {"...": "..."}
64
+
65
+ * `:bcc` - Add an email to bcc to
66
+
67
+ * `:tags` - Array of Strings to tag the message with. Stats are
68
+ accumulated using tags, though we only store the first 100 we see,
69
+ so this should not be unique or change frequently. Tags should be
70
+ 50 characters or less. Any tags starting with an underscore are
71
+ reserved for internal use and will cause errors.
72
+
73
+ * `:google_analytics_domains` - Array of Strings indicating for which any
74
+ matching URLs will automatically have Google Analytics parameters appended
75
+ to their query string automatically.
76
+
77
+ * `:google_analytics_campaign` - String indicating the value to set for
78
+ the utm_campaign tracking parameter. If this isn't provided the email's
79
+ from address will be used instead.
80
+
81
+ ## Sending an email
82
+
83
+ You can send the email by using the familiar syntax:
84
+
85
+ `InvitationMailer.invite(invitation).deliver`
86
+
87
+ ## Creating a test method
88
+ When switching over to Mandrill for transactional emails we found that it was hard to setup a mailer in the console to send test emails easily (those darn designers), but really, you don't want to have to setup test objects everytime you want to send a test email. You can set up a testing 'stub' once and then call the `.test` method to send the test email.
89
+
90
+ You can test the above email by typing: `InvitationMailer.test(:invite, email:<your email>)` into the Rails Console.
91
+
92
+ The test for this particular Mailer is setup like so:
93
+
94
+ ```
95
+ test_setup_for :invite do |mailer, options|
96
+ invitation = OpenStruct.new({
97
+ email: options[:email],
98
+ owner_name: 'foobar',
99
+ secret: rand(9000000..1000000).to_s
100
+ })
101
+ mailer.invite(invitation).deliver
102
+ end
103
+ ```
104
+
105
+ The mailer and options passed to the `.test` method are yielded to the block.
106
+
107
+ The `:email` option is the only required option, make sure to add at least this to your test object.
108
+
109
+ ## Helper Methods
110
+ * `.test_friendly_url`(object, route helper as a symbol) - This helper is used for using route helpers, but still staying compatible with using OpenStructs for stubing out the mailing test objects (there is probably a much better way of doing this)
@@ -0,0 +1,297 @@
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
7
+ # default from: 'support@codeschool.com'
8
+
9
+ # def invite(invitation)
10
+ # mandrill_mail template: 'Group Invite',
11
+ # subject: I18n.t('invitation_mailer.invite.subject'),
12
+ # to: {email: invitation.email, name: 'user level 1'},
13
+ # vars: {
14
+ # 'OWNER_NAME' => invitation.owner_name,
15
+ # 'INVITATION_URL' => new_invitation_url(email: invitation.email, secret: invitation.secret)
16
+ # },
17
+ # template_content: {}
18
+ # end
19
+ # end
20
+
21
+ # #default:
22
+ # :from - set the default from email address for the mailer
23
+
24
+ # .mandrill_mail
25
+ # :template(required) - Template name from within Mandrill
26
+
27
+ # :subject(required) - Subject of the email
28
+
29
+ # :to(required) - Accepts an email String, or hash with :name and :email keys
30
+ # ex. {email: 'someone@email.com', name: 'Bob Bertly'}
31
+
32
+ # :vars - A Hash of merge tags made available to the email. Use them in the
33
+ # email by wrapping them in '*||*' vars: {'OWNER_NAME' => 'Suzy'} is used
34
+ # by doing: *|OWNER_NAME|* in the email template within Mandrill
35
+
36
+ # :template_content - A Hash of values and content for Mandrill editable content blocks.
37
+ # In MailChimp templates there are editable regions with 'mc:edit' attributes that look
38
+ # a little like: '<div mc:edit="header">My email content</div>' You can insert content directly into
39
+ # these fields by passing a Hash {'header' => 'my email content'}
40
+
41
+ # :headers - Extra headers to add to the message (currently only Reply-To and X-* headers are allowed) {"...": "..."}
42
+
43
+ # :bcc - Add an email to bcc to
44
+
45
+ # :tags - Array of Strings to tag the message with. Stats are
46
+ # accumulated using tags, though we only store the first 100 we see,
47
+ # so this should not be unique or change frequently. Tags should be
48
+ # 50 characters or less. Any tags starting with an underscore are
49
+ # reserved for internal use and will cause errors.
50
+
51
+ # :google_analytics_domains - Array of Strings indicating for which any
52
+ # matching URLs will automatically have Google Analytics parameters appended
53
+ # to their query string automatically.
54
+
55
+ # :google_analytics_campaign - String indicating the value to set for
56
+ # the utm_campaign tracking parameter. If this isn't provided the email's
57
+ # from address will be used instead.
58
+
59
+
60
+ class MandrillMailer
61
+ include Rails.application.routes.url_helpers
62
+ include ActionView::Helpers::NumberHelper
63
+
64
+ # Public: Defaults for the mailer. Currently the only option is from:
65
+ #
66
+ # options - The Hash options used to refine the selection (default: {}):
67
+ # :from - Default from email address
68
+ #
69
+ # Examples
70
+ #
71
+ # default from: 'foo@bar.com'
72
+ #
73
+ # Returns options
74
+ def self.default(args)
75
+ @@defaults ||= {}
76
+ @@defaults[:from] ||= 'example@email.com'
77
+ @@defaults.merge!(args)
78
+ end
79
+
80
+ # Public: setup a way to test mailer methods
81
+ #
82
+ # mailer_method - Name of the mailer method the test setup is for
83
+ # block - Block of code to execute to perform the test. The mailer
84
+ # and options are passed to the block. The options have to
85
+ # contain at least the :email to send the test to.
86
+ #
87
+ # Examples
88
+ #
89
+ # test_setup_for :invite do |mailer, options|
90
+ # invitation = OpenStruct.new({
91
+ # email: options[:email],
92
+ # owner_name: 'foobar',
93
+ # secret: rand(9000000..1000000).to_s
94
+ # })
95
+ # mailer.invite(invitation).deliver
96
+ # end
97
+ #
98
+ # Returns the duplicated String.
99
+ def self.test_setup_for(mailer_method, &block)
100
+ @@mailer_methods ||= {}
101
+ @@mailer_methods[mailer_method] = block
102
+ end
103
+
104
+ # Public: Executes a test email
105
+ #
106
+ # mailer_method - Method to execute
107
+ # options - The Hash options used to refine the selection (default: {}):
108
+ # :email - The email to send the test to.
109
+ #
110
+ # Examples
111
+ #
112
+ # InvitationMailer.test(:invite, email: 'benny@envylabs.com')
113
+ #
114
+ # Returns the duplicated String.
115
+ def self.test(mailer_method, options={})
116
+ unless options[:email]
117
+ raise Exception 'Please specify a :email option(email to send the test to)'
118
+ end
119
+
120
+ if @@mailer_methods[mailer_method]
121
+ @@mailer_methods[mailer_method].call(self.new, options)
122
+ else
123
+ raise Exception "The mailer method: #{mailer_method} does not have test setup"
124
+ end
125
+
126
+ end
127
+
128
+ # Public: this enables the api key to be set in an initializer
129
+ # ex. MandrillMailer.api_key = ENV[MANDRILL_API_KEY]
130
+ #
131
+ # key - Api key for the Mandrill api
132
+ #
133
+ #
134
+ # Returns the key(String)
135
+ def self.api_key=(key)
136
+ @@api_key = key
137
+ end
138
+
139
+ # Public: Triggers the stored Mandril params to be sent to the Mandrill api
140
+ #
141
+ # text - The String to be duplicated.
142
+ # count - The Integer number of times to duplicate the text.
143
+ #
144
+ # Examples
145
+ #
146
+ # multiplex('Tom', 4)
147
+ # # => 'TomTomTomTom'
148
+ #
149
+ # Returns the duplicated String.
150
+ def deliver
151
+ mandrill = Mailchimp::Mandrill.new(api_key)
152
+ mandrill.messages_send_template(@data)
153
+ end
154
+
155
+ protected
156
+
157
+ # Public: Url helper for creating OpenStruct compatible urls
158
+ # This is used for making sure urls will still work with
159
+ # OpenStructs used in the email testing code
160
+ #
161
+ # OpenStruct should have a .url property to work with this
162
+ #
163
+ # object - Object that would normally be passed into the route helper
164
+ # route_helper - The route helper as a symbol needed for the url
165
+ #
166
+ # Examples
167
+ #
168
+ # 'VIDEO_URL' => open_struct_url(video, :code_tv_video_url)
169
+ #
170
+ # Returns the url as a string
171
+ def test_friendly_url(object, route_helper)
172
+ if object.kind_of? OpenStruct
173
+ object.url
174
+ else
175
+ method(route_helper).call(object)
176
+ end
177
+ end
178
+
179
+ # Makes this class act as a singleton without it actually being a singleton
180
+ # This keeps the syntax the same as the orginal mailers so we can swap quickly if something
181
+ # goes wrong.
182
+ def self.method_missing(method, *args)
183
+ return super unless respond_to?(method)
184
+ new.method(method).call(*args)
185
+ end
186
+
187
+ def self.respond_to?(method, include_private = false)
188
+ super || instance_methods.include?(method)
189
+ end
190
+
191
+ # Public: Build the hash needed to send to the mandrill api
192
+ #
193
+ # args - The Hash options used to refine the selection:
194
+ # :template - Template name in Mandrill
195
+ # :subject - Subject of the email
196
+ # :to - Email to send the mandrill email to
197
+ # :vars - Merge vars used in the email for dynamic data
198
+ # :bcc - bcc email for the mandrill email
199
+ # :tags - Tags for the email
200
+ # :google_analytics_domains - Google analytics domains
201
+ # :google_analytics_campaign - Google analytics campaign
202
+ #
203
+ # Examples
204
+ #
205
+ # mandrill_mail template: 'Group Invite',
206
+ # subject: I18n.t('invitation_mailer.invite.subject'),
207
+ # to: invitation.email,
208
+ # vars: {
209
+ # 'OWNER_NAME' => invitation.owner_name,
210
+ # 'INVITATION_URL' => new_invitation_url(email: invitation.email, secret: invitation.secret)
211
+ # }
212
+ #
213
+ # Returns the the mandrill mailer class (this is so you can chain #deliver like a normal mailer)
214
+ def mandrill_mail(args)
215
+
216
+ # Mandrill requires template content to be there
217
+ args[:template_content] = {"blank" => ""} if args[:template_content].blank?
218
+
219
+ # format the :to param to what Mandrill expects if a string or array is passed
220
+ args[:to] = format_to_params(args[:to])
221
+
222
+ @data = {"key" => api_key,
223
+ "template_name" => args[:template],
224
+ "template_content" => mandrill_args(args[:template_content]),
225
+ "message" => {
226
+ "subject" => args[:subject],
227
+ "from_email" => args[:from] || @@defaults[:from],
228
+ "from_name" => args[:from_name] || @@defaults[:from],
229
+ "to" => args[:to],
230
+ "headers" => args[:headers],
231
+ "track_opens" => true,
232
+ "track_clicks" => true,
233
+ "auto_text" => true,
234
+ "url_strip_qs" => true,
235
+ "bcc_address" => args[:bcc],
236
+ "global_merge_vars" => mandrill_args(args[:vars]),
237
+ # "merge_vars" =>[
238
+ # {
239
+ # "rcpt" => "email@email.com"
240
+ # "vars" => {"name" => "VARS", "content" => "vars content"}
241
+ # }
242
+ # ]
243
+
244
+ "tags" => args[:tags],
245
+ "google_analytics_domains" => args[:google_analytics_domains],
246
+ "google_analytics_campaign" => args[:google_analytics_campaign]
247
+ # "metadata" =>["..."],
248
+ # "attachments" =>[
249
+ # {"type" => "example type", "name" => "example name", "content" => "example content"}
250
+ # ]
251
+ }
252
+ }
253
+
254
+ # return self so we can chain deliver after the method call, like a normal mailer.
255
+ return self
256
+ end
257
+
258
+ def data
259
+ @data
260
+ end
261
+
262
+ def image_path(image)
263
+ ActionController::Base.helpers.asset_path(image)
264
+ end
265
+
266
+ def image_url(image)
267
+ "#{root_url}#{image_path(image).split('/').reject!(&:empty?).join('/')}"
268
+ end
269
+
270
+ # convert a normal hash into the format mandrill needs
271
+ def mandrill_args(args)
272
+ args.map do |k,v|
273
+ {'name' => k, 'content' => v}
274
+ end
275
+ end
276
+
277
+ # handle if to params is an array of either hashes or strings or the single string
278
+ def format_to_params(to_params)
279
+ if to_params.kind_of? Array
280
+ to_params.map do |p|
281
+ to_params_item(p)
282
+ end
283
+ else
284
+ [to_params_item(to_params)]
285
+ end
286
+ end
287
+
288
+ # single to params item
289
+ def to_params_item(item)
290
+ return {"email" => item, "name" => "Code School Customer"} unless item.kind_of? Hash
291
+ item
292
+ end
293
+
294
+ def api_key
295
+ @@api_key || ''
296
+ end
297
+ end
@@ -0,0 +1,3 @@
1
+ module MandrillMailer
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,5 @@
1
+ require 'mandrill_mailer/mandrill_mailer'
2
+
3
+ module MandrillMailer
4
+
5
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mandrill_mailer/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "mandrill_mailer"
7
+ s.version = MandrillMailer::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Adam Rensel"]
10
+ s.email = ["adamrensel@codeschool.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Transactional Mailer for Mandrill}
13
+ s.description = %q{Transactional Mailer for Mandrill}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mandrill_mailer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam Rensel
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-24 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Transactional Mailer for Mandrill
15
+ email:
16
+ - adamrensel@codeschool.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - README.md
24
+ - lib/mandrill_mailer.rb
25
+ - lib/mandrill_mailer/mandrill_mailer.rb
26
+ - lib/mandrill_mailer/version.rb
27
+ - mandrill_mailer.gemspec
28
+ homepage: ''
29
+ licenses: []
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 1.8.24
49
+ signing_key:
50
+ specification_version: 3
51
+ summary: Transactional Mailer for Mandrill
52
+ test_files: []