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
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<title>Courrier Inbox</title>
|
|
6
|
-
|
|
7
|
-
<style>
|
|
8
|
-
*, *::before, *::after { box-sizing: border-box; }
|
|
9
|
-
* { margin: 0; padding: 0; }
|
|
10
|
-
body { margin: 0; padding: 0; font-size: 16px; line-height: 1.5; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; background-color: rgb(241, 245, 249); }
|
|
11
|
-
|
|
12
|
-
.sidebar {
|
|
13
|
-
display: flex;
|
|
14
|
-
flex-direction: column;
|
|
15
|
-
position: sticky;
|
|
16
|
-
top: 0;
|
|
17
|
-
padding: .5rem;
|
|
18
|
-
width: min(350px, 33.3333%); height: 100dvh;
|
|
19
|
-
border-right: 1px solid rgb(226, 232, 240);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.sidebar__options {
|
|
23
|
-
position: sticky;
|
|
24
|
-
bottom: 0;
|
|
25
|
-
padding: .5rem;
|
|
26
|
-
background-color: rgb(241, 245, 249);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.sidebar__btn-clear {
|
|
30
|
-
border: none;
|
|
31
|
-
display: flex;
|
|
32
|
-
align-items: center;
|
|
33
|
-
justify-content: center;
|
|
34
|
-
column-gap: 0.25rem;
|
|
35
|
-
width: 100%;
|
|
36
|
-
padding: .5rem;
|
|
37
|
-
font-size: .875rem; line-height: 1.25rem;
|
|
38
|
-
font-weight: 500;
|
|
39
|
-
color: rgb(71, 85, 105);
|
|
40
|
-
background-color: rgb(226, 232, 240);
|
|
41
|
-
border-radius: .5rem;
|
|
42
|
-
cursor: default;
|
|
43
|
-
|
|
44
|
-
&:hover { background-color: rgb(203, 213, 225); }
|
|
45
|
-
&:active { transform: scale(.98); }
|
|
46
|
-
|
|
47
|
-
[data-slot="icon"] {
|
|
48
|
-
width: .875rem; height: .875rem;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.email-previews {
|
|
53
|
-
display: flex;
|
|
54
|
-
flex-direction: column;
|
|
55
|
-
flex: 1;
|
|
56
|
-
row-gap: .5rem;
|
|
57
|
-
overflow-y: auto;
|
|
58
|
-
width: 100%;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.email-preview {
|
|
62
|
-
display: flex;
|
|
63
|
-
flex-direction: row;
|
|
64
|
-
column-gap: .5rem;
|
|
65
|
-
width: 100%;
|
|
66
|
-
padding: .5rem .75rem;
|
|
67
|
-
text-decoration: none;
|
|
68
|
-
border-radius: .5rem;
|
|
69
|
-
|
|
70
|
-
&:hover {
|
|
71
|
-
background-color: rgba(226, 232, 240, .75);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.email-preview--empty {
|
|
76
|
-
display: none;
|
|
77
|
-
text-align: center;
|
|
78
|
-
|
|
79
|
-
&:only-child {
|
|
80
|
-
display: block;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.email-preview__avatar {
|
|
85
|
-
flex-shrink: 0;
|
|
86
|
-
padding: .25rem;
|
|
87
|
-
width: 1.5rem; height: 1.5rem;
|
|
88
|
-
background-color: rgb(203, 213, 225);
|
|
89
|
-
color: rgb(51, 65, 85);
|
|
90
|
-
border-radius: 9999px;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.email-preview__content {
|
|
94
|
-
font-size: 0.875rem; line-height: 1.25rem;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.email-preview__recipient {
|
|
98
|
-
font-size: 1rem; line-height: 1.5rem;
|
|
99
|
-
font-weight: 600;
|
|
100
|
-
letter-spacing: -.025em;
|
|
101
|
-
color: rgb(51, 65, 85);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.email-preview__subject {
|
|
105
|
-
margin-top: .125rem;
|
|
106
|
-
overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1;
|
|
107
|
-
color: rgb(100, 116, 139);
|
|
108
|
-
}
|
|
109
|
-
</style>
|
|
110
|
-
</head>
|
|
111
|
-
<body>
|
|
112
|
-
<div style="display: flex; column-gap: 1rem;">
|
|
113
|
-
<aside class="sidebar">
|
|
114
|
-
<ul class="email-previews">
|
|
115
|
-
<li class="email-preview--empty">
|
|
116
|
-
<p class="email-preview__subject">
|
|
117
|
-
No emails yet…
|
|
118
|
-
</p>
|
|
119
|
-
</li>
|
|
120
|
-
|
|
121
|
-
<% @emails.each do |email| %>
|
|
122
|
-
<li>
|
|
123
|
-
<%= link_to courrier.preview_path(email.filename), data: {remote: true}, class: "email-preview" do %>
|
|
124
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" data-slot="icon" class="email-preview__avatar">
|
|
125
|
-
<path fill-rule="evenodd" d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z" clip-rule="evenodd"/>
|
|
126
|
-
</svg>
|
|
127
|
-
|
|
128
|
-
<div class="email-preview__content">
|
|
129
|
-
<small class="email-preview__recipient">
|
|
130
|
-
<%= email.metadata.to %>
|
|
131
|
-
</small>
|
|
132
|
-
|
|
133
|
-
<p class="email-preview__subject">
|
|
134
|
-
<%= email.metadata.subject || "No subject" %>
|
|
135
|
-
</p>
|
|
136
|
-
</div>
|
|
137
|
-
<% end %>
|
|
138
|
-
</li>
|
|
139
|
-
<% end %>
|
|
140
|
-
</ul>
|
|
141
|
-
|
|
142
|
-
<div class="sidebar__options">
|
|
143
|
-
<%= button_to courrier.cleanup_path, class: "sidebar__btn-clear" do %>
|
|
144
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" data-slot="icon">
|
|
145
|
-
<path fill-rule="evenodd" d="M16.5 4.478v.227a48.816 48.816 0 0 1 3.878.512.75.75 0 1 1-.256 1.478l-.209-.035-1.005 13.07a3 3 0 0 1-2.991 2.77H8.084a3 3 0 0 1-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 0 1-.256-1.478A48.567 48.567 0 0 1 7.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 0 1 3.369 0c1.603.051 2.815 1.387 2.815 2.951Zm-6.136-1.452a51.196 51.196 0 0 1 3.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 0 0-6 0v-.113c0-.794.609-1.428 1.364-1.452Zm-.355 5.945a.75.75 0 1 0-1.5.058l.347 9a.75.75 0 1 0 1.499-.058l-.346-9Zm5.48.058a.75.75 0 1 0-1.498-.058l-.347 9a.75.75 0 0 0 1.5.058l.345-9Z" clip-rule="evenodd"/>
|
|
146
|
-
</svg>
|
|
147
|
-
|
|
148
|
-
Clear inbox
|
|
149
|
-
<% end %>
|
|
150
|
-
</div>
|
|
151
|
-
</aside>
|
|
152
|
-
|
|
153
|
-
<article style="flex: 1;" id="email-preview">
|
|
154
|
-
</article>
|
|
155
|
-
</div>
|
|
156
|
-
|
|
157
|
-
<script>
|
|
158
|
-
document.querySelectorAll("a[data-remote]").forEach(link => {
|
|
159
|
-
link.addEventListener("click", (event) => {
|
|
160
|
-
event.preventDefault();
|
|
161
|
-
|
|
162
|
-
fetch(link.href)
|
|
163
|
-
.then(response => response.text())
|
|
164
|
-
.then(html => {
|
|
165
|
-
document.getElementById("email-preview").innerHTML = html;
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
</script>
|
|
170
|
-
</body>
|
|
171
|
-
</html>
|
data/config/routes.rb
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Courrier
|
|
4
|
-
class Configuration
|
|
5
|
-
class Inbox
|
|
6
|
-
attr_accessor :destination, :auto_open, :template_path
|
|
7
|
-
|
|
8
|
-
def initialize
|
|
9
|
-
@destination = default_destination
|
|
10
|
-
@auto_open = false
|
|
11
|
-
@template_path = File.expand_path("../../../courrier/email/providers/inbox/default.html.erb", __FILE__)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
def default_destination
|
|
17
|
-
defined?(Rails) ? Rails.root.join("tmp", "courrier", "emails").to_s : File.join(Dir.tmpdir, "courrier", "emails")
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
{
|
|
3
|
-
"to": "<%= email %>",
|
|
4
|
-
"subject": "<%= @options.subject %>"
|
|
5
|
-
}
|
|
6
|
-
-->
|
|
7
|
-
|
|
8
|
-
<!DOCTYPE html>
|
|
9
|
-
<html>
|
|
10
|
-
<head>
|
|
11
|
-
<meta charset="UTF-8">
|
|
12
|
-
<title><%= @options.subject %></title>
|
|
13
|
-
<style>
|
|
14
|
-
*, *::before, *::after { box-sizing: border-box; }
|
|
15
|
-
* { margin: 0; padding: 0; }
|
|
16
|
-
body { margin: 0; padding: 0; line-height: 1.5; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; background-color: rgb(241, 245, 249); }
|
|
17
|
-
pre { margin: 0; white-space: pre-wrap; }
|
|
18
|
-
.email {
|
|
19
|
-
width: 100%;
|
|
20
|
-
max-width: 65rem;
|
|
21
|
-
margin-left: auto; margin-right: auto;
|
|
22
|
-
background-color: #fff;
|
|
23
|
-
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
|
24
|
-
border-bottom-right-radius: 1rem; border-bottom-left-radius: 1rem;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.email__header { display: flex; align-items: center; padding: .75rem; -moz-column-gap: .75rem; column-gap: .75rem; }
|
|
28
|
-
|
|
29
|
-
.email__avatar {
|
|
30
|
-
flex-shrink: 0;
|
|
31
|
-
padding: .25rem;
|
|
32
|
-
width: 2rem; height: 2rem;
|
|
33
|
-
background-color: rgb(203, 213, 225);
|
|
34
|
-
color: rgb(51, 65, 85);
|
|
35
|
-
border-radius: 9999px;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.email__recipient { flex-grow: 1; font-size: .875rem; line-height: 1.25rem; }
|
|
39
|
-
|
|
40
|
-
.email__recipient-name { font-weight: 600; color: rgb(51, 65, 85); }
|
|
41
|
-
|
|
42
|
-
.email__metadata { display: flex; align-items: center; justify-content: space-between; }
|
|
43
|
-
|
|
44
|
-
.email__recipient-email { color: rgb(100, 116, 139); }
|
|
45
|
-
|
|
46
|
-
.email__datetime { font-size: .75rem; line-height: 1rem; color: rgb(148, 163, 184); }
|
|
47
|
-
|
|
48
|
-
.email__subject {
|
|
49
|
-
margin-left: 3.5rem;
|
|
50
|
-
font-size: 1.25rem; line-height: 1.75rem;
|
|
51
|
-
font-weight: 700;
|
|
52
|
-
letter-spacing: -.025em;
|
|
53
|
-
color: rgb(30, 41, 59)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.email__preview { margin-top: .75rem; margin-left: 3.5rem; padding-bottom: 1rem; }
|
|
57
|
-
|
|
58
|
-
.preview-toggle { display: none; }
|
|
59
|
-
.preview-toggle-label {
|
|
60
|
-
display: inline-block;
|
|
61
|
-
padding: .25rem .875rem;
|
|
62
|
-
font-size: .75rem; line-height: 1rem;
|
|
63
|
-
font-weight: 600;
|
|
64
|
-
color: rgb(30, 41, 59);
|
|
65
|
-
background-color: rgb(255, 255, 255);
|
|
66
|
-
border: 1px solid rgb(226, 232, 240);
|
|
67
|
-
border-radius: .375rem;
|
|
68
|
-
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
69
|
-
cursor: pointer;
|
|
70
|
-
|
|
71
|
-
&:hover { border-color: rgb(203, 213, 225); }
|
|
72
|
-
&:active { transform: scale(.98); }
|
|
73
|
-
}
|
|
74
|
-
.preview-toggle[disabled] + .preview-toggle-label { opacity: 0.5; cursor: not-allowed; }
|
|
75
|
-
|
|
76
|
-
.email__preview-html, .email__preview-text { margin-top: 1.5rem;}
|
|
77
|
-
.email__preview-html { display: none; }
|
|
78
|
-
.preview-toggle:checked ~ .email__preview-text { display: none; }
|
|
79
|
-
.preview-toggle:checked ~ .email__preview-html { display: block; }
|
|
80
|
-
</style>
|
|
81
|
-
</head>
|
|
82
|
-
<body>
|
|
83
|
-
<article class="email">
|
|
84
|
-
<header class="email__header">
|
|
85
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" data-slot="icon" class="email__avatar">
|
|
86
|
-
<path fill-rule="evenodd" d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z" clip-rule="evenodd"/>
|
|
87
|
-
</svg>
|
|
88
|
-
|
|
89
|
-
<div class="email__recipient">
|
|
90
|
-
<% if name %>
|
|
91
|
-
<p class="email__recipient-name">
|
|
92
|
-
<%= name %>
|
|
93
|
-
</p>
|
|
94
|
-
<% end %>
|
|
95
|
-
|
|
96
|
-
<div class="email__metadata">
|
|
97
|
-
<p class="email__recipient-email">
|
|
98
|
-
<%= email %>
|
|
99
|
-
</p>
|
|
100
|
-
|
|
101
|
-
<time class="email__datetime" datetime="#{Time.now.strftime("%Y-%m-%d %H:%M:%S %z")}">
|
|
102
|
-
<%= Time.now.strftime("%Y-%m-%d %H:%M:%S %z") %>
|
|
103
|
-
</time>
|
|
104
|
-
</div>
|
|
105
|
-
</div>
|
|
106
|
-
</header>
|
|
107
|
-
|
|
108
|
-
<p class="email__subject">
|
|
109
|
-
<%= @options.subject %>
|
|
110
|
-
</p>
|
|
111
|
-
|
|
112
|
-
<div class="email__preview">
|
|
113
|
-
<input type="checkbox" id="preview-toggle" class="preview-toggle" <%= html ? "" : "disabled" %>>
|
|
114
|
-
<label for="preview-toggle" class="preview-toggle-label">Toggle HTML/Text</label>
|
|
115
|
-
|
|
116
|
-
<div class="email__preview-text">
|
|
117
|
-
<pre><%= text || "(no text content)" %></pre>
|
|
118
|
-
</div>
|
|
119
|
-
|
|
120
|
-
<div class="email__preview-html">
|
|
121
|
-
<%= html || "<p>(no HTML content)</p>" %>
|
|
122
|
-
</div>
|
|
123
|
-
</div>
|
|
124
|
-
</article>
|
|
125
|
-
</body>
|
|
126
|
-
</html>
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "tmpdir"
|
|
4
|
-
require "fileutils"
|
|
5
|
-
require "launchy"
|
|
6
|
-
|
|
7
|
-
module Courrier
|
|
8
|
-
class Email
|
|
9
|
-
module Providers
|
|
10
|
-
class Inbox < Base
|
|
11
|
-
def deliver
|
|
12
|
-
FileUtils.mkdir_p(config.destination)
|
|
13
|
-
|
|
14
|
-
file_path = File.join(config.destination, "#{Time.now.to_i}.html")
|
|
15
|
-
|
|
16
|
-
File.write(file_path, ERB.new(File.read(config.template_path)).result(binding))
|
|
17
|
-
|
|
18
|
-
Launchy.open(file_path) if config.auto_open
|
|
19
|
-
|
|
20
|
-
"📮 Email saved to #{file_path} and #{email_destination}"
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def name = extract(@options.to)[:name]
|
|
24
|
-
|
|
25
|
-
def email = extract(@options.to)[:email]
|
|
26
|
-
|
|
27
|
-
def text = prepare(@options.text)
|
|
28
|
-
|
|
29
|
-
def html = prepare(@options.html)
|
|
30
|
-
|
|
31
|
-
private
|
|
32
|
-
|
|
33
|
-
def extract(to)
|
|
34
|
-
if to.to_s =~ /(.*?)\s*<(.+?)>/
|
|
35
|
-
{name: $1.strip, email: $2.strip}
|
|
36
|
-
else
|
|
37
|
-
{name: nil, email: to.to_s.strip}
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def prepare(content)
|
|
42
|
-
content.to_s.gsub(URL_PARSER.make_regexp(%w[http https])) do |url|
|
|
43
|
-
%(<a href="#{url}">#{url}</a>)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def config = @config ||= Courrier.configuration.inbox
|
|
48
|
-
|
|
49
|
-
def email_destination
|
|
50
|
-
return "opened in your default browser" if config.auto_open
|
|
51
|
-
|
|
52
|
-
path = begin
|
|
53
|
-
Rails.application.routes.url_helpers.courrier_path
|
|
54
|
-
rescue
|
|
55
|
-
"/courrier/ (Note: Add `mount Courrier::Engine => \"/courrier\"` to your routes.rb to enable proper routing)"
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
"available at #{path}"
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
URL_PARSER = (
|
|
62
|
-
defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
class Email < Data.define(:path, :filename, :metadata)
|
|
66
|
-
Metadata = Data.define(:to, :subject)
|
|
67
|
-
|
|
68
|
-
def self.from_file(path)
|
|
69
|
-
content = File.read(path)
|
|
70
|
-
json = content[/<!--\s*(.*?)\s*-->/m, 1]
|
|
71
|
-
metadata = JSON.parse(json, symbolize_names: true)
|
|
72
|
-
|
|
73
|
-
new(
|
|
74
|
-
path: path,
|
|
75
|
-
filename: File.basename(path),
|
|
76
|
-
metadata: Metadata.new(**metadata)
|
|
77
|
-
)
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
data/lib/courrier/engine.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Courrier
|
|
4
|
-
module Jobs
|
|
5
|
-
class EmailDeliveryJob < ActiveJob::Base
|
|
6
|
-
def perform(data)
|
|
7
|
-
email_class = data[:email_class].constantize
|
|
8
|
-
|
|
9
|
-
email_class.new(
|
|
10
|
-
provider: data[:provider],
|
|
11
|
-
api_key: data[:api_key],
|
|
12
|
-
from: data[:options][:from],
|
|
13
|
-
to: data[:options][:to],
|
|
14
|
-
reply_to: data[:options][:reply_to],
|
|
15
|
-
cc: data[:options][:cc],
|
|
16
|
-
bcc: data[:options][:bcc],
|
|
17
|
-
provider_options: data[:provider_options],
|
|
18
|
-
context_options: data[:context_options]
|
|
19
|
-
).deliver_now
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
data/lib/courrier/railtie.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module Courrier
|
|
2
|
-
class Railtie < Rails::Railtie
|
|
3
|
-
config.after_initialize do
|
|
4
|
-
Courrier::Email.default_url_options = Courrier.configuration.default_url_options
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
ActiveSupport.on_load(:action_view) do
|
|
8
|
-
include Courrier::Email::Address
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
ActiveSupport.on_load(:action_controller) do
|
|
12
|
-
include Courrier::Email::Address
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
ActiveSupport.on_load(:active_job) do
|
|
16
|
-
include Courrier::Email::Address
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
rake_tasks do
|
|
20
|
-
load File.expand_path("../tasks/courrier.rake", __FILE__)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
namespace :tmp do
|
|
2
|
-
task :courrier do
|
|
3
|
-
rm_rf Dir["#{Courrier.configuration.inbox.destination}/[^.]*"], verbose: false
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
task clear: :courrier
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
namespace :courrier do
|
|
10
|
-
desc "Clear email files from `#{Courrier.configuration.inbox.destination}`"
|
|
11
|
-
|
|
12
|
-
task clear: "tmp:courrier"
|
|
13
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
module Courrier
|
|
2
|
-
class EmailGenerator < Rails::Generators::NamedBase
|
|
3
|
-
AVAILABLE_TEMPLATES = %w[welcome password_reset]
|
|
4
|
-
|
|
5
|
-
desc "Create a new Courrier Email class"
|
|
6
|
-
|
|
7
|
-
source_root File.expand_path("templates", __dir__)
|
|
8
|
-
|
|
9
|
-
check_class_collision suffix: "Email"
|
|
10
|
-
|
|
11
|
-
class_option :skip_suffix, type: :boolean, default: false
|
|
12
|
-
class_option :template, type: :string, desc: "Template type (#{AVAILABLE_TEMPLATES.join(", ")})"
|
|
13
|
-
|
|
14
|
-
def copy_mailer_file
|
|
15
|
-
template template_file, destination_path
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
def file_name = super.delete_suffix("_email")
|
|
21
|
-
|
|
22
|
-
def parent_class = defined?(ApplicationEmail) ? ApplicationEmail : Courrier::Email
|
|
23
|
-
|
|
24
|
-
def template_file
|
|
25
|
-
if options[:template] && template_exists?("email/#{options[:template]}.rb.tt")
|
|
26
|
-
"email/#{options[:template]}.rb.tt"
|
|
27
|
-
else
|
|
28
|
-
"email.rb.tt"
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def destination_path
|
|
33
|
-
File.join(Courrier.configuration.email_path, class_path, "#{file_name}#{options[:skip_suffix] ? "" : "_email"}.rb")
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def template_exists?(path)
|
|
37
|
-
find_in_source_paths(path)
|
|
38
|
-
rescue
|
|
39
|
-
nil
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
module Courrier
|
|
2
|
-
class InstallGenerator < Rails::Generators::Base
|
|
3
|
-
desc "Creates the initializer for Courrier"
|
|
4
|
-
|
|
5
|
-
source_root File.expand_path("templates", __dir__)
|
|
6
|
-
|
|
7
|
-
def copy_initializer_file
|
|
8
|
-
template "initializer.rb", "config/initializers/courrier.rb"
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# Usage:
|
|
2
|
-
#
|
|
3
|
-
# PasswordResetEmail.deliver to: user.email, reset_url: edit_password_url(user.password_reset_token)
|
|
4
|
-
#
|
|
5
|
-
class <%= class_name %><%= options[:skip_suffix] ? "" : "Email" %> < <%= parent_class %>
|
|
6
|
-
def subject = "Reset your password"
|
|
7
|
-
|
|
8
|
-
def text
|
|
9
|
-
<<~TEXT
|
|
10
|
-
You can reset your password within the next 15 minutes on this password reset page:
|
|
11
|
-
#{reset_url}
|
|
12
|
-
|
|
13
|
-
If you didn't request a password reset, please ignore this email.
|
|
14
|
-
TEXT
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def html
|
|
18
|
-
<<~HTML
|
|
19
|
-
<p>
|
|
20
|
-
You can reset your password within the next 15 minutes on
|
|
21
|
-
<a href="#{reset_url}">this password reset page</a>.
|
|
22
|
-
</p>
|
|
23
|
-
|
|
24
|
-
<p>
|
|
25
|
-
If you didn't request a password reset, please ignore this email.
|
|
26
|
-
</p>
|
|
27
|
-
HTML
|
|
28
|
-
end
|
|
29
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# Usage:
|
|
2
|
-
#
|
|
3
|
-
# WelcomeEmail.deliver to: user.email, name: "John", login_url: "https://example.com/login"
|
|
4
|
-
#
|
|
5
|
-
class <%= class_name %><%= options[:skip_suffix] ? "" : "Email" %> < <%= parent_class %>
|
|
6
|
-
def subject = "Welcome to My First App, #{name}!"
|
|
7
|
-
|
|
8
|
-
def text
|
|
9
|
-
<<~TEXT
|
|
10
|
-
Welcome, #{name}!
|
|
11
|
-
|
|
12
|
-
We're excited to have you on board. Here's how to get started:
|
|
13
|
-
|
|
14
|
-
1. Log in to your account: #{login_url}
|
|
15
|
-
2. Complete your profile
|
|
16
|
-
3. Explore our features
|
|
17
|
-
|
|
18
|
-
If you have any questions, our help center is available to assist you.
|
|
19
|
-
|
|
20
|
-
Thanks for joining us!
|
|
21
|
-
TEXT
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def html
|
|
25
|
-
<<~HTML
|
|
26
|
-
<p>Welcome, #{name}!</p>
|
|
27
|
-
|
|
28
|
-
<p>We're excited to have you on board. Here's how to get started:</p>
|
|
29
|
-
|
|
30
|
-
<ol>
|
|
31
|
-
<li><a href="#{login_url}">Log in to your account</a></li>
|
|
32
|
-
<li>Complete your profile</li>
|
|
33
|
-
<li>Explore our features</li>
|
|
34
|
-
</ol>
|
|
35
|
-
|
|
36
|
-
<p>If you have any questions, our help center is available to assist you.</p>
|
|
37
|
-
|
|
38
|
-
<p>
|
|
39
|
-
Thanks for joining us!
|
|
40
|
-
</p>
|
|
41
|
-
HTML
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
Courrier.configure do |config|
|
|
2
|
-
include Courrier::Email::Address
|
|
3
|
-
|
|
4
|
-
# Set your email delivery provider
|
|
5
|
-
# config.email = {
|
|
6
|
-
# provider: "", # default, `logger`, choose from: <%= Courrier::Email::Provider::PROVIDERS.keys.join(", ") %>
|
|
7
|
-
# api_key: "" your transactional email provider's API key
|
|
8
|
-
# }
|
|
9
|
-
|
|
10
|
-
# Set your marketing email provider
|
|
11
|
-
# config.subscriber = {
|
|
12
|
-
# provider: ""
|
|
13
|
-
# }
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
# Configure provider-specific settings
|
|
17
|
-
# config.providers.loops.transactional_id = ""
|
|
18
|
-
# config.providers.mailgun.domain = ""
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# Set default sender details
|
|
22
|
-
config.from = email_with_name("support@example.com", "Example Support") # => `Example Support <support@example.com>`
|
|
23
|
-
# config.reply_to = ""
|
|
24
|
-
# config.cc = ""
|
|
25
|
-
# config.bcc = ""
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# Set host for Rails URL helpers, e.g. `{host: "https://railsdesigner.com/"}`
|
|
29
|
-
# config.default_url_options = {}
|
|
30
|
-
|
|
31
|
-
# Generate text version from HTML content
|
|
32
|
-
# Default: `false`
|
|
33
|
-
# config.auto_generate_text = false
|
|
34
|
-
|
|
35
|
-
# Location for generated Courrier Emails
|
|
36
|
-
# Default: `app/emails`
|
|
37
|
-
# config.email_path = ""
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
# Select logger for the `logger` provider
|
|
41
|
-
# Default: `::Logger.new($stdout)` - Ruby's built-in Logger
|
|
42
|
-
# config.logger = ""
|
|
43
|
-
end
|