diff --git a/README.md b/README.md index 6a6c0dd..b9d34a1 100644 --- a/README.md +++ b/README.md @@ -57,12 +57,14 @@ Here is an example of what typical usage may look like: include SendGrid sendgrid_category :use_subject_lines sendgrid_enable :ganalytics, :opentrack - + sendgrid_unique_args :key1 => "value1", :key2 => "value2" + def welcome_message(user) sendgrid_category "Welcome" + sendgrid_unique_args :key2 => "newvalue2", :key3 => "value3" mail :to => user.email, :subject => "Welcome #{user.name} :-)" end - + def goodbye_message(user) sendgrid_disable :ganalytics mail :to => user.email, :subject => "Fare thee well :-(" @@ -88,15 +90,19 @@ Here are a list of supported options for sendgrid\_enable and sendgrid\_disable: * Call sendgrid\_footer\_text(:html => 'My HTML footer rocks!', :plain => 'My plain text footer is so-so.') to set custom footer text for html, plain or both. * :spamcheck * Call sendgrid\_spamcheck\_maxscore(4.5) to set a custom SpamAssassin threshold at which SendGrid drops emails (default value is 5.0). - + For further explanation see [SendGrid's wiki page on filters.](http://wiki.sendgrid.com/doku.php?id=filters) +Custom parameters can be set using the sendgrid_unique_args methods. Any key/value pairs defined thusly will +be included as parameters in SendGrid post backs. These are especially useful in cases where the recipient's +email address is not unique or when multiple applications/environments are using the same SendGrid account. + Delivering to multiple recipients --------------------------------- There is a per-mailer-method setting that can be used to deliver campaigns to multiple (many) recipients in a single delivery/SMTP call. -It is quite easy to build a robust mass-delivery system utilizing this feature, and it is quite difficult to deliver a large email campaign quickly without this feature. +It is quite easy to build a robust mass-delivery system utilizing this feature, and it is quite difficult to deliver a large email campaign quickly without this feature. Note: While it may be worth asking yourself, a SendGrid engineer told me it's best to keep the number of recipients to <= 1,000 per delivery. diff --git a/Rakefile b/Rakefile index 1a8fa4f..f358624 100644 --- a/Rakefile +++ b/Rakefile @@ -10,7 +10,7 @@ begin SendGrid is an email deliverability API that is affordable and has lots of bells and whistles.} gem.email = "stephenrb@gmail.com" gem.homepage = "http://github.com/stephenb/sendgrid" - gem.authors = ["Stephen Blankenship"] + gem.authors = ["Stephen Blankenship", "Marc Tremblay", "Bob Burbach"] gem.add_dependency "json" # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings end diff --git a/VERSION b/VERSION index 7f20734..7dea76e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.1 \ No newline at end of file +1.0.1 diff --git a/lib/sendgrid.rb b/lib/sendgrid.rb index 0ce9caf..8a6cfc1 100644 --- a/lib/sendgrid.rb +++ b/lib/sendgrid.rb @@ -12,28 +12,37 @@ module SendGrid :spamcheck, :bypass_list_management ] - + + VALID_GANALYTICS_OPTIONS = [ + :utm_source, + :utm_medium, + :utm_campaign, + :utm_term, + :utm_content + ] + def self.included(base) base.class_eval do class << self attr_accessor :default_sg_category, :default_sg_options, :default_subscriptiontrack_text, - :default_footer_text, :default_spamcheck_score + :default_footer_text, :default_spamcheck_score, :default_sg_unique_args end - attr_accessor :sg_category, :sg_options, :sg_disabled_options, :sg_recipients, :sg_substitutions, :subscriptiontrack_text, :footer_text, :spamcheck_score + attr_accessor :sg_category, :sg_options, :sg_disabled_options, :sg_recipients, :sg_substitutions, + :subscriptiontrack_text, :footer_text, :spamcheck_score, :sg_unique_args end - - # NOTE: This commented-out approach may be a "safer" option for Rails 3, but it + + # NOTE: This commented-out approach may be a "safer" option for Rails 3, but it # would cause the headers to get set during delivery, and not when the message is initialized. # If base supports register_interceptor (i.e., Rails 3 ActionMailer), use it... # if base.respond_to?(:register_interceptor) # base.register_interceptor(SendgridInterceptor) # end - + base.extend(ClassMethods) end - + module ClassMethods - + # Sets a default category for all emails. # :use_subject_lines has special behavior that uses the subject-line of # each outgoing email for the SendGrid category. This special behavior @@ -42,7 +51,7 @@ module ClassMethods def sendgrid_category(category) self.default_sg_category = category end - + # Enables a default option for all emails. # See documentation for details. # @@ -58,19 +67,19 @@ def sendgrid_enable(*options) self.default_sg_options = Array.new unless self.default_sg_options options.each { |option| self.default_sg_options << option if VALID_OPTIONS.include?(option) } end - + # Sets the default text for subscription tracking (must be enabled). - # There are two options: - # 1. Add an unsubscribe link at the bottom of the email + # There are two options: + # 1. Add an unsubscribe link at the bottom of the email # {:html => "Unsubscribe <% here %>", :plain => "Unsubscribe here: <% %>"} # 2. Replace given text with the unsubscribe link # {:replace => "" } def sendgrid_subscriptiontrack_text(texts) self.default_subscriptiontrack_text = texts end - + # Sets the default footer text (must be enabled). - # Should be a hash containing the html/plain text versions: + # Should be a hash containing the html/plain text versions: # {:html => "html version", :plain => "plan text version"} def sendgrid_footer_text(texts) self.default_footer_text = texts @@ -80,6 +89,11 @@ def sendgrid_footer_text(texts) def sendgrid_spamcheck_maxscore(score) self.default_spamcheck_score = score end + + # Sets the default unique arguments to send + def sendgrid_unique_args(unique_args = {}) + self.default_sg_unique_args = unique_args + end end # Call within mailer method to override the default value. @@ -87,12 +101,17 @@ def sendgrid_category(category) @sg_category = category end + # Call within mailer method to add/override unique arguments in the defaults + def sendgrid_unique_args(unique_args = {}) + @sg_unique_args = unique_args + end + # Call within mailer method to add an option not in the defaults. def sendgrid_enable(*options) @sg_options = Array.new unless @sg_options options.each { |option| @sg_options << option if VALID_OPTIONS.include?(option) } end - + # Call within mailer method to remove one of the defaults. def sendgrid_disable(*options) @sg_disabled_options = Array.new unless @sg_disabled_options @@ -104,7 +123,7 @@ def sendgrid_recipients(emails) @sg_recipients = Array.new unless @sg_recipients @sg_recipients = emails end - + # Call within mailer method to add an array of substitions # NOTE: you must ensure that the length of the substitions equals the # length of the sendgrid_recipients. @@ -128,6 +147,13 @@ def sendgrid_spamcheck_maxscore(score) @spamcheck_score = score end + # Call within mailer method to set custom google analytics options + # http://sendgrid.com/documentation/appsGoogleAnalytics + def sendgrid_ganalytics_options(options) + @ganalytics_options = [] + options.each { |option| @ganalytics_options << option if VALID_GANALYTICS_OPTIONS.include?(option[0].to_sym) } + end + # Call within mailer method to set unique args for this email. def sendgrid_unique_args(args) @sg_unique_args = args @@ -154,7 +180,7 @@ def mail(headers={}, &block) else # Sets the custom X-SMTPAPI header after creating the email but before delivery - # NOTE: This override is used for Rails 2 ActionMailer classes. + # NOTE: This override is used for Rails 2 ActionMailer classes. def create!(method_name, *parameters) super if @sg_substitutions && !@sg_substitutions.empty? @@ -174,6 +200,14 @@ def create!(method_name, *parameters) def sendgrid_json_headers(mail) header_opts = {} + # set the unique arguments + if @sg_unique_args || self.class.default_sg_unique_args + unique_args = self.class.default_sg_unique_args || {} + unique_args = unique_args.merge(@sg_unique_args) + + header_opts[:unique_args] = unique_args + end + # Set category if @sg_category && @sg_category == :use_subject_lines header_opts[:category] = mail.subject @@ -184,12 +218,12 @@ def sendgrid_json_headers(mail) elsif self.class.default_sg_category header_opts[:category] = self.class.default_sg_category end - + # Set multi-recipients if @sg_recipients && !@sg_recipients.empty? header_opts[:to] = @sg_recipients end - + # Set custom substitions if @sg_substitutions && !@sg_substitutions.empty? header_opts[:sub] = @sg_substitutions @@ -214,10 +248,10 @@ def sendgrid_json_headers(mail) if @sg_unique_args && !@sg_unique_args.empty? header_opts[:unique_args] = @sg_unique_args end - + header_opts.to_json.gsub(/(["\]}])([,:])(["\[{])/, '\\1\\2 \\3') end - + def filters_hash_from_options(enabled_opts, disabled_opts) filters = {} enabled_opts.each do |opt| @@ -239,7 +273,7 @@ def filters_hash_from_options(enabled_opts, disabled_opts) filters[:subscriptiontrack]['settings']['text/plain'] = self.class.default_subscriptiontrack_text[:plain] end end - + when :footer if @footer_text filters[:footer]['settings']['text/html'] = @footer_text[:html] @@ -248,21 +282,28 @@ def filters_hash_from_options(enabled_opts, disabled_opts) filters[:footer]['settings']['text/html'] = self.class.default_footer_text[:html] filters[:footer]['settings']['text/plain'] = self.class.default_footer_text[:plain] end - + when :spamcheck if self.class.default_spamcheck_score || @spamcheck_score filters[:spamcheck]['settings']['maxscore'] = @spamcheck_score || self.class.default_spamcheck_score end + + when :ganalytics + if @ganalytics_options + @ganalytics_options.each do |key, value| + filters[:ganalytics]['settings'][key.to_s] = value + end + end end end - + if disabled_opts disabled_opts.each do |opt| filters[opt] = {'settings' => {'enable' => 0}} end end - + return filters end - + end diff --git a/sendgrid.gemspec b/sendgrid.gemspec index 32a21b3..2ee78c4 100644 --- a/sendgrid.gemspec +++ b/sendgrid.gemspec @@ -8,9 +8,9 @@ Gem::Specification.new do |s| s.version = "1.0.1" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = ["Stephen Blankenship"] + s.authors = ["Stephen Blankenship", "Marc Tremblay", "Bob Burbach"] s.date = %q{2011-09-08} - s.description = %q{This gem allows simple integration between ActionMailer and SendGrid. + s.description = %q{This gem allows simple integration between ActionMailer and SendGrid. SendGrid is an email deliverability API that is affordable and has lots of bells and whistles.} s.email = %q{stephenrb@gmail.com} s.extra_rdoc_files = [