courrier 0.10.0 → 0.11.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 +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +16 -24
- data/README.md +120 -75
- data/courrier.gemspec +4 -4
- data/lib/courrier/configuration.rb +2 -4
- data/lib/courrier/email/provider.rb +10 -4
- data/lib/courrier/email/providers/cloudflare.rb +35 -0
- data/lib/courrier/email/providers/lettermint.rb +31 -0
- data/lib/courrier/email/providers/ses.rb +75 -0
- data/lib/courrier/email/providers/smtp2go.rb +29 -0
- data/lib/courrier/email/request.rb +1 -1
- data/lib/courrier/email/transformer.rb +9 -9
- data/lib/courrier/email.rb +22 -35
- data/lib/courrier/errors.rb +0 -2
- data/lib/courrier/test.rb +38 -0
- data/lib/courrier/test_helper.rb +65 -0
- data/lib/courrier/version.rb +1 -1
- data/lib/courrier.rb +2 -2
- metadata +17 -31
- data/app/controllers/courrier/previews/cleanups_controller.rb +0 -13
- data/app/controllers/courrier/previews_controller.rb +0 -23
- data/app/views/courrier/previews/index.html.erb +0 -171
- data/config/routes.rb +0 -8
- data/lib/courrier/configuration/inbox.rb +0 -21
- data/lib/courrier/email/providers/inbox/default.html.erb +0 -126
- data/lib/courrier/email/providers/inbox.rb +0 -83
- data/lib/courrier/engine.rb +0 -7
- data/lib/courrier/jobs/email_delivery_job.rb +0 -23
- data/lib/courrier/railtie.rb +0 -23
- data/lib/courrier/tasks/courrier.rake +0 -13
- data/lib/generators/courrier/email_generator.rb +0 -42
- data/lib/generators/courrier/install_generator.rb +0 -11
- data/lib/generators/courrier/templates/email/password_reset.rb.tt +0 -29
- data/lib/generators/courrier/templates/email/welcome.rb.tt +0 -43
- data/lib/generators/courrier/templates/email.rb.tt +0 -13
- data/lib/generators/courrier/templates/initializer.rb.tt +0 -43
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Courrier
|
|
4
|
+
class Email
|
|
5
|
+
module Providers
|
|
6
|
+
class Ses < Base
|
|
7
|
+
def deliver
|
|
8
|
+
uri = URI.parse("https://email.#{@provider_options[:region]}.amazonaws.com/v2/email/outbound-emails")
|
|
9
|
+
|
|
10
|
+
request = Net::HTTP::Post.new(uri)
|
|
11
|
+
default_headers.merge(@custom_headers).each { |name, value| request[name] = value }
|
|
12
|
+
|
|
13
|
+
sign!(request)
|
|
14
|
+
|
|
15
|
+
request.body = JSON.dump(body)
|
|
16
|
+
|
|
17
|
+
options = {use_ssl: uri.scheme == "https"}
|
|
18
|
+
response = Net::HTTP.start(uri.hostname, uri.port, options) { it.request(request) }
|
|
19
|
+
|
|
20
|
+
Courrier::Email::Result.new(response: response)
|
|
21
|
+
rescue => error
|
|
22
|
+
Courrier::Email::Result.new(error: error)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def body
|
|
26
|
+
{
|
|
27
|
+
"FromEmailAddress" => @options.from,
|
|
28
|
+
"Destination" => {
|
|
29
|
+
"ToAddresses" => Array(@options.to),
|
|
30
|
+
"CcAddresses" => @options.cc ? Array(@options.cc) : nil,
|
|
31
|
+
"BccAddresses" => @options.bcc ? Array(@options.bcc) : nil
|
|
32
|
+
}.compact,
|
|
33
|
+
|
|
34
|
+
"ReplyToAddresses" => @options.reply_to ? Array(@options.reply_to) : nil,
|
|
35
|
+
"Content" => {
|
|
36
|
+
"Simple" => {
|
|
37
|
+
"Subject" => {"Data" => @options.subject},
|
|
38
|
+
|
|
39
|
+
"Body" => {
|
|
40
|
+
"Text" => {"Data" => @options.text},
|
|
41
|
+
"Html" => {"Data" => @options.html}
|
|
42
|
+
}.compact
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}.compact
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def default_headers
|
|
51
|
+
{
|
|
52
|
+
"Content-Type" => "application/json",
|
|
53
|
+
"Accept" => "application/json"
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def sign!(request)
|
|
58
|
+
require "aws-sigv4"
|
|
59
|
+
|
|
60
|
+
Aws::Sigv4::Signer.new(
|
|
61
|
+
service: "ses",
|
|
62
|
+
region: @provider_options[:region],
|
|
63
|
+
access_key_id: @provider_options[:access_key_id],
|
|
64
|
+
secret_access_key: @provider_options[:secret_access_key],
|
|
65
|
+
session_token: @provider_options[:session_token]
|
|
66
|
+
).sign_request(
|
|
67
|
+
http_method: request.method,
|
|
68
|
+
url: request.uri.to_s,
|
|
69
|
+
headers: request.to_hash
|
|
70
|
+
).headers.each { |name, value| request[name] = value }
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Courrier
|
|
4
|
+
class Email
|
|
5
|
+
module Providers
|
|
6
|
+
class Smtp2go < Base
|
|
7
|
+
ENDPOINT_URL = "https://api.smtp2go.com/v3/email/send"
|
|
8
|
+
|
|
9
|
+
def body
|
|
10
|
+
{
|
|
11
|
+
"sender" => @options.from,
|
|
12
|
+
"to" => @options.to.to_s.split(",").map(&:strip),
|
|
13
|
+
"cc" => @options.cc&.split(",")&.map(&:strip),
|
|
14
|
+
"bcc" => @options.bcc&.split(",")&.map(&:strip),
|
|
15
|
+
"subject" => @options.subject,
|
|
16
|
+
"html_body" => @options.html,
|
|
17
|
+
"text_body" => @options.text
|
|
18
|
+
}.compact
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def default_headers
|
|
24
|
+
{"X-Smtp2go-Api-Key" => @api_key}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -25,7 +25,7 @@ module Courrier
|
|
|
25
25
|
options = {use_ssl: uri.scheme == "https"}
|
|
26
26
|
|
|
27
27
|
begin
|
|
28
|
-
response = Net::HTTP.start(uri.hostname, uri.port, options) {
|
|
28
|
+
response = Net::HTTP.start(uri.hostname, uri.port, options) { it.request(request) }
|
|
29
29
|
|
|
30
30
|
Result.new(response: response)
|
|
31
31
|
rescue => error
|
|
@@ -11,30 +11,30 @@ module Courrier
|
|
|
11
11
|
|
|
12
12
|
def to_text
|
|
13
13
|
Nokogiri::HTML(@content)
|
|
14
|
-
.then { remove_unwanted_elements(
|
|
15
|
-
.then { process_links(
|
|
16
|
-
.then { preserve_line_breaks(
|
|
17
|
-
.then { clean_up(
|
|
14
|
+
.then { remove_unwanted_elements(it) }
|
|
15
|
+
.then { process_links(it) }
|
|
16
|
+
.then { preserve_line_breaks(it) }
|
|
17
|
+
.then { clean_up(it) }
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
private
|
|
21
21
|
|
|
22
22
|
BLOCK_ELEMENTS = %w[p div h1 h2 h3 h4 h5 h6 pre blockquote li]
|
|
23
23
|
|
|
24
|
-
def remove_unwanted_elements(html) = html.tap {
|
|
24
|
+
def remove_unwanted_elements(html) = html.tap { it.css("script, style").remove }
|
|
25
25
|
|
|
26
26
|
def process_links(html)
|
|
27
27
|
html.tap do |document|
|
|
28
28
|
document.css("a")
|
|
29
|
-
.select { valid?(
|
|
30
|
-
.reject {
|
|
31
|
-
.each {
|
|
29
|
+
.select { valid?(it) }
|
|
30
|
+
.reject { it.text.strip.empty? || it.text.strip == it["href"] }
|
|
31
|
+
.each { it.content = "#{it.text.strip} (#{it["href"]})" }
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def preserve_line_breaks(html)
|
|
36
36
|
html.tap do |document|
|
|
37
|
-
document.css(BLOCK_ELEMENTS.join(",")).each {
|
|
37
|
+
document.css(BLOCK_ELEMENTS.join(",")).each { it.after("\n") }
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
data/lib/courrier/email.rb
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
require "erb"
|
|
4
4
|
|
|
5
5
|
require "courrier/email/address"
|
|
6
|
-
require "courrier/jobs/email_delivery_job" if defined?(Rails)
|
|
7
6
|
require "courrier/email/layouts"
|
|
8
7
|
require "courrier/markdown"
|
|
9
8
|
require "courrier/email/options"
|
|
@@ -52,23 +51,29 @@ module Courrier
|
|
|
52
51
|
self.layouts = options
|
|
53
52
|
end
|
|
54
53
|
|
|
54
|
+
def before_deliver(&block)
|
|
55
|
+
(@before_deliver ||= []) << block
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def after_deliver(&block)
|
|
59
|
+
(@after_deliver ||= []) << block
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def before_deliver_callbacks
|
|
63
|
+
@before_deliver || []
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def after_deliver_callbacks
|
|
67
|
+
@after_deliver || []
|
|
68
|
+
end
|
|
69
|
+
|
|
55
70
|
def deliver(**options)
|
|
56
71
|
new(options).deliver_now
|
|
57
72
|
end
|
|
58
73
|
alias_method :deliver_now, :deliver
|
|
59
74
|
|
|
60
|
-
def deliver_later(**options)
|
|
61
|
-
new(options).deliver_later
|
|
62
|
-
end
|
|
63
|
-
|
|
64
75
|
def inherited(subclass)
|
|
65
76
|
super
|
|
66
|
-
|
|
67
|
-
# If you read this and know how to move this Rails-specific logic somewhere
|
|
68
|
-
# else, e.g. `lib/courrier/railtie.rb`, open a PR ❤️
|
|
69
|
-
if defined?(Rails) && Rails.application
|
|
70
|
-
subclass.include Rails.application.routes.url_helpers
|
|
71
|
-
end
|
|
72
77
|
end
|
|
73
78
|
end
|
|
74
79
|
|
|
@@ -100,6 +105,8 @@ module Courrier
|
|
|
100
105
|
return nil
|
|
101
106
|
end
|
|
102
107
|
|
|
108
|
+
return nil if self.class.before_deliver_callbacks.any? { |callback| callback.call(self) == false }
|
|
109
|
+
|
|
103
110
|
Provider.new(
|
|
104
111
|
provider: @provider,
|
|
105
112
|
api_key: @api_key,
|
|
@@ -107,33 +114,13 @@ module Courrier
|
|
|
107
114
|
provider_options: Courrier.configuration&.providers&.[](@provider.to_s.downcase.to_sym),
|
|
108
115
|
context_options: @context_options,
|
|
109
116
|
custom_headers: self.class.headers
|
|
110
|
-
).deliver
|
|
111
|
-
|
|
112
|
-
alias_method :deliver_now, :deliver
|
|
117
|
+
).deliver.tap do |result|
|
|
118
|
+
Test.record(self, result)
|
|
113
119
|
|
|
114
|
-
|
|
115
|
-
if delivery_disabled?
|
|
116
|
-
Courrier.configuration&.logger&.info "[Courrier] Email delivery skipped: delivery is disabled via environment variable"
|
|
117
|
-
|
|
118
|
-
return nil
|
|
120
|
+
self.class.after_deliver_callbacks.each { |callback| callback.call(self, result) }
|
|
119
121
|
end
|
|
120
|
-
|
|
121
|
-
data = {
|
|
122
|
-
email_class: self.class.name,
|
|
123
|
-
provider: @provider,
|
|
124
|
-
api_key: @api_key,
|
|
125
|
-
options: @options.to_h,
|
|
126
|
-
provider_options: Courrier.configuration&.providers&.[](@provider.to_s.downcase.to_sym),
|
|
127
|
-
context_options: @context_options
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
job = Courrier::Jobs::EmailDeliveryJob
|
|
131
|
-
job = job.set(**self.class.queue_options) if self.class.queue_options.any?
|
|
132
|
-
|
|
133
|
-
job.perform_later(data)
|
|
134
|
-
rescue => error
|
|
135
|
-
raise Courrier::BackgroundDeliveryError, "Failed to enqueue email: #{error.message}"
|
|
136
122
|
end
|
|
123
|
+
alias_method :deliver_now, :deliver
|
|
137
124
|
|
|
138
125
|
private
|
|
139
126
|
|
data/lib/courrier/errors.rb
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Courrier
|
|
4
|
+
module Test
|
|
5
|
+
Delivery = Data.define(:email_class, :to, :from, :reply_to, :cc, :bcc, :subject, :body, :headers, :provider, :result, :timestamp) do
|
|
6
|
+
def success?
|
|
7
|
+
result.success?
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
def deliveries
|
|
13
|
+
@deliveries ||= []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def clear!
|
|
17
|
+
@deliveries = []
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def record(email, result)
|
|
21
|
+
deliveries << Delivery.new(
|
|
22
|
+
email_class: email.class.name,
|
|
23
|
+
to: email.options.to,
|
|
24
|
+
from: email.options.from,
|
|
25
|
+
reply_to: email.options.reply_to,
|
|
26
|
+
cc: email.options.cc,
|
|
27
|
+
bcc: email.options.bcc,
|
|
28
|
+
subject: email.options.subject,
|
|
29
|
+
body: {text: email.options.text, html: email.options.html},
|
|
30
|
+
headers: email.class.headers,
|
|
31
|
+
provider: email.provider,
|
|
32
|
+
result: result,
|
|
33
|
+
timestamp: Time.now
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Courrier
|
|
4
|
+
module TestHelper
|
|
5
|
+
def assert_emails_delivered(count)
|
|
6
|
+
actual = Test.deliveries.size
|
|
7
|
+
|
|
8
|
+
assert_equal count, actual, "Expected #{count} email(s) to be delivered, but #{actual} were delivered"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def assert_no_emails_delivered
|
|
12
|
+
assert_emails_delivered(0)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def assert_email_delivered(email_class = nil, to: nil, from: nil, subject: nil, provider: nil)
|
|
16
|
+
deliveries = Test.deliveries
|
|
17
|
+
|
|
18
|
+
matching = deliveries.find do |delivery|
|
|
19
|
+
match_email_class(email_class, delivery.email_class) &&
|
|
20
|
+
match_recipient(to, delivery.to) &&
|
|
21
|
+
match_recipient(from, delivery.from) &&
|
|
22
|
+
match_subject(subject, delivery.subject) &&
|
|
23
|
+
match_provider(provider, delivery.provider)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
assert matching, assertion_message(email_class, to: to, from: from, subject: subject, provider: provider, deliveries: deliveries)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def match_email_class(expected, actual)
|
|
32
|
+
return true if expected.nil?
|
|
33
|
+
|
|
34
|
+
expected == actual || (expected.is_a?(Class) && actual == expected.name)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def match_recipient(expected, actual)
|
|
38
|
+
return true if expected.nil?
|
|
39
|
+
|
|
40
|
+
actual.to_s.include?(expected.to_s)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def match_subject(expected, actual)
|
|
44
|
+
return true if expected.nil?
|
|
45
|
+
|
|
46
|
+
actual.to_s.include?(expected.to_s)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def match_provider(expected, actual)
|
|
50
|
+
return true if expected.nil?
|
|
51
|
+
|
|
52
|
+
actual.to_s == expected.to_s
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def assertion_message(email_class, to:, from:, subject:, provider:, deliveries:)
|
|
56
|
+
"Expected email matching #{[].tap do |criteria|
|
|
57
|
+
criteria << "email_class=#{email_class}" if email_class
|
|
58
|
+
criteria << "to=#{to}" if to
|
|
59
|
+
criteria << "from=#{from}" if from
|
|
60
|
+
criteria << "subject=#{subject}" if subject
|
|
61
|
+
criteria << "provider=#{provider}" if provider
|
|
62
|
+
end.join(", ")} but none found. #{deliveries.size} email(s) delivered."
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
data/lib/courrier/version.rb
CHANGED
data/lib/courrier.rb
CHANGED
|
@@ -5,8 +5,8 @@ require "courrier/errors"
|
|
|
5
5
|
require "courrier/configuration"
|
|
6
6
|
require "courrier/email"
|
|
7
7
|
require "courrier/subscriber"
|
|
8
|
-
require "courrier/
|
|
9
|
-
require "courrier/
|
|
8
|
+
require "courrier/test"
|
|
9
|
+
require "courrier/test_helper"
|
|
10
10
|
|
|
11
11
|
module Courrier
|
|
12
12
|
end
|
metadata
CHANGED
|
@@ -1,35 +1,34 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: courrier
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rails Designer
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: logger
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
18
|
+
version: '1.5'
|
|
20
19
|
- - "<"
|
|
21
20
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: '
|
|
21
|
+
version: '3'
|
|
23
22
|
type: :runtime
|
|
24
23
|
prerelease: false
|
|
25
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
25
|
requirements:
|
|
27
26
|
- - ">="
|
|
28
27
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '
|
|
28
|
+
version: '1.5'
|
|
30
29
|
- - "<"
|
|
31
30
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
31
|
+
version: '3'
|
|
33
32
|
- !ruby/object:Gem::Dependency
|
|
34
33
|
name: nokogiri
|
|
35
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -62,17 +61,12 @@ files:
|
|
|
62
61
|
- Gemfile.lock
|
|
63
62
|
- README.md
|
|
64
63
|
- Rakefile
|
|
65
|
-
- app/controllers/courrier/previews/cleanups_controller.rb
|
|
66
|
-
- app/controllers/courrier/previews_controller.rb
|
|
67
|
-
- app/views/courrier/previews/index.html.erb
|
|
68
64
|
- bin/console
|
|
69
65
|
- bin/release
|
|
70
66
|
- bin/setup
|
|
71
|
-
- config/routes.rb
|
|
72
67
|
- courrier.gemspec
|
|
73
68
|
- lib/courrier.rb
|
|
74
69
|
- lib/courrier/configuration.rb
|
|
75
|
-
- lib/courrier/configuration/inbox.rb
|
|
76
70
|
- lib/courrier/configuration/providers.rb
|
|
77
71
|
- lib/courrier/email.rb
|
|
78
72
|
- lib/courrier/email/address.rb
|
|
@@ -80,8 +74,8 @@ files:
|
|
|
80
74
|
- lib/courrier/email/options.rb
|
|
81
75
|
- lib/courrier/email/provider.rb
|
|
82
76
|
- lib/courrier/email/providers/base.rb
|
|
83
|
-
- lib/courrier/email/providers/
|
|
84
|
-
- lib/courrier/email/providers/
|
|
77
|
+
- lib/courrier/email/providers/cloudflare.rb
|
|
78
|
+
- lib/courrier/email/providers/lettermint.rb
|
|
85
79
|
- lib/courrier/email/providers/logger.rb
|
|
86
80
|
- lib/courrier/email/providers/loops.rb
|
|
87
81
|
- lib/courrier/email/providers/mailgun.rb
|
|
@@ -90,16 +84,15 @@ files:
|
|
|
90
84
|
- lib/courrier/email/providers/postmark.rb
|
|
91
85
|
- lib/courrier/email/providers/resend.rb
|
|
92
86
|
- lib/courrier/email/providers/sendgrid.rb
|
|
87
|
+
- lib/courrier/email/providers/ses.rb
|
|
88
|
+
- lib/courrier/email/providers/smtp2go.rb
|
|
93
89
|
- lib/courrier/email/providers/sparkpost.rb
|
|
94
90
|
- lib/courrier/email/providers/userlist.rb
|
|
95
91
|
- lib/courrier/email/request.rb
|
|
96
92
|
- lib/courrier/email/result.rb
|
|
97
93
|
- lib/courrier/email/transformer.rb
|
|
98
|
-
- lib/courrier/engine.rb
|
|
99
94
|
- lib/courrier/errors.rb
|
|
100
|
-
- lib/courrier/jobs/email_delivery_job.rb
|
|
101
95
|
- lib/courrier/markdown.rb
|
|
102
|
-
- lib/courrier/railtie.rb
|
|
103
96
|
- lib/courrier/subscriber.rb
|
|
104
97
|
- lib/courrier/subscriber/base.rb
|
|
105
98
|
- lib/courrier/subscriber/beehiiv.rb
|
|
@@ -109,21 +102,15 @@ files:
|
|
|
109
102
|
- lib/courrier/subscriber/mailchimp.rb
|
|
110
103
|
- lib/courrier/subscriber/mailerlite.rb
|
|
111
104
|
- lib/courrier/subscriber/result.rb
|
|
112
|
-
- lib/courrier/
|
|
105
|
+
- lib/courrier/test.rb
|
|
106
|
+
- lib/courrier/test_helper.rb
|
|
113
107
|
- lib/courrier/version.rb
|
|
114
|
-
|
|
115
|
-
- lib/generators/courrier/install_generator.rb
|
|
116
|
-
- lib/generators/courrier/templates/email.rb.tt
|
|
117
|
-
- lib/generators/courrier/templates/email/password_reset.rb.tt
|
|
118
|
-
- lib/generators/courrier/templates/email/welcome.rb.tt
|
|
119
|
-
- lib/generators/courrier/templates/initializer.rb.tt
|
|
120
|
-
homepage: https://railsdesigner.com/courrier/
|
|
108
|
+
homepage: https://railsdesigner.com/open-source/courrier/
|
|
121
109
|
licenses:
|
|
122
110
|
- MIT
|
|
123
111
|
metadata:
|
|
124
|
-
homepage_uri: https://railsdesigner.com/courrier/
|
|
112
|
+
homepage_uri: https://railsdesigner.com/open-source/courrier/
|
|
125
113
|
source_code_uri: https://github.com/Rails-Designer/courrier/
|
|
126
|
-
post_install_message:
|
|
127
114
|
rdoc_options: []
|
|
128
115
|
require_paths:
|
|
129
116
|
- lib
|
|
@@ -131,15 +118,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
131
118
|
requirements:
|
|
132
119
|
- - ">="
|
|
133
120
|
- !ruby/object:Gem::Version
|
|
134
|
-
version:
|
|
121
|
+
version: 4.0.0
|
|
135
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
123
|
requirements:
|
|
137
124
|
- - ">="
|
|
138
125
|
- !ruby/object:Gem::Version
|
|
139
126
|
version: '0'
|
|
140
127
|
requirements: []
|
|
141
|
-
rubygems_version:
|
|
142
|
-
signing_key:
|
|
128
|
+
rubygems_version: 4.0.3
|
|
143
129
|
specification_version: 4
|
|
144
130
|
summary: API-powered email delivery for Ruby apps
|
|
145
131
|
test_files: []
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Courrier
|
|
4
|
-
class PreviewsController < ActionController::Base
|
|
5
|
-
def index
|
|
6
|
-
@emails = emails.map { Courrier::Email::Providers::Inbox::Email.from_file(_1) }
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def show
|
|
10
|
-
file_path = File.join(Courrier.configuration.inbox.destination, params[:id])
|
|
11
|
-
content = File.read(file_path)
|
|
12
|
-
|
|
13
|
-
render html: content.html_safe, layout: false
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
private
|
|
17
|
-
|
|
18
|
-
def emails
|
|
19
|
-
@emails ||= Dir.glob("#{Courrier.configuration.inbox.destination}/*.html")
|
|
20
|
-
.sort_by { -File.basename(_1, ".html").to_i }
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|