brightbytes-sendgrid 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OTI3NjE1NjIxNDJjNGEyZGUxZGUyMDJlOTMwNjQxMTEyOTk5MWFmMA==
5
+ data.tar.gz: !binary |-
6
+ YTlhNDdiYjUyYjRkZTY3ZjBiMmE3ZjNkZTJkMjViMTVmODkwNDY5Ng==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZWNhZjJhMWYwY2U3NGFlNjIwM2FmZGVlMGQ1MjczZmYwYzVmODAwODZmZjc3
10
+ ZDk2M2IzMDUxYWE3Nzg2OTY3NzhlY2Y2ZDhmZjUwMGY2ZTZiYTMxOTEwMDdl
11
+ ZDhiMTkxYTQwZjA5OTgxZmIzN2U5NmI4NjVkMDQ2MzQ1NTM0ZjU=
12
+ data.tar.gz: !binary |-
13
+ M2VmOGI0MGFlZTI0Yzg0MzRiYTRhNWEzOTZiOTFiMGZjOWI4MjQ4M2MwNjY5
14
+ MGJhNmJmNDJkNDNkMGQyNGZiYjNhODZiOGM5YzBmZjQyNTE5NDZhMmZhMmIx
15
+ ZTAyZTdjNDM0MjE2MDE4ODM0NWYwNGVkOWZjMzBkYjc1MTcwZDU=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ brightbytes-sendgrid
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3-p484
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in brightbytes-sendgrid.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Serhiy Rozum
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 BrightBytes Inc.
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.md ADDED
@@ -0,0 +1,90 @@
1
+ # Brightbytes::Sendgrid
2
+
3
+ This gem allows for painless integration between ActionMailer and the SendGrid SMTP API.
4
+ 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).
5
+
6
+ SendGrid's service allows to automatically include Unsubscribe link into your emails. Unfortunately, SendGrid doesn't manage multiple unsubscriptions lists based on your's emails categories.
7
+
8
+ Visit [SendGrid SMTP API](http://sendgrid.com/docs/API_Reference/SMTP_API/index.html) to learn more.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'brightbytes-sendgrid'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install brightbytes-sendgrid
23
+
24
+ In your config/initializers/sendgrid.rb:
25
+
26
+ ActionMailer::Base.send :include, Brightbytes::Sendgrid
27
+
28
+ Brightbytes::Sendgrid.configure do |config|
29
+ config.default_categories :system
30
+ config.unsubscribe_categories :system, :onboarding
31
+ config.unsubscribe_url 'http://brightbytes.net/unsubscribe'
32
+ end
33
+
34
+ Or use it with selected mailers:
35
+
36
+ Brightbytes::Sendgrid
37
+
38
+ ## Usage
39
+
40
+ You can use following methods to set both global and per-email SendGrid SMTP API header options:
41
+
42
+ **sendgrid_substitute**
43
+
44
+ sendgrid_substitute :full_name, ['Jack', 'John']
45
+ sendgrid_substitute '{{some_text}}', 'another text'
46
+
47
+ **sendgrid_section**
48
+
49
+ sendgrid_section :greeting, I18n.translate('Hello')
50
+
51
+ **sendgrid_unique_args**
52
+
53
+ sendgrid_unique_args email_id: 12345
54
+
55
+ **sendgrid_categories**
56
+
57
+ sendgrid_categories :newsletter
58
+
59
+ **sendgrid_recipients**
60
+
61
+ sendgrid_recipients 'email1@email.com', 'email2@email.com'
62
+
63
+ **sendgrid_enable**
64
+
65
+ sendgrid_enable :opentrack
66
+
67
+ **sendgrid_disable**
68
+
69
+ sendgrid_disable :clicktrack
70
+
71
+ ## Auto generated unsubscribe link
72
+
73
+ It is not a SendGrid **subscriptiontrack** filter!
74
+
75
+ What we diong here is just collecting recipients and generating unsubscribe links for every recipient.
76
+ Those links will be sent as a substitutions to SendGrid.
77
+
78
+ So, to make this feature work, you have to:
79
+
80
+ 1. Configure unsubscribe categories. It will trigger link generator
81
+ 2. Configure an unsubscribe_url. The resulting URL will be composed of unsubscribe_url and email and category parameters.
82
+ 3. Put {{unsubscribe}} placeholder somewhere in your email body
83
+
84
+ ##Contributors
85
+
86
+ This gem is written using code samples from:
87
+
88
+ * [http://github.com/stephenb/sendgrid](http://github.com/stephenb/sendgrid)
89
+ * [https://github.com/kylejginavan/sendgrid_smtpapi](https://github.com/kylejginavan/sendgrid_smtpapi)
90
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'brightbytes/sendgrid/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "brightbytes-sendgrid"
8
+ spec.version = Brightbytes::Sendgrid::VERSION
9
+ spec.authors = ["Serhiy Rozum"]
10
+ spec.email = ["serhiy@brightbytes.net"]
11
+ spec.summary = %q{BrightBytes and Sendgrid integration gem}
12
+ spec.description = %q{Gem to extend ActionMailer with SMTP API support}
13
+ spec.homepage = "https://github.com/brightbytes/brightbytes-sendgrid"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake", "~> 10.1"
23
+ spec.add_development_dependency "rspec", "~> 2.14"
24
+ spec.add_development_dependency "actionmailer", "~> 3.2"
25
+
26
+ spec.add_dependency "activesupport", "~> 3.2"
27
+ end
@@ -0,0 +1,61 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+ require 'brightbytes/sendgrid/smtp_api_header'
4
+ require 'brightbytes/sendgrid/config'
5
+ require 'brightbytes/sendgrid/unsubscribe'
6
+ require 'brightbytes/sendgrid/version'
7
+
8
+ module Brightbytes
9
+ module Sendgrid
10
+ extend ActiveSupport::Concern
11
+
12
+ autoload :SmtpApiHeader, 'sendgrid/smtp_api_header'
13
+ autoload :Config, 'sendgrid/config'
14
+ autoload :Unsubscribe, 'sendgrid/unsubscribe'
15
+ autoload :VERSION, 'sendgrid/version'
16
+
17
+ included do
18
+ delegate *Brightbytes::Sendgrid::SmtpApiHeader::DELEGATE_METHODS, to: :sendgrid, prefix: true
19
+ alias_method_chain :mail, :sendgrid
20
+ end
21
+
22
+ protected
23
+
24
+ def sendgrid
25
+ @sendgrid ||= Brightbytes::Sendgrid::SmtpApiHeader.new(self.class.sendgrid.data)
26
+ end
27
+
28
+ def mail_with_sendgrid(headers={}, &block)
29
+ mail_without_sendgrid(headers, &block).tap do |message|
30
+ # Add Unsubscribe links
31
+ Brightbytes::Sendgrid::Unsubscribe.add_links(sendgrid, message)
32
+ # Store Sendgrid in Message for future use
33
+ message.instance_variable_set :@sendgrid, sendgrid
34
+ # Add X-SMTPAPI Header
35
+ message.header['X-SMTPAPI'] = sendgrid.to_json if sendgrid.data.present?
36
+ end
37
+ end
38
+
39
+ module ClassMethods
40
+
41
+ delegate *Brightbytes::Sendgrid::SmtpApiHeader::DELEGATE_METHODS, to: :sendgrid, prefix: true
42
+
43
+ def sendgrid
44
+ @sendgrid ||= Brightbytes::Sendgrid::SmtpApiHeader.new(Brightbytes::Sendgrid.config.sendgrid.data)
45
+ end
46
+
47
+ end
48
+
49
+ class << self
50
+
51
+ def config
52
+ Brightbytes::Sendgrid::Config.instance
53
+ end
54
+
55
+ def configure
56
+ yield(self.config) if block_given?
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,34 @@
1
+ require 'singleton'
2
+
3
+ module Brightbytes
4
+ module Sendgrid
5
+ class Config
6
+ include Singleton
7
+
8
+ # Sendgrid default settings storage
9
+
10
+ delegate *Brightbytes::Sendgrid::SmtpApiHeader::DELEGATE_METHODS, to: :sendgrid, prefix: :default
11
+
12
+ def sendgrid
13
+ @sendgrid ||= Brightbytes::Sendgrid::SmtpApiHeader.new
14
+ end
15
+
16
+ # Unsubscribe default settings storage
17
+
18
+ class UnsubscribeConfig < Struct.new(:categories, :url); end
19
+
20
+ def unsubscribe
21
+ @unsubscribe ||= UnsubscribeConfig.new([],nil)
22
+ end
23
+
24
+ def unsubscribe_categories(*categories)
25
+ unsubscribe.categories = categories.flatten.map(&:to_sym)
26
+ end
27
+
28
+ def unsubscribe_url(url)
29
+ unsubscribe.url = url
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,130 @@
1
+ require 'json'
2
+
3
+ module Brightbytes
4
+ module Sendgrid
5
+ class SmtpApiHeader
6
+
7
+ DELEGATE_METHODS = [
8
+ :substitute,
9
+ :add_substitute,
10
+ :section,
11
+ :unique_args,
12
+ :categories,
13
+ :add_categories,
14
+ :recipients,
15
+ :add_recipients,
16
+ :filter_setting,
17
+ :enable,
18
+ :disable,
19
+ :ganalytics_options
20
+ ]
21
+
22
+ VALID_FILTERS = [
23
+ :bcc,
24
+ :dkim,
25
+ :domainkeys,
26
+ :forwardspam,
27
+ :opentrack,
28
+ :clicktrack,
29
+ :ganalytics,
30
+ :gravatar,
31
+ :subscriptiontrack,
32
+ :template,
33
+ :footer,
34
+ :spamcheck,
35
+ :bypass_list_management
36
+ ]
37
+
38
+ VALID_GANALYTICS_OPTIONS = [
39
+ :utm_source,
40
+ :utm_medium,
41
+ :utm_campaign,
42
+ :utm_term,
43
+ :utm_content
44
+ ]
45
+
46
+ SUBST_PATTERN = '{{\1}}'
47
+
48
+ attr_reader :data
49
+
50
+ def initialize(default_data = nil)
51
+ @data = default_data.instance_of?(Hash) ? default_data.dup : Hash.new { |h,k| h[k] = Hash.new(&h.default_proc) }
52
+ end
53
+
54
+ def substitute(key, values)
55
+ @data[:sub][key_to_tag(key)] = Array.wrap(values)
56
+ end
57
+
58
+ def add_substitute(key, values)
59
+ @data[:sub][key_to_tag(key)] = [] unless @data[:sub][key_to_tag(key)].instance_of?(Array)
60
+ @data[:sub][key_to_tag(key)] += Array.wrap(values)
61
+ end
62
+
63
+ def section(key, value)
64
+ @data[:section][key_to_tag(key)] = value.to_s
65
+ end
66
+
67
+ def unique_args(value)
68
+ @data[:unique_args] = value if value.instance_of?(Hash)
69
+ end
70
+
71
+ # getter/setter
72
+ def categories(*categories)
73
+ @data[:category] = categories.flatten.map(&:to_sym) if categories.flatten.present?
74
+ @data.fetch(:category, [])
75
+ end
76
+
77
+ def add_categories(*categories)
78
+ init_array_key :category
79
+ @data[:category] |= categories.flatten.map(&:to_sym)
80
+ end
81
+
82
+ # getter/setter
83
+ def recipients(*recipients)
84
+ @data[:to] = recipients.flatten if recipients.flatten.present?
85
+ @data.fetch(:to, [])
86
+ end
87
+
88
+ def add_recipients(*recipients)
89
+ init_array_key :to
90
+ @data[:to] += recipients.flatten
91
+ end
92
+
93
+ def filter_setting(filter, setting, value)
94
+ return unless VALID_FILTERS.include? filter
95
+ @data[:filters][filter][:settings][setting] = value
96
+ end
97
+
98
+ def enable(*filters)
99
+ filters.flatten.each { |filter| filter_setting filter, :enabled, 1 }
100
+ end
101
+
102
+ def disable(*filters)
103
+ filters.flatten.each { |filter| filter_setting filter, :enabled, 0 }
104
+ end
105
+
106
+ def ganalytics_options(options = {})
107
+ options.reject! { |k,v| !VALID_GANALYTICS_OPTIONS.include?(k) }
108
+ if options.present?
109
+ options.each { |setting, value| filter_setting :ganalytics, setting, value }
110
+ enable :ganalytics
111
+ end
112
+ end
113
+
114
+ def to_json
115
+ JSON.generate(@data, {indent: '', space: ' ', space_before: '', object_nl: '', array_nl: ''})
116
+ end
117
+
118
+ private
119
+
120
+ def key_to_tag(key)
121
+ key.is_a?(Symbol) ? key.to_s.sub(/(.*)/, SUBST_PATTERN) : key.to_s
122
+ end
123
+
124
+ def init_array_key(key)
125
+ @data[key] = [] unless @data[key].instance_of?(Array)
126
+ end
127
+
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,78 @@
1
+ # Unsubscribe feature have some conventions:
2
+ # - {{unsubscribe}} substitution variable must be placed somewhere in email template or body
3
+ #
4
+ module Brightbytes
5
+ module Sendgrid
6
+ class Unsubscribe
7
+
8
+ class << self
9
+
10
+ def add_links(sendgrid, message)
11
+ new(sendgrid, message).add_links
12
+ end
13
+
14
+ end
15
+
16
+ attr_reader :sendgrid
17
+ attr_reader :message
18
+
19
+ def initialize(sendgrid, message)
20
+ @sendgrid, @message = sendgrid, message
21
+ end
22
+
23
+ def add_links
24
+ return unless feature_active?
25
+ if categories.present?
26
+ sendgrid.section :unsubscribe, "<a href=\"{{unsubscribe_link}}\">Unsubscribe</a>"
27
+ emails.each do |email|
28
+ sendgrid.add_substitute :unsubscribe_link, unsubscribe_link(email)
29
+ end
30
+ else
31
+ sendgrid.section :unsubscribe, ''
32
+ sendgrid.add_substitute :unsubscribe_link, Array.new(emails.size, '')
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def config
39
+ Brightbytes::Sendgrid.config.unsubscribe
40
+ end
41
+
42
+ delegate :categories, :url, to: :config, prefix: :unsubscribe
43
+
44
+ def feature_active?
45
+ unsubscribe_categories.present? || unsubscribe_url.present?
46
+ end
47
+
48
+ def categories
49
+ @categories ||= unsubscribe_categories & sendgrid.categories
50
+ end
51
+
52
+ def emails
53
+ @emails ||= recipients.map{ |e| e =~ /([^<]+)\s<(.*)>|(.*)/; $2 || $3 }
54
+ end
55
+
56
+ def recipients
57
+ sendgrid.recipients + message_recipients
58
+ end
59
+
60
+ def message_recipients
61
+ Array.wrap(message.to) + Array.wrap(message.cc) + Array.wrap(message.bcc)
62
+ end
63
+
64
+ def unsubscribe_link(email)
65
+ if unsubscribe_url.instance_of? Proc
66
+ unsubscribe_url.call(email: email, category: categories)
67
+ else
68
+ "#{unsubscribe_url}#{unsubscribe_url[-1] == '?' ? '' : '?'}#{url_parameters(email)}"
69
+ end
70
+ end
71
+
72
+ def url_parameters(email)
73
+ URI.encode_www_form(email: email, category: categories)
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,5 @@
1
+ module Brightbytes
2
+ module Sendgrid
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe Brightbytes::Sendgrid::SmtpApiHeader do
4
+
5
+ let(:header) { described_class.new }
6
+
7
+ subject { header.to_json }
8
+
9
+ it { should eql '{}' }
10
+
11
+ it "contains substitution" do
12
+ header.substitute :key, 'Hello'
13
+ should eql '{"sub": {"{{key}}": ["Hello"]}}'
14
+ end
15
+
16
+ it "adds substitution" do
17
+ header.substitute :key, 'Hello'
18
+ header.add_substitute :key, ['Again', 'And Again']
19
+ should eql '{"sub": {"{{key}}": ["Hello","Again","And Again"]}}'
20
+ end
21
+
22
+ it "contains section" do
23
+ header.section :key, 'Hello'
24
+ should eql '{"section": {"{{key}}": "Hello"}}'
25
+ end
26
+
27
+ it "contains category" do
28
+ header.categories :category_name
29
+ should eql '{"category": ["category_name"]}'
30
+ end
31
+
32
+ it "adds category" do
33
+ header.categories :category_name
34
+ header.add_categories :new_category, :category_name
35
+ should eql '{"category": ["category_name","new_category"]}'
36
+ end
37
+
38
+ it "contains 1 recipient (as array)" do
39
+ header.recipients 'email1@email.com'
40
+ should eql '{"to": ["email1@email.com"]}'
41
+ end
42
+
43
+ it "adds recipients" do
44
+ header.recipients 'email1@email.com'
45
+ header.add_recipients 'email2@email.com'
46
+ should eql '{"to": ["email1@email.com","email2@email.com"]}'
47
+ end
48
+
49
+ it "contains unique args" do
50
+ header.unique_args arg1: 'val1'
51
+ should eql '{"unique_args": {"arg1": "val1"}}'
52
+ end
53
+
54
+ it "contains valid filter settings" do
55
+ header.filter_setting :opentrack, :setting, 'value'
56
+ should eql '{"filters": {"opentrack": {"settings": {"setting": "value"}}}}'
57
+ end
58
+
59
+ it "skips invalid filter settings" do
60
+ header.filter_setting :somefilter, :setting, 'value'
61
+ should eql '{}'
62
+ end
63
+
64
+ it "enables filters" do
65
+ header.enable :opentrack, :bcc
66
+ should eql '{"filters": {"opentrack": {"settings": {"enabled": 1}},"bcc": {"settings": {"enabled": 1}}}}'
67
+ end
68
+
69
+ it "disables filters" do
70
+ header.disable :opentrack, :bcc
71
+ should eql '{"filters": {"opentrack": {"settings": {"enabled": 0}},"bcc": {"settings": {"enabled": 0}}}}'
72
+ end
73
+
74
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Brightbytes::Sendgrid::VERSION do
4
+ it "should be a version number" do
5
+ should_not be_nil
6
+ end
7
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe SendgridMailer do
4
+
5
+ let(:header) { subject.header.to_s.gsub(/\r|\n/, "") }
6
+
7
+ describe "when sendgrid default category is set" do
8
+ subject(:message) { described_class.default_category }
9
+
10
+ it 'header should have category' do
11
+ header.should include('"category": ["system"]')
12
+ end
13
+ end
14
+
15
+ describe "when sendgrid category is set" do
16
+ subject(:message) { described_class.new_category }
17
+
18
+ it 'header should have new category' do
19
+ header.should include('"category": ["new_category"]')
20
+ end
21
+ end
22
+
23
+ describe "when sendgrid recipients are set" do
24
+ subject(:message) { described_class.with_recipients }
25
+
26
+ it 'header should have recipients' do
27
+ header.should include('"to": ["email1@email.com","email2@email.com"]')
28
+ end
29
+ end
30
+
31
+ describe "when unsubscribe not required" do
32
+ subject(:message) { described_class.unsubscribe_not_required }
33
+
34
+ before(:each) { sendgrid_config_setup }
35
+
36
+ it 'unsubscribe section should be empty' do
37
+ header.should include('"{{unsubscribe}}": ""')
38
+ end
39
+ end
40
+
41
+ describe "when unsubscribe required" do
42
+ subject(:message) { described_class.unsubscribe_required }
43
+
44
+ before(:each) { sendgrid_config_setup }
45
+
46
+ it 'unsubscribe section should be set' do
47
+ header.should include('"{{unsubscribe}}": "<a href=\"{{unsubscribe_link}}\">Unsubscribe</a>"')
48
+ end
49
+
50
+ it 'unsubscribe link should be set' do
51
+ header.should include('"{{unsubscribe_link}}": ["http://example.com/u?email=email1%40email.com&category=unsubscribe","http://example.com/u?email=email2%40email.com&category=unsubscribe","http://example.com/u?email=email%40email.com&category=unsubscribe"]')
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Brightbytes::Sendgrid do
4
+
5
+ describe "config" do
6
+
7
+ subject { described_class.config }
8
+
9
+ it "should be an instance of Config " do
10
+ should be_instance_of Brightbytes::Sendgrid::Config
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe StandardMailer do
4
+
5
+ let(:header) { subject.header.to_s.gsub(/\r|\n/, "") }
6
+
7
+ describe "when sendgrid not engaged" do
8
+ subject(:message) { described_class.sendgrid_not_engaged }
9
+
10
+ it 'header should not be set' do
11
+ header.should_not include('X-SMTPAPI:')
12
+ end
13
+ end
14
+
15
+ describe "when unsubscribe not required" do
16
+ subject(:message) { described_class.unsubscribe_not_required }
17
+
18
+ before(:each) { sendgrid_config_setup }
19
+
20
+ it 'unsubscribe section should be empty' do
21
+ header.should include('"{{unsubscribe}}": ""')
22
+ end
23
+ end
24
+
25
+ describe "when unsubscribe required" do
26
+ subject(:message) { described_class.unsubscribe_required }
27
+
28
+ before(:each) { sendgrid_config_setup }
29
+
30
+ it 'unsubscribe section should be set' do
31
+ header.should include('"{{unsubscribe}}": "<a href=\"{{unsubscribe_link}}\">Unsubscribe</a>"')
32
+ end
33
+
34
+ it 'unsubscribe link should be set' do
35
+ header.should include('"{{unsubscribe_link}}": ["http://example.com/u?email=email%40email.com&category=unsubscribe"]')
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,33 @@
1
+ class SendgridMailer < ActionMailer::Base
2
+ default from: 'noreply@brightbytes.net',
3
+ subject: 'Clarity'
4
+
5
+ sendgrid_categories :system
6
+
7
+ def default_category
8
+ mail to: 'email@email.com', body: 'Hello!'
9
+ end
10
+
11
+ def new_category
12
+ sendgrid_categories :new_category
13
+ mail to: 'email@email.com', body: 'Hello!'
14
+ end
15
+
16
+ def with_recipients
17
+ sendgrid_recipients 'email1@email.com', 'email2@email.com'
18
+ mail to: 'email@email.com', body: 'Hello!'
19
+ end
20
+
21
+ def unsubscribe_not_required
22
+ sendgrid_recipients 'email1@email.com', 'email2@email.com'
23
+ mail to: 'email@email.com', body: 'Hello!'
24
+ end
25
+
26
+ def unsubscribe_required
27
+ sendgrid_recipients 'email1@email.com', 'email2@email.com'
28
+ sendgrid_categories :unsubscribe
29
+ mail to: 'email@email.com', body: 'Hello!'
30
+ end
31
+
32
+
33
+ end
@@ -0,0 +1,18 @@
1
+ class StandardMailer < ActionMailer::Base
2
+ default from: 'noreply@brightbytes.net',
3
+ subject: 'Clarity'
4
+
5
+ def sendgrid_not_engaged
6
+ mail to: 'email@email.com', body: 'Hello!'
7
+ end
8
+
9
+ def unsubscribe_not_required
10
+ mail to: 'email@email.com', body: 'Hello!'
11
+ end
12
+
13
+ def unsubscribe_required
14
+ sendgrid_categories :unsubscribe
15
+ mail to: 'email@email.com', body: 'Hello!'
16
+ end
17
+
18
+ end
@@ -0,0 +1,36 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'action_mailer'
3
+ require 'brightbytes/sendgrid'
4
+
5
+ ActionMailer::Base.delivery_method = :test
6
+ ActionMailer::Base.perform_deliveries = true
7
+ ActionMailer::Base.deliveries = []
8
+
9
+ ActionMailer::Base.send :include, Brightbytes::Sendgrid
10
+
11
+ Dir["#{File.dirname(__FILE__)}/mailers/*.rb"].each { |f| require f }
12
+
13
+ def sendgrid_config_setup
14
+ Brightbytes::Sendgrid.configure do |config|
15
+ config.unsubscribe_categories :unsubscribe
16
+ config.unsubscribe_url 'http://example.com/u'
17
+ end
18
+ end
19
+
20
+ def sendgrid_config_reset
21
+ Brightbytes::Sendgrid.configure do |config|
22
+ config.unsubscribe_categories []
23
+ config.unsubscribe_url nil
24
+ end
25
+ end
26
+
27
+ RSpec.configure do |config|
28
+
29
+ config.after(:each) do
30
+ Brightbytes::Sendgrid.configure do |config|
31
+ config.unsubscribe_categories []
32
+ config.unsubscribe_url nil
33
+ end
34
+ end
35
+
36
+ end
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: brightbytes-sendgrid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Serhiy Rozum
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: actionmailer
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '3.2'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '3.2'
83
+ description: Gem to extend ActionMailer with SMTP API support
84
+ email:
85
+ - serhiy@brightbytes.net
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - .rspec
92
+ - .ruby-gemset
93
+ - .ruby-version
94
+ - .travis.yml
95
+ - Gemfile
96
+ - LICENSE.txt
97
+ - MIT-LICENSE
98
+ - README.md
99
+ - Rakefile
100
+ - brightbytes-sendgrid.gemspec
101
+ - lib/brightbytes/sendgrid.rb
102
+ - lib/brightbytes/sendgrid/config.rb
103
+ - lib/brightbytes/sendgrid/smtp_api_header.rb
104
+ - lib/brightbytes/sendgrid/unsubscribe.rb
105
+ - lib/brightbytes/sendgrid/version.rb
106
+ - spec/brightbytes/sendgrid/smtp_api_header_spec.rb
107
+ - spec/brightbytes/sendgrid/version_spec.rb
108
+ - spec/brightbytes/sendgrid_mailer_spec.rb
109
+ - spec/brightbytes/sendgrid_spec.rb
110
+ - spec/brightbytes/standard_mailer_spec.rb
111
+ - spec/mailers/sendgrid_mailer.rb
112
+ - spec/mailers/standard_mailer.rb
113
+ - spec/spec_helper.rb
114
+ homepage: https://github.com/brightbytes/brightbytes-sendgrid
115
+ licenses:
116
+ - MIT
117
+ metadata: {}
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 2.2.1
135
+ signing_key:
136
+ specification_version: 4
137
+ summary: BrightBytes and Sendgrid integration gem
138
+ test_files:
139
+ - spec/brightbytes/sendgrid/smtp_api_header_spec.rb
140
+ - spec/brightbytes/sendgrid/version_spec.rb
141
+ - spec/brightbytes/sendgrid_mailer_spec.rb
142
+ - spec/brightbytes/sendgrid_spec.rb
143
+ - spec/brightbytes/standard_mailer_spec.rb
144
+ - spec/mailers/sendgrid_mailer.rb
145
+ - spec/mailers/standard_mailer.rb
146
+ - spec/spec_helper.rb