gitlab-mail_room 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.gitlab-ci.yml +27 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +10 -0
  6. data/CHANGELOG.md +125 -0
  7. data/CODE_OF_CONDUCT.md +24 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +361 -0
  11. data/Rakefile +6 -0
  12. data/bin/mail_room +5 -0
  13. data/lib/mail_room.rb +16 -0
  14. data/lib/mail_room/arbitration.rb +16 -0
  15. data/lib/mail_room/arbitration/noop.rb +18 -0
  16. data/lib/mail_room/arbitration/redis.rb +58 -0
  17. data/lib/mail_room/cli.rb +62 -0
  18. data/lib/mail_room/configuration.rb +36 -0
  19. data/lib/mail_room/connection.rb +195 -0
  20. data/lib/mail_room/coordinator.rb +41 -0
  21. data/lib/mail_room/crash_handler.rb +29 -0
  22. data/lib/mail_room/delivery.rb +24 -0
  23. data/lib/mail_room/delivery/letter_opener.rb +34 -0
  24. data/lib/mail_room/delivery/logger.rb +37 -0
  25. data/lib/mail_room/delivery/noop.rb +22 -0
  26. data/lib/mail_room/delivery/postback.rb +72 -0
  27. data/lib/mail_room/delivery/que.rb +63 -0
  28. data/lib/mail_room/delivery/sidekiq.rb +88 -0
  29. data/lib/mail_room/logger/structured.rb +21 -0
  30. data/lib/mail_room/mailbox.rb +182 -0
  31. data/lib/mail_room/mailbox_watcher.rb +62 -0
  32. data/lib/mail_room/version.rb +4 -0
  33. data/logfile.log +1 -0
  34. data/mail_room.gemspec +34 -0
  35. data/spec/fixtures/test_config.yml +16 -0
  36. data/spec/lib/arbitration/redis_spec.rb +146 -0
  37. data/spec/lib/cli_spec.rb +61 -0
  38. data/spec/lib/configuration_spec.rb +29 -0
  39. data/spec/lib/connection_spec.rb +65 -0
  40. data/spec/lib/coordinator_spec.rb +61 -0
  41. data/spec/lib/crash_handler_spec.rb +41 -0
  42. data/spec/lib/delivery/letter_opener_spec.rb +29 -0
  43. data/spec/lib/delivery/logger_spec.rb +46 -0
  44. data/spec/lib/delivery/postback_spec.rb +107 -0
  45. data/spec/lib/delivery/que_spec.rb +45 -0
  46. data/spec/lib/delivery/sidekiq_spec.rb +76 -0
  47. data/spec/lib/logger/structured_spec.rb +55 -0
  48. data/spec/lib/mailbox_spec.rb +132 -0
  49. data/spec/lib/mailbox_watcher_spec.rb +64 -0
  50. data/spec/spec_helper.rb +32 -0
  51. metadata +277 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 83ebaaed437f93cd2df69d48f6542842364fdab407bbf6620347b7a9e0d95199
4
+ data.tar.gz: d374aee24abf12a1cd274c3dbc9bd9e9feeb440b0eec314807487163617e9cab
5
+ SHA512:
6
+ metadata.gz: c76aa09decd47a81ee95f12d9a9c0470f48caabaf1443e461784677c58f8685a394198618498ae61d663819af4a99be4a359d5397e05f6cbab456973b995a3d8
7
+ data.tar.gz: f9815fff30eea223d91046f15e84d2fd4f584114c3a18743ba9f54134aa831138bb8f0936747130b5bc8da8f41b30d6e953a14c8ad4b3bc997bdb62d3e5b447e
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ log
@@ -0,0 +1,27 @@
1
+ # Cache gems in between builds
2
+
3
+ .test-template: &test
4
+ cache:
5
+ paths:
6
+ - vendor/ruby
7
+ script:
8
+ - bundle exec rspec spec
9
+ before_script:
10
+ - apt update && apt install -y libicu-dev
11
+ - ruby -v # Print out ruby version for debugging
12
+ # Uncomment next line if your rails app needs a JS runtime:
13
+ # - apt-get update -q && apt-get install nodejs -yqq
14
+ - gem install bundler --no-document # Bundler is not installed with the image
15
+ - bundle install -j $(nproc) --path vendor # Install dependencies into ./vendor/ruby
16
+
17
+ rspec-2.4:
18
+ image: "ruby:2.4"
19
+ <<: *test
20
+
21
+ rspec-2.5:
22
+ image: "ruby:2.5"
23
+ <<: *test
24
+
25
+ rspec-2.6:
26
+ image: "ruby:2.6"
27
+ <<: *test
@@ -0,0 +1 @@
1
+ 2.6.0
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ - 2.4
5
+ - 2.5
6
+ - 2.6
7
+ services:
8
+ - redis-server
9
+ script: bundle exec rspec spec
10
+ sudo: false
@@ -0,0 +1,125 @@
1
+ ## mail_room 0.10.0 ##
2
+
3
+ * Remove imap backports
4
+ * Increase minimum ruby version to 2.3
5
+ * Postback basic_auth support - PR#92
6
+ * Docs for ActionMailbox - PR#92
7
+ * Configuration option for delivery_klass - PR#93
8
+ * Expunge deleted - PR#90
9
+ * Raise error on a few fields of missing configuration - PR#89
10
+ * Remove fakeredis gem - PR#87
11
+
12
+ *Tony Pitale <@tpitale>*
13
+
14
+ * Fix redis arbitration to use NX+EX - PR#86
15
+
16
+ *Craig Miskell <@craigmiskell-gitlab>*
17
+
18
+ * Structured (JSON) logger - PR#88
19
+
20
+ *charlie <@cablett>*
21
+
22
+ ## mail_room 0.9.1 ##
23
+
24
+ * __FILE__ support in yml ERb config - PR#80
25
+
26
+ *Gabriel Mazetto <@brodock>*
27
+
28
+ ## mail_room 0.9.0 ##
29
+
30
+ * Redis Sentinel configuration support - PR#79
31
+
32
+ *Gabriel Mazetto <@brodock>*
33
+
34
+ ## mail_room 0.8.1 ##
35
+
36
+ * Check watching thread exists before joining - PR#78
37
+
38
+ *Michal Galet <@galet>*
39
+
40
+ ## mail_room 0.8.0 ##
41
+
42
+ * Rework the mailbox watcher and handler into a new Connection class to abstract away IMAP handling details
43
+
44
+ *Tony Pitale <@tpitale>*
45
+
46
+ ## mail_room 0.7.0 ##
47
+
48
+ * Backports idle timeout from ruby 2.3.0
49
+ * Sets default to 29 minutes to prevent IMAP disconnects
50
+ * Validates that the timeout does not exceed 29 minutes
51
+
52
+ *Tony Pitale <@tpitale>*
53
+
54
+ ## mail_room 0.6.1 ##
55
+
56
+ * ERB parsing of configuration yml file to enable using ENV variables
57
+
58
+ *Douwe Maan <@DouweM>*
59
+
60
+ ## mail_room 0.6.0 ##
61
+
62
+ * Add redis Arbitration to reduce multiple deliveries of the same message when running multiple MailRoom instances on the same inbox
63
+
64
+ *Douwe Maan <@DouweM>*
65
+
66
+ ## mail_room 0.5.2 ##
67
+
68
+ * Fix Sidekiq delivery method for non-UTF8 email
69
+
70
+ *Douwe Maan <@DouweM>*
71
+
72
+ * Add StartTLS session support
73
+
74
+ *Tony Pitale <@tpitale>*
75
+
76
+ ## mail_room 0.5.1 ##
77
+
78
+ * Re-idle after 29 minutes to maintain IDLE connection
79
+
80
+ *Douwe Maan <@DouweM>*
81
+
82
+ ## mail_room 0.5.0 ##
83
+
84
+ * Que delivery method
85
+
86
+ *Tony Pitale <@tpitale>*
87
+
88
+ ## mail_room 0.4.2 ##
89
+
90
+ * rescue from all IOErrors, not just EOFError
91
+
92
+ *Douwe Maan <@DouweM>*
93
+
94
+ ## mail_room 0.4.1 ##
95
+
96
+ * Fix redis default host/port configuration
97
+ * Mailbox does not attempt delivery without a message
98
+
99
+ *Douwe Maan <@DouweM>*
100
+
101
+ ## mail_room 0.4.0 ##
102
+
103
+ * Sidekiq delivery method
104
+ * Option to delete messages after delivered
105
+
106
+ *Douwe Maan <@DouweM>*
107
+
108
+ * -q/--quiet do not raise errors on missing configuration
109
+ * prefetch mail messages before idling
110
+ * delivery-method-specific delivery options configuration
111
+
112
+ *Tony Pitale <@tpitale>*
113
+
114
+ ## mail_room 0.3.1 ##
115
+
116
+ * Rescue from EOFError and re-setup mailroom
117
+
118
+ *Tony Pitale <@tpitale>*
119
+
120
+ ## mail_room 0.3.0 ##
121
+
122
+ * Reconnect and idle if disconnected during an existing idle.
123
+ * Set idling thread to abort on exception so any unhandled exceptions will stop mail_room running.
124
+
125
+ *Tony Pitale <@tpitale>*
@@ -0,0 +1,24 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
6
+
7
+ Examples of unacceptable behavior by participants include:
8
+
9
+ * The use of sexualized language or imagery
10
+ * Personal attacks
11
+ * Trolling or insulting/derogatory comments
12
+ * Public or private harassment
13
+ * Publishing other's private information, such as physical or electronic addresses, without explicit permission
14
+ * Other unethical or unprofessional conduct
15
+
16
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
17
+
18
+ By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
19
+
20
+ This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
21
+
22
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at [INSERT EMAIL ADDRESS]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident.
23
+
24
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.3.0, available at [http://contributor-covenant.org/version/1/3/0/](http://contributor-covenant.org/version/1/3/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mail_room.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Tony Pitale
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,361 @@
1
+ # mail_room #
2
+
3
+ ## Fork notice
4
+
5
+ mail_room contains some merged functionality that GitLab requires, so this mirror fork is to help us release custom functionality.
6
+
7
+ ## README
8
+
9
+ mail_room is a configuration based process that will idle on IMAP connections and execute a delivery method when a new message is received. Examples of delivery methods include:
10
+
11
+ * POST to a delivery URL (Postback)
12
+ * Queue a job to Sidekiq or Que for later processing (Sidekiq or Que)
13
+ * Log the message or open with LetterOpener (Logger or LetterOpener)
14
+
15
+ [![Build Status](https://travis-ci.org/tpitale/mail_room.png?branch=master)](https://travis-ci.org/tpitale/mail_room)
16
+ [![Code Climate](https://codeclimate.com/github/tpitale/mail_room/badges/gpa.svg)](https://codeclimate.com/github/tpitale/mail_room)
17
+
18
+ ## Installation ##
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ gem 'mail_room'
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install mail_room
31
+
32
+ You will also need to install `faraday` or `letter_opener` if you use the `postback` or `letter_opener` delivery methods, respectively.
33
+
34
+ ## Usage ##
35
+
36
+ mail_room -c /path/to/config.yml
37
+
38
+ **Note:** To ignore missing config file or missing `mailboxes` key, use `-q` or `--quiet`
39
+
40
+ ## Configuration ##
41
+
42
+ ```yaml
43
+ ---
44
+ :mailboxes:
45
+ -
46
+ :email: "user1@gmail.com"
47
+ :password: "password"
48
+ :name: "inbox"
49
+ :search_command: 'NEW'
50
+ :logger:
51
+ :log_path: /path/to/logfile/for/mailroom
52
+ :delivery_options:
53
+ :delivery_url: "http://localhost:3000/inbox"
54
+ :delivery_token: "abcdefg"
55
+ :content_type: "text/plain"
56
+
57
+ -
58
+ :email: "user2@gmail.com"
59
+ :password: "password"
60
+ :name: "inbox"
61
+ :delivery_method: postback
62
+ :delivery_options:
63
+ :delivery_url: "http://localhost:3000/inbox"
64
+ :delivery_token: "abcdefg"
65
+ -
66
+ :email: "user3@gmail.com"
67
+ :password: "password"
68
+ :name: "inbox"
69
+ :delivery_method: logger
70
+ :delivery_options:
71
+ :log_path: "/var/log/user3-email.log"
72
+ -
73
+ :email: "user4@gmail.com"
74
+ :password: "password"
75
+ :name: "inbox"
76
+ :delivery_method: letter_opener
77
+ :delete_after_delivery: true
78
+ :expunge_deleted: true
79
+ :delivery_options:
80
+ :location: "/tmp/user4-email"
81
+ -
82
+ :email: "user5@gmail.com"
83
+ :password: "password"
84
+ :name: "inbox"
85
+ :delivery_method: sidekiq
86
+ :delivery_options:
87
+ :redis_url: redis://localhost:6379
88
+ :worker: EmailReceiverWorker
89
+ -
90
+ :email: "user6@gmail.com"
91
+ :password: "password"
92
+ :name: "inbox"
93
+ :delivery_method: sidekiq
94
+ :delivery_options:
95
+ # When pointing to sentinel, follow this sintax for redis URLs:
96
+ # redis://:<password>@<master-name>/
97
+ :redis_url: redis://:password@my-redis-sentinel/
98
+ :sentinels:
99
+ -
100
+ :host: 127.0.0.1
101
+ :port: 26379
102
+ :worker: EmailReceiverWorker
103
+ ```
104
+
105
+ **Note:** If using `delete_after_delivery`, you also probably want to use
106
+ `expunge_deleted` unless you really know what you're doing.
107
+
108
+ ## delivery_method ##
109
+
110
+ ### postback ###
111
+
112
+ Requires `faraday` gem be installed.
113
+
114
+ *NOTE:* If you're using Ruby `>= 2.0`, you'll need to use Faraday from `>= 0.8.9`. Versions before this seem to have some weird behavior with `mail_room`.
115
+
116
+ The default delivery method, requires `delivery_url` and `delivery_token` in
117
+ configuration.
118
+
119
+ You can pass `content_type:` option to overwrite `faraday's` default content-type(`application/x-www-form-urlencoded`) for post requests, we recommend passing `text/plain` as content-type.
120
+
121
+ As the postback is essentially using your app as if it were an API endpoint,
122
+ you may need to disable forgery protection as you would with a JSON API.
123
+
124
+ ### sidekiq ###
125
+
126
+ Deliver the message by pushing it onto the configured Sidekiq queue to be handled by a custom worker.
127
+
128
+ Requires `redis` gem to be installed.
129
+
130
+ Configured with `:delivery_method: sidekiq`.
131
+
132
+ Delivery options:
133
+ - **redis_url**: The Redis server to connect with. Use the same Redis URL that's used to configure Sidekiq.
134
+ Required, defaults to `redis://localhost:6379`.
135
+ - **sentinels**: A list of sentinels servers used to provide HA to Redis. (see [Sentinel Support](#sentinel-support))
136
+ Optional.
137
+ - **namespace**: The Redis namespace Sidekiq works under. Use the same Redis namespace that's used to configure Sidekiq.
138
+ Optional.
139
+ - **queue**: The Sidekiq queue the job is pushed onto. Make sure Sidekiq actually reads off this queue.
140
+ Required, defaults to `default`.
141
+ - **worker**: The worker class that will handle the message.
142
+ Required.
143
+
144
+ An example worker implementation looks like this:
145
+
146
+
147
+ ```ruby
148
+ class EmailReceiverWorker
149
+ include Sidekiq::Worker
150
+
151
+ def perform(message)
152
+ mail = Mail::Message.new(message)
153
+
154
+ puts "New mail from #{mail.from.first}: #{mail.subject}"
155
+ end
156
+ end
157
+ ```
158
+
159
+ ### que ###
160
+
161
+ Deliver the message by pushing it onto the configured Que queue to be handled by a custom worker.
162
+
163
+ Requires `pg` gem to be installed.
164
+
165
+ Configured with `:delivery_method: que`.
166
+
167
+ Delivery options:
168
+ - **host**: The postgresql server host to connect with. Use the database you use with Que.
169
+ Required, defaults to `localhost`.
170
+ - **port**: The postgresql server port to connect with. Use the database you use with Que.
171
+ Required, defaults to `5432`.
172
+ - **database**: The postgresql database to use. Use the database you use with Que.
173
+ Required.
174
+ - **queue**: The Que queue the job is pushed onto. Make sure Que actually reads off this queue.
175
+ Required, defaults to `default`.
176
+ - **job_class**: The worker class that will handle the message.
177
+ Required.
178
+ - **priority**: The priority you want this job to run at.
179
+ Required, defaults to `100`, lowest Que default priority.
180
+
181
+ An example worker implementation looks like this:
182
+
183
+ ```ruby
184
+ class EmailReceiverJob < Que::Job
185
+ def run(message)
186
+ mail = Mail::Message.new(message)
187
+
188
+ puts "New mail from #{mail.from.first}: #{mail.subject}"
189
+ end
190
+ end
191
+ ```
192
+
193
+ ### logger ###
194
+
195
+ Configured with `:delivery_method: logger`.
196
+
197
+ If the `:log_path:` delivery option is not provided, defaults to `STDOUT`
198
+
199
+ ### noop ###
200
+
201
+ Configured with `:delivery_method: noop`.
202
+
203
+ Does nothing, like it says.
204
+
205
+ ### letter_opener ###
206
+
207
+ Requires `letter_opener` gem be installed.
208
+
209
+ Configured with `:delivery_method: letter_opener`.
210
+
211
+ Uses Ryan Bates' excellent [letter_opener](https://github.com/ryanb/letter_opener) gem.
212
+
213
+ ## ActionMailbox in Rails ##
214
+
215
+ MailRoom can deliver mail to Rails using the ActionMailbox [configuration options for an SMTP relay](https://edgeguides.rubyonrails.org/action_mailbox_basics.html#configuration).
216
+
217
+ In summary (from the ActionMailbox docs)
218
+
219
+ 1. Configure Rails to use the `:relay` ingress option:
220
+ ```rb
221
+ # config/environments/production.rb
222
+ config.action_mailbox.ingress = :relay
223
+ ```
224
+
225
+ 2. Generate a strong password (e.g., using SecureRandom or something) and add it to Rails config:
226
+ using `rails credentials:edit` under `action_mailbox.ingress_password`.
227
+
228
+ And finally, configure MailRoom to use the postback configuration with the options:
229
+
230
+ ```yaml
231
+ :delivery_method: postback
232
+ :delivery_options:
233
+ :delivery_url: https://example.com/rails/action_mailbox/relay/inbound_emails
234
+ :delivery_username: actionmailbox
235
+ :delivery_password: <INGRESS_PASSWORD>
236
+ ```
237
+
238
+ ## Receiving `postback` in Rails ##
239
+
240
+ If you have a controller that you're sending to, with forgery protection
241
+ disabled, you can get the raw string of the email using `request.body.read`.
242
+
243
+ I would recommend having the `mail` gem bundled and parse the email using
244
+ `Mail.read_from_string(request.body.read)`.
245
+
246
+ *Note:* If you get the exception (`Rack::QueryParser::InvalidParameterError (invalid %-encoding...`)
247
+ it's probably because the content-type is set to Faraday's default, which is `HEADERS['content-type'] = 'application/x-www-form-urlencoded'`. It can cause `Rack` to crash due to `InvalidParameterError` exception. When you send a post with `application/x-www-form-urlencoded`, `Rack` will attempt to parse the input and can end up raising an exception, for example if the email that you are forwarding contain `%%` in its content or headers it will cause Rack to crash with the message above.
248
+
249
+ ## idle_timeout ##
250
+
251
+ By default, the IDLE command will wait for 29 minutes (in order to keep the server connection happy).
252
+ If you'd prefer not to wait that long, you can pass `imap_timeout` in seconds for your mailbox configuration.
253
+
254
+ ## Search Command ##
255
+
256
+ This setting allows configuration of the IMAP search command sent to the server. This still defaults 'UNSEEN'. You may find that 'NEW' works better for you.
257
+
258
+ ## IMAP Server Configuration ##
259
+
260
+ You can set per-mailbox configuration for the IMAP server's `host` (default: 'imap.gmail.com'), `port` (default: 993), `ssl` (default: true), and `start_tls` (default: false).
261
+
262
+ If you want to set additional options for IMAP SSL you can pass a YAML hash to match [SSLContext#set_params](http://docs.ruby-lang.org/en/2.2.0/OpenSSL/SSL/SSLContext.html#method-i-set_params). If you set `verify_mode` to `:none` it'll replace with the appropriate constant.
263
+
264
+ If you're seeing the error `Please log in via your web browser: https://support.google.com/mail/accounts/answer/78754 (Failure)`, you need to configure your Gmail account to allow less secure apps to access it: https://support.google.com/accounts/answer/6010255.
265
+
266
+ ## Running in Production ##
267
+
268
+ I suggest running with either upstart or init.d. Check out this wiki page for some example scripts for both: https://github.com/tpitale/mail_room/wiki/Init-Scripts-for-Running-mail_room
269
+
270
+ ## Arbitration ##
271
+
272
+ When running multiple instances of MailRoom against a single mailbox, to try to prevent delivery of the same message multiple times, we can configure Arbitration using Redis.
273
+
274
+ ```yaml
275
+ :mailboxes:
276
+ -
277
+ :email: "user1@gmail.com"
278
+ :password: "password"
279
+ :name: "inbox"
280
+ :delivery_method: postback
281
+ :delivery_options:
282
+ :delivery_url: "http://localhost:3000/inbox"
283
+ :delivery_token: "abcdefg"
284
+
285
+ :arbitration_method: redis
286
+ :arbitration_options:
287
+ # The Redis server to connect with. Defaults to redis://localhost:6379.
288
+ :redis_url: redis://redis.example.com:6379
289
+ # The Redis namespace to house the Redis keys under. Optional.
290
+ :namespace: mail_room
291
+ -
292
+ :email: "user2@gmail.com"
293
+ :password: "password"
294
+ :name: "inbox"
295
+ :delivery_method: postback
296
+ :delivery_options:
297
+ :delivery_url: "http://localhost:3000/inbox"
298
+ :delivery_token: "abcdefg"
299
+
300
+ :arbitration_method: redis
301
+ :arbitration_options:
302
+ # When pointing to sentinel, follow this sintax for redis URLs:
303
+ # redis://:<password>@<master-name>/
304
+ :redis_url: redis://:password@my-redis-sentinel/
305
+ :sentinels:
306
+ -
307
+ :host: 127.0.0.1
308
+ :port: 26379
309
+ # The Redis namespace to house the Redis keys under. Optional.
310
+ :namespace: mail_room
311
+ ```
312
+
313
+ **Note:** This will likely never be a _perfect_ system for preventing multiple deliveries of the same message, so I would advise checking the unique `message_id` if you are running in this situation.
314
+
315
+ **Note:** There are other scenarios for preventing duplication of messages at scale that _may_ be more appropriate in your particular setup. One such example is using multiple inboxes in reply-by-email situations. Another is to use labels and configure a different `SEARCH` command for each instance of MailRoom.
316
+
317
+ ## Sentinel Support
318
+
319
+ Redis Sentinel provides high availability for Redis. Please read their [documentation](http://redis.io/topics/sentinel)
320
+ first, before enabling it with mail_room.
321
+
322
+ To connect to a Sentinel, you need to setup authentication to both sentinels and redis daemons first, and make sure
323
+ both are binding to a reachable IP address.
324
+
325
+ In mail_room, when you are connecting to a Sentinel, you have to inform the `master-name` and the `password` through
326
+ `redis_url` param, following this syntax:
327
+
328
+ ```
329
+ redis://:<password>@<master-name>/
330
+ ```
331
+
332
+ You also have to inform at least one pair of `host` and `port` for a sentinel in your cluster.
333
+ To have a minimum reliable setup, you need at least `3` sentinel nodes and `3` redis servers (1 master, 2 slaves).
334
+
335
+ ## Logging ##
336
+
337
+ MailRoom will output JSON-formatted logs to give some observability into its operations.
338
+
339
+ Simply configure a `log_path` for the `logger` on any of your mailboxes. By default, nothing will be logged.
340
+
341
+ If you wish to log to `STDOUT` or `STDERR` instead of a file, you can pass `:stdout` or `:stderr`,
342
+ respectively and MailRoom will log there.
343
+
344
+ ## Contributing ##
345
+
346
+ 1. Fork it
347
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
348
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
349
+ 4. Push to the branch (`git push origin my-new-feature`)
350
+ 5. Create new Pull Request
351
+ 6. If accepted, ask for commit rights
352
+
353
+ ## TODO ##
354
+
355
+ 1. specs, this is just a (working) proof of concept √
356
+ 2. finish code for POSTing to callback with auth √
357
+ 3. accept mailbox configuration for one account directly on the commandline; or ask for it
358
+ 4. add example rails endpoint, with auth examples
359
+ 5. add example configs for upstart/init.d √
360
+ 6. log to stdout √
361
+ 7. add a development mode that opens in letter_opener by ryanb √