sendgrid_events 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rvmrc +5 -0
- data/.travis.yml +4 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +141 -0
- data/MIT-LICENSE +20 -0
- data/README.md +33 -0
- data/Rakefile +13 -0
- data/app/controllers/sendgrid_events/sendgrid_events_controller.rb +8 -0
- data/app/models/sendgrid_events/sendgrid_email_record.rb +14 -0
- data/lib/generators/sendgrid_events/install/templates/initializer.rb +5 -0
- data/lib/generators/sendgrid_events/install/templates/routes.rb +2 -0
- data/lib/generators/sendgrid_events/install/templates/sendgrid_events_table.rb +16 -0
- data/lib/generators/sendgrid_events/install_generator.rb +34 -0
- data/lib/sendgrid_events.rb +8 -0
- data/lib/sendgrid_events/action_mailer_override.rb +23 -0
- data/lib/sendgrid_events/configure.rb +23 -0
- data/lib/sendgrid_events/engine.rb +12 -0
- data/lib/sendgrid_events/handlers.rb +3 -0
- data/lib/sendgrid_events/handlers/base.rb +50 -0
- data/lib/sendgrid_events/handlers/bounced.rb +7 -0
- data/lib/sendgrid_events/handlers/clicked.rb +7 -0
- data/lib/sendgrid_events/handlers/deferred.rb +7 -0
- data/lib/sendgrid_events/handlers/delivered.rb +10 -0
- data/lib/sendgrid_events/handlers/dispatch.rb +34 -0
- data/lib/sendgrid_events/handlers/dropped.rb +7 -0
- data/lib/sendgrid_events/handlers/opened.rb +7 -0
- data/lib/sendgrid_events/handlers/processed.rb +7 -0
- data/lib/sendgrid_events/handlers/spam_reported.rb +7 -0
- data/lib/sendgrid_events/handlers/unsubscribed.rb +7 -0
- data/lib/sendgrid_events/receiver.rb +18 -0
- data/lib/sendgrid_events/version.rb +3 -0
- data/script/rails +8 -0
- data/sendgrid_events.gemspec +28 -0
- data/spec/sendgrid_events/handlers/base_spec.rb +47 -0
- data/spec/sendgrid_events/handlers/bounced_spec.rb +31 -0
- data/spec/sendgrid_events/handlers/clicked_spec.rb +31 -0
- data/spec/sendgrid_events/handlers/deferred_spec.rb +31 -0
- data/spec/sendgrid_events/handlers/delivered_spec.rb +31 -0
- data/spec/sendgrid_events/handlers/dispatch_spec.rb +8 -0
- data/spec/sendgrid_events/handlers/dropped_spec.rb +31 -0
- data/spec/sendgrid_events/handlers/opened_spec.rb +31 -0
- data/spec/sendgrid_events/handlers/processed_spec.rb +31 -0
- data/spec/sendgrid_events/handlers/spam_reported_spec.rb +31 -0
- data/spec/sendgrid_events/handlers/unsubscribed_spec.rb +31 -0
- data/spec/sendgrid_events/receiver_spec.rb +32 -0
- data/spec/spec_helper.rb +39 -0
- metadata +272 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sendgrid_events (0.0.1)
|
5
|
+
enumerated_field
|
6
|
+
rails (~> 3.0.15)
|
7
|
+
sendgrid
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
abstract (1.0.0)
|
13
|
+
actionmailer (3.0.15)
|
14
|
+
actionpack (= 3.0.15)
|
15
|
+
mail (~> 2.2.19)
|
16
|
+
actionpack (3.0.15)
|
17
|
+
activemodel (= 3.0.15)
|
18
|
+
activesupport (= 3.0.15)
|
19
|
+
builder (~> 2.1.2)
|
20
|
+
erubis (~> 2.6.6)
|
21
|
+
i18n (~> 0.5.0)
|
22
|
+
rack (~> 1.2.5)
|
23
|
+
rack-mount (~> 0.6.14)
|
24
|
+
rack-test (~> 0.5.7)
|
25
|
+
tzinfo (~> 0.3.23)
|
26
|
+
activemodel (3.0.15)
|
27
|
+
activesupport (= 3.0.15)
|
28
|
+
builder (~> 2.1.2)
|
29
|
+
i18n (~> 0.5.0)
|
30
|
+
activerecord (3.0.15)
|
31
|
+
activemodel (= 3.0.15)
|
32
|
+
activesupport (= 3.0.15)
|
33
|
+
arel (~> 2.0.10)
|
34
|
+
tzinfo (~> 0.3.23)
|
35
|
+
activeresource (3.0.15)
|
36
|
+
activemodel (= 3.0.15)
|
37
|
+
activesupport (= 3.0.15)
|
38
|
+
activesupport (3.0.15)
|
39
|
+
addressable (2.2.8)
|
40
|
+
arel (2.0.10)
|
41
|
+
awesome_print (1.0.2)
|
42
|
+
builder (2.1.2)
|
43
|
+
capybara (1.1.2)
|
44
|
+
mime-types (>= 1.16)
|
45
|
+
nokogiri (>= 1.3.3)
|
46
|
+
rack (>= 1.0.0)
|
47
|
+
rack-test (>= 0.5.4)
|
48
|
+
selenium-webdriver (~> 2.0)
|
49
|
+
xpath (~> 0.1.4)
|
50
|
+
childprocess (0.3.3)
|
51
|
+
ffi (~> 1.0.6)
|
52
|
+
diff-lcs (1.1.3)
|
53
|
+
enumerated_field (0.3.8)
|
54
|
+
activemodel (~> 3.0.0)
|
55
|
+
activesupport (~> 3.0.0)
|
56
|
+
erubis (2.6.6)
|
57
|
+
abstract (>= 1.0.0)
|
58
|
+
factory_girl (2.6.4)
|
59
|
+
activesupport (>= 2.3.9)
|
60
|
+
factory_girl_rails (1.7.0)
|
61
|
+
factory_girl (~> 2.6.0)
|
62
|
+
railties (>= 3.0.0)
|
63
|
+
ffi (1.0.11)
|
64
|
+
i18n (0.5.0)
|
65
|
+
json (1.7.3)
|
66
|
+
libwebsocket (0.1.4)
|
67
|
+
addressable
|
68
|
+
mail (2.2.19)
|
69
|
+
activesupport (>= 2.3.6)
|
70
|
+
i18n (>= 0.4.0)
|
71
|
+
mime-types (~> 1.16)
|
72
|
+
treetop (~> 1.4.8)
|
73
|
+
mime-types (1.19)
|
74
|
+
multi_json (1.3.6)
|
75
|
+
nokogiri (1.5.5)
|
76
|
+
polyglot (0.3.3)
|
77
|
+
rack (1.2.5)
|
78
|
+
rack-mount (0.6.14)
|
79
|
+
rack (>= 1.0.0)
|
80
|
+
rack-test (0.5.7)
|
81
|
+
rack (>= 1.0)
|
82
|
+
rails (3.0.15)
|
83
|
+
actionmailer (= 3.0.15)
|
84
|
+
actionpack (= 3.0.15)
|
85
|
+
activerecord (= 3.0.15)
|
86
|
+
activeresource (= 3.0.15)
|
87
|
+
activesupport (= 3.0.15)
|
88
|
+
bundler (~> 1.0)
|
89
|
+
railties (= 3.0.15)
|
90
|
+
railties (3.0.15)
|
91
|
+
actionpack (= 3.0.15)
|
92
|
+
activesupport (= 3.0.15)
|
93
|
+
rake (>= 0.8.7)
|
94
|
+
rdoc (~> 3.4)
|
95
|
+
thor (~> 0.14.4)
|
96
|
+
rake (0.9.2.2)
|
97
|
+
rdoc (3.12)
|
98
|
+
json (~> 1.4)
|
99
|
+
rspec (2.11.0)
|
100
|
+
rspec-core (~> 2.11.0)
|
101
|
+
rspec-expectations (~> 2.11.0)
|
102
|
+
rspec-mocks (~> 2.11.0)
|
103
|
+
rspec-core (2.11.0)
|
104
|
+
rspec-expectations (2.11.1)
|
105
|
+
diff-lcs (~> 1.1.3)
|
106
|
+
rspec-mocks (2.11.1)
|
107
|
+
rspec-rails (2.11.0)
|
108
|
+
actionpack (>= 3.0)
|
109
|
+
activesupport (>= 3.0)
|
110
|
+
railties (>= 3.0)
|
111
|
+
rspec (~> 2.11.0)
|
112
|
+
rubyzip (0.9.9)
|
113
|
+
selenium-webdriver (2.24.0)
|
114
|
+
childprocess (>= 0.2.5)
|
115
|
+
libwebsocket (~> 0.1.3)
|
116
|
+
multi_json (~> 1.0)
|
117
|
+
rubyzip
|
118
|
+
sendgrid (1.0.1)
|
119
|
+
json
|
120
|
+
json
|
121
|
+
sqlite3 (1.3.6)
|
122
|
+
thor (0.14.6)
|
123
|
+
treetop (1.4.10)
|
124
|
+
polyglot
|
125
|
+
polyglot (>= 0.3.1)
|
126
|
+
tzinfo (0.3.33)
|
127
|
+
xpath (0.1.4)
|
128
|
+
nokogiri (~> 1.3)
|
129
|
+
|
130
|
+
PLATFORMS
|
131
|
+
ruby
|
132
|
+
|
133
|
+
DEPENDENCIES
|
134
|
+
awesome_print
|
135
|
+
capybara
|
136
|
+
factory_girl_rails (~> 1.7)
|
137
|
+
rails (~> 3.0.15)
|
138
|
+
rake
|
139
|
+
rspec-rails (~> 2.6)
|
140
|
+
sendgrid_events!
|
141
|
+
sqlite3
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
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,33 @@
|
|
1
|
+
# SendgridEvents
|
2
|
+
|
3
|
+
SendgridEvents is a gem designed to give your application [Sendgrid postbacks](http://docs.sendgrid.com/documentation/api/event-api/).
|
4
|
+
With these postbacks you are more able to track the status of your emails programatically.
|
5
|
+
|
6
|
+
This gem creates a `SendgridEmailRecord` table for this tracking and you can attach handlers to specific
|
7
|
+
events.
|
8
|
+
|
9
|
+
# Installation
|
10
|
+
|
11
|
+
add
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'sendgrid_events'
|
15
|
+
```
|
16
|
+
|
17
|
+
to your Gemfile and run
|
18
|
+
|
19
|
+
```
|
20
|
+
bundle install
|
21
|
+
```
|
22
|
+
|
23
|
+
After that you'll want to run:
|
24
|
+
|
25
|
+
```
|
26
|
+
rails g sendgrid_events:install
|
27
|
+
rake db:migrate
|
28
|
+
```
|
29
|
+
|
30
|
+
Finally, you'll want to edit your `config/initializers/sendgrid_events.rb`. Currently
|
31
|
+
you just have the option to include or disclude certain event handlers.
|
32
|
+
|
33
|
+
This project rocks and uses MIT-LICENSE.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require "rspec/core/rake_task"
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
namespace :spec do
|
8
|
+
RSpec::Core::RakeTask.new(:docs) do |t|
|
9
|
+
t.rspec_opts = ["--format doc"]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
task :default => :spec
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SendgridEvents
|
2
|
+
class SendgridEmailRecord < ActiveRecord::Base
|
3
|
+
#belongs_to :sender, :polymorphic => true # What models can we use here?
|
4
|
+
# Message
|
5
|
+
include EnumeratedField
|
6
|
+
enum_field :status, [
|
7
|
+
%w[processing processing],
|
8
|
+
%w[dropped dropped],
|
9
|
+
%w[deferred deferred],
|
10
|
+
%w[bounced bounced],
|
11
|
+
%w[delivered delivered]
|
12
|
+
]
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateSendGridEmailRecordTable < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :sendgrid_email_records do |t|
|
4
|
+
t.string :status
|
5
|
+
t.string :to
|
6
|
+
t.string :from
|
7
|
+
t.string :subject
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :sendgrid_email_records
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
module SendgridEvents
|
3
|
+
module Generators
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
source_root File.expand_path "../install/templates", __FILE__
|
7
|
+
|
8
|
+
def self.next_migration_number(path)
|
9
|
+
unless @prev_migration_nr
|
10
|
+
@prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
|
11
|
+
else
|
12
|
+
@prev_migration_nr += 1
|
13
|
+
end
|
14
|
+
@prev_migration_nr.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def install_migrations
|
18
|
+
puts "Copying Sengrid Events migrations..."
|
19
|
+
migration_template "sendgrid_events_table.rb", "db/migrate/sendgrid_events_table.rb"
|
20
|
+
end
|
21
|
+
|
22
|
+
def install_initializer
|
23
|
+
puts "Copying initializer..."
|
24
|
+
copy_file "initializer.rb", "config/initializers/sendgrid_events.rb"
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_routes
|
28
|
+
insert_into_file Rails.root.join('config', 'routes.rb'),
|
29
|
+
File.open(File.join(File.expand_path("../install/templates", __FILE__), 'routes.rb')).read,
|
30
|
+
:after => /Application\.routes\.draw do$/
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'active_support/core_ext/string'
|
2
|
+
require 'sendgrid'
|
3
|
+
require 'sendgrid_events/version'
|
4
|
+
require 'sendgrid_events/engine'
|
5
|
+
require 'sendgrid_events/handlers'
|
6
|
+
require 'sendgrid_events/receiver'
|
7
|
+
require 'sendgrid_events/action_mailer_override'
|
8
|
+
require 'sendgrid_events/configure'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SendgridEvents
|
2
|
+
module ActionMailerOverride
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
alias_method_chain :sendgrid_unique_args, :merge_args
|
6
|
+
end
|
7
|
+
|
8
|
+
def sendgrid_unique_args_with_merge_args(args={})
|
9
|
+
@sg_unique_args ||= {}
|
10
|
+
@sg_unique_args.merge! args
|
11
|
+
end
|
12
|
+
|
13
|
+
def mail(headers={}, &block)
|
14
|
+
id = SendgridEmailRecord.create!(:to => headers[:to],
|
15
|
+
:from => headers[:from],
|
16
|
+
:subject => headers[:subject],
|
17
|
+
:status => 'processing').id
|
18
|
+
sendgrid_unique_args :sendgrid_events_id => id
|
19
|
+
super headers, &block
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
SendGrid.send :include, SendgridEvents::ActionMailerOverride
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SendgridEvents
|
2
|
+
class Configure
|
3
|
+
def self.mount_at(val = nil)
|
4
|
+
@mount_at ||= val
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.config(&block)
|
8
|
+
class_eval &block
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.handle(list)
|
12
|
+
Handlers::Dispatch.selected_handlers = list
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.receive(boolean)
|
16
|
+
@receive = boolean
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.receive?
|
20
|
+
@receive.nil? ? true : @receive
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ::SendgridEvents
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
config.mount_at = '/sendgrid_events/' #TODO Config file
|
4
|
+
class << self
|
5
|
+
attr_accessor :root
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.root
|
9
|
+
@root ||= Pathname.new(File.expand_path('../../', __FILE__))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module SendgridEvents
|
2
|
+
module Handlers
|
3
|
+
class Base
|
4
|
+
def self.registered_handlers
|
5
|
+
Dispatch.registered_handlers
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.selected_handlers
|
9
|
+
Dispatch.selected_handlers
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.acceptable_handlers
|
13
|
+
Dispatch.acceptable_handlers
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.choose_and_handle(event)
|
17
|
+
if registered_handlers[event[:event]] and selected_handlers[event[:event]]
|
18
|
+
registered_handlers[event[:event]].handle(event)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.register_as_handler_for(handlee)
|
23
|
+
if acceptable_handlers[handlee]
|
24
|
+
handlee = handlee.to_s
|
25
|
+
registered_handlers[handlee] = self.name.constantize
|
26
|
+
self.name.constantize.send :define_singleton_method, :handlee do
|
27
|
+
handlee
|
28
|
+
end
|
29
|
+
else
|
30
|
+
raise ArgumentError, "#{handlee.to_s.titleize} is not in the Dispatch's list of acceptable handlers"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.handler(&block)
|
35
|
+
block_given? ? @handler = block : @handler
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.handle(event)
|
39
|
+
found_event = find_and_update_event(event)
|
40
|
+
handler.call(found_event) unless found_event.nil? or handler.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.find_and_update_event(event)
|
44
|
+
SendgridEmailRecord.find_by_id(event[:sendgrid_events_id]).tap do |record|
|
45
|
+
record.update_attributes(:status => handlee) unless record.nil?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|