griddler-sendgrid 0.0.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: be5d9a9db3c7daa2c8becdb06c09410bfeea98e1
4
- data.tar.gz: bf3746c3b5e995637e8e54c8e2839ccd281823fb
2
+ SHA256:
3
+ metadata.gz: d317e0fd7a30052cf0ff5c61a647cdcb6e07bd75955b3c166e20c1f9cd1b0447
4
+ data.tar.gz: fb6919536c21963cccd1635fcda3af024d1a05a84ecb6bd8289db76b2c7502e5
5
5
  SHA512:
6
- metadata.gz: 52805795500e3655a05eb660069a094348f767e44940a4182f1ec110b5a0c5793607dbbebcb1ce27d1ce5b6947fbf530327233f2604aa6eabb0dd8cd6a3bd170
7
- data.tar.gz: 46432b91937362c31bc53aa4b62609d823bb7812e2f396c4ec38da585dac8d78bb360c699d99de6f799aeb996e8cf8422bc641221b405f38a3e2871b0ffcf816
6
+ metadata.gz: 68f28a1cd5877623bcb53df9b7971abf68e3b319552166c977f967f08761d948ce91e423666341fd3586114eee56cfcea9b50cdf9974f37aa06b0d39b70388c1
7
+ data.tar.gz: b78f00363bb1975a2f7519c1af8abc804167ac19982a9daf42de47932fa4c9a3a10e75098c8c197bafdd72f30f0a88a1063b214b56eb4c51351ab4028b9ab839
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ ## HEAD (unreleased)
2
+
3
+ ## 1.2.0
4
+
5
+ - Rescue `Mail::AddressList` parse errors ([#34](https://github.com/thoughtbot/griddler-sendgrid/pull/34))
6
+ - Update SendGrid API links ([#32](https://github.com/thoughtbot/griddler-sendgrid/pull/32) and [#33](https://github.com/thoughtbot/griddler-sendgrid/pull/33))
7
+
8
+ ## 1.1.0
9
+ * Expose charsets as Hash in normalized params ([#29](https://github.com/thoughtbot/griddler-sendgrid/pull/29/))
10
+ * Add support for Sendgrid spam check ([#30](https://github.com/thoughtbot/griddler-sendgrid/pull/30))
11
+ * Set minimum version of `mail` to be `2.7.0` so that UTF-8 encoded emails continue to work properly
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  Griddler::Sendgrid
2
2
  ==================
3
3
 
4
- This is an adapter that allows [Griddler](/thoughtbot/griddler) to be used with
4
+ This is an adapter that allows [Griddler](https://github.com/thoughtbot/griddler) to be used with
5
5
  [SendGrid's Parse API].
6
6
 
7
- [SendGrid's Parse API]: http://sendgrid.com/docs/API%20Reference/Webhooks/parse.html
7
+ [SendGrid's Parse API]: https://sendgrid.com/docs/for-developers/parsing-email/setting-up-the-inbound-parse-webhook/
8
8
 
9
9
  Installation
10
10
  ------------
@@ -12,7 +12,6 @@ Installation
12
12
  Add this line to your application's Gemfile:
13
13
 
14
14
  ```ruby
15
- gem 'griddler'
16
15
  gem 'griddler-sendgrid'
17
16
  ```
18
17
 
@@ -20,16 +19,17 @@ Usage
20
19
  -----
21
20
 
22
21
  * SendGrid has done a [great
23
- tutorial](http://blog.sendgrid.com/receiving-email-in-your-rails-app-with-griddler/)
22
+ tutorial](https://sendgrid.com/blog/receiving-email-in-your-rails-app-with-griddler/)
24
23
  on integrating Griddler with your application.
25
24
  * And of course, view our own blog post on the subject over at [Giant
26
25
  Robots](http://robots.thoughtbot.com/handle-incoming-email-with-griddler).
26
+ * *Note:* Make sure to uncheck the "Spam Check" and "Send Raw" checkboxes on the [Parse Webhook settings page](http://sendgrid.com/developer/reply), otherwise the returned parsed email will have the body stripped out.
27
27
 
28
28
  More Information
29
29
  ----------------
30
30
 
31
31
  * [SendGrid](http://www.sendgrid.com)
32
- * [SendGrid Parse API](http://www.sendgrid.com/docs/API Reference/Webhooks/parse.html)
32
+ * [SendGrid Parse API](https://sendgrid.com/docs/for-developers/parsing-email/setting-up-the-inbound-parse-webhook/)
33
33
 
34
34
  Credits
35
35
  -------
@@ -18,7 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.require_paths = ['lib']
19
19
 
20
20
  spec.add_development_dependency 'rake'
21
- spec.add_development_dependency 'rspec'
21
+ spec.add_development_dependency 'rspec', '~> 3.5'
22
22
 
23
- spec.add_dependency 'griddler'
23
+ spec.add_dependency 'griddler', '>= 1.5.2'
24
+ spec.add_dependency 'mail', '>= 2.7.0'
24
25
  end
@@ -12,9 +12,16 @@ module Griddler
12
12
 
13
13
  def normalize_params
14
14
  params.merge(
15
- to: recipients(:to),
16
- cc: recipients(:cc),
15
+ to: recipients(:to).map(&:format),
16
+ cc: recipients(:cc).map(&:format),
17
+ bcc: get_bcc,
17
18
  attachments: attachment_files,
19
+ charsets: charsets,
20
+ spam_report: {
21
+ report: params[:spam_report],
22
+ score: params[:spam_score],
23
+ }
24
+
18
25
  )
19
26
  end
20
27
 
@@ -23,17 +30,58 @@ module Griddler
23
30
  attr_reader :params
24
31
 
25
32
  def recipients(key)
26
- ( params[key] || '' ).split(',')
33
+ Mail::AddressList.new(params[key] || '').addresses
34
+ rescue Mail::Field::IncompleteParseError
35
+ []
27
36
  end
28
37
 
29
- def attachment_files
30
- params.delete('attachment-info')
31
- attachment_count = params[:attachments].to_i
38
+ def get_bcc
39
+ if bcc = bcc_from_envelope
40
+ bcc - recipients(:to).map(&:address) - recipients(:cc).map(&:address)
41
+ else
42
+ []
43
+ end
44
+ end
45
+
46
+ def bcc_from_envelope
47
+ JSON.parse(params[:envelope])["to"] if params[:envelope].present?
48
+ end
49
+
50
+ def charsets
51
+ return {} unless params[:charsets].present?
52
+ JSON.parse(params[:charsets]).symbolize_keys
53
+ rescue JSON::ParserError
54
+ {}
55
+ end
32
56
 
57
+
58
+ def attachment_files
33
59
  attachment_count.times.map do |index|
34
- params.delete("attachment#{index + 1}".to_sym)
60
+ extract_file_at(index)
35
61
  end
36
62
  end
63
+
64
+ def attachment_count
65
+ params[:attachments].to_i
66
+ end
67
+
68
+ def extract_file_at(index)
69
+ filename = attachment_filename(index)
70
+
71
+ params.delete("attachment#{index + 1}".to_sym).tap do |file|
72
+ if filename.present?
73
+ file.original_filename = filename
74
+ end
75
+ end
76
+ end
77
+
78
+ def attachment_filename(index)
79
+ attachment_info.fetch("attachment#{index + 1}", {})["filename"]
80
+ end
81
+
82
+ def attachment_info
83
+ @attachment_info ||= JSON.parse(params.delete("attachment-info") || "{}")
84
+ end
37
85
  end
38
86
  end
39
87
  end
@@ -1,5 +1,5 @@
1
1
  module Griddler
2
2
  module Sendgrid
3
- VERSION = "0.0.1"
3
+ VERSION = "1.2.0"
4
4
  end
5
5
  end
@@ -14,6 +14,7 @@ describe Griddler::Sendgrid::Adapter, '.normalize_params' do
14
14
  to: 'Hello World <hi@example.com>',
15
15
  cc: 'emily@example.com',
16
16
  from: 'There <there@example.com>',
17
+ charsets: { to: 'UTF-8', text: 'iso-8859-1' }.to_json
17
18
  }
18
19
 
19
20
  it 'changes attachments to an array of files' do
@@ -23,15 +24,15 @@ describe Griddler::Sendgrid::Adapter, '.normalize_params' do
23
24
  attachment2: upload_2,
24
25
  'attachment-info' => <<-eojson
25
26
  {
26
- 'attachment2': {
27
- 'filename': 'photo2.jpg',
28
- 'name': 'photo2.jpg',
29
- 'type': 'image/jpeg'
27
+ "attachment2": {
28
+ "filename": "photo2.jpg",
29
+ "name": "photo2.jpg",
30
+ "type": "image/jpeg"
30
31
  },
31
- 'attachment1': {
32
- 'filename': 'photo1.jpg',
33
- 'name': 'photo1.jpg',
34
- 'type': 'image/jpeg'
32
+ "attachment1": {
33
+ "filename": "photo1.jpg",
34
+ "name": "photo1.jpg",
35
+ "type": "image/jpeg"
35
36
  }
36
37
  }
37
38
  eojson
@@ -44,6 +45,33 @@ describe Griddler::Sendgrid::Adapter, '.normalize_params' do
44
45
  normalized_params.should_not have_key(:attachment_info)
45
46
  end
46
47
 
48
+ it "uses sendgrid attachment info for filename" do
49
+ params = default_params.merge(
50
+ attachments: "2",
51
+ attachment1: upload_1,
52
+ attachment2: upload_2,
53
+ "attachment-info" => <<-eojson
54
+ {
55
+ "attachment2": {
56
+ "filename": "sendgrid-filename2.jpg",
57
+ "name": "photo2.jpg",
58
+ "type": "image/jpeg"
59
+ },
60
+ "attachment1": {
61
+ "filename": "sendgrid-filename1.jpg",
62
+ "name": "photo1.jpg",
63
+ "type": "image/jpeg"
64
+ }
65
+ }
66
+ eojson
67
+ )
68
+
69
+ attachments = normalize_params(params)[:attachments]
70
+
71
+ attachments.first.original_filename.should eq "sendgrid-filename1.jpg"
72
+ attachments.second.original_filename.should eq "sendgrid-filename2.jpg"
73
+ end
74
+
47
75
  it 'has no attachments' do
48
76
  params = default_params.merge(attachments: '0')
49
77
 
@@ -51,10 +79,15 @@ describe Griddler::Sendgrid::Adapter, '.normalize_params' do
51
79
  normalized_params[:attachments].should be_empty
52
80
  end
53
81
 
54
- it 'wraps to in an array' do
82
+ it 'splits to into an array' do
55
83
  normalized_params = normalize_params(default_params)
56
84
 
57
- normalized_params[:to].should eq [default_params[:to]]
85
+ normalized_params[:to].should eq [
86
+ '"Mr Fugushima at Fugu, Inc" <hi@example.com>',
87
+ 'Foo bar <foo@example.com>',
88
+ '"Eichhörnchen" <squirrel@example.com>',
89
+ 'no-name@example.com',
90
+ ]
58
91
  end
59
92
 
60
93
  it 'wraps cc in an array' do
@@ -70,12 +103,78 @@ describe Griddler::Sendgrid::Adapter, '.normalize_params' do
70
103
  normalized_params[:cc].should eq []
71
104
  end
72
105
 
106
+ it 'returns an array even if bcc is an empty string' do
107
+ params = default_params.merge(envelope: '')
108
+ normalized_params = normalize_params(params)
109
+
110
+ normalized_params[:bcc].should eq []
111
+ end
112
+
113
+ it 'wraps bcc in an array' do
114
+ normalized_params = normalize_params(default_params)
115
+
116
+ normalized_params[:bcc].should eq ["johny@example.com"]
117
+ end
118
+
119
+ it 'returns an array even if bcc is empty' do
120
+ params = default_params.merge(envelope: nil)
121
+ normalized_params = normalize_params(params)
122
+
123
+ normalized_params[:bcc].should eq []
124
+ end
125
+
126
+ it 'returns an empty array when the envelope to is the same as the base to' do
127
+ params = default_params.merge(envelope: "{\"to\":[\"hi@example.com\"]}")
128
+ normalized_params = normalize_params(params)
129
+
130
+ normalized_params[:bcc].should eq []
131
+ end
132
+
133
+ it 'returns the charsets as a hash' do
134
+ normalized_params = normalize_params(default_params)
135
+ charsets = normalized_params[:charsets]
136
+
137
+ charsets.should be_present
138
+ charsets[:text].should eq 'iso-8859-1'
139
+ charsets[:to].should eq 'UTF-8'
140
+ end
141
+
142
+ it 'does not explode if charsets is not JSON-able' do
143
+ params = default_params.merge(charsets: 'This is not JSON')
144
+
145
+ normalize_params(params)[:charsets].should eq({})
146
+ end
147
+
148
+ it 'does not explode if address is not parseable' do
149
+ params = default_params.merge(cc: '"Closing Bracket Missing For Some Reason" <hi@example.com')
150
+
151
+ normalize_params(params)[:cc].should eq([])
152
+ end
153
+
154
+ it 'defaults charsets to an empty hash if it is not specified in params' do
155
+ params = default_params.except(:charsets)
156
+ normalize_params(params)[:charsets].should eq({})
157
+ end
158
+
159
+ it 'normalizes the spam report into a griddler friendly format' do
160
+ normalized_params = normalize_params(default_params)
161
+
162
+ normalized_params[:spam_report].should eq({
163
+ score: '1.234',
164
+ report: 'Some spam report',
165
+ })
166
+ end
167
+
73
168
  def default_params
74
169
  {
75
170
  text: 'hi',
76
- to: 'hi@example.com',
171
+ to: '"Mr Fugushima at Fugu, Inc" <hi@example.com>, Foo bar <foo@example.com>, Eichhörnchen <squirrel@example.com>, <no-name@example.com>',
77
172
  cc: 'cc@example.com',
78
173
  from: 'there@example.com',
174
+ envelope: "{\"to\":[\"johny@example.com\"], \"from\": [\"there@example.com\"]}",
175
+ charsets: { to: 'UTF-8', text: 'iso-8859-1' }.to_json,
176
+ spam_score: '1.234',
177
+ spam_report: 'Some spam report'
79
178
  }
80
179
  end
81
180
  end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Griddler::Email, '#to_h' do
4
+ it 'accepts normalized params from Griddler::Sendgrid::Adapter' do
5
+ normalized_params = Griddler::Sendgrid::Adapter.normalize_params(default_params)
6
+ email = Griddler::Email.new(normalized_params)
7
+
8
+ email_properties = email.to_h
9
+
10
+ expect(email_properties[:subject]).to eq 'Some subject'
11
+ expect(email_properties[:spam_score]).to eq '1.234'
12
+ end
13
+
14
+ def default_params
15
+ {
16
+ subject: 'Some subject',
17
+ text: 'hi',
18
+ to: '"Mr Fugushima at Fugu, Inc" <hi@example.com>, Foo bar <foo@example.com>, Eichhörnchen <squirrel@example.com>, <no-name@example.com>',
19
+ cc: 'cc@example.com',
20
+ from: 'there@example.com',
21
+ envelope: "{\"to\":[\"johny@example.com\"], \"from\": [\"there@example.com\"]}",
22
+ spam_score: '1.234',
23
+ spam_report: 'Some spam report',
24
+ }
25
+ end
26
+ end
data/spec/spec_helper.rb CHANGED
@@ -3,8 +3,10 @@ require 'griddler/sendgrid'
3
3
  require 'action_dispatch'
4
4
 
5
5
  RSpec.configure do |config|
6
- config.treat_symbols_as_metadata_keys_with_true_values = true
7
6
  config.run_all_when_everything_filtered = true
8
7
  config.order = 'random'
9
8
  config.include Griddler::Testing
9
+ config.expect_with(:rspec) do |c|
10
+ c.syntax = [:should, :expect]
11
+ end
10
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: griddler-sendgrid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Caleb Thompson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-16 00:00:00.000000000 Z
11
+ date: 2019-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -28,30 +28,44 @@ dependencies:
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '3.5'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '3.5'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: griddler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 1.5.2
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 1.5.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: mail
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 2.7.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 2.7.0
55
69
  description: Adapter to allow the use of SendGrid Parse API with Griddler
56
70
  email:
57
71
  - caleb@calebthompson.io
@@ -61,6 +75,7 @@ extra_rdoc_files: []
61
75
  files:
62
76
  - ".gitignore"
63
77
  - ".rspec"
78
+ - CHANGELOG.md
64
79
  - Gemfile
65
80
  - LICENSE.txt
66
81
  - README.md
@@ -72,6 +87,7 @@ files:
72
87
  - spec/fixtures/photo1.jpg
73
88
  - spec/fixtures/photo2.jpg
74
89
  - spec/griddler/sendgrid/adapter_spec.rb
90
+ - spec/integration/email_spec.rb
75
91
  - spec/spec_helper.rb
76
92
  homepage: https://github.com/thoughtbot/griddler
77
93
  licenses:
@@ -93,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
109
  version: '0'
94
110
  requirements: []
95
111
  rubyforge_project:
96
- rubygems_version: 2.2.2
112
+ rubygems_version: 2.7.6.2
97
113
  signing_key:
98
114
  specification_version: 4
99
115
  summary: SendGrid adapter for Griddler
@@ -101,4 +117,5 @@ test_files:
101
117
  - spec/fixtures/photo1.jpg
102
118
  - spec/fixtures/photo2.jpg
103
119
  - spec/griddler/sendgrid/adapter_spec.rb
120
+ - spec/integration/email_spec.rb
104
121
  - spec/spec_helper.rb