griddler-sendgrid 0.0.1 → 1.2.0

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 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