actionmailbox 6.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.md +13 -0
  5. data/app/controllers/action_mailbox/base_controller.rb +38 -0
  6. data/app/controllers/action_mailbox/ingresses/amazon/inbound_emails_controller.rb +54 -0
  7. data/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb +103 -0
  8. data/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb +82 -0
  9. data/app/controllers/action_mailbox/ingresses/postmark/inbound_emails_controller.rb +62 -0
  10. data/app/controllers/action_mailbox/ingresses/relay/inbound_emails_controller.rb +65 -0
  11. data/app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller.rb +54 -0
  12. data/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller.rb +34 -0
  13. data/app/controllers/rails/conductor/action_mailbox/reroutes_controller.rb +19 -0
  14. data/app/controllers/rails/conductor/base_controller.rb +14 -0
  15. data/app/jobs/action_mailbox/incineration_job.rb +22 -0
  16. data/app/jobs/action_mailbox/routing_job.rb +13 -0
  17. data/app/models/action_mailbox/inbound_email.rb +49 -0
  18. data/app/models/action_mailbox/inbound_email/incineratable.rb +20 -0
  19. data/app/models/action_mailbox/inbound_email/incineratable/incineration.rb +26 -0
  20. data/app/models/action_mailbox/inbound_email/message_id.rb +38 -0
  21. data/app/models/action_mailbox/inbound_email/routable.rb +24 -0
  22. data/app/views/layouts/rails/conductor.html.erb +7 -0
  23. data/app/views/rails/conductor/action_mailbox/inbound_emails/index.html.erb +15 -0
  24. data/app/views/rails/conductor/action_mailbox/inbound_emails/new.html.erb +47 -0
  25. data/app/views/rails/conductor/action_mailbox/inbound_emails/show.html.erb +15 -0
  26. data/config/routes.rb +20 -0
  27. data/db/migrate/20180917164000_create_action_mailbox_tables.rb +17 -0
  28. data/lib/action_mailbox.rb +16 -0
  29. data/lib/action_mailbox/base.rb +118 -0
  30. data/lib/action_mailbox/callbacks.rb +34 -0
  31. data/lib/action_mailbox/engine.rb +42 -0
  32. data/lib/action_mailbox/gem_version.rb +17 -0
  33. data/lib/action_mailbox/mail_ext.rb +6 -0
  34. data/lib/action_mailbox/mail_ext/address_equality.rb +9 -0
  35. data/lib/action_mailbox/mail_ext/address_wrapping.rb +9 -0
  36. data/lib/action_mailbox/mail_ext/addresses.rb +29 -0
  37. data/lib/action_mailbox/mail_ext/from_source.rb +7 -0
  38. data/lib/action_mailbox/mail_ext/recipients.rb +9 -0
  39. data/lib/action_mailbox/relayer.rb +75 -0
  40. data/lib/action_mailbox/router.rb +42 -0
  41. data/lib/action_mailbox/router/route.rb +42 -0
  42. data/lib/action_mailbox/routing.rb +22 -0
  43. data/lib/action_mailbox/test_case.rb +12 -0
  44. data/lib/action_mailbox/test_helper.rb +44 -0
  45. data/lib/action_mailbox/version.rb +10 -0
  46. data/lib/rails/generators/installer.rb +10 -0
  47. data/lib/rails/generators/mailbox/USAGE +12 -0
  48. data/lib/rails/generators/mailbox/mailbox_generator.rb +32 -0
  49. data/lib/rails/generators/mailbox/templates/application_mailbox.rb.tt +3 -0
  50. data/lib/rails/generators/mailbox/templates/mailbox.rb.tt +4 -0
  51. data/lib/rails/generators/test_unit/mailbox_generator.rb +20 -0
  52. data/lib/rails/generators/test_unit/templates/mailbox_test.rb.tt +13 -0
  53. data/lib/tasks/ingress.rake +72 -0
  54. data/lib/tasks/install.rake +20 -0
  55. metadata +184 -0
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionMailbox
4
+ # See +ActionMailbox::Base+ for how to specify routing.
5
+ module Routing
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ cattr_accessor :router, default: ActionMailbox::Router.new
10
+ end
11
+
12
+ class_methods do
13
+ def routing(routes)
14
+ router.add_routes(routes)
15
+ end
16
+
17
+ def route(inbound_email)
18
+ router.route(inbound_email)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_mailbox/test_helper"
4
+ require "active_support/test_case"
5
+
6
+ module ActionMailbox
7
+ class TestCase < ActiveSupport::TestCase
8
+ include ActionMailbox::TestHelper
9
+ end
10
+ end
11
+
12
+ ActiveSupport.run_load_hooks :action_mailbox_test_case, ActionMailbox::TestCase
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mail"
4
+
5
+ module ActionMailbox
6
+ module TestHelper
7
+ # Create an +InboundEmail+ record using an eml fixture in the format of message/rfc822
8
+ # referenced with +fixture_name+ located in +test/fixtures/files/fixture_name+.
9
+ def create_inbound_email_from_fixture(fixture_name, status: :processing)
10
+ create_inbound_email_from_source file_fixture(fixture_name).read, status: status
11
+ end
12
+
13
+ # Create an +InboundEmail+ by specifying it using +Mail.new+ options. Example:
14
+ #
15
+ # create_inbound_email_from_mail(from: "david@loudthinking.com", subject: "Hello!")
16
+ def create_inbound_email_from_mail(status: :processing, **mail_options)
17
+ create_inbound_email_from_source Mail.new(mail_options).to_s, status: status
18
+ end
19
+
20
+ # Create an +InboundEmail+ using the raw rfc822 +source+ as text.
21
+ def create_inbound_email_from_source(source, status: :processing)
22
+ ActionMailbox::InboundEmail.create_and_extract_message_id! source, status: status
23
+ end
24
+
25
+
26
+ # Create an +InboundEmail+ from fixture using the same arguments as +create_inbound_email_from_fixture+
27
+ # and immediately route it to processing.
28
+ def receive_inbound_email_from_fixture(*args)
29
+ create_inbound_email_from_fixture(*args).tap(&:route)
30
+ end
31
+
32
+ # Create an +InboundEmail+ from fixture using the same arguments as +create_inbound_email_from_mail+
33
+ # and immediately route it to processing.
34
+ def receive_inbound_email_from_mail(**kwargs)
35
+ create_inbound_email_from_mail(**kwargs).tap(&:route)
36
+ end
37
+
38
+ # Create an +InboundEmail+ from fixture using the same arguments as +create_inbound_email_from_source+
39
+ # and immediately route it to processing.
40
+ def receive_inbound_email_from_source(**kwargs)
41
+ create_inbound_email_from_source(**kwargs).tap(&:route)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "gem_version"
4
+
5
+ module ActionMailbox
6
+ # Returns the currently-loaded version of Action Mailbox as a <tt>Gem::Version</tt>.
7
+ def self.version
8
+ gem_version
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ say "Copying application_mailbox.rb to app/mailboxes"
4
+ copy_file "#{__dir__}/mailbox/templates/application_mailbox.rb", "app/mailboxes/application_mailbox.rb"
5
+
6
+ environment <<~end_of_config, env: "production"
7
+ # Prepare the ingress controller used to receive mail
8
+ # config.action_mailbox.ingress = :amazon
9
+
10
+ end_of_config
@@ -0,0 +1,12 @@
1
+ Description:
2
+ ============
3
+ Stubs out a new mailbox class in app/mailboxes and invokes your template
4
+ engine and test framework generators.
5
+
6
+ Example:
7
+ ========
8
+ rails generate mailbox inbox
9
+
10
+ creates a InboxMailbox class and test:
11
+ Mailbox: app/mailboxes/inbox_mailbox.rb
12
+ Test: test/mailboxes/inbox_mailbox_test.rb
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module Generators
5
+ class MailboxGenerator < NamedBase
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ check_class_collision suffix: "Mailbox"
9
+
10
+ def create_mailbox_file
11
+ template "mailbox.rb", File.join("app/mailboxes", class_path, "#{file_name}_mailbox.rb")
12
+
13
+ in_root do
14
+ if behavior == :invoke && !File.exist?(application_mailbox_file_name)
15
+ template "application_mailbox.rb", application_mailbox_file_name
16
+ end
17
+ end
18
+ end
19
+
20
+ hook_for :test_framework
21
+
22
+ private
23
+ def file_name # :doc:
24
+ @_file_name ||= super.sub(/_mailbox\z/i, "")
25
+ end
26
+
27
+ def application_mailbox_file_name
28
+ "app/mailboxes/application_mailbox.rb"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationMailbox < ActionMailbox::Base
2
+ # routing /something/i => :somewhere
3
+ end
@@ -0,0 +1,4 @@
1
+ class <%= class_name %>Mailbox < ApplicationMailbox
2
+ def process
3
+ end
4
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TestUnit
4
+ module Generators
5
+ class MailboxGenerator < ::Rails::Generators::NamedBase
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ check_class_collision suffix: "MailboxTest"
9
+
10
+ def create_test_files
11
+ template "mailbox_test.rb", File.join("test/mailboxes", class_path, "#{file_name}_mailbox_test.rb")
12
+ end
13
+
14
+ private
15
+ def file_name # :doc:
16
+ @_file_name ||= super.sub(/_mailbox\z/i, "")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ class <%= class_name %>MailboxTest < ActionMailbox::TestCase
6
+ # test "receive mail" do
7
+ # receive_inbound_email_from_mail \
8
+ # to: '"someone" <someone@example.com>',
9
+ # from: '"else" <else@example.com>',
10
+ # subject: "Hello world!",
11
+ # body: "Hello?"
12
+ # end
13
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :action_mailbox do
4
+ namespace :ingress do
5
+ task :environment do
6
+ require "active_support"
7
+ require "active_support/core_ext/object/blank"
8
+ require "action_mailbox/relayer"
9
+ end
10
+
11
+ desc "Relay an inbound email from Exim to Action Mailbox (URL and INGRESS_PASSWORD required)"
12
+ task exim: "action_mailbox:ingress:environment" do
13
+ url, password = ENV.values_at("URL", "INGRESS_PASSWORD")
14
+
15
+ if url.blank? || password.blank?
16
+ print "URL and INGRESS_PASSWORD are required"
17
+ exit 64 # EX_USAGE
18
+ end
19
+
20
+ ActionMailbox::Relayer.new(url: url, password: password).relay(STDIN.read).tap do |result|
21
+ print result.message
22
+
23
+ case
24
+ when result.success?
25
+ exit 0
26
+ when result.transient_failure?
27
+ exit 75 # EX_TEMPFAIL
28
+ else
29
+ exit 69 # EX_UNAVAILABLE
30
+ end
31
+ end
32
+ end
33
+
34
+ desc "Relay an inbound email from Postfix to Action Mailbox (URL and INGRESS_PASSWORD required)"
35
+ task postfix: "action_mailbox:ingress:environment" do
36
+ url, password = ENV.values_at("URL", "INGRESS_PASSWORD")
37
+
38
+ if url.blank? || password.blank?
39
+ print "4.3.5 URL and INGRESS_PASSWORD are required"
40
+ exit 1
41
+ end
42
+
43
+ ActionMailbox::Relayer.new(url: url, password: password).relay(STDIN.read).tap do |result|
44
+ print "#{result.status_code} #{result.message}"
45
+ exit result.success?
46
+ end
47
+ end
48
+
49
+ desc "Relay an inbound email from Qmail to Action Mailbox (URL and INGRESS_PASSWORD required)"
50
+ task qmail: "action_mailbox:ingress:environment" do
51
+ url, password = ENV.values_at("URL", "INGRESS_PASSWORD")
52
+
53
+ if url.blank? || password.blank?
54
+ print "URL and INGRESS_PASSWORD are required"
55
+ exit 111
56
+ end
57
+
58
+ ActionMailbox::Relayer.new(url: url, password: password).relay(STDIN.read).tap do |result|
59
+ print result.message
60
+
61
+ case
62
+ when result.success?
63
+ exit 0
64
+ when result.transient_failure?
65
+ exit 111
66
+ else
67
+ exit 100
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :action_mailbox do
4
+ # Prevent migration installation task from showing up twice.
5
+ Rake::Task["install:migrations"].clear_comments
6
+
7
+ desc "Copy over the migration"
8
+ task install: %w[ environment run_installer copy_migrations ]
9
+
10
+ task :run_installer do
11
+ installer_template = File.expand_path("../rails/generators/installer.rb", __dir__)
12
+ system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{installer_template}"
13
+ end
14
+
15
+ task :copy_migrations do
16
+ Rake::Task["active_storage:install:migrations"].invoke
17
+ Rake::Task["railties:install:migrations"].reenable # Otherwise you can't run 2 migration copy tasks in one invocation
18
+ Rake::Task["action_mailbox:install:migrations"].invoke
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,184 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: actionmailbox
3
+ version: !ruby/object:Gem::Version
4
+ version: 6.0.0.beta1
5
+ platform: ruby
6
+ authors:
7
+ - David Heinemeier Hansson
8
+ - George Claghorn
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2019-01-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '='
19
+ - !ruby/object:Gem::Version
20
+ version: 6.0.0.beta1
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '='
26
+ - !ruby/object:Gem::Version
27
+ version: 6.0.0.beta1
28
+ - !ruby/object:Gem::Dependency
29
+ name: activerecord
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '='
33
+ - !ruby/object:Gem::Version
34
+ version: 6.0.0.beta1
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '='
40
+ - !ruby/object:Gem::Version
41
+ version: 6.0.0.beta1
42
+ - !ruby/object:Gem::Dependency
43
+ name: activestorage
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '='
47
+ - !ruby/object:Gem::Version
48
+ version: 6.0.0.beta1
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '='
54
+ - !ruby/object:Gem::Version
55
+ version: 6.0.0.beta1
56
+ - !ruby/object:Gem::Dependency
57
+ name: activejob
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '='
61
+ - !ruby/object:Gem::Version
62
+ version: 6.0.0.beta1
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 6.0.0.beta1
70
+ - !ruby/object:Gem::Dependency
71
+ name: actionpack
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '='
75
+ - !ruby/object:Gem::Version
76
+ version: 6.0.0.beta1
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '='
82
+ - !ruby/object:Gem::Version
83
+ version: 6.0.0.beta1
84
+ - !ruby/object:Gem::Dependency
85
+ name: mail
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 2.7.1
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: 2.7.1
98
+ description: Receive and process incoming emails in Rails applications.
99
+ email:
100
+ - david@loudthinking.com
101
+ - george@basecamp.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - CHANGELOG.md
107
+ - MIT-LICENSE
108
+ - README.md
109
+ - app/controllers/action_mailbox/base_controller.rb
110
+ - app/controllers/action_mailbox/ingresses/amazon/inbound_emails_controller.rb
111
+ - app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb
112
+ - app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb
113
+ - app/controllers/action_mailbox/ingresses/postmark/inbound_emails_controller.rb
114
+ - app/controllers/action_mailbox/ingresses/relay/inbound_emails_controller.rb
115
+ - app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller.rb
116
+ - app/controllers/rails/conductor/action_mailbox/inbound_emails_controller.rb
117
+ - app/controllers/rails/conductor/action_mailbox/reroutes_controller.rb
118
+ - app/controllers/rails/conductor/base_controller.rb
119
+ - app/jobs/action_mailbox/incineration_job.rb
120
+ - app/jobs/action_mailbox/routing_job.rb
121
+ - app/models/action_mailbox/inbound_email.rb
122
+ - app/models/action_mailbox/inbound_email/incineratable.rb
123
+ - app/models/action_mailbox/inbound_email/incineratable/incineration.rb
124
+ - app/models/action_mailbox/inbound_email/message_id.rb
125
+ - app/models/action_mailbox/inbound_email/routable.rb
126
+ - app/views/layouts/rails/conductor.html.erb
127
+ - app/views/rails/conductor/action_mailbox/inbound_emails/index.html.erb
128
+ - app/views/rails/conductor/action_mailbox/inbound_emails/new.html.erb
129
+ - app/views/rails/conductor/action_mailbox/inbound_emails/show.html.erb
130
+ - config/routes.rb
131
+ - db/migrate/20180917164000_create_action_mailbox_tables.rb
132
+ - lib/action_mailbox.rb
133
+ - lib/action_mailbox/base.rb
134
+ - lib/action_mailbox/callbacks.rb
135
+ - lib/action_mailbox/engine.rb
136
+ - lib/action_mailbox/gem_version.rb
137
+ - lib/action_mailbox/mail_ext.rb
138
+ - lib/action_mailbox/mail_ext/address_equality.rb
139
+ - lib/action_mailbox/mail_ext/address_wrapping.rb
140
+ - lib/action_mailbox/mail_ext/addresses.rb
141
+ - lib/action_mailbox/mail_ext/from_source.rb
142
+ - lib/action_mailbox/mail_ext/recipients.rb
143
+ - lib/action_mailbox/relayer.rb
144
+ - lib/action_mailbox/router.rb
145
+ - lib/action_mailbox/router/route.rb
146
+ - lib/action_mailbox/routing.rb
147
+ - lib/action_mailbox/test_case.rb
148
+ - lib/action_mailbox/test_helper.rb
149
+ - lib/action_mailbox/version.rb
150
+ - lib/rails/generators/installer.rb
151
+ - lib/rails/generators/mailbox/USAGE
152
+ - lib/rails/generators/mailbox/mailbox_generator.rb
153
+ - lib/rails/generators/mailbox/templates/application_mailbox.rb.tt
154
+ - lib/rails/generators/mailbox/templates/mailbox.rb.tt
155
+ - lib/rails/generators/test_unit/mailbox_generator.rb
156
+ - lib/rails/generators/test_unit/templates/mailbox_test.rb.tt
157
+ - lib/tasks/ingress.rake
158
+ - lib/tasks/install.rake
159
+ homepage: https://rubyonrails.org
160
+ licenses:
161
+ - MIT
162
+ metadata:
163
+ source_code_uri: https://github.com/rails/rails/tree/v6.0.0.beta1/actionmailbox
164
+ changelog_uri: https://github.com/rails/rails/blob/v6.0.0.beta1/actionmailbox/CHANGELOG.md
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: 2.5.0
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">"
177
+ - !ruby/object:Gem::Version
178
+ version: 1.3.1
179
+ requirements: []
180
+ rubygems_version: 3.0.1
181
+ signing_key:
182
+ specification_version: 4
183
+ summary: Inbound email handling framework.
184
+ test_files: []