mandrill_mailer 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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