Skip to content

Commit 341b16e

Browse files
committed
Add README
1 parent b0cc690 commit 341b16e

File tree

5 files changed

+182
-21
lines changed

5 files changed

+182
-21
lines changed

Gemfile.lock

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ PATH
22
remote: .
33
specs:
44
supermail (0.1.0)
5+
mail (~> 2.0)
56

67
GEM
78
remote: https://rubygems.org/
@@ -13,6 +14,21 @@ GEM
1314
pp (>= 0.6.0)
1415
rdoc (>= 4.0.0)
1516
reline (>= 0.4.2)
17+
mail (2.8.1)
18+
mini_mime (>= 0.1.1)
19+
net-imap
20+
net-pop
21+
net-smtp
22+
mini_mime (1.1.5)
23+
net-imap (0.5.6)
24+
date
25+
net-protocol
26+
net-pop (0.1.2)
27+
net-protocol
28+
net-protocol (0.2.2)
29+
timeout
30+
net-smtp (0.5.1)
31+
net-protocol
1632
pp (0.6.2)
1733
prettyprint
1834
prettyprint (0.2.0)
@@ -38,6 +54,7 @@ GEM
3854
rspec-support (~> 3.13.0)
3955
rspec-support (3.13.2)
4056
stringio (3.1.6)
57+
timeout (0.4.3)
4158

4259
PLATFORMS
4360
arm64-darwin-24

README.md

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,87 @@
11
# Supermail
22

3-
TODO: Delete this and the text below, and describe your gem
4-
5-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/supermail`. To experiment with that code, run `bin/console` for an interactive prompt.
3+
Supermail is a slightly more intuitive way of organizing Emails in a Rails application.
64

75
## Installation
86

9-
TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
10-
117
Install the gem and add to the application's Gemfile by executing:
128

139
```bash
14-
bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
10+
bundle add supermail
1511
```
1612

17-
If bundler is not being used to manage dependencies, install the gem by executing:
13+
Then install it in Rails.
1814

1915
```bash
20-
gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
16+
rails generate supermail:install
17+
```
18+
19+
This creates the `app/emails/application_email.rb` file that you can customize as the base for all emails.
20+
21+
```ruby
22+
class ApplicationEmail < Supermail::Email
23+
def from = "Supermail <noreply@supermail.com>"
24+
25+
class HTML
26+
def after_template
27+
p { "Best, The Supermail Team" }
28+
end
29+
end
30+
31+
class Text
32+
def after_template
33+
"Best,\nThe Supermail Team"
34+
end
35+
end
36+
end
2137
```
2238

2339
## Usage
2440

25-
TODO: Write usage instructions here
41+
To generate a new email, run the following command:
42+
43+
```bash
44+
rails generate supermail:email User::Welcome
45+
```
46+
47+
This will create a new email class in `app/mailers/user/welcome.rb`.
48+
49+
```ruby
50+
# ./app/email/user/welcome.rb
51+
class User::Welcome < ApplicationEmail
52+
def initialize(user:)
53+
@user = user
54+
end
55+
56+
def subject = "Welcome to Supermail!"
57+
58+
class HTML
59+
def view_template
60+
h1 { "Welcome, #{@user.name}!" }
61+
p { "We're excited to have you on board." }
62+
end
63+
end
64+
65+
class Text
66+
def view_template
67+
"Welcome, #{@user.name}!\n\nWe're excited to have you on board."
68+
end
69+
end
70+
end
71+
```
72+
73+
Then, to send the email.
74+
75+
```ruby
76+
User::Welcome.new(user: User.first).deliver_now
77+
```
78+
79+
If you want to tweak the message on the fly, you can modify the message, then deliver it.
80+
81+
```ruby
82+
User::Welcome.new(user: User.first).message.tap do
83+
it.to << "another@example.com"
84+
end.deliver_now
2685

2786
## Development
2887

@@ -32,4 +91,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
3291

3392
## Contributing
3493

35-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/supermail.
94+
Bug reports and pull requests are welcome on GitHub at https://github.com/rubymonolith/supermail.

lib/supermail.rb

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,84 @@
22

33
require_relative "supermail/version"
44

5+
require 'mail'
6+
require "supermail/version"
7+
58
module Supermail
69
class Error < StandardError; end
7-
# Your code goes here...
10+
11+
# A simple Email builder that wraps Mail::Message
12+
class Email
13+
# Hook to ensure default initialization runs before any subclass initialize
14+
module Defaults
15+
def initialize(*args, &block)
16+
# default fields
17+
@cc = []
18+
@bcc = []
19+
@headers = {}
20+
@attachments = []
21+
super
22+
end
23+
end
24+
25+
# Whenever subclassing, prepend Defaults to ensure it wraps initialize
26+
def self.inherited(subclass)
27+
subclass.prepend Defaults
28+
super
29+
end
30+
31+
attr_accessor :from, :to, :cc, :bcc, :subject,
32+
:reply_to, :return_path, :date, :message_id,
33+
:in_reply_to, :references, :headers,
34+
:text_body, :html_body, :attachments
35+
36+
# Builds a Mail::Message from this Email's attributes
37+
# @return [Mail::Message]
38+
def message
39+
mail = Mail.new
40+
mail.from = Array(from) if from
41+
mail.to = Array(to)
42+
mail.cc = cc if cc.any?
43+
mail.bcc = bcc if bcc.any?
44+
mail.reply_to = Array(reply_to) if reply_to
45+
mail.return_path = return_path if return_path
46+
mail.date = date if date
47+
mail.message_id = message_id if message_id
48+
mail.in_reply_to = in_reply_to if in_reply_to
49+
mail.references = references if references
50+
51+
# Custom headers
52+
headers.each { |key, value| mail.header[key] = value }
53+
54+
mail.subject = subject if subject
55+
56+
# Bodies
57+
if text_body
58+
mail.text_part = Mail::Part.new do
59+
body text_body
60+
end
61+
end
62+
63+
if html_body
64+
mail.html_part = Mail::Part.new do
65+
content_type 'text/html; charset=UTF-8'
66+
body html_body
67+
end
68+
end
69+
70+
# Attachments (each as a hash: { filename:, content: })
71+
attachments.each do |att|
72+
mail.add_file filename: att[:filename], content: att[:content]
73+
end
74+
75+
mail
76+
end
77+
78+
# Delivers the built Mail::Message via its configured delivery_method
79+
# @return [Mail::Message]
80+
def deliver
81+
raise Error, "`to` address is required" unless to
82+
message.deliver!
83+
end
84+
end
885
end

spec/supermail_spec.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
# frozen_string_literal: true
22

3-
RSpec.describe Supermail do
3+
RSpec.describe Supermail::Email do
44
it "has a version number" do
55
expect(Supermail::VERSION).not_to be nil
66
end
77

8-
it "does something useful" do
9-
expect(false).to eq(true)
8+
let(:email) { Supermail::Email.new }
9+
before do
10+
email.to = "user@example.com"
11+
email.subject = "Hello"
12+
end
13+
14+
describe "#to" do
15+
it "returns email address" do
16+
expect(email.to).to eq("user@example.com")
17+
end
1018
end
1119
end

supermail.gemspec

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ Gem::Specification.new do |spec|
88
spec.authors = ["Brad Gessler"]
99
spec.email = ["bradgessler@gmail.com"]
1010

11-
spec.summary = "TODO: Write a short summary, because RubyGems requires one."
12-
spec.description = "TODO: Write a longer description or delete this line."
13-
spec.homepage = "TODO: Put your gem's website or public repo URL here."
11+
spec.summary = "Build emails with plain ol' Ruby objects."
12+
spec.description = spec.summary
13+
spec.homepage = "https://github.com/rubymonolith/supermail"
1414
spec.required_ruby_version = ">= 3.1.0"
1515

16-
spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
16+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
1717

1818
spec.metadata["homepage_uri"] = spec.homepage
19-
spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
20-
spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
19+
spec.metadata["source_code_uri"] = spec.homepage
20+
spec.metadata["changelog_uri"] = spec.homepage
2121

2222
# Specify which files should be added to the gem when it is released.
2323
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
3333
spec.require_paths = ["lib"]
3434

3535
# Uncomment to register a new dependency of your gem
36-
# spec.add_dependency "example-gem", "~> 1.0"
36+
spec.add_dependency "mail", "~> 2.0"
3737

3838
# For more information and examples about making a new gem, check out our
3939
# guide at: https://bundler.io/guides/creating_gem.html

0 commit comments

Comments
 (0)