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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +16 -24
  4. data/README.md +120 -75
  5. data/courrier.gemspec +4 -4
  6. data/lib/courrier/configuration.rb +2 -4
  7. data/lib/courrier/email/provider.rb +10 -4
  8. data/lib/courrier/email/providers/cloudflare.rb +35 -0
  9. data/lib/courrier/email/providers/lettermint.rb +31 -0
  10. data/lib/courrier/email/providers/ses.rb +75 -0
  11. data/lib/courrier/email/providers/smtp2go.rb +29 -0
  12. data/lib/courrier/email/request.rb +1 -1
  13. data/lib/courrier/email/transformer.rb +9 -9
  14. data/lib/courrier/email.rb +22 -35
  15. data/lib/courrier/errors.rb +0 -2
  16. data/lib/courrier/test.rb +38 -0
  17. data/lib/courrier/test_helper.rb +65 -0
  18. data/lib/courrier/version.rb +1 -1
  19. data/lib/courrier.rb +2 -2
  20. metadata +17 -31
  21. data/app/controllers/courrier/previews/cleanups_controller.rb +0 -13
  22. data/app/controllers/courrier/previews_controller.rb +0 -23
  23. data/app/views/courrier/previews/index.html.erb +0 -171
  24. data/config/routes.rb +0 -8
  25. data/lib/courrier/configuration/inbox.rb +0 -21
  26. data/lib/courrier/email/providers/inbox/default.html.erb +0 -126
  27. data/lib/courrier/email/providers/inbox.rb +0 -83
  28. data/lib/courrier/engine.rb +0 -7
  29. data/lib/courrier/jobs/email_delivery_job.rb +0 -23
  30. data/lib/courrier/railtie.rb +0 -23
  31. data/lib/courrier/tasks/courrier.rake +0 -13
  32. data/lib/generators/courrier/email_generator.rb +0 -42
  33. data/lib/generators/courrier/install_generator.rb +0 -11
  34. data/lib/generators/courrier/templates/email/password_reset.rb.tt +0 -29
  35. data/lib/generators/courrier/templates/email/welcome.rb.tt +0 -43
  36. data/lib/generators/courrier/templates/email.rb.tt +0 -13
  37. data/lib/generators/courrier/templates/initializer.rb.tt +0 -43
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 555584763bab84eb75f07a5a7fa43fb4e4a65c3b1bb52de2c8e551c744fd0625
4
- data.tar.gz: 4901dfab5c8c70d2f741e6c5edc0014e2aa7a9ca4afddc011d0d946464da709d
3
+ metadata.gz: d793cbc73ad9612cbb5e010e6aed85f9885e41fc8b672d16f82a6d155f63b726
4
+ data.tar.gz: 1143fc17abc330c3f94192ec95aea7618583266491f109b62aee3178826ede97
5
5
  SHA512:
6
- metadata.gz: 93d5a592840d197493eafc3b8cac47b03218b9d8bdce88ef2e666685468a32879583ea7bb7adc1e84a665864ee5d4aebc80e982606f78836d2cf996e7fd5e602
7
- data.tar.gz: d2e4391d1ea6d24031fbba9539f4935386b552184e145a4a2582e0a9a72003d3f79ed2afc6091ca9b2f4069b725e8a778602b8d31fe688999fad2badc4535276
6
+ metadata.gz: 64991e00fdb46c81164c29ffc7dc9de6078bcbc6cad12407355424f19f54e3a767e8732abf1438105d1f14b3ebe8ecf8367aa88bd7e53fadd7787fa8dd163609
7
+ data.tar.gz: eed7664f6a7211fc98e8cd53e0dc24ad1784e5373575c006feb04fb7d3a2706da3127c0db801b3c960697f774cd3df68df3622b975f365ed5fdfa211327aa3d3
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ source "https://rubygems.org"
5
5
  gemspec
6
6
 
7
7
  group :development do
8
- gem "standard", "~> 1.49"
8
+ gem "standard", "~> 1.54.0"
9
9
  end
10
10
 
11
11
  group :development, :test do
data/Gemfile.lock CHANGED
@@ -1,18 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- courrier (0.10.0)
5
- launchy (>= 3.1, < 4)
4
+ courrier (0.11.0)
5
+ logger (>= 1.5, < 3)
6
6
  nokogiri (>= 1.18, < 2)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- addressable (2.8.7)
12
- public_suffix (>= 2.0.2, < 7.0)
13
11
  ast (2.4.3)
14
- childprocess (5.1.0)
15
- logger (~> 1.5)
16
12
  date (3.4.1)
17
13
  debug (1.10.0)
18
14
  irb (~> 1.10)
@@ -24,18 +20,14 @@ GEM
24
20
  reline (>= 0.4.2)
25
21
  json (2.11.1)
26
22
  language_server-protocol (3.17.0.4)
27
- launchy (3.1.1)
28
- addressable (~> 2.8)
29
- childprocess (~> 5.0)
30
- logger (~> 1.6)
31
23
  lint_roller (1.1.0)
32
24
  logger (1.7.0)
33
- minitest (5.25.5)
34
- nokogiri (1.18.8-arm64-darwin)
25
+ minitest (5.27.0)
26
+ nokogiri (1.19.3-arm64-darwin)
35
27
  racc (~> 1.4)
36
- nokogiri (1.18.8-x86_64-darwin)
28
+ nokogiri (1.19.3-x86_64-darwin)
37
29
  racc (~> 1.4)
38
- nokogiri (1.18.8-x86_64-linux-gnu)
30
+ nokogiri (1.19.3-x86_64-linux-gnu)
39
31
  racc (~> 1.4)
40
32
  parallel (1.27.0)
41
33
  parser (3.3.8.0)
@@ -44,11 +36,10 @@ GEM
44
36
  pp (0.6.2)
45
37
  prettyprint
46
38
  prettyprint (0.2.0)
47
- prism (1.4.0)
39
+ prism (1.9.0)
48
40
  psych (5.2.3)
49
41
  date
50
42
  stringio
51
- public_suffix (6.0.2)
52
43
  racc (1.8.1)
53
44
  rainbow (3.1.1)
54
45
  rake (13.2.1)
@@ -57,7 +48,7 @@ GEM
57
48
  regexp_parser (2.10.0)
58
49
  reline (0.6.1)
59
50
  io-console (~> 0.5)
60
- rubocop (1.75.3)
51
+ rubocop (1.84.2)
61
52
  json (~> 2.3)
62
53
  language_server-protocol (~> 3.17.0.2)
63
54
  lint_roller (~> 1.1.0)
@@ -65,21 +56,21 @@ GEM
65
56
  parser (>= 3.3.0.2)
66
57
  rainbow (>= 2.2.2, < 4.0)
67
58
  regexp_parser (>= 2.9.3, < 3.0)
68
- rubocop-ast (>= 1.44.0, < 2.0)
59
+ rubocop-ast (>= 1.49.0, < 2.0)
69
60
  ruby-progressbar (~> 1.7)
70
61
  unicode-display_width (>= 2.4.0, < 4.0)
71
- rubocop-ast (1.44.1)
62
+ rubocop-ast (1.49.1)
72
63
  parser (>= 3.3.7.2)
73
- prism (~> 1.4)
64
+ prism (~> 1.7)
74
65
  rubocop-performance (1.25.0)
75
66
  lint_roller (~> 1.1)
76
67
  rubocop (>= 1.75.0, < 2.0)
77
68
  rubocop-ast (>= 1.38.0, < 2.0)
78
69
  ruby-progressbar (1.13.0)
79
- standard (1.49.0)
70
+ standard (1.54.0)
80
71
  language_server-protocol (~> 3.17.0.2)
81
72
  lint_roller (~> 1.0)
82
- rubocop (~> 1.75.2)
73
+ rubocop (~> 1.84.0)
83
74
  standard-custom (~> 1.0.0)
84
75
  standard-performance (~> 1.8)
85
76
  standard-custom (1.0.2)
@@ -91,10 +82,11 @@ GEM
91
82
  stringio (3.1.7)
92
83
  unicode-display_width (3.1.4)
93
84
  unicode-emoji (~> 4.0, >= 4.0.4)
94
- unicode-emoji (4.0.4)
85
+ unicode-emoji (4.2.0)
95
86
 
96
87
  PLATFORMS
97
88
  arm64-darwin-23
89
+ arm64-darwin-24
98
90
  x86_64-darwin-23
99
91
  x86_64-linux
100
92
 
@@ -103,7 +95,7 @@ DEPENDENCIES
103
95
  debug (~> 1.9, >= 1.9.2)
104
96
  minitest (~> 5.25, >= 5.25.5)
105
97
  rake (~> 13.2, >= 13.2.1)
106
- standard (~> 1.49)
98
+ standard (~> 1.54.0)
107
99
 
108
100
  BUNDLED WITH
109
101
  2.6.8
data/README.md CHANGED
@@ -38,22 +38,24 @@ Add the gem:
38
38
  ```bash
39
39
  bundle add courrier
40
40
  ```
41
+ > [!tip]
42
+ > For **Rails** apps, use [`rails_courrier`](https://github.com/Rails-Designer/rails_courrier) instead. It includes generators, ActiveJob support (`deliver_later`), inbox previews and more.
41
43
 
42
- Generate the configuration file:
43
- ```bash
44
- bin/rails generate courrier:install
45
- ```
44
+ Configure Courrier in your app:
45
+ ```ruby
46
+ Courrier.configure do |config|
47
+ config.email = {
48
+ provider: "postmark",
49
+ api_key: "your-api-key"
50
+ }
46
51
 
47
- This creates `config/initializers/courrier.rb` for configuring email providers and default settings.
52
+ config.from = "devs@example.com"
53
+ end
54
+ ```
48
55
 
49
56
 
50
57
  ## Usage
51
58
 
52
- Generate a new email:
53
- ```bash
54
- bin/rails generate courrier:email Order
55
- ```
56
-
57
59
  ```ruby
58
60
  class OrderEmail < Courrier::Email
59
61
  def subject = "Here is your order!"
@@ -91,8 +93,13 @@ Courrier.configure do |config|
91
93
  config.default_url_options = { host: "railsdesigner.com" }
92
94
 
93
95
  # Provider-specific configuration
96
+ config.providers.cloudflare.account_id = "your-account-id"
94
97
  config.providers.loops.transactional_id = "default-template"
95
98
  config.providers.mailgun.domain = "notifications.railsdesigner.com"
99
+
100
+ config.providers.ses.region = "us-east-1"
101
+ config.providers.ses.access_key_id = "your-access-key-id"
102
+ config.providers.ses.secret_access_key = "your-secret-access-key"
96
103
  end
97
104
  ```
98
105
 
@@ -127,11 +134,12 @@ class OrderEmail < Courrier::Email
127
134
  def subject = "Rails Icons now supports SVG sprites!"
128
135
 
129
136
  def text = # …
130
- def markdown = # …
137
+
138
+ def html = # …
131
139
  end
132
140
  ```
133
141
 
134
- Useful for adding provider-specific headers like List-Unsubscribe for Postmark, X-Mailer identifiers, or custom metadata headers required.
142
+ Useful for adding provider-specific headers like List-Unsubscribe for Postmark, X-Mailer identifiers or custom metadata headers required.
135
143
 
136
144
 
137
145
  ## Custom attributes
@@ -139,7 +147,7 @@ Useful for adding provider-specific headers like List-Unsubscribe for Postmark,
139
147
  Besides the standard email attributes (`from`, `to`, `reply_to`, etc.), you can pass any additional attributes that will be available in your email templates:
140
148
  ```ruby
141
149
  OrderEmail.deliver to: "recipient@railsdesigner.com",\
142
- download_url: downloads_path(token: "token")
150
+ download_url: "https://example.com/download?token=abc123"
143
151
  ```
144
152
 
145
153
  These custom attributes are accessible directly in your email class:
@@ -170,7 +178,7 @@ When sending an email through Courrier, a `Result` object is returned that provi
170
178
  ### Example
171
179
 
172
180
  ```ruby
173
- delivery = OrderEmail.deliver(to: "recipient@example.com")
181
+ delivery = OrderEmail.deliver to: "recipient@example.com"
174
182
 
175
183
  if delivery.success?
176
184
  puts "Email sent successfully!"
@@ -185,11 +193,17 @@ end
185
193
 
186
194
  Courrier supports these transactional email providers:
187
195
 
196
+ - [AWS SES](https://aws.amazon.com/ses/) — requires `aws-sigv4` gem
197
+ - [Cloudflare Email Service](https://developers.cloudflare.com/email-service/)
198
+ - [Lettermint](https://lettermint.co)
188
199
  - [Loops](https://loops.so)
189
200
  - [Mailgun](https://mailgun.com)
190
201
  - [MailPace](https://mailpace.com)
191
202
  - [Postmark](https://postmarkapp.com)
192
203
  - [Resend](https://resend.com)
204
+ - [SendGrid](https://sendgrid.com)
205
+ - [SMTP2GO](https://www.smtp2go.com/)
206
+ - [SparkPost](https://www.sparkpost.com/)
193
207
  - [Userlist](https://userlist.com)
194
208
 
195
209
 
@@ -198,36 +212,6 @@ Courrier supports these transactional email providers:
198
212
  Additional functionality to help with development and testing:
199
213
 
200
214
 
201
- ### Background jobs (Rails only)
202
-
203
- Use `deliver_later` to enqueue delivering using Rails' ActiveJob. You can set
204
- various ActiveJob-supported options in the email class, like so: `enqueue queue: "emails", wait: 5.minutes`.
205
-
206
- - `queue`, enqueue the email on the specified queue;
207
- - `wait`, enqueue the email to be delivered with a delay;
208
- - `wait_until`, enqueue the email to be delivered at (after) a specific date/time;
209
- - `priority`, enqueues the email with the specified priority.
210
-
211
-
212
- ### Inbox (Rails only)
213
-
214
- You can preview your emails in the inbox:
215
- ```ruby
216
- config.provider = "inbox"
217
-
218
- # And add to your routes:
219
- mount Courrier::Engine => "/courrier"
220
- ```
221
-
222
- If you want to automatically open every email in your default browser:
223
- ```ruby
224
- config.provider = "inbox"
225
- config.inbox.auto_open = true
226
- ```
227
-
228
- Emails are automatically cleared with `bin/rails tmp:clear`, or manually with `bin/rails courrier:clear`.
229
-
230
-
231
215
  ### Layout support
232
216
 
233
217
  Wrap your email content using layouts:
@@ -277,17 +261,18 @@ Instead of defining `text` and `html` methods, you can create ERB template files
277
261
  ```ruby
278
262
  class OrderEmail < Courrier::Email
279
263
  def subject = "Your order is ready!"
264
+
280
265
  # text and html content will be loaded from template files
281
266
  end
282
267
  ```
283
268
 
284
- Create template files alongside your email class:
285
- - `app/emails/order_email.text.erb`
286
- - `app/emails/order_email.html.erb`
269
+ Create template files alongside your email class (default path is `courrier/emails`):
270
+ - `courrier/emails/order_email.text.erb`
271
+ - `courrier/emails/order_email.html.erb`
287
272
 
288
273
  Templates have access to all context options and instance variables:
289
274
  ```erb
290
- <!-- app/emails/order_email.html.erb -->
275
+ <!-- courrier/emails/order_email.html.erb -->
291
276
  <h1>Hello <%= name %>!</h1>
292
277
  <p>Your order #<%= order_id %> is ready for pickup.</p>
293
278
  ```
@@ -299,7 +284,7 @@ class OrderEmail < Courrier::Email
299
284
 
300
285
  def text = "Hello #{name}! Your order ##{order_id} is ready."
301
286
 
302
- # html will be loaded from app/emails/order_email.html.erb
287
+ # html will be loaded from courrier/emails/order_email.html.erb
303
288
  end
304
289
  ```
305
290
 
@@ -333,12 +318,12 @@ end
333
318
 
334
319
  ### Markdown templates
335
320
 
336
- Create markdown template files alongside your email class:
337
- - `app/emails/order_email.md.erb`
338
- - `app/emails/order_email.markdown.erb`
321
+ Create markdown template files alongside your email class (default path is `courrier/emails`):
322
+ - `courrier/emails/order_email.md.erb`
323
+ - `courrier/emails/order_email.markdown.erb`
339
324
 
340
325
  ```erb
341
- <!-- app/emails/order_email.md.erb -->
326
+ <!-- courrier/emails/order_email.md.erb -->
342
327
  # Hello <%= name %>!
343
328
 
344
329
  Your order **#<%= order_id %>** is ready for pickup.
@@ -355,7 +340,7 @@ Method definitions take precedence over template files. You can mix approaches.
355
340
 
356
341
  Automatically generate plain text versions from your HTML emails:
357
342
  ```ruby
358
- config.auto_generate_text = true # Defaults to false
343
+ config.auto_generate_text = true # defaults to false
359
344
  ```
360
345
 
361
346
 
@@ -363,17 +348,6 @@ config.auto_generate_text = true # Defaults to false
363
348
 
364
349
  Compose email addresses with display names:
365
350
  ```ruby
366
- class SignupsController < ApplicationController
367
- def create
368
- recipient = email_with_name("devs@railsdesigner.com", "Rails Designer Devs")
369
-
370
- WelcomeEmail.deliver to: recipient
371
- end
372
- end
373
- ```
374
-
375
- In Plain Ruby Objects:
376
- ```ruby
377
351
  class Signup
378
352
  include Courrier::Email::Address
379
353
 
@@ -391,8 +365,8 @@ end
391
365
  Use Ruby's built-in Logger for development and testing:
392
366
 
393
367
  ```ruby
394
- config.provider = "logger" # outputs emails to STDOUT
395
- config.logger = custom_logger # optional: defaults to ::Logger.new($stdout)
368
+ config.provider = "logger" # outputs emails to STDOUT
369
+ config.logger = custom_logger # optional: defaults to ::Logger.new($stdout)
396
370
  ```
397
371
 
398
372
 
@@ -417,6 +391,82 @@ config.provider = "CustomProvider"
417
391
  Check the [existing providers](https://github.com/Rails-Designer/courrier/tree/main/lib/courrier/email/providers) for implementation examples.
418
392
 
419
393
 
394
+ ### Testing
395
+
396
+ Courrier provides `Test` and `TestHelper` for testing email delivery, similar to Action Mailer's testing API.
397
+
398
+ Access all delivered emails:
399
+ ```ruby
400
+ # Clear deliveries between tests
401
+ Courrier::Test.clear!
402
+
403
+ # Access all deliveries
404
+ Courrier::Test.deliveries
405
+ ```
406
+
407
+ Each delivery record contains:
408
+
409
+ - `email_class`; the email class name
410
+ - `to`, `from`, `reply_to`, `cc`, `bcc`; email addresses
411
+ - `subject`; email subject
412
+ - `body` - Hash with `:text` and `:html` keys
413
+ - `headers`; custom headers
414
+ - `provider`; provider used
415
+ - `result`; result object with `success?` method
416
+ - `timestamp`; delivery time
417
+
418
+ Include the helper in your test class for assertions:
419
+ ```ruby
420
+ class OrderTest < Minitest::Test
421
+ include Courrier::TestHelper
422
+
423
+ def setup
424
+ Courrier::Test.clear!
425
+ end
426
+
427
+ def test_sends_confirmation_email
428
+ order = Order.create! product: "Widget", customer_email: "customer@example.com"
429
+
430
+ OrderEmail.deliver to: order.customer_email, order: order
431
+
432
+ assert_emails_delivered 1
433
+ assert_email_delivered to: "customer@example.com"
434
+ assert_email_delivered OrderEmail, subject: "Order"
435
+ end
436
+
437
+ def test_no_emails_when_order_cancelled
438
+ order = Order.create! product: "Widget", status: :cancelled
439
+
440
+ assert_no_emails_delivered
441
+ end
442
+ end
443
+ ```
444
+
445
+ Available assertions:
446
+
447
+ - `assert_emails_delivered(count)`; assert the number of emails delivered
448
+ - `assert_no_emails_delivered`; assert no emails were delivered
449
+ - `assert_email_delivered(email_class, to:, from:, subject:, provider:)`; assert an email matching criteria was delivered
450
+
451
+
452
+ ### Delivery callbacks
453
+
454
+ Hook into the email delivery lifecycle with `before_deliver` and `after_deliver` callbacks:
455
+ ```ruby
456
+ class OrderEmail < Courrier::Email
457
+ before_deliver do |email|
458
+ puts "Sending to #{email.options.to}" # access email options, abort delivery by returning false
459
+ end
460
+
461
+ after_deliver do |email, result|
462
+ puts "Delivered: #{result.success?}" # access email and delivery result
463
+ end
464
+ end
465
+ ```
466
+
467
+ Callbacks are isolated per class (subclasses don't inherit parent callbacks).
468
+
469
+
420
470
  ## Newsletter subscriptions
421
471
 
422
472
  Manage subscribers across popular email marketing platforms:
@@ -463,6 +513,7 @@ config.subscriber = {
463
513
  }
464
514
  ```
465
515
 
516
+
466
517
  ### Custom providers
467
518
 
468
519
  Create custom providers by inheriting from `Courrier::Subscriber::Base`:
@@ -502,17 +553,11 @@ See [existing providers](https://github.com/Rails-Designer/courrier/tree/main/li
502
553
 
503
554
  ## FAQ
504
555
 
505
- ### Is this a replacement for ActionMailer?
506
- Yes! While different in approach, Courrier can fully replace ActionMailer. It's a modern alternative that focuses on API-based delivery. The main difference is in how emails are structured - Courrier uses a more straightforward, class-based approach.
507
-
508
556
  ### Is this for Rails only?
509
- Not at all! While Courrier has some Rails-specific goodies (like the inbox preview feature and generators), it works great with any Ruby application.
557
+ Not at all! Courrier works with any Ruby application. For Rails apps, use [`rails_courrier`](https://github.com/Rails-Designer/rails_courrier).
510
558
 
511
559
  ### Can it send using SMTP?
512
- No. Courrier is specifically built for API-based email delivery. If SMTP is needed, ActionMailer would be a better choices.
513
-
514
- ### What's the main benefit over ActionMailer?
515
- Courrier offers a simpler, more modern approach to sending emails. Each email is a standalone class, configuration is straightforward (typically just only an API key is needed) and it packs few quality-of-life features (like the inbox feature and auto-generate text version).
560
+ No. Courrier is specifically built for API-based email delivery.
516
561
 
517
562
 
518
563
  ## Contributing
data/courrier.gemspec CHANGED
@@ -10,16 +10,16 @@ Gem::Specification.new do |spec|
10
10
 
11
11
  spec.summary = "API-powered email delivery for Ruby apps"
12
12
  spec.description = "API-powered email delivery for Ruby apps with support for Postmark, SendGrid, Mailgun and more."
13
- spec.homepage = "https://railsdesigner.com/courrier/"
13
+ spec.homepage = "https://railsdesigner.com/open-source/courrier/"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.metadata["homepage_uri"] = spec.homepage
17
17
  spec.metadata["source_code_uri"] = "https://github.com/Rails-Designer/courrier/"
18
18
 
19
- spec.files = Dir["{bin,app,config,lib}/**/*", "Rakefile", "README.md", "courrier.gemspec", "Gemfile", "Gemfile.lock"]
19
+ spec.files = Dir["{bin,lib}/**/*", "Rakefile", "README.md", "courrier.gemspec", "Gemfile", "Gemfile.lock"]
20
20
 
21
- spec.required_ruby_version = ">= 3.2.0"
21
+ spec.required_ruby_version = ">= 4.0.0"
22
22
 
23
- spec.add_dependency "launchy", ">= 3.1", "< 4"
23
+ spec.add_dependency "logger", ">= 1.5", "< 3"
24
24
  spec.add_dependency "nokogiri", ">= 1.18", "< 2"
25
25
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "courrier/configuration/inbox"
4
3
  require "courrier/configuration/providers"
5
4
 
6
5
  module Courrier
@@ -22,7 +21,7 @@ module Courrier
22
21
  attr_accessor :email, :subscriber, :logger, :email_path, :layouts, :default_url_options, :auto_generate_text,
23
22
  :from, :reply_to, :cc, :bcc
24
23
 
25
- attr_reader :providers, :inbox
24
+ attr_reader :providers
26
25
 
27
26
  def initialize
28
27
  @email = {provider: "logger"}
@@ -41,7 +40,6 @@ module Courrier
41
40
  @bcc = nil
42
41
 
43
42
  @providers = Courrier::Configuration::Providers.new
44
- @inbox = Courrier::Configuration::Inbox.new
45
43
  end
46
44
 
47
45
  def provider
@@ -71,7 +69,7 @@ module Courrier
71
69
  private
72
70
 
73
71
  def default_email_path
74
- defined?(Rails) ? Rails.root.join("app", "emails").to_s : File.join("courrier", "emails")
72
+ File.join("courrier", "emails")
75
73
  end
76
74
  end
77
75
  end
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "courrier/email/providers/base"
4
- require "courrier/email/providers/inbox"
4
+ require "courrier/email/providers/cloudflare"
5
+ require "courrier/email/providers/lettermint"
5
6
  require "courrier/email/providers/logger"
6
7
  require "courrier/email/providers/loops"
7
8
  require "courrier/email/providers/mailgun"
@@ -9,7 +10,9 @@ require "courrier/email/providers/mailjet"
9
10
  require "courrier/email/providers/mailpace"
10
11
  require "courrier/email/providers/postmark"
11
12
  require "courrier/email/providers/resend"
13
+ require "courrier/email/providers/ses"
12
14
  require "courrier/email/providers/sendgrid"
15
+ require "courrier/email/providers/smtp2go"
13
16
  require "courrier/email/providers/sparkpost"
14
17
  require "courrier/email/providers/userlist"
15
18
 
@@ -17,15 +20,18 @@ module Courrier
17
20
  class Email
18
21
  class Provider
19
22
  PROVIDERS = {
20
- inbox: Courrier::Email::Providers::Inbox,
23
+ cloudflare: Courrier::Email::Providers::Cloudflare,
21
24
  logger: Courrier::Email::Providers::Logger,
25
+ lettermint: Courrier::Email::Providers::Lettermint,
22
26
  loops: Courrier::Email::Providers::Loops,
23
27
  mailgun: Courrier::Email::Providers::Mailgun,
24
28
  mailjet: Courrier::Email::Providers::Mailjet,
25
29
  mailpace: Courrier::Email::Providers::Mailpace,
26
30
  postmark: Courrier::Email::Providers::Postmark,
27
31
  resend: Courrier::Email::Providers::Resend,
32
+ ses: Courrier::Email::Providers::Ses,
28
33
  sendgrid: Courrier::Email::Providers::Sendgrid,
34
+ smtp2go: Courrier::Email::Providers::Smtp2go,
29
35
  sparkpost: Courrier::Email::Providers::Sparkpost,
30
36
  userlist: Courrier::Email::Providers::Userlist
31
37
  }
@@ -72,7 +78,7 @@ module Courrier
72
78
  end
73
79
 
74
80
  def api_key_required_providers?
75
- !%w[logger inbox].include?(@provider.to_s)
81
+ !%w[logger].include?(@provider.to_s)
76
82
  end
77
83
 
78
84
  def api_key_blank?
@@ -80,7 +86,7 @@ module Courrier
80
86
  end
81
87
 
82
88
  def production?
83
- defined?(Rails) && Rails.env.production?
89
+ ENV["RACK_ENV"] == "production"
84
90
  end
85
91
  end
86
92
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Courrier
4
+ class Email
5
+ module Providers
6
+ class Cloudflare < Base
7
+ def body
8
+ {
9
+ "from" => @options.from,
10
+ "to" => @options.to,
11
+ "reply_to" => @options.reply_to,
12
+ "cc" => @options.cc,
13
+ "bcc" => @options.bcc,
14
+ "subject" => @options.subject,
15
+ "text" => @options.text,
16
+ "html" => @options.html
17
+ }.compact
18
+ end
19
+
20
+ private
21
+
22
+ def endpoint_url
23
+ account_id = @provider_options.account_id
24
+ raise Courrier::ArgumentError, "Cloudflare requires an `account_id`" unless account_id
25
+
26
+ "https://api.cloudflare.com/client/v4/accounts/#{account_id}/email/sending/send"
27
+ end
28
+
29
+ def default_headers
30
+ {"Authorization" => "Bearer #{@api_key}"}
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Courrier
4
+ class Email
5
+ module Providers
6
+ class Lettermint < Base
7
+ ENDPOINT_URL = "https://api.lettermint.co/v1/send"
8
+
9
+ def body
10
+ {
11
+ "route" => @provider_options.route,
12
+ "from" => @options.from,
13
+ "to" => @options.to.to_s.split(",").map(&:strip),
14
+ "cc" => @options.cc&.split(",")&.map(&:strip),
15
+ "bcc" => @options.bcc&.split(",")&.map(&:strip),
16
+ "reply_to" => @options.reply_to&.split(",")&.map(&:strip),
17
+ "subject" => @options.subject,
18
+ "html" => @options.html,
19
+ "text" => @options.text
20
+ }.compact
21
+ end
22
+
23
+ private
24
+
25
+ def default_headers
26
+ {"x-lettermint-token" => @api_key}
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end