Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 307 lines (260 sloc) 11.004 kB
81b3bf9 @drewtempelmeyer Oops. Removed json
drewtempelmeyer authored
1 require 'json'
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
2
3 module SendGrid
4
5 VALID_OPTIONS = [
6 :opentrack,
7 :clicktrack,
8 :ganalytics,
9 :gravatar,
10 :subscriptiontrack,
11 :footer,
93f73ac @chaslemley added bypass_list_management to list of valid options for sendgrid_en…
chaslemley authored
12 :spamcheck,
13 :bypass_list_management
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
14 ]
469609a @stephenb Bumping version.
authored
15
16 VALID_GANALYTICS_OPTIONS = [
17 :utm_source,
18 :utm_medium,
19 :utm_campaign,
20 :utm_term,
21 :utm_content
22 ]
23
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
24 def self.included(base)
25 base.class_eval do
26 class << self
27 attr_accessor :default_sg_category, :default_sg_options, :default_subscriptiontrack_text,
469609a @stephenb Bumping version.
authored
28 :default_footer_text, :default_spamcheck_score, :default_sg_unique_args
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
29 end
469609a @stephenb Bumping version.
authored
30 attr_accessor :sg_category, :sg_options, :sg_disabled_options, :sg_recipients, :sg_substitutions,
31 :subscriptiontrack_text, :footer_text, :spamcheck_score, :sg_unique_args
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
32 end
469609a @stephenb Bumping version.
authored
33
34 # NOTE: This commented-out approach may be a "safer" option for Rails 3, but it
bad5afa @stephenb Updated to support Rails 3's ActionMailer
authored
35 # would cause the headers to get set during delivery, and not when the message is initialized.
36 # If base supports register_interceptor (i.e., Rails 3 ActionMailer), use it...
37 # if base.respond_to?(:register_interceptor)
38 # base.register_interceptor(SendgridInterceptor)
39 # end
469609a @stephenb Bumping version.
authored
40
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
41 base.extend(ClassMethods)
42 end
469609a @stephenb Bumping version.
authored
43
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
44 module ClassMethods
469609a @stephenb Bumping version.
authored
45
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
46 # Sets a default category for all emails.
47 # :use_subject_lines has special behavior that uses the subject-line of
48 # each outgoing email for the SendGrid category. This special behavior
49 # can still be overridden by calling sendgrid_category from within a
50 # mailer method.
51 def sendgrid_category(category)
52 self.default_sg_category = category
53 end
469609a @stephenb Bumping version.
authored
54
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
55 # Enables a default option for all emails.
56 # See documentation for details.
57 #
58 # Supported options:
59 # * :opentrack
60 # * :clicktrack
61 # * :ganalytics
62 # * :gravatar
63 # * :subscriptiontrack
64 # * :footer
65 # * :spamcheck
66 def sendgrid_enable(*options)
67 self.default_sg_options = Array.new unless self.default_sg_options
68 options.each { |option| self.default_sg_options << option if VALID_OPTIONS.include?(option) }
69 end
f9f58ac @stephenb Revert railtie setup
authored
70
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
71 # Sets the default text for subscription tracking (must be enabled).
469609a @stephenb Bumping version.
authored
72 # There are two options:
73 # 1. Add an unsubscribe link at the bottom of the email
851256b @chaslemley added ability to use the subscriptiontrack replace feature
chaslemley authored
74 # {:html => "Unsubscribe <% here %>", :plain => "Unsubscribe here: <% %>"}
75 # 2. Replace given text with the unsubscribe link
76 # {:replace => "<unsubscribe_link>" }
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
77 def sendgrid_subscriptiontrack_text(texts)
78 self.default_subscriptiontrack_text = texts
79 end
469609a @stephenb Bumping version.
authored
80
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
81 # Sets the default footer text (must be enabled).
469609a @stephenb Bumping version.
authored
82 # Should be a hash containing the html/plain text versions:
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
83 # {:html => "html version", :plain => "plan text version"}
84 def sendgrid_footer_text(texts)
85 self.default_footer_text = texts
86 end
87
88 # Sets the default spamcheck score text (must be enabled).
89 def sendgrid_spamcheck_maxscore(score)
90 self.default_spamcheck_score = score
91 end
469609a @stephenb Bumping version.
authored
92
e6cef17 @stephenb Merge branch 'master' of https://github.com/DanOlson/sendgrid into Da…
authored
93 # Sets unique args at the class level. Should be a hash
94 # of name, value pairs.
95 # { :some_unique_arg => "some_value"}
469609a @stephenb Bumping version.
authored
96 def sendgrid_unique_args(unique_args = {})
97 self.default_sg_unique_args = unique_args
98 end
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
99 end
100
101 # Call within mailer method to override the default value.
102 def sendgrid_category(category)
103 @sg_category = category
104 end
105
e6cef17 @stephenb Merge branch 'master' of https://github.com/DanOlson/sendgrid into Da…
authored
106 # Call within mailer method to set unique args for this email.
107 # Merged with class-level unique args, if any exist.
469609a @stephenb Bumping version.
authored
108 def sendgrid_unique_args(unique_args = {})
109 @sg_unique_args = unique_args
110 end
111
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
112 # Call within mailer method to add an option not in the defaults.
113 def sendgrid_enable(*options)
114 @sg_options = Array.new unless @sg_options
115 options.each { |option| @sg_options << option if VALID_OPTIONS.include?(option) }
116 end
469609a @stephenb Bumping version.
authored
117
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
118 # Call within mailer method to remove one of the defaults.
119 def sendgrid_disable(*options)
120 @sg_disabled_options = Array.new unless @sg_disabled_options
121 options.each { |option| @sg_disabled_options << option if VALID_OPTIONS.include?(option) }
122 end
123
78bba34 @stephenb adding support for sendgrid_recipients and sendgrid_substitute
authored
124 # Call within mailer method to add an array of recipients
125 def sendgrid_recipients(emails)
126 @sg_recipients = Array.new unless @sg_recipients
127 @sg_recipients = emails
128 end
469609a @stephenb Bumping version.
authored
129
78bba34 @stephenb adding support for sendgrid_recipients and sendgrid_substitute
authored
130 # Call within mailer method to add an array of substitions
131 # NOTE: you must ensure that the length of the substitions equals the
132 # length of the sendgrid_recipients.
133 def sendgrid_substitute(placeholder, subs)
134 @sg_substitutions = Hash.new unless @sg_substitutions
135 @sg_substitutions[placeholder] = subs
136 end
137
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
138 # Call within mailer method to override the default value.
139 def sendgrid_subscriptiontrack_text(texts)
140 @subscriptiontrack_text = texts
141 end
e0b191d @rmm5t Set the custom X-SMTPAPI header after creating the email instead of b…
rmm5t authored
142
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
143 # Call within mailer method to override the default value.
144 def sendgrid_footer_text(texts)
145 @footer_text = texts
146 end
e0b191d @rmm5t Set the custom X-SMTPAPI header after creating the email instead of b…
rmm5t authored
147
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
148 # Call within mailer method to override the default value.
149 def sendgrid_spamcheck_maxscore(score)
150 @spamcheck_score = score
151 end
152
469609a @stephenb Bumping version.
authored
153 # Call within mailer method to set custom google analytics options
154 # http://sendgrid.com/documentation/appsGoogleAnalytics
155 def sendgrid_ganalytics_options(options)
156 @ganalytics_options = []
157 options.each { |option| @ganalytics_options << option if VALID_GANALYTICS_OPTIONS.include?(option[0].to_sym) }
158 end
f9f58ac @stephenb Revert railtie setup
authored
159
160 # only override the appropriate methods for the current ActionMailer version
161 if ActionMailer::Base.respond_to?(:mail)
5d670f7 @drewtempelmeyer Add railtie to automatically include SendGrid in ActionMailer. Restru…
drewtempelmeyer authored
162
f9f58ac @stephenb Revert railtie setup
authored
163 protected
d683213 @yenif only override methods for current version of rails
yenif authored
164
165 # Sets the custom X-SMTPAPI header after creating the email but before delivery
f9f58ac @stephenb Revert railtie setup
authored
166 # NOTE: This override is used for Rails 3 ActionMailer classes.
f5f7806 no longer dependent on Rails.version method. Using ActionMailer::Bas…
Brad Cantin authored
167 def mail(headers={}, &block)
4ff3e21 @einarmagnus Let mail() and create!() return what their overridden versions do.
einarmagnus authored
168 m = super
d683213 @yenif only override methods for current version of rails
yenif authored
169 if @sg_substitutions && !@sg_substitutions.empty?
170 @sg_substitutions.each do |find, replace|
171 raise ArgumentError.new("Array for #{find} is not the same size as the recipient array") if replace.size != @sg_recipients.size
172 end
def109b @chaslemley added exception for a mismatch in substitution array and recipient ar…
chaslemley authored
173 end
f9f58ac @stephenb Revert railtie setup
authored
174 puts "SendGrid X-SMTPAPI: #{sendgrid_json_headers(message)}" if Object.const_defined?("SENDGRID_DEBUG_OUTPUT") && SENDGRID_DEBUG_OUTPUT
b8e29fe @drewtempelmeyer Remove puts. Add DEBUG constant. Remove old rails code
drewtempelmeyer authored
175 self.headers['X-SMTPAPI'] = sendgrid_json_headers(message)
176 m
bad5afa @stephenb Updated to support Rails 3's ActionMailer
authored
177 end
f5f7806 no longer dependent on Rails.version method. Using ActionMailer::Bas…
Brad Cantin authored
178
f9f58ac @stephenb Revert railtie setup
authored
179 else
180
181 # Sets the custom X-SMTPAPI header after creating the email but before delivery
182 # NOTE: This override is used for Rails 2 ActionMailer classes.
183 def create!(method_name, *parameters)
184 super
185 if @sg_substitutions && !@sg_substitutions.empty?
186 @sg_substitutions.each do |find, replace|
187 raise ArgumentError.new("Array for #{find} is not the same size as the recipient array") if replace.size != @sg_recipients.size
188 end
189 end
190 puts "SendGrid X-SMTPAPI: #{sendgrid_json_headers(mail)}" if Object.const_defined?("SENDGRID_DEBUG_OUTPUT") && SENDGRID_DEBUG_OUTPUT
191 @mail['X-SMTPAPI'] = sendgrid_json_headers(mail)
192 end
193
194 end
195
e0b191d @rmm5t Set the custom X-SMTPAPI header after creating the email instead of b…
rmm5t authored
196 private
197
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
198 # Take all of the options and turn it into the json format that SendGrid expects
199 def sendgrid_json_headers(mail)
200 header_opts = {}
201
238103c @akenger More issues with unique_args
akenger authored
202 #if not called within the mailer method, this will be nil so we default to empty hash
203 @sg_unique_args = @sg_unique_args || {}
f9f58ac @stephenb Revert railtie setup
authored
204
469609a @stephenb Bumping version.
authored
205 # set the unique arguments
206 if @sg_unique_args || self.class.default_sg_unique_args
207 unique_args = self.class.default_sg_unique_args || {}
208 unique_args = unique_args.merge(@sg_unique_args)
209
d9bc4e4 @stephenb Don't add unique_args to custom header if it's an empty hash.
authored
210 header_opts[:unique_args] = unique_args unless unique_args.empty?
469609a @stephenb Bumping version.
authored
211 end
212
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
213 # Set category
214 if @sg_category && @sg_category == :use_subject_lines
215 header_opts[:category] = mail.subject
216 elsif @sg_category
217 header_opts[:category] = @sg_category
218 elsif self.class.default_sg_category && self.class.default_sg_category.to_sym == :use_subject_lines
219 header_opts[:category] = mail.subject
220 elsif self.class.default_sg_category
221 header_opts[:category] = self.class.default_sg_category
222 end
469609a @stephenb Bumping version.
authored
223
78bba34 @stephenb adding support for sendgrid_recipients and sendgrid_substitute
authored
224 # Set multi-recipients
225 if @sg_recipients && !@sg_recipients.empty?
226 header_opts[:to] = @sg_recipients
227 end
469609a @stephenb Bumping version.
authored
228
78bba34 @stephenb adding support for sendgrid_recipients and sendgrid_substitute
authored
229 # Set custom substitions
230 if @sg_substitutions && !@sg_substitutions.empty?
231 header_opts[:sub] = @sg_substitutions
232 end
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
233
087c2cf @stephenb Bug fix, custom header is now set direclty on the mail instance. Also…
authored
234 # Set enables/disables
235 enabled_opts = []
236 if @sg_options && !@sg_options.empty?
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
237 # merge the options so that the instance-level "overrides"
087c2cf @stephenb Bug fix, custom header is now set direclty on the mail instance. Also…
authored
238 merged = self.class.default_sg_options || []
239 merged += @sg_options
240 enabled_opts = merged
241 elsif self.class.default_sg_options
242 enabled_opts = self.class.default_sg_options
243 end
244 if !enabled_opts.empty? || (@sg_disabled_options && !@sg_disabled_options.empty?)
ceba467 @stephenb fixing tests, removing empty filters from header
authored
245 filters = filters_hash_from_options(enabled_opts, @sg_disabled_options)
246 header_opts[:filters] = filters if filters && !filters.empty?
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
247 end
936ab76 @yenif add unique args header
yenif authored
248
106296b @chaslemley fix error where header return json may be marked as invalid by sendgr…
chaslemley authored
249 header_opts.to_json.gsub(/(["\]}])([,:])(["\[{])/, '\\1\\2 \\3')
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
250 end
469609a @stephenb Bumping version.
authored
251
087c2cf @stephenb Bug fix, custom header is now set direclty on the mail instance. Also…
authored
252 def filters_hash_from_options(enabled_opts, disabled_opts)
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
253 filters = {}
087c2cf @stephenb Bug fix, custom header is now set direclty on the mail instance. Also…
authored
254 enabled_opts.each do |opt|
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
255 filters[opt] = {'settings' => {'enable' => 1}}
256 case opt.to_sym
257 when :subscriptiontrack
258 if @subscriptiontrack_text
6990619 @stephenb fixing bug related to @subscriptiontrack_text
authored
259 if @subscriptiontrack_text[:replace]
260 filters[:subscriptiontrack]['settings']['replace'] = @subscriptiontrack_text[:replace]
851256b @chaslemley added ability to use the subscriptiontrack replace feature
chaslemley authored
261 else
262 filters[:subscriptiontrack]['settings']['text/html'] = @subscriptiontrack_text[:html]
263 filters[:subscriptiontrack]['settings']['text/plain'] = @subscriptiontrack_text[:plain]
264 end
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
265 elsif self.class.default_subscriptiontrack_text
851256b @chaslemley added ability to use the subscriptiontrack replace feature
chaslemley authored
266 if self.class.default_subscriptiontrack_text[:replace]
267 filters[:subscriptiontrack]['settings']['replace'] = self.class.default_subscriptiontrack_text[:replace]
268 else
269 filters[:subscriptiontrack]['settings']['text/html'] = self.class.default_subscriptiontrack_text[:html]
270 filters[:subscriptiontrack]['settings']['text/plain'] = self.class.default_subscriptiontrack_text[:plain]
271 end
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
272 end
469609a @stephenb Bumping version.
authored
273
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
274 when :footer
275 if @footer_text
276 filters[:footer]['settings']['text/html'] = @footer_text[:html]
277 filters[:footer]['settings']['text/plain'] = @footer_text[:plain]
278 elsif self.class.default_footer_text
279 filters[:footer]['settings']['text/html'] = self.class.default_footer_text[:html]
280 filters[:footer]['settings']['text/plain'] = self.class.default_footer_text[:plain]
281 end
469609a @stephenb Bumping version.
authored
282
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
283 when :spamcheck
284 if self.class.default_spamcheck_score || @spamcheck_score
285 filters[:spamcheck]['settings']['maxscore'] = @spamcheck_score || self.class.default_spamcheck_score
286 end
469609a @stephenb Bumping version.
authored
287
288 when :ganalytics
289 if @ganalytics_options
290 @ganalytics_options.each do |key, value|
291 filters[:ganalytics]['settings'][key.to_s] = value
292 end
293 end
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
294 end
295 end
469609a @stephenb Bumping version.
authored
296
087c2cf @stephenb Bug fix, custom header is now set direclty on the mail instance. Also…
authored
297 if disabled_opts
298 disabled_opts.each do |opt|
299 filters[opt] = {'settings' => {'enable' => 0}}
300 end
301 end
469609a @stephenb Bumping version.
authored
302
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
303 return filters
304 end
469609a @stephenb Bumping version.
authored
305
c18d0e6 @stephenb this thing should be pretty effing close to working now.
authored
306 end
Something went wrong with that request. Please try again.