mandrill_mailer 0.0.1 → 0.0.2

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/Gemfile.lock ADDED
@@ -0,0 +1,66 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mandrill_mailer (0.0.2)
5
+ actionpack
6
+ activesupport
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ actionpack (3.2.8)
12
+ activemodel (= 3.2.8)
13
+ activesupport (= 3.2.8)
14
+ builder (~> 3.0.0)
15
+ erubis (~> 2.7.0)
16
+ journey (~> 1.0.4)
17
+ rack (~> 1.4.0)
18
+ rack-cache (~> 1.2)
19
+ rack-test (~> 0.6.1)
20
+ sprockets (~> 2.1.3)
21
+ activemodel (3.2.8)
22
+ activesupport (= 3.2.8)
23
+ builder (~> 3.0.0)
24
+ activesupport (3.2.8)
25
+ i18n (~> 0.6)
26
+ multi_json (~> 1.0)
27
+ builder (3.0.3)
28
+ coderay (1.0.7)
29
+ diff-lcs (1.1.3)
30
+ erubis (2.7.0)
31
+ hike (1.2.1)
32
+ i18n (0.6.1)
33
+ journey (1.0.4)
34
+ method_source (0.8)
35
+ multi_json (1.3.6)
36
+ pry (0.9.10)
37
+ coderay (~> 1.0.5)
38
+ method_source (~> 0.8)
39
+ slop (~> 3.3.1)
40
+ rack (1.4.1)
41
+ rack-cache (1.2)
42
+ rack (>= 0.4)
43
+ rack-test (0.6.1)
44
+ rack (>= 1.0)
45
+ rspec (2.11.0)
46
+ rspec-core (~> 2.11.0)
47
+ rspec-expectations (~> 2.11.0)
48
+ rspec-mocks (~> 2.11.0)
49
+ rspec-core (2.11.1)
50
+ rspec-expectations (2.11.3)
51
+ diff-lcs (~> 1.1.3)
52
+ rspec-mocks (2.11.3)
53
+ slop (3.3.3)
54
+ sprockets (2.1.3)
55
+ hike (~> 1.2)
56
+ rack (~> 1.0)
57
+ tilt (~> 1.1, != 1.3.0)
58
+ tilt (1.3.3)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ mandrill_mailer!
65
+ pry
66
+ rspec
data/README.md CHANGED
@@ -3,6 +3,7 @@ MandrilMailer class for sending transactional emails through mandril.
3
3
  Only template based emails are supported at this time.
4
4
 
5
5
  ## Usage
6
+ Add `gem 'mailchimp'`
6
7
  Add `gem 'mandrill_mailer'` to your Gemfile
7
8
 
8
9
  Add this to your `mail.rb` in initializers:
@@ -0,0 +1,308 @@
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
+ module MandrillMailer
60
+ class TransactionalMailer
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
+ def default_url_options=(options={})
140
+ @@url_host = options[:host]
141
+ end
142
+
143
+ # Public: Triggers the stored Mandril params to be sent to the Mandrill api
144
+ #
145
+ # text - The String to be duplicated.
146
+ # count - The Integer number of times to duplicate the text.
147
+ #
148
+ # Examples
149
+ #
150
+ # multiplex('Tom', 4)
151
+ # # => 'TomTomTomTom'
152
+ #
153
+ # Returns the duplicated String.
154
+ def deliver
155
+ mandrill = Mailchimp::Mandrill.new(api_key)
156
+ mandrill.messages_send_template(@data)
157
+ end
158
+
159
+ # Public: Build the hash needed to send to the mandrill api
160
+ #
161
+ # args - The Hash options used to refine the selection:
162
+ # :template - Template name in Mandrill
163
+ # :subject - Subject of the email
164
+ # :to - Email to send the mandrill email to
165
+ # :vars - Merge vars used in the email for dynamic data
166
+ # :bcc - bcc email for the mandrill email
167
+ # :tags - Tags for the email
168
+ # :google_analytics_domains - Google analytics domains
169
+ # :google_analytics_campaign - Google analytics campaign
170
+ #
171
+ # Examples
172
+ #
173
+ # mandrill_mail template: 'Group Invite',
174
+ # subject: I18n.t('invitation_mailer.invite.subject'),
175
+ # to: invitation.email,
176
+ # vars: {
177
+ # 'OWNER_NAME' => invitation.owner_name,
178
+ # 'INVITATION_URL' => new_invitation_url(email: invitation.email, secret: invitation.secret)
179
+ # }
180
+ #
181
+ # Returns the the mandrill mailer class (this is so you can chain #deliver like a normal mailer)
182
+ def mandrill_mail(args)
183
+
184
+ # Mandrill requires template content to be there
185
+ args[:template_content] = {"blank" => ""} if args[:template_content].blank?
186
+
187
+ # format the :to param to what Mandrill expects if a string or array is passed
188
+ args[:to] = format_to_params(args[:to])
189
+
190
+ @data = {"key" => api_key,
191
+ "template_name" => args[:template],
192
+ "template_content" => mandrill_args(args[:template_content]),
193
+ "message" => {
194
+ "subject" => args[:subject],
195
+ "from_email" => args[:from] || @@defaults[:from],
196
+ "from_name" => args[:from_name] || @@defaults[:from],
197
+ "to" => args[:to],
198
+ "headers" => args[:headers],
199
+ "track_opens" => true,
200
+ "track_clicks" => true,
201
+ "auto_text" => true,
202
+ "url_strip_qs" => true,
203
+ "bcc_address" => args[:bcc],
204
+ "global_merge_vars" => mandrill_args(args[:vars]),
205
+ # "merge_vars" =>[
206
+ # {
207
+ # "rcpt" => "email@email.com"
208
+ # "vars" => {"name" => "VARS", "content" => "vars content"}
209
+ # }
210
+ # ]
211
+
212
+ "tags" => args[:tags],
213
+ "google_analytics_domains" => args[:google_analytics_domains],
214
+ "google_analytics_campaign" => args[:google_analytics_campaign]
215
+ # "metadata" =>["..."],
216
+ # "attachments" =>[
217
+ # {"type" => "example type", "name" => "example name", "content" => "example content"}
218
+ # ]
219
+ }
220
+ }
221
+
222
+ # return self so we can chain deliver after the method call, like a normal mailer.
223
+ return self
224
+ end
225
+
226
+ def data
227
+ @data
228
+ end
229
+
230
+ protected
231
+
232
+ # Public: Url helper for creating OpenStruct compatible urls
233
+ # This is used for making sure urls will still work with
234
+ # OpenStructs used in the email testing code
235
+ #
236
+ # OpenStruct should have a .url property to work with this
237
+ #
238
+ # object - Object that would normally be passed into the route helper
239
+ # route_helper - The route helper as a symbol needed for the url
240
+ #
241
+ # Examples
242
+ #
243
+ # 'VIDEO_URL' => open_struct_url(video, :code_tv_video_url)
244
+ #
245
+ # Returns the url as a string
246
+ def test_friendly_url(object, route_helper)
247
+ if object.kind_of? OpenStruct
248
+ object.url
249
+ else
250
+ method(route_helper).call(object)
251
+ end
252
+ end
253
+
254
+ # Makes this class act as a singleton without it actually being a singleton
255
+ # This keeps the syntax the same as the orginal mailers so we can swap quickly if something
256
+ # goes wrong.
257
+ def self.method_missing(method, *args)
258
+ return super unless respond_to?(method)
259
+ new.method(method).call(*args)
260
+ end
261
+
262
+ def self.respond_to?(method, include_private = false)
263
+ super || instance_methods.include?(method)
264
+ end
265
+
266
+ # Proxy route helpers to rails if Rails exists
267
+ def method_missing(method, *args)
268
+ return super unless defined?(Rails) && Rails.application.routes.url_helpers.respond_to?(method)
269
+ Rails.application.routes.url_helpers.method(method).call(*args, host: @@url_host)
270
+ end
271
+
272
+ def image_path(image)
273
+ ActionController::Base.helpers.asset_path(image)
274
+ end
275
+
276
+ def image_url(image)
277
+ "#{root_url}#{image_path(image).split('/').reject!(&:empty?).join('/')}"
278
+ end
279
+
280
+ # convert a normal hash into the format mandrill needs
281
+ def mandrill_args(args)
282
+ args.map do |k,v|
283
+ {'name' => k, 'content' => v}
284
+ end
285
+ end
286
+
287
+ # handle if to params is an array of either hashes or strings or the single string
288
+ def format_to_params(to_params)
289
+ if to_params.kind_of? Array
290
+ to_params.map do |p|
291
+ to_params_item(p)
292
+ end
293
+ else
294
+ [to_params_item(to_params)]
295
+ end
296
+ end
297
+
298
+ # single to params item
299
+ def to_params_item(item)
300
+ return {"email" => item, "name" => "Code School Customer"} unless item.kind_of? Hash
301
+ item
302
+ end
303
+
304
+ def api_key
305
+ @@api_key || ''
306
+ end
307
+ end
308
+ end
@@ -1,3 +1,3 @@
1
1
  module MandrillMailer
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,4 +1,6 @@
1
- require 'mandrill_mailer/mandrill_mailer'
1
+ require 'action_view'
2
+ require 'mandrill_mailer/transactional_mailer'
3
+ require 'mandrill_mailer/version'
2
4
 
3
5
  module MandrillMailer
4
6
 
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Adam Rensel"]
10
10
  s.email = ["adamrensel@codeschool.com"]
11
- s.homepage = ""
11
+ s.homepage = "https://github.com/renz45/mandrill_mailer"
12
12
  s.summary = %q{Transactional Mailer for Mandrill}
13
13
  s.description = %q{Transactional Mailer for Mandrill}
14
14
 
@@ -16,4 +16,9 @@ Gem::Specification.new do |s|
16
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
+
20
+ s.add_dependency 'activesupport'
21
+ s.add_dependency 'actionpack'
22
+ s.add_development_dependency 'pry'
23
+ s.add_development_dependency 'rspec'
19
24
  end
@@ -0,0 +1,132 @@
1
+ require "spec_helper"
2
+
3
+ describe MandrillMailer::TransactionalMailer do
4
+ let(:image_path) { '/assets/image.jpg' }
5
+ let(:default_host) { 'localhost:3000' }
6
+ let(:mailer) {described_class.new}
7
+ let(:api_key) { '1237861278' }
8
+
9
+ before do
10
+ MandrillMailer::TransactionalMailer.api_key = api_key
11
+ MandrillMailer::TransactionalMailer.default_url_options = { host: default_host }
12
+ MandrillMailer::TransactionalMailer.any_instance.stub(:image_path).and_return(image_path)
13
+ end
14
+
15
+ # this only works from within a Rails application
16
+ # describe '#image_url' do
17
+ # subject { mailer.send(:image_url, 'image.jpg') }
18
+
19
+ # it 'should return the full path to the image' do
20
+ # should eq "http://#{default_host}#{image_path}"
21
+ # end
22
+ # end
23
+
24
+ describe '#mandrill_args' do
25
+ let(:arg_name) { 'USER_NAME' }
26
+ let(:arg_value) { 'bob' }
27
+
28
+ subject { mailer.send(:mandrill_args, {arg_name => arg_value}) }
29
+
30
+ it 'should convert the args to the correct format' do
31
+ should eq [{'name' => arg_name, 'content' => arg_value}]
32
+ end
33
+ end
34
+
35
+ describe '#format_to_params' do
36
+ let(:email) { 'bob@email.com' }
37
+ let(:name) { 'bob' }
38
+ let(:default_name) { 'Code School Customer' }
39
+
40
+ context 'with a single email string' do
41
+ subject { mailer.send(:format_to_params, email) }
42
+
43
+ it 'should format args to a format mandrill likes' do
44
+ should eq [{"email" => email, "name" => default_name}]
45
+ end
46
+ end
47
+
48
+ context 'with a single email string array' do
49
+ subject { mailer.send(:format_to_params, [email]) }
50
+
51
+ it 'should format args to a format mandrill likes' do
52
+ should eq [{"email" => email, "name" => default_name}]
53
+ end
54
+ end
55
+
56
+ context 'with a single email/name Hash' do
57
+ subject { mailer.send(:format_to_params, {"email" => email, "name" => name}) }
58
+
59
+ it 'should format args to a format mandrill likes' do
60
+ should eq [{"email" => email, "name" => name}]
61
+ end
62
+ end
63
+
64
+ context 'with a single email/name hash Array' do
65
+ subject { mailer.send(:format_to_params, [{"email" => email, "name" => name}]) }
66
+
67
+ it 'should format args to a format mandrill likes' do
68
+ should eq [{"email" => email, "name" => name}]
69
+ end
70
+ end
71
+ end
72
+
73
+ describe '#mandrill_mail' do
74
+ let(:template_content_name) { 'edit' }
75
+ let(:template_content_content) { 'edit_content' }
76
+ let(:from_email) { 'from@email.com' }
77
+ let(:var_name) { 'USER_NAME' }
78
+ let(:var_content) { 'bobert' }
79
+ let(:to_email) { 'bob@email.com' }
80
+ let(:to_name) { 'bob' }
81
+
82
+ let(:data) do
83
+ {
84
+ template: 'Email Template',
85
+ subject: "super secret",
86
+ to: {'email' => to_email, 'name' => to_name},
87
+ vars: {
88
+ var_name => var_content
89
+ },
90
+ template_content: {template_content_name => template_content_content},
91
+ headers: {"Reply-To" => "support@email.com"},
92
+ bcc: 'email@email.com',
93
+ tags: ['tag1'],
94
+ google_analytics_domains: ["http://site.com"],
95
+ google_analytics_campaign: '1237423474'
96
+ }
97
+ end
98
+ subject { mailer.mandrill_mail(data) }
99
+
100
+ before do
101
+ MandrillMailer::TransactionalMailer.default from: from_email
102
+ end
103
+
104
+ it 'should return the current class instance' do
105
+ should eq mailer
106
+ end
107
+
108
+ it 'should produce the correct data' do
109
+ mail = MandrillMailer::TransactionalMailer.new().mandrill_mail(data)
110
+ mail.data.should eq ({"key" => api_key,
111
+ "template_name" => data[:template],
112
+ "template_content" => [{'name' => template_content_name, 'content' => template_content_content}],
113
+ "message" => {
114
+ "subject" => data[:subject],
115
+ "from_email" => from_email,
116
+ "from_name" => from_email,
117
+ "to" => [{'email' => to_email, 'name' => to_name}],
118
+ "headers" => data[:headers],
119
+ "track_opens" => true,
120
+ "track_clicks" => true,
121
+ "auto_text" => true,
122
+ "url_strip_qs" => true,
123
+ "bcc_address" => data[:bcc],
124
+ "global_merge_vars" => [{"name" => var_name, "content" => var_content}],
125
+ "tags" => data[:tags],
126
+ "google_analytics_domains" => data[:google_analytics_domains],
127
+ "google_analytics_campaign" => data[:google_analytics_campaign]
128
+ }
129
+ })
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,10 @@
1
+ require 'rspec'
2
+ require 'mandrill_mailer'
3
+
4
+ # Requires supporting files with custom matchers and macros, etc,
5
+ # in ./support/ and its subdirectories.
6
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
7
+
8
+ RSpec.configure do |config|
9
+ config.mock_with :rspec
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mandrill_mailer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,71 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
  date: 2012-09-24 00:00:00.000000000 Z
13
- dependencies: []
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: actionpack
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: pry
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
14
78
  description: Transactional Mailer for Mandrill
15
79
  email:
16
80
  - adamrensel@codeschool.com
@@ -20,12 +84,15 @@ extra_rdoc_files: []
20
84
  files:
21
85
  - .gitignore
22
86
  - Gemfile
87
+ - Gemfile.lock
23
88
  - README.md
24
89
  - lib/mandrill_mailer.rb
25
- - lib/mandrill_mailer/mandrill_mailer.rb
90
+ - lib/mandrill_mailer/transactional_mailer.rb
26
91
  - lib/mandrill_mailer/version.rb
27
92
  - mandrill_mailer.gemspec
28
- homepage: ''
93
+ - spec/mandrill_mailer_spec.rb
94
+ - spec/spec_helper.rb
95
+ homepage: https://github.com/renz45/mandrill_mailer
29
96
  licenses: []
30
97
  post_install_message:
31
98
  rdoc_options: []
@@ -49,4 +116,6 @@ rubygems_version: 1.8.24
49
116
  signing_key:
50
117
  specification_version: 3
51
118
  summary: Transactional Mailer for Mandrill
52
- test_files: []
119
+ test_files:
120
+ - spec/mandrill_mailer_spec.rb
121
+ - spec/spec_helper.rb
@@ -1,297 +0,0 @@
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