fluent-plugin-sendgrid-event 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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/Gemfile +4 -0
- data/README.md +47 -0
- data/Rakefile +10 -0
- data/fluent-plugin-sendgrid-event.gemspec +25 -0
- data/lib/fluent/plugin/in_sendgrid_event.rb +83 -0
- data/test/helper.rb +28 -0
- data/test/plugin/test_in_sendgrid_event.rb +134 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: af4ed2dd208e0d2ee36d2a06ff960dd1456cc82d
|
4
|
+
data.tar.gz: db3a6d8ce63603e354f3248168f8f0214170f1c1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b9d8efaf4a385570a44231b0a244a21d3aaa94e23637a19acc58e511e365b8d0e5e605345fb3b23a7a01d222fe7e75f3fd4db2357c6c027a039d13f3899b1f09
|
7
|
+
data.tar.gz: 89a2bb97ba30d6dec52de424e5b80dbf31bdd0a2e11ffa73539389189b48be9250c41834076803bdbec3e06b3dd094ecad909f2f3dc029ddf34020aa47dc813d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# fluent-plugin-sendgrid-event
|
2
|
+
|
3
|
+
Fluentd input plugin to receive sendgrid event.
|
4
|
+
|
5
|
+
SendGrid is a delivering email platform. Please visit below link for the specification of event webhook.
|
6
|
+
https://sendgrid.com/docs/API_Reference/Webhooks/event.html
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'fluent-plugin-sendgrid-event'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install fluent-plugin-sendgrid-event
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
The following is an example of configuration.
|
27
|
+
|
28
|
+
```
|
29
|
+
<source>
|
30
|
+
type sendgrid_event
|
31
|
+
host 127.0.0.1
|
32
|
+
port 9191
|
33
|
+
tag sendgrid
|
34
|
+
</source>
|
35
|
+
```
|
36
|
+
|
37
|
+
## Contributing
|
38
|
+
|
39
|
+
1. Fork it ( http://github.com/hiroakis/fluent-plugin-sendgrid-event/fork )
|
40
|
+
2. Create your feature branch (git checkout -b my-new-feature)
|
41
|
+
3. Commit your changes (git commit -am 'Add some feature')
|
42
|
+
4. Push to the branch (git push origin my-new-feature)
|
43
|
+
5. Create new Pull Request
|
44
|
+
|
45
|
+
## License
|
46
|
+
|
47
|
+
MIT
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "fluent-plugin-sendgrid-event"
|
7
|
+
spec.version = "0.0.1"
|
8
|
+
spec.authors = ["Hiroaki Sano"]
|
9
|
+
spec.email = ["hiroaki.sano.9stories@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{Fluent input plugin to receive sendgrid event.}
|
12
|
+
spec.homepage = "https://github.com/hiroakis/fluent-plugin-sendgrid-event"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split("\n")
|
16
|
+
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
21
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
22
|
+
spec.add_development_dependency "test-unit"
|
23
|
+
|
24
|
+
spec.add_runtime_dependency "fluentd"
|
25
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Fluent
|
2
|
+
class SendGridEventInput < Input
|
3
|
+
Plugin.register_input('sendgrid_event', self)
|
4
|
+
|
5
|
+
config_param :tag, :string, :default => nil
|
6
|
+
config_param :host, :string, :default => "0.0.0.0"
|
7
|
+
config_param :port, :integer, :default => 9191
|
8
|
+
config_param :request_uri, :string, :default => "/"
|
9
|
+
|
10
|
+
unless method_defined?(:log)
|
11
|
+
define_method("log") { $log }
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def configure(conf)
|
19
|
+
log.trace "in_sendgrid_event: configure"
|
20
|
+
super
|
21
|
+
|
22
|
+
if @tag.nil?
|
23
|
+
raise Fluent::ConfigError, "sendgrid_event: 'tag' parameter is required"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def start
|
28
|
+
log.trace "in_sendgrid_event: start"
|
29
|
+
super
|
30
|
+
|
31
|
+
@thread = Thread.new(&method(:run))
|
32
|
+
end
|
33
|
+
|
34
|
+
def shutdown
|
35
|
+
log.trace "in_sendgrid_event: shutdown"
|
36
|
+
super
|
37
|
+
|
38
|
+
@server.shutdown
|
39
|
+
Thread.kill(@thread)
|
40
|
+
end
|
41
|
+
|
42
|
+
def run
|
43
|
+
log.trace "in_sendgrid_event: run"
|
44
|
+
listen = {
|
45
|
+
:BindAddress => @host,
|
46
|
+
:Port => @port
|
47
|
+
}
|
48
|
+
|
49
|
+
@server = WEBrick::HTTPServer.new(listen)
|
50
|
+
@server.mount_proc(@request_uri) do |req, res|
|
51
|
+
begin
|
52
|
+
if req.request_method == "POST" && req.body
|
53
|
+
events = JSON.parse(req.body)
|
54
|
+
events.each do |event|
|
55
|
+
emit_event(event)
|
56
|
+
end
|
57
|
+
log.trace "in_sendgrid_event: success"
|
58
|
+
res.status = 200
|
59
|
+
else
|
60
|
+
log.error "in_sendgrid_event: invalid request"
|
61
|
+
res.status = 400
|
62
|
+
end
|
63
|
+
rescue JSON::ParserError => e
|
64
|
+
log.error "in_sendgrid_event: #{e}"
|
65
|
+
res.status = 400
|
66
|
+
rescue WEBrick::HTTPStatus::LengthRequired => e
|
67
|
+
log.error "in_sendgrid_event: #{e}"
|
68
|
+
res.status = 411
|
69
|
+
rescue Exception => e
|
70
|
+
log.warn "in_sendgrid_event: Retry: Reason: #{e}"
|
71
|
+
log.warn "#{e.backtrace.join('\n')}"
|
72
|
+
res.status = 503
|
73
|
+
end
|
74
|
+
end
|
75
|
+
@server.start
|
76
|
+
end # The end of run method
|
77
|
+
|
78
|
+
def emit_event(event)
|
79
|
+
log.trace "in_sendgrid_event: emit_event"
|
80
|
+
Engine.emit("#{tag}", Engine.now, event)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
13
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
14
|
+
require 'fluent/test'
|
15
|
+
unless ENV.has_key?('VERBOSE')
|
16
|
+
nulllogger = Object.new
|
17
|
+
nulllogger.instance_eval {|obj|
|
18
|
+
def method_missing(method, *args)
|
19
|
+
# pass
|
20
|
+
end
|
21
|
+
}
|
22
|
+
$log = nulllogger
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'fluent/plugin/in_sendgrid_event'
|
26
|
+
|
27
|
+
class Test::Unit::TestCase
|
28
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class SendGridEventTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
Fluent::Test.setup
|
7
|
+
end
|
8
|
+
|
9
|
+
CONFIG = %[
|
10
|
+
type sendgrid_event
|
11
|
+
host 127.0.0.1
|
12
|
+
port 9191
|
13
|
+
tag sendgrid.event
|
14
|
+
]
|
15
|
+
|
16
|
+
def create_driver(conf=CONFIG, tag='test')
|
17
|
+
Fluent::Test::OutputTestDriver.new(Fluent::SendGridEventInput, tag).configure(conf)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_configuration
|
21
|
+
d = create_driver
|
22
|
+
assert_equal '127.0.0.1', d.instance.host
|
23
|
+
assert_equal 9191, d.instance.port
|
24
|
+
assert_equal 'sendgrid.event', d.instance.tag
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_configuration_with_empty_tag
|
28
|
+
assert_raise(Fluent::ConfigError) {
|
29
|
+
create_driver %[
|
30
|
+
type sendgrid_event
|
31
|
+
host 127.0.0.1
|
32
|
+
port 9191
|
33
|
+
# tag sendgrid.event
|
34
|
+
]
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
# This data is from https://sendgrid.com/docs/API_Reference/Webhooks/event.html
|
39
|
+
def valid_event_json
|
40
|
+
[
|
41
|
+
{
|
42
|
+
"sg_message_id":"sendgrid_internal_message_id",
|
43
|
+
"email": "john.doe@sendgrid.com",
|
44
|
+
"timestamp": 1337197600,
|
45
|
+
"smtp-id": "<4FB4041F.6080505@sendgrid.com>",
|
46
|
+
"event": "processed"
|
47
|
+
},
|
48
|
+
{
|
49
|
+
"sg_message_id":"sendgrid_internal_message_id",
|
50
|
+
"email": "john.doe@sendgrid.com",
|
51
|
+
"timestamp": 1337966815,
|
52
|
+
"category": "newuser",
|
53
|
+
"event": "click",
|
54
|
+
"url": "https://sendgrid.com"
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"sg_message_id":"sendgrid_internal_message_id",
|
58
|
+
"email": "john.doe@sendgrid.com",
|
59
|
+
"timestamp": 1337969592,
|
60
|
+
"smtp-id": "<20120525181309.C1A9B40405B3@Example-Mac.local>",
|
61
|
+
"event": "group_unsubscribe",
|
62
|
+
"asm_group_id": 42
|
63
|
+
}
|
64
|
+
].to_json
|
65
|
+
end
|
66
|
+
|
67
|
+
def invalid_event_json
|
68
|
+
valid_event_json.gsub!(":", ";")
|
69
|
+
end
|
70
|
+
|
71
|
+
def send_event(post_data)
|
72
|
+
require 'net/http'
|
73
|
+
http = Net::HTTP.new("localhost", 9191)
|
74
|
+
req = Net::HTTP::Post.new('/')
|
75
|
+
req.body = post_data
|
76
|
+
req["Content-Type"] = "application/json"
|
77
|
+
res = http.request(req)
|
78
|
+
res
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_with_valid_event_json
|
82
|
+
d = create_driver %[
|
83
|
+
type sendgrid_event
|
84
|
+
host 127.0.0.1
|
85
|
+
port 9191
|
86
|
+
tag sendgrid.event
|
87
|
+
]
|
88
|
+
|
89
|
+
d.run do
|
90
|
+
res = send_event(valid_event_json)
|
91
|
+
assert_equal("200", res.code)
|
92
|
+
end
|
93
|
+
|
94
|
+
assert_equal(3, d.emits.size)
|
95
|
+
|
96
|
+
assert_equal("sendgrid.event", d.emits[0][0])
|
97
|
+
assert_equal("sendgrid_internal_message_id", d.emits[0][2]["sg_message_id"])
|
98
|
+
assert_equal("john.doe@sendgrid.com", d.emits[0][2]["email"])
|
99
|
+
assert_equal(1337197600, d.emits[0][2]["timestamp"])
|
100
|
+
assert_equal("<4FB4041F.6080505@sendgrid.com>", d.emits[0][2]["smtp-id"])
|
101
|
+
assert_equal("processed", d.emits[0][2]["event"])
|
102
|
+
|
103
|
+
assert_equal("sendgrid.event", d.emits[1][0])
|
104
|
+
assert_equal("sendgrid_internal_message_id", d.emits[1][2]["sg_message_id"])
|
105
|
+
assert_equal("john.doe@sendgrid.com", d.emits[1][2]["email"])
|
106
|
+
assert_equal(1337966815, d.emits[1][2]["timestamp"])
|
107
|
+
assert_equal("newuser", d.emits[1][2]["category"])
|
108
|
+
assert_equal("click", d.emits[1][2]["event"])
|
109
|
+
assert_equal("https://sendgrid.com", d.emits[1][2]["url"])
|
110
|
+
|
111
|
+
assert_equal("sendgrid.event", d.emits[2][0])
|
112
|
+
assert_equal("sendgrid_internal_message_id", d.emits[2][2]["sg_message_id"])
|
113
|
+
assert_equal("john.doe@sendgrid.com", d.emits[2][2]["email"])
|
114
|
+
assert_equal(1337969592, d.emits[2][2]["timestamp"])
|
115
|
+
assert_equal("<20120525181309.C1A9B40405B3@Example-Mac.local>", d.emits[2][2]["smtp-id"])
|
116
|
+
assert_equal("group_unsubscribe", d.emits[2][2]["event"])
|
117
|
+
assert_equal(42, d.emits[2][2]["asm_group_id"])
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_invalid_event_json
|
121
|
+
d = create_driver %[
|
122
|
+
type sendgrid_event
|
123
|
+
host 127.0.0.1
|
124
|
+
port 9191
|
125
|
+
tag sendgrid.event
|
126
|
+
]
|
127
|
+
|
128
|
+
d.run do
|
129
|
+
res = send_event(invalid_event_json)
|
130
|
+
assert_equal("400", res.code)
|
131
|
+
end
|
132
|
+
assert_equal(0, d.emits.size)
|
133
|
+
end
|
134
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-sendgrid-event
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hiroaki Sano
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-14 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.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
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.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: test-unit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: fluentd
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- hiroaki.sano.9stories@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- Gemfile
|
78
|
+
- README.md
|
79
|
+
- Rakefile
|
80
|
+
- fluent-plugin-sendgrid-event.gemspec
|
81
|
+
- lib/fluent/plugin/in_sendgrid_event.rb
|
82
|
+
- test/helper.rb
|
83
|
+
- test/plugin/test_in_sendgrid_event.rb
|
84
|
+
homepage: https://github.com/hiroakis/fluent-plugin-sendgrid-event
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 2.4.5
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Fluent input plugin to receive sendgrid event.
|
108
|
+
test_files:
|
109
|
+
- test/helper.rb
|
110
|
+
- test/plugin/test_in_sendgrid_event.rb
|