griddler 0.6.4 → 1.0.0.pre.alpha.1

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
2
  SHA1:
3
- metadata.gz: 5a2cacfe5e74d1231a76e4502ed28c88399fd769
4
- data.tar.gz: 3213db391f6032cfa65f6d0fa2e0323b45016001
3
+ metadata.gz: e799f0b0004bfe2b6628c40f370f2f16eab17223
4
+ data.tar.gz: b82b19547ba1ed0280e2e16460c54d4c22ed6cd0
5
5
  SHA512:
6
- metadata.gz: c9cf20906c65491d019e30b68dfd669c5f16f80eca4cbb922410c91f63b338e723e52f1a7912e56a2f6dfc10b041806eb64fe2ce7bc6adfdea3a1038ac88c304
7
- data.tar.gz: b047cccc5d6ea2fdfce31da626671fe11de304ec5d338850afacdf1640da27f51d60c31bee2b72d54d9c64db6147c17a9ad4d5d54e93d193e32d5925d1f6e6b7
6
+ metadata.gz: 240c7e9eda058081f8ee93e55f564f4c2a2683506c40d929cfc8fba43fbcbd7787fd91eef94871c272062ba9ae683a144e50cbcc442ddb2f3d22555c6762d35d
7
+ data.tar.gz: b5c5a4c2ad91fdaf9816178409cb12daca799ba9dd6be5e7311adf758bc879dfd14cf62e8fa0c7742a79e6c18a00c76b6581ae8ad929daa33af8fa46bc3839e7
data/README.md CHANGED
@@ -6,133 +6,58 @@ Griddler
6
6
 
7
7
  ### Receive emails in your Rails app
8
8
 
9
- Griddler is a Rails engine (full plugin) that provides an endpoint for the
10
- [SendGrid parse api](http://sendgrid.com/docs/API%20Reference/Webhooks/parse.html),
11
- [Cloudmailin parse api](http://cloudmailin.com),
12
- [Postmark parse api](http://developer.postmarkapp.com/developer-inbound-parse.html) or
13
- [Mandrill parse api](http://help.mandrill.com/entries/21699367-Inbound-Email-Processing-Overview)
14
- [Mailgun routes](http://documentation.mailgun.com/user_manual.html#receiving-messages-via-http-through-a-forward-action)
15
- that hands off a built email object to a class implemented by you.
9
+ Griddler is a Rails engine that provides an endpoint for the
10
+ [SendGrid](http://sendgrid.com/docs/API%20Reference/Webhooks/parse.html),
11
+ [Cloudmailin](http://cloudmailin.com),
12
+ [Postmark](http://developer.postmarkapp.com/developer-inbound-parse.html),
13
+ [Mandrill](http://help.mandrill.com/entries/21699367-Inbound-Email-Processing-Overview), or
14
+ [Mailgun](http://documentation.mailgun.com/user\_manual.html#receiving-messages-via-http-through-a-forward-action)
15
+ parse APIs that hands off a built email object to a class implemented by you.
16
16
 
17
17
  Tutorials
18
18
  ---------
19
19
 
20
- * SendGrid has done a
20
+ * SendGrid wrote a
21
21
  [great tutorial](http://blog.sendgrid.com/receiving-email-in-your-rails-app-with-griddler/)
22
22
  on integrating Griddler with your application.
23
- * And of course, view our own blog post on the subject over at
24
- [Giant Robots](http://robots.thoughtbot.com/post/42286882447/handle-incoming-email-with-griddler).
23
+ * We have our own blog post on the subject over at
24
+ [Giant Robots](http://robots.thoughtbot.com/handle-incoming-email-with-griddler).
25
25
 
26
26
  Installation
27
27
  ------------
28
28
 
29
- Add griddler to your application's Gemfile and run `bundle install`:
29
+ 1. Add `griddler` and an [adapter] gem to your application's Gemfile
30
+ and run `bundle install`.
30
31
 
31
- ```ruby
32
- gem 'griddler'
33
- ```
34
- A route is needed for the endpoint which receives `POST` messages. Currently,
35
- the route is automatically appended to the route table like so:
36
-
37
- ```ruby
38
- email_processor POST /email_processor(.:format) griddler/emails#create
39
- ```
32
+ [adapter]: #adapters
40
33
 
41
- **NOTE: This behavior is deprecated and will be removed by version 0.7.0 in favor
42
- of manually adding the route.**
34
+ 2. A route is needed for the endpoint which receives `POST` messages. To add the
35
+ route, in `config/routes.rb` you may either use the provided routing method
36
+ `mount_griddler` or set the route explicitly. Examples:
43
37
 
44
- To manually add the route, in `config/routes.rb` you may either use the provided
45
- routing method `mount_griddler` or set the route explicitly. Examples:
38
+ ```ruby
39
+ # config/routes.rb
46
40
 
47
- ```ruby
48
- # mount using default path
49
- mount_griddler
41
+ # mount using default path: /email_processor
42
+ mount_griddler
50
43
 
51
- # mount using a custom path
52
- mount_griddler('/email/incoming')
44
+ # mount using a custom path
45
+ mount_griddler('/email/incoming')
53
46
 
54
- # the "get off my lawn", DIY approach:
55
- post '/email_processor' => 'griddler/emails#create'
56
- ```
47
+ # the DIY approach:
48
+ post '/email_processor' => 'griddler/emails#create'
49
+ ```
57
50
 
58
- Defaults
59
- --------
51
+ ### Configuration Options
60
52
 
61
- By default Griddler will look for a class to be created in your application
62
- called EmailProcessor with a class method implemented, named process, taking
63
- in one argument (presumably `email`). For example, in `./lib/email_processor.rb`:
64
-
65
- ```ruby
66
- class EmailProcessor
67
- def self.process(email)
68
- # all of your application-specific code here - creating models,
69
- # processing reports, etc
70
- end
71
- end
72
- ```
73
-
74
- The contents of the `email` object passed into your process method is an object
75
- that responds to:
76
-
77
- * `.to`
78
- * `.from`
79
- * `.cc`
80
- * `.subject`
81
- * `.body`
82
- * `.raw_text`
83
- * `.raw_html`
84
- * `.raw_body`
85
- * `.attachments`
86
- * `.headers`
87
- * `.raw_headers`
88
-
89
- Each of those has some sensible defaults.
90
-
91
- `.raw_body`, `.raw_headers`, and `.subject` will contain the obvious
92
- values found in the email, the raw values from those fields.
93
-
94
- `.body` will contain the full contents of the email body **unless** there is a
95
- line in the email containing the string `-- Reply ABOVE THIS LINE --`. In that
96
- case `.body` will contain everything before that line.
97
-
98
- `.to` will contain an array of hashes. Each hash will have the following
99
- information of each recipient:
100
-
101
- * `token`: All the text before the email's "@". We've found that this is the
102
- most often used portion of the email address and consider it to be the token
103
- we'll key off of for interaction with our application.
104
-
105
- * `host`: All the text after the email's "@". This is important to filter
106
- the recipients sent to the application vs emails to other domains. More
107
- info below on the Upgrading to 0.5.0 section.
108
-
109
- * `email`: The email address of the recipient.
110
-
111
- * `full`: The whole recipient field. E.g, `Some User <hello@example.com>`
112
- * `name`: The name of the recipient. E.g, `Some User`
113
-
114
- `.from` will default to the `email` value of a hash like `.to`, and can be
115
- configured to return the full hash.
116
-
117
- `.cc` behaves and can be configured like `.to`. If the adapter does not
118
- pass along a `cc` key then the headers will be parsed.
119
-
120
- `.attachments` will contain an array of attachments as multipart/form-data files
121
- which can be passed off to attachment libraries like Carrierwave or Paperclip.
122
-
123
- `.headers` will contain a hash of header names and values as parsed by the Mail
124
- gem. Headers will only be parsed if the adapter supports a headers option.
125
-
126
- Configuration Options
127
- ---------------------
128
-
129
- An initializer can be created to control some of the options in Griddler. Defaults
130
- are shown below with sample overrides following. In `config/initializers/griddler.rb`:
53
+ An initializer can be created to control some of the options in Griddler.
54
+ Defaults are shown below with sample overrides following. In
55
+ `config/initializers/griddler.rb`:
131
56
 
132
57
  ```ruby
133
58
  Griddler.configure do |config|
134
- config.processor_class = EmailProcessor # MyEmailProcessor
135
- config.processor_method = :process # :custom_method
59
+ config.processor_class = EmailProcessor # CommentViaEmail
60
+ config.processor_method = :process # :create_comment (A method on CommentViaEmail)
136
61
  config.to = :hash # :full, :email, :token
137
62
  config.cc = :email # :full, :hash, :token
138
63
  config.from = :email # :full, :token, :hash
@@ -145,21 +70,63 @@ Griddler.configure do |config|
145
70
  end
146
71
  ```
147
72
 
148
- * `config.processor_class` is the class Griddler will use to handle your incoming emails.
149
- * `config.processor_method` is the method Griddler will call on the processor class when handling your incoming emails.
150
- * `config.reply_delimiter` is the string searched for that will split your body.
151
- * `config.to`, `config.cc` and `config.from` are the format of the returned value for that
152
- address in the email object. `:hash` will return all options within a -- (surprise!) -- hash.
153
- * `config.email_service` tells Griddler which email service you are using. The
154
- supported email service options are `:sendgrid` (the default), `:cloudmailin`
155
- (expects multipart format), `:postmark` and `:mandrill`.
73
+ | Option | Meaning
74
+ | ------ | -------
75
+ | `processor_class` | The class Griddler will use to handle your incoming emails.
76
+ | `processor_method` | The method Griddler will call on the processor class when handling your incoming emails.
77
+ | `reply_delimiter` | The string searched for that will split your body.
78
+ | `email_service` | Tells Griddler which email service you are using. The supported email service options are `:sendgrid` (the default), `:cloudmailin` (expects multipart format), `:postmark` and `:mandrill`. You will also need to have an appropriate [adapter] gem included in your Gemfile.
79
+ | `to`, `config.cc` and `config.from` | The format of the returned value for that address in the email object. `:hash` will return all options within a -- (surprise!) -- hash.
80
+
81
+ By default Griddler will look for a class named `EmailProcessor` with a class
82
+ method named `process`, taking in one argument, a `Griddler::Email` instance
83
+ representing the incoming email. For example, in `./lib/email_processor.rb`:
84
+
85
+ ```ruby
86
+ class EmailProcessor
87
+ def self.process(email)
88
+ # all of your application-specific code here - creating models,
89
+ # processing reports, etc
90
+ end
91
+ end
92
+ ```
93
+
94
+ Griddler::Email attributes
95
+ --------------------------
96
+
97
+ | Attribute | Description
98
+ | -------------- | -----------
99
+ | `#to` | An array of hashes containing recipient address information. See [Email Addresses](#email-addresses) for more information.
100
+ | `#from` | A hash containing the sender address information.
101
+ | `#cc` | An array of hashes containing cc email address information.
102
+ | `#subject` | The subject of the email message.
103
+ | `#body` | The full contents of the email body **unless** there is a line in the email containing the string `-- Reply ABOVE THIS LINE --`. In that case `.body` will contain everything before that line.
104
+ | `#raw_text` | The raw text part of the body.
105
+ | `#raw_html` | The raw html part of the body.
106
+ | `#raw_body` | The raw body information provided by the email service.
107
+ | `#attachments` | An array of `File` objects containing any attachments.
108
+ | `#headers` | A hash of headers parsed by `Mail::Header`.
109
+ | `#raw_headers` | The raw headers included in the message.
110
+
111
+ ### Email Addresses
112
+
113
+ Gridder::Email provides email addresses as hashes. Each hash will have the following
114
+ information of each recipient:
115
+
116
+ | Key | Value
117
+ | --- | -----
118
+ | `:token` | All the text before the email's "@". We've found that this is the most often used portion of the email address and consider it to be the token we'll key off of for interaction with our application.
119
+ | `:host` | All the text after the email's "@". This is important to filter the recipients sent to the application vs emails to other domains. More info below on the Upgrading to 0.5.0 section.
120
+ | `:email` | The email address of the recipient.
121
+ | `:full` | The whole recipient field (e.g., `Some User <hello@example.com>`).
122
+ | `:name` | The name of the recipient (e.g., `Some User`).
156
123
 
157
124
  Testing In Your App
158
125
  -------------------
159
126
 
160
- You may want to create a factory for when testing the integration of Griddler into
161
- your application. If you're using factory\_girl this can be accomplished with the
162
- following sample factory.
127
+ You may want to create a factory for when testing the integration of Griddler
128
+ into your application. If you're using factory\_girl this can be accomplished
129
+ with the following sample factory:
163
130
 
164
131
  ```ruby
165
132
  factory :email, class: OpenStruct do
@@ -175,7 +142,7 @@ factory :email, class: OpenStruct do
175
142
  ActionDispatch::Http::UploadedFile.new({
176
143
  filename: 'img.png',
177
144
  type: 'image/png',
178
- tempfile: File.new("#{File.expand_path File.dirname(__FILE__)}/fixtures/img.png")
145
+ tempfile: File.new("#{File.expand_path(File.dirname(__FILE__))}/fixtures/img.png")
179
146
  })
180
147
  ]}
181
148
  end
@@ -186,76 +153,49 @@ Bear in mind, if you plan on using the `:with_attachment` trait, that this
186
153
  example assumes your factories are in `spec/factories.rb` and you have
187
154
  an image file in `spec/fixtures/`.
188
155
 
189
- To use it in your test(s) just build with `email = build(:email)`
156
+ To use it in your tests, build with `email = build(:email)`
190
157
  or `email = build(:email, :with_attachment)`.
191
158
 
192
159
  Adapters
193
160
  --------
194
161
 
195
- `Griddler::Email` expects certain parameters to be in place for proper parsing
196
- to occur. When writing an adapter, ensure that the `normalized_params` method
197
- of your adapter returns a hash with these keys:
198
-
199
- * `:to` The recipient field
200
- * `:from` The sender field
201
- * `:subject` Email subject
202
- * `:text` The text body of the email
203
- * `:html` The html body of the email, nil or empty string if not present
204
- * `:attachments` (can be an empty array) Array of attachments to the email
205
- * `:headers` (optional) The raw headers of the email
206
- * `:charsets` (optional) A JSON string containing the character sets of the
207
- fields extracted from the message
208
-
209
- Upgrading to Griddler 0.5.0
210
- ---------------------------
211
-
212
- Because of an issue with the way Griddler handled recipients in the `To` header,
213
- a breaking change was introduced in Griddler 0.5.0 that requires a minor change
214
- to `EmailProcessor` or `processor_class`.
215
-
216
- Previously, a single address was returned from `Griddler::Email#to`. Moving
217
- forward, this field will always be an array. Generally speaking, you will want
218
- to do something like this to handle the change:
162
+ Depending on the service you want to use Griddler with, you'll need to add an
163
+ adapter gem in addition to `griddler`.
219
164
 
220
- ```ruby
221
- # before
222
- def initialize(email)
223
- @to = email.to
224
- @from = email.from
225
- @body = email.body
226
- end
227
-
228
- # after
229
- def initialize(email)
230
- @to = pick_meaningful_recipient(email.to)
231
- @from = email.from
232
- @body = email.body
233
- end
165
+ | Service | Adapter
166
+ | ------- | -------
167
+ | sendgrid | [griddler-sendgrid]
168
+ | mandrill | [griddler-mandrill]
234
169
 
235
- private
170
+ [griddler-sendgrid]: https://github.com/thoughtbot/griddler-sendgrid
171
+ [griddler-mandrill]: https://github.com/wingrunr21/griddler-mandrill
236
172
 
237
- def pick_meaningful_recipient(recipients)
238
- recipients.find { |address| address =~ /@mydomain.com$/ }
239
- end
240
- ```
173
+ Writing an Adapter
174
+ ------------------
241
175
 
242
- Using Griddler with Mandrill
243
- ----------------------------
176
+ Griddler can theoretically work with any email => POST service. In order to work
177
+ correctly, adapters need to have their POST parameters restructured.
244
178
 
245
- When adding a webhook in their administration panel, Mandrill will issue a HEAD
246
- request to check if the webhook is valid (see
247
- [Adding Routes](http://help.mandrill.com/entries/21699367-Inbound-Email-Processing-Overview)).
248
- If the HEAD request fails, Mandrill will not allow you to add the webhook.
249
- Since Griddler is only configured to handle POST requests, you will not be able
250
- to add the webhook as-is. To solve this, add a temporary route to your
251
- application that can handle the HEAD request:
252
-
253
- ```ruby
254
- # routes.rb
255
- get "/email_processor", to: proc { [200, {}, ["OK"]] }, as: "mandrill_head_test_request"
256
- ```
257
-
258
- Once you have correctly configured Mandrill, you can go ahead and delete this code.
179
+ `Griddler::Email` expects certain parameters to be in place for proper parsing
180
+ to occur. When writing an adapter, ensure that the `normalized_params` method of
181
+ your adapter returns a hash with these keys:
182
+
183
+ | Parameter | Contents
184
+ | --------- | --------
185
+ | `:to` | The recipient field
186
+ | `:from` | The sender field
187
+ | `:subject` | Email subject
188
+ | `:text` | The text body of the email
189
+ | `:html` | The html body of the email, nil or empty string if not present
190
+ | `:attachments` | Array of attachments to the email. Can be an empty array.
191
+ | `:headers` | The raw headers of the email. **Optional**.
192
+ | `:charsets` | A JSON string containing the character sets of the fields extracted from the message. **Optional**.
193
+
194
+ All keys are required unless otherwise stated.
195
+
196
+ Adapters should be provided as gems. If you write an adapter, let us know and we
197
+ will add it to this README. See [griddler-sendgrid] for an example
198
+ implementation.
259
199
 
260
200
  More Information
261
201
  ----------------
@@ -269,7 +209,7 @@ More Information
269
209
  * [Mandrill](http://mandrill.com)
270
210
  * [Mandrill Docs](http://help.mandrill.com/forums/21092258-Inbound-Email-Processing)
271
211
  * [Mailgun](http://mailgun.com)
272
- * [Mailgun Docs](http://documentation.mailgun.com/user_manual.html#receiving-forwarding-and-storing-messages)
212
+ * [Mailgun Docs](http://documentation.mailgun.com/user\_manual.html#receiving-forwarding-and-storing-messages)
273
213
 
274
214
  Credits
275
215
  -------
@@ -279,13 +219,8 @@ Griddler was written by Caleb Thompson and Joel Oliveira.
279
219
  Large portions of the codebase were extracted from thoughtbot's
280
220
  [Trajectory](http://www.apptrajectory.com).
281
221
 
222
+ Thanks to our [contributors](https://github.com/thoughtbot/griddler/contributors)!
223
+
282
224
  ![thoughtbot](http://thoughtbot.com/images/tm/logo.png)
283
225
 
284
226
  The names and logos for thoughtbot are trademarks of thoughtbot, inc.
285
-
286
- License
287
- -------
288
-
289
- Griddler is Copyright © 2014 Caleb Thompson, Joel Oliveira and thoughtbot. It is
290
- free software, and may be redistributed under the terms specified in the LICENSE
291
- file.
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ begin
4
4
  require 'bundler/gem_tasks'
5
5
  rescue LoadError
6
6
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ exit 1
7
8
  end
8
9
 
9
10
  Bundler::GemHelper.install_tasks
data/lib/griddler.rb CHANGED
@@ -6,11 +6,14 @@ require 'griddler/email'
6
6
  require 'griddler/email_parser'
7
7
  require 'griddler/configuration'
8
8
  require 'griddler/route_extensions'
9
- require 'griddler/adapters/sendgrid_adapter'
9
+ require 'griddler/adapter_registry'
10
10
  require 'griddler/adapters/cloudmailin_adapter'
11
11
  require 'griddler/adapters/postmark_adapter'
12
- require 'griddler/adapters/mandrill_adapter'
13
12
  require 'griddler/adapters/mailgun_adapter'
14
13
 
15
- module Griddler
16
- end
14
+ require 'griddler/sendgrid'
15
+ require 'griddler/mandrill'
16
+
17
+ Griddler.adapter_registry.register(:cloudmailin, Griddler::Adapters::CloudmailinAdapter)
18
+ Griddler.adapter_registry.register(:postmark, Griddler::Adapters::PostmarkAdapter)
19
+ Griddler.adapter_registry.register(:mailgun, Griddler::Adapters::MailgunAdapter)
@@ -0,0 +1,28 @@
1
+ module Griddler
2
+ class AdapterRegistry
3
+ DEFAULT_ADAPTER = :sendgrid
4
+
5
+ def initialize
6
+ @registry = {}
7
+ end
8
+
9
+ def register(adapter_name, adapter_class)
10
+ if adapter_name == DEFAULT_ADAPTER
11
+ @registry[:default] = adapter_class
12
+ end
13
+ @registry[adapter_name] = adapter_class
14
+ end
15
+
16
+ def [](adapter_name)
17
+ @registry[adapter_name]
18
+ end
19
+
20
+ def fetch(key, &block)
21
+ @registry.fetch(key, &block)
22
+ end
23
+ end
24
+
25
+ def self.adapter_registry
26
+ @adapter_registry ||= AdapterRegistry.new
27
+ end
28
+ end
@@ -12,7 +12,7 @@ module Griddler
12
12
 
13
13
  def normalize_params
14
14
  params.merge(
15
- to: recipients,
15
+ to: tos,
16
16
  cc: ccs,
17
17
  text: params['body-plain'],
18
18
  html: params['body-html'],
@@ -25,24 +25,32 @@ module Griddler
25
25
 
26
26
  attr_reader :params
27
27
 
28
- def recipients
29
- params[:recipient].split(',')
28
+ def tos
29
+ to = param_or_header(:To)
30
+ to = params[:recipient] unless to
31
+ to.split(',').map(&:strip)
30
32
  end
31
33
 
32
34
  def ccs
33
- cc = if params[:Cc].present?
34
- params[:Cc]
35
- else
36
- extract_header_cc
37
- end
35
+ cc = param_or_header(:Cc)
38
36
  cc.split(',').map(&:strip)
39
37
  end
40
38
 
41
- def extract_header_cc
42
- header = params['message-headers'].select{|h|
43
- h.first == 'Cc'
44
- }.first
45
- header.to_a.last
39
+ def extract_header(key)
40
+ return nil unless params['message-headers'].present?
41
+
42
+ headers = params['message-headers'].select do |h|
43
+ h.first.to_s == key.to_s
44
+ end
45
+ headers.flatten.last
46
+ end
47
+
48
+ def param_or_header(key)
49
+ if params[key].present?
50
+ params[key]
51
+ else
52
+ extract_header(key)
53
+ end
46
54
  end
47
55
 
48
56
  def attachment_files
@@ -42,7 +42,18 @@ module Griddler
42
42
  end
43
43
 
44
44
  def processor_class
45
- @processor_class ||= EmailProcessor
45
+ @processor_class ||=
46
+ begin
47
+ if Kernel.const_defined?(:EmailProcessor)
48
+ EmailProcessor
49
+ else
50
+ raise NameError.new(<<-ERROR.strip_heredoc, 'EmailProcessor')
51
+ To use Griddler, you must either define `EmailProcessor` or configure a
52
+ different processor. See https://github.com/thoughtbot/griddler#defaults for
53
+ more information.
54
+ ERROR
55
+ end
56
+ end
46
57
  end
47
58
 
48
59
  def processor_method
@@ -54,27 +65,11 @@ module Griddler
54
65
  end
55
66
 
56
67
  def email_service
57
- @email_service_adapter ||= adapter_class[:sendgrid]
68
+ @email_service_adapter ||= Griddler.adapter_registry[:sendgrid]
58
69
  end
59
70
 
60
71
  def email_service=(new_email_service)
61
- if new_email_service == :default
62
- new_email_service = :sendgrid
63
- end
64
-
65
- @email_service_adapter = adapter_class.fetch(new_email_service) { raise Griddler::Errors::EmailServiceAdapterNotFound }
66
- end
67
-
68
- private
69
-
70
- def adapter_class
71
- {
72
- sendgrid: Griddler::Adapters::SendgridAdapter,
73
- cloudmailin: Griddler::Adapters::CloudmailinAdapter,
74
- postmark: Griddler::Adapters::PostmarkAdapter,
75
- mandrill: Griddler::Adapters::MandrillAdapter,
76
- mailgun: Griddler::Adapters::MailgunAdapter
77
- }
72
+ @email_service_adapter = Griddler.adapter_registry.fetch(new_email_service) { raise Griddler::Errors::EmailServiceAdapterNotFound }
78
73
  end
79
74
  end
80
75
  end
@@ -0,0 +1,57 @@
1
+ require 'action_dispatch'
2
+
3
+ module Griddler::Testing
4
+ def upload_1
5
+ @upload_1 ||= UploadedImage.new('photo1.jpg').file
6
+ end
7
+
8
+ def upload_2
9
+ @upload_2 ||= UploadedImage.new('photo2.jpg').file
10
+ end
11
+
12
+ def normalize_params(params)
13
+ Griddler::Sendgrid::Adapter.normalize_params(params)
14
+ end
15
+
16
+ class UploadedImage
17
+ def initialize(name)
18
+ @name = name
19
+ end
20
+
21
+ def file
22
+ ActionDispatch::Http::UploadedFile.new({
23
+ filename: @name,
24
+ type: 'image/jpeg',
25
+ tempfile: fixture_file
26
+ })
27
+ end
28
+
29
+ private
30
+
31
+ def fixture_file
32
+ cwd = File.expand_path File.dirname(__FILE__)
33
+ File.new(File.join(cwd, '..', '..', 'spec', 'fixtures', @name))
34
+ end
35
+ end
36
+ end
37
+
38
+ shared_examples_for 'Griddler adapter' do |adapter, service_params|
39
+ it 'adapts params to expected values' do
40
+ Griddler.configuration.email_service = adapter
41
+
42
+ normalized_params = Griddler.configuration.email_service.normalize_params(service_params)
43
+
44
+ Array.wrap(normalized_params).each do |params|
45
+ email = Griddler::Email.new(params)
46
+
47
+ email.to.should eq([{
48
+ token: 'hi',
49
+ host: 'example.com',
50
+ full: 'Hello World <hi@example.com>',
51
+ email: 'hi@example.com',
52
+ name: 'Hello World',
53
+ }])
54
+ email.cc.should eq ['emily@example.com']
55
+ end
56
+ end
57
+ end
@@ -1,3 +1,3 @@
1
1
  module Griddler
2
- VERSION = "0.6.4"
2
+ VERSION = "1.0.0-alpha.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: griddler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 1.0.0.pre.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Caleb Thompson
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2014-03-13 00:00:00.000000000 Z
14
+ date: 2014-06-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rails
@@ -97,21 +97,19 @@ files:
97
97
  - Rakefile
98
98
  - app/controllers/griddler/emails_controller.rb
99
99
  - config/initializers/griddler.rb
100
- - config/routes.rb
101
100
  - lib/griddler.rb
101
+ - lib/griddler/adapter_registry.rb
102
102
  - lib/griddler/adapters/cloudmailin_adapter.rb
103
103
  - lib/griddler/adapters/mailgun_adapter.rb
104
- - lib/griddler/adapters/mandrill_adapter.rb
105
104
  - lib/griddler/adapters/postmark_adapter.rb
106
- - lib/griddler/adapters/sendgrid_adapter.rb
107
105
  - lib/griddler/configuration.rb
108
106
  - lib/griddler/email.rb
109
107
  - lib/griddler/email_parser.rb
110
108
  - lib/griddler/engine.rb
111
109
  - lib/griddler/errors.rb
112
110
  - lib/griddler/route_extensions.rb
111
+ - lib/griddler/testing.rb
113
112
  - lib/griddler/version.rb
114
- - lib/tasks/griddler_tasks.rake
115
113
  homepage: http://thoughtbot.com
116
114
  licenses: []
117
115
  metadata: {}
@@ -130,9 +128,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
130
128
  version: 1.9.2
131
129
  required_rubygems_version: !ruby/object:Gem::Requirement
132
130
  requirements:
133
- - - ">="
131
+ - - ">"
134
132
  - !ruby/object:Gem::Version
135
- version: '0'
133
+ version: 1.3.1
136
134
  requirements: []
137
135
  rubyforge_project:
138
136
  rubygems_version: 2.2.2
data/config/routes.rb DELETED
@@ -1,3 +0,0 @@
1
- Rails.application.routes.draw do
2
- post '/email_processor' => 'griddler/emails#create', as: :email_processor
3
- end
@@ -1,71 +0,0 @@
1
- module Griddler
2
- module Adapters
3
- class MandrillAdapter
4
- def initialize(params)
5
- @params = params
6
- end
7
-
8
- def self.normalize_params(params)
9
- adapter = new(params)
10
- adapter.normalize_params
11
- end
12
-
13
- def normalize_params
14
- events.map do |event|
15
- {
16
- to: recipients(:to, event),
17
- cc: recipients(:cc, event),
18
- from: full_email([ event[:from_email], event[:from_name] ]),
19
- subject: event[:subject],
20
- text: event.fetch(:text, ''),
21
- html: event.fetch(:html, ''),
22
- raw_body: event[:raw_msg],
23
- attachments: attachment_files(event)
24
- }
25
- end
26
- end
27
-
28
- private
29
-
30
- attr_reader :params
31
-
32
- def events
33
- @events ||= ActiveSupport::JSON.decode(params[:mandrill_events]).map do |event|
34
- event['msg'].with_indifferent_access
35
- end
36
- end
37
-
38
- def recipients(field, event)
39
- Array.wrap(event[field]).map { |recipient| full_email(recipient) }
40
- end
41
-
42
- def full_email(contact_info)
43
- email = contact_info[0]
44
- if contact_info[1]
45
- "#{contact_info[1]} <#{email}>"
46
- else
47
- email
48
- end
49
- end
50
-
51
- def attachment_files(event)
52
- attachments = event[:attachments] || Array.new
53
- attachments.map do |key, attachment|
54
- ActionDispatch::Http::UploadedFile.new({
55
- filename: attachment[:name],
56
- type: attachment[:type],
57
- tempfile: create_tempfile(attachment)
58
- })
59
- end
60
- end
61
-
62
- def create_tempfile(attachment)
63
- filename = attachment[:name]
64
- tempfile = Tempfile.new(filename, Dir::tmpdir, encoding: 'ascii-8bit')
65
- tempfile.write(Base64.decode64(attachment[:content]))
66
- tempfile.rewind
67
- tempfile
68
- end
69
- end
70
- end
71
- end
@@ -1,39 +0,0 @@
1
- module Griddler
2
- module Adapters
3
- class SendgridAdapter
4
- def initialize(params)
5
- @params = params
6
- end
7
-
8
- def self.normalize_params(params)
9
- adapter = new(params)
10
- adapter.normalize_params
11
- end
12
-
13
- def normalize_params
14
- params.merge(
15
- to: recipients(:to),
16
- cc: recipients(:cc),
17
- attachments: attachment_files,
18
- )
19
- end
20
-
21
- private
22
-
23
- attr_reader :params
24
-
25
- def recipients(key)
26
- ( params[key] || '' ).split(',')
27
- end
28
-
29
- def attachment_files
30
- params.delete('attachment-info')
31
- attachment_count = params[:attachments].to_i
32
-
33
- attachment_count.times.map do |index|
34
- params.delete("attachment#{index + 1}".to_sym)
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :griddler do
3
- # # Task goes here
4
- # end