rmm5t-sendgrid 0.1.0.20090110

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Stephen Blankenship
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,123 @@
1
+ h1. sendgrid
2
+
3
+ h3. What is SendGrid?
4
+
5
+ SendGrid is an awesome way to send large amounts of email (bells and whistles included) without spending large amounts of money. This gem allows for painless integration between ActionMailer and the SendGrid SMTP API. The current scope of this gem is focused around setting configuration options for outgoing email (essentially, setting categories, filters and the settings that can accompany those filters). SendGrid's service allows for some other cool stuff (such as postback notification of unsubscribes, bounces, etc.), but you'll have to integrate those features on your own.
6
+
7
+ Visit "SendGrid":http://sendgrid.com to learn more.
8
+
9
+ h3. Getting Started
10
+
11
+ First of all, you'll need the gem. You can add sendgrid to your Rails requirements:
12
+ <pre>
13
+ config.gem "sendgrid", :source => 'http://gemcutter.org'
14
+ </pre>
15
+
16
+ Or, you can install it as a gem:
17
+ <pre>
18
+ # if you haven't already, add gemcutter to your gem sources
19
+ sudo gem install gemcutter
20
+ gem tumble
21
+ # install sendgrid
22
+ sudo gem install sendgrid
23
+ </pre>
24
+
25
+ Before you can do anything with the sendgrid gem, you'll need to create your very own SendGrid account. Go ahead and do so at "http://sendgrid.com":http://sendgrid.com (there's even a FREE account option).
26
+
27
+ Next, update your application's SMTP settings to use SendGrid's servers (see "SendGrid's getting started guide":http://wiki.sendgrid.com/doku.php?id=get_started for instructions).
28
+
29
+ Example:
30
+ <pre>
31
+ ActionMailer::Base.smtp_settings = {
32
+ :address => "smtp.sendgrid.net",
33
+ :port => 25,
34
+ :domain => "mysite.com",
35
+ :authentication => :plain,
36
+ :user_name => "sendgrd_username@mysite.com",
37
+ :password => "sendgrid_password"
38
+ }
39
+ </pre>
40
+
41
+ h3. Using the sendgrid Gem
42
+
43
+ If you do not already have an ActionMailer class up and running, then check out "this guide.":http://guides.rubyonrails.org/action_mailer_basics.html#walkthrough-to-generating-a-mailer
44
+
45
+ 1) add the following line within your mailer class:
46
+ <pre>
47
+ include SendGrid
48
+ </pre>
49
+
50
+ 2) customize your sendgrid settings:
51
+
52
+ There are 2 types of settings
53
+ - Category settings
54
+ - Enable/disable settings
55
+
56
+ You can set both global and per-email settings - the same syntax is used in either case.
57
+ Here is an example of what typical usage may look like:
58
+
59
+ <pre>
60
+ class MyMailer < ActionMailer::Base
61
+ include SendGrid
62
+ sendgrid_category :use_subject_lines
63
+ sendgrid_enable :ganalytics, :opentracking
64
+
65
+ def welcome_message(to_user)
66
+ sendgrid_category "Welcome"
67
+
68
+ recipients to_user.email
69
+ subject "Welcome :-)"
70
+ body :to_user => to_user
71
+ end
72
+
73
+ def goodbye_message(to_user)
74
+ sendgrid_disable :ganalytics
75
+
76
+ recipients to_user.email
77
+ subject "Fare thee well :-("
78
+ body :to_user => to_user
79
+ end
80
+ end
81
+ </pre>
82
+
83
+ Category settings can be any text you like and will allow you to view statistics per-category (very nice). There is also a custom global setting that will automatically use the subject-line of your email as the sendgrid_category:
84
+ <pre>
85
+ sendgrid_category :use_subject_lines
86
+ </pre>
87
+ Calling sendgrid_cateogry from within one of your mailer methods will override this global setting. Similarly, calling sendgrid_enable/sendgrid_disable from within a mailer method will add or remove from any defaults that may have been set globally.
88
+
89
+ Here are a list of supported options for sendgrid_enable and sendgrid_disable:
90
+ * :opentrack
91
+ * :clicktrack
92
+ * :ganalytics
93
+ * :gravatar
94
+ * :subscriptiontrack
95
+ ** Call sendgrid_subscriptiontrack_text(:html => 'Unsubscribe <% Here %>', :plain => 'Unsubscribe Here: <% %>') to set a custom format for html/plain or both.
96
+ * :footer
97
+ ** 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.
98
+ * :spamcheck
99
+ ** Call sendgrid_spamcheck_maxscore(4.5) to set a custom SpamAssassin threshold at which SendGrid drops emails (default value is 5.0).
100
+
101
+ For further explanation see "SendGrid's wiki page on filters.":http://wiki.sendgrid.com/doku.php?id=filters
102
+
103
+ h3. Delivering to multiple recipients
104
+
105
+ There is a per-mailer-method setting that can be used to deliver campaigns to multiple recipients at once. You should still set the "recipients" to an address per the normal ActionMailer usage, but it will not be used.
106
+
107
+ <pre>
108
+ sendgrid_recipients ["email1@blah.com", "email2@blah.com", "email2@blah.com", ...]
109
+ </pre>
110
+
111
+ One issue that arises when delivering multiple emails at once is custom content. Luckily, there is also a per-mailer-method setting that can be used to substitute custom content.
112
+
113
+ <pre>
114
+ sendgrid_substitue "<subme>", ["sub text for 1st recipient", "sub text for 2nd recipient", "sub text for 3rd recipient", ...]
115
+ </pre>
116
+
117
+ In this example, if <code><subme></code> is in the body of your email SendGrid will automatically substitute it for the string corresponding the recipient being delivered to. NOTE: You should ensure that the length of the substitution array is equal to the length of the recipients array.
118
+
119
+ h3. TODO
120
+
121
+ * Test coverage (I would appreciate help writing tests).
122
+ * Possibly integrate with SendGrid's Event API and some of the other goodies they provide.
123
+
data/Rakefile ADDED
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rmm5t-sendgrid"
8
+ gem.summary = %Q{A gem that allows simple integration of ActionMailer with SendGrid (http://sendgrid.com)}
9
+ gem.description = %Q{This gem allows simple integration between ActionMailer and SendGrid.
10
+ SendGrid is an email deliverability API that is affordable and has lots of bells and whistles.}
11
+ gem.email = "stephenrb@gmail.com"
12
+ gem.homepage = "http://github.com/rmm5t/sendgrid"
13
+ gem.authors = ["Stephen Blankenship"]
14
+ # gem.add_development_dependency "thoughtbot-shoulda"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'lib' << 'test'
25
+ test.pattern = 'test/**/*_test.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ begin
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/*_test.rb'
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => :test
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ if File.exist?('VERSION')
49
+ version = File.read('VERSION')
50
+ else
51
+ version = ""
52
+ end
53
+
54
+ rdoc.rdoc_dir = 'rdoc'
55
+ rdoc.title = "sendgrid #{version}"
56
+ rdoc.rdoc_files.include('README*')
57
+ rdoc.rdoc_files.include('lib/**/*.rb')
58
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0.20090110
data/lib/sendgrid.rb ADDED
@@ -0,0 +1,210 @@
1
+ require 'json'
2
+
3
+ module SendGrid
4
+
5
+ VALID_OPTIONS = [
6
+ :opentrack,
7
+ :clicktrack,
8
+ :ganalytics,
9
+ :gravatar,
10
+ :subscriptiontrack,
11
+ :footer,
12
+ :spamcheck
13
+ ]
14
+
15
+ def self.included(base)
16
+ base.class_eval do
17
+ class << self
18
+ attr_accessor :default_sg_category, :default_sg_options, :default_subscriptiontrack_text,
19
+ :default_footer_text, :default_spamcheck_score
20
+ end
21
+ attr_accessor :sg_category, :sg_options, :sg_disabled_options, :sg_recipients, :sg_substitutions, :subscriptiontrack_text, :footer_text, :spamcheck_score
22
+ end
23
+ base.extend(ClassMethods)
24
+ end
25
+
26
+ module ClassMethods
27
+
28
+ # Sets a default category for all emails.
29
+ # :use_subject_lines has special behavior that uses the subject-line of
30
+ # each outgoing email for the SendGrid category. This special behavior
31
+ # can still be overridden by calling sendgrid_category from within a
32
+ # mailer method.
33
+ def sendgrid_category(category)
34
+ self.default_sg_category = category
35
+ end
36
+
37
+ # Enables a default option for all emails.
38
+ # See documentation for details.
39
+ #
40
+ # Supported options:
41
+ # * :opentrack
42
+ # * :clicktrack
43
+ # * :ganalytics
44
+ # * :gravatar
45
+ # * :subscriptiontrack
46
+ # * :footer
47
+ # * :spamcheck
48
+ def sendgrid_enable(*options)
49
+ self.default_sg_options = Array.new unless self.default_sg_options
50
+ options.each { |option| self.default_sg_options << option if VALID_OPTIONS.include?(option) }
51
+ end
52
+
53
+ # Sets the default text for subscription tracking (must be enabled).
54
+ # Should be a hash containing the html/plain text versions:
55
+ # {:html => "html version", :plain => "plan text version"}
56
+ def sendgrid_subscriptiontrack_text(texts)
57
+ self.default_subscriptiontrack_text = texts
58
+ end
59
+
60
+ # Sets the default footer text (must be enabled).
61
+ # Should be a hash containing the html/plain text versions:
62
+ # {:html => "html version", :plain => "plan text version"}
63
+ def sendgrid_footer_text(texts)
64
+ self.default_footer_text = texts
65
+ end
66
+
67
+ # Sets the default spamcheck score text (must be enabled).
68
+ def sendgrid_spamcheck_maxscore(score)
69
+ self.default_spamcheck_score = score
70
+ end
71
+ end
72
+
73
+ # Call within mailer method to override the default value.
74
+ def sendgrid_category(category)
75
+ @sg_category = category
76
+ end
77
+
78
+ # Call within mailer method to add an option not in the defaults.
79
+ def sendgrid_enable(*options)
80
+ @sg_options = Array.new unless @sg_options
81
+ options.each { |option| @sg_options << option if VALID_OPTIONS.include?(option) }
82
+ end
83
+
84
+ # Call within mailer method to remove one of the defaults.
85
+ def sendgrid_disable(*options)
86
+ @sg_disabled_options = Array.new unless @sg_disabled_options
87
+ options.each { |option| @sg_disabled_options << option if VALID_OPTIONS.include?(option) }
88
+ end
89
+
90
+ # Call within mailer method to add an array of recipients
91
+ def sendgrid_recipients(emails)
92
+ @sg_recipients = Array.new unless @sg_recipients
93
+ @sg_recipients = emails
94
+ end
95
+
96
+ # Call within mailer method to add an array of substitions
97
+ # NOTE: you must ensure that the length of the substitions equals the
98
+ # length of the sendgrid_recipients.
99
+ def sendgrid_substitute(placeholder, subs)
100
+ @sg_substitutions = Hash.new unless @sg_substitutions
101
+ @sg_substitutions[placeholder] = subs
102
+ end
103
+
104
+ # Call within mailer method to override the default value.
105
+ def sendgrid_subscriptiontrack_text(texts)
106
+ @subscriptiontrack_text = texts
107
+ end
108
+
109
+ # Call within mailer method to override the default value.
110
+ def sendgrid_footer_text(texts)
111
+ @footer_text = texts
112
+ end
113
+
114
+ # Call within mailer method to override the default value.
115
+ def sendgrid_spamcheck_maxscore(score)
116
+ @spamcheck_score = score
117
+ end
118
+
119
+ # Sets the custom X-SMTPAPI header after creating the email but before delivery
120
+ def create!(method_name, *parameters)
121
+ super
122
+ puts "SendGrid X-SMTPAPI: #{sendgrid_json_headers(mail)}" if Object.const_defined?("SENDGRID_DEBUG_OUTPUT") && SENDGRID_DEBUG_OUTPUT
123
+ @mail['X-SMTPAPI'] = sendgrid_json_headers(mail)
124
+ end
125
+
126
+ private
127
+
128
+ # Take all of the options and turn it into the json format that SendGrid expects
129
+ def sendgrid_json_headers(mail)
130
+ header_opts = {}
131
+
132
+ # Set category
133
+ if @sg_category && @sg_category == :use_subject_lines
134
+ header_opts[:category] = mail.subject
135
+ elsif @sg_category
136
+ header_opts[:category] = @sg_category
137
+ elsif self.class.default_sg_category && self.class.default_sg_category.to_sym == :use_subject_lines
138
+ header_opts[:category] = mail.subject
139
+ elsif self.class.default_sg_category
140
+ header_opts[:category] = self.class.default_sg_category
141
+ end
142
+
143
+ # Set multi-recipients
144
+ if @sg_recipients && !@sg_recipients.empty?
145
+ header_opts[:to] = @sg_recipients
146
+ end
147
+
148
+ # Set custom substitions
149
+ if @sg_substitutions && !@sg_substitutions.empty?
150
+ header_opts[:sub] = @sg_substitutions
151
+ end
152
+
153
+ # Set enables/disables
154
+ header_opts[:filters] = {} unless header_opts.has_key?(:filters)
155
+ enabled_opts = []
156
+ if @sg_options && !@sg_options.empty?
157
+ # merge the options so that the instance-level "overrides"
158
+ merged = self.class.default_sg_options || []
159
+ merged += @sg_options
160
+ enabled_opts = merged
161
+ elsif self.class.default_sg_options
162
+ enabled_opts = self.class.default_sg_options
163
+ end
164
+ if !enabled_opts.empty? || (@sg_disabled_options && !@sg_disabled_options.empty?)
165
+ header_opts[:filters] = filters_hash_from_options(enabled_opts, @sg_disabled_options)
166
+ end
167
+
168
+ header_opts.to_json
169
+ end
170
+
171
+ def filters_hash_from_options(enabled_opts, disabled_opts)
172
+ filters = {}
173
+ enabled_opts.each do |opt|
174
+ filters[opt] = {'settings' => {'enable' => 1}}
175
+ case opt.to_sym
176
+ when :subscriptiontrack
177
+ if @subscriptiontrack_text
178
+ filters[:subscriptiontrack]['settings']['text/html'] = @subscriptiontrack_text[:html]
179
+ filters[:subscriptiontrack]['settings']['text/plain'] = @subscriptiontrack_text[:plain]
180
+ elsif self.class.default_subscriptiontrack_text
181
+ filters[:subscriptiontrack]['settings']['text/html'] = self.class.default_subscriptiontrack_text[:html]
182
+ filters[:subscriptiontrack]['settings']['text/plain'] = self.class.default_subscriptiontrack_text[:plain]
183
+ end
184
+
185
+ when :footer
186
+ if @footer_text
187
+ filters[:footer]['settings']['text/html'] = @footer_text[:html]
188
+ filters[:footer]['settings']['text/plain'] = @footer_text[:plain]
189
+ elsif self.class.default_footer_text
190
+ filters[:footer]['settings']['text/html'] = self.class.default_footer_text[:html]
191
+ filters[:footer]['settings']['text/plain'] = self.class.default_footer_text[:plain]
192
+ end
193
+
194
+ when :spamcheck
195
+ if self.class.default_spamcheck_score || @spamcheck_score
196
+ filters[:spamcheck]['settings']['maxscore'] = @spamcheck_score || self.class.default_spamcheck_score
197
+ end
198
+ end
199
+ end
200
+
201
+ if disabled_opts
202
+ disabled_opts.each do |opt|
203
+ filters[opt] = {'settings' => {'enable' => 0}}
204
+ end
205
+ end
206
+
207
+ return filters
208
+ end
209
+
210
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class SendgridTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'sendgrid'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rmm5t-sendgrid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.20090110
5
+ platform: ruby
6
+ authors:
7
+ - Stephen Blankenship
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-10 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: |-
17
+ This gem allows simple integration between ActionMailer and SendGrid.
18
+ SendGrid is an email deliverability API that is affordable and has lots of bells and whistles.
19
+ email: stephenrb@gmail.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files:
25
+ - LICENSE
26
+ - README.textile
27
+ files:
28
+ - .document
29
+ - .gitignore
30
+ - LICENSE
31
+ - README.textile
32
+ - Rakefile
33
+ - VERSION
34
+ - lib/sendgrid.rb
35
+ - test/sendgrid_test.rb
36
+ - test/test_helper.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/rmm5t/sendgrid
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: A gem that allows simple integration of ActionMailer with SendGrid (http://sendgrid.com)
65
+ test_files:
66
+ - test/sendgrid_test.rb
67
+ - test/test_helper.rb