mailclerk 0.1.1 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0746f6e459e89ebf5c23c33c940f10f4639d7b92e9bffbb7bb0f0c217608d8e9
4
- data.tar.gz: 12c12b1846326a577d6423dd7b20ecf77156c50d4e3ab084327b72224a4b8023
3
+ metadata.gz: 97393aafed17d2eb1ca2d9c8242154c116e3bbb58e60596efd5f03b8697fb7df
4
+ data.tar.gz: 65cf703eede9e9213f0a7cb439dbed5e908cb127184634002a7618d0b7cfff8d
5
5
  SHA512:
6
- metadata.gz: 1867bff480e230a049d3ec3f14221ca83ace81ed745cbefd1b3b7ef7ec6d6d561f7b8f9fe37b9d0d83d178f50ed28061bf6f35768f806dd4e9d27997a7f6c289
7
- data.tar.gz: 5aa6071e289c6194fe43abfba94ed141200b1c385c42ac897e4c09dd0b0bf722f079f7e69b0d96d767deac7273a47a5475b31d60aac3160575dfb431e0006ffa
6
+ metadata.gz: 0f6fac55f44d59eb8fbd49709117543d666a26f53b9f650c89b14c04705b62d82df88c7ff5ea447dcddba692bd73c6d5d381725e54956de130a8a2c1949d0bdd
7
+ data.tar.gz: 81906cfdb4a73edbad522ef11fc75354d3dc97d9c03b26ed693c398fdaa5646b74ab113d3cb66e7188887c108a037e0b2b6c93d0762481468e1a7ede6a1afafc
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="mailcerk.png" alt="Mailclerk Logo"/>
2
+ <img src="https://github.com/mailclerk/mailclerk-ruby/blob/main/mailclerk.png?raw=true" alt="Mailclerk Logo"/>
3
3
  </p>
4
4
 
5
5
  # Mailclerk
@@ -16,8 +16,9 @@ Mailclerk helps anyone on your team design great emails, improve their performan
16
16
  - [Setup](#setup)
17
17
  - [API Key & URL](#api-key--url)
18
18
  - [Usage](#usage)
19
+ - [Testing](#testing)
19
20
  - [Varying API Keys](#varying-api-keys)
20
- - [Tests](#tests)
21
+ - [Gem Tests](#gem-tests)
21
22
  - [Versioning](#versioning)
22
23
  - [Code of Conduct](#code-of-conduct)
23
24
  - [Contributions](#contributions)
@@ -28,7 +29,7 @@ Mailclerk helps anyone on your team design great emails, improve their performan
28
29
 
29
30
  ## Requirements
30
31
 
31
- 1. [Ruby 2.7.0](https://www.ruby-lang.org)
32
+ 1. [Ruby 2.4.0](https://www.ruby-lang.org)
32
33
 
33
34
  ## Setup
34
35
 
@@ -50,16 +51,16 @@ To set the Mailclerk API Key (begins with `mc_`), you can provide it as an
50
51
  environmental variable: `MAILCLERK_API_KEY`. Alternatively, you can
51
52
  set it directly on the Mailclerk module:
52
53
 
53
- ```
54
- # config/initializers/mailcerk.rb
55
- Mailclerk.api_key = "mc_yourprivatekey"
54
+ ```ruby
55
+ # config/initializers/mailclerk.rb
56
+ Mailclerk.api_key = "mc_live_yourprivatekey"
56
57
  ```
57
58
 
58
59
  _If you are using version control like git, we strongly recommend storing your
59
60
  production API keys in environmental variables_.
60
61
 
61
- The default API endpoint is `https://api.mailcerk.app`. To change this, you
62
- can provide a `MAILCLERK_API_URL` ENV variable or set `Mailclerk.mailcerk_url`.
62
+ The default API endpoint is `https://api.mailclerk.app`. To change this, you
63
+ can provide a `MAILCLERK_API_URL` ENV variable or set `Mailclerk.mailclerk_url`.
63
64
 
64
65
  ## Usage
65
66
 
@@ -67,44 +68,114 @@ You'll need an active account and at least one template (in the example `welcome
67
68
 
68
69
  To send an email to "alice@example.com":
69
70
 
70
- ```
71
+ ```ruby
71
72
  Mailclerk.deliver("welcome-email", "alice@example.com")
73
+ Mailclerk.deliver("welcome-email", "Alice Adams <alice@example.com>")
74
+ Mailclerk.deliver("welcome-email", { name: "Alice Adams", address: "<alice@example.com>" })
72
75
  ```
73
76
 
74
77
  If the template has any dynamic data, you can include it in the third parameter
75
78
  as a hash:
76
79
 
77
- ```
80
+ ```ruby
78
81
  Mailclerk.deliver("welcome-email", "alice@example.com", { name: "Alice" })
79
82
  ```
80
83
 
81
84
  See [Mailclerk documentation](https://dashboard.mailclerk.app/docs) for more details.
82
85
 
86
+ ## Testing
87
+
88
+ Your Mailclerk environment has two API keys: a production key (beginning with `mc_live`)
89
+ and a test key (beginning with `mc_test`). If you use the test key, emails will
90
+ not be delivered, but will show up in the logs on your Mailclerk account and can be
91
+ previewed there. This replaces tools like [Letter Opener](https://github.com/ryanb/letter_opener) for previewing emails in development.
92
+
93
+ To avoid cluttering up your Mailclerk test logs with sends triggered by your
94
+ automated test suite, call `Mailclerk.outbox.enable` in the file that
95
+ configures your tests. For example, in Rspec with Rails, add:
96
+
97
+ ```ruby
98
+ # spec/rails_helper.rb
99
+ Mailclerk.outbox.enable
100
+ ```
101
+
102
+ This will also enable utility methods which you can use to write tests that check
103
+ emails are sent with the correct data:
104
+
105
+ ```ruby
106
+ # Number of emails "sent"
107
+ Mailclerk.outbox.length
108
+
109
+ # Returns all emails of matching a template or email recipient. See method
110
+ Mailclerk.outbox.filter(template: "welcome-email")
111
+ Mailclerk.outbox.filter(recipient_email: "felix@example.com")
112
+
113
+ # Returns the most recent email (instance of Mailclerk::TestEmail):
114
+ email = Mailclerk.outbox.last
115
+ email.template # "welcome-email"
116
+ email.recipient_email # "felix@example.com"
117
+ email.subject # "Welcome to Acme Felix"
118
+ email.html # "<html><body>..."
119
+ ```
120
+
121
+ In between test cases, you should clear the stored emails by calling `Mailclerk.outbox.reset`.
122
+
123
+ For example, in Rspec with Rails:
124
+
125
+ ```ruby
126
+ # spec/rails_helper.rb
127
+ RSpec.configure do |config|
128
+ config.before(:each) do
129
+ Mailclerk.outbox.reset
130
+ end
131
+ end
132
+ ```
133
+
134
+ `Mailclerk::OutboxEmail` has the following attributes:
135
+
136
+ | Attribute | Description |
137
+ | ----------------- | -------------------------------------------------------------------------- |
138
+ | `template` | Slug of the template sent (1st argument to `Mailclerk.deliver`) |
139
+ | `recipient` | Hash representing the send recipient (2nd argument to `Mailclerk.deliver`) |
140
+ | `recipient_email` | Email of the send recipient |
141
+ | `recipient_name` | Name of the send recipient (nil if not specified) |
142
+ | `data` | Dynamic data for the send (3rd argument to `Mailclerk.deliver`) |
143
+ | `options` | Options specified for the send (4th argument to `Mailclerk.deliver`) |
144
+ | `from` | From Mailclerk: Hash with `name` and `address` of the sender |
145
+ | `subject` | From Mailclerk: Text of the send's subject line |
146
+ | `preheader` | From Mailclerk: Text of the send's preheader |
147
+ | `html` | From Mailclerk: Rendered body HTML for the send |
148
+ | `text` | From Mailclerk: Rendered plaintext version of the send |
149
+ | `headers` | From Mailclerk: Extra email headers (e.g. `reply-to`) |
150
+
151
+ See the [Mailclerk testing documentation](https://dashboard.mailclerk.app/docs#testing)
152
+ for more details.
153
+
83
154
  ## Varying API Keys
84
155
 
85
156
  If you need to use multiple API keys, you can also initialize `Mailclerk::Client`
86
157
  instances with different keys. This:
87
158
 
88
- ```
89
- mc_client = Mailclerk.new("mc_yourprivatekey")
159
+ ```ruby
160
+ mc_client = Mailclerk.new("mc_live_yourprivatekey")
90
161
  mc_client.deliver("welcome-email", "bob@example.com")
91
162
  ```
92
163
 
93
164
  Is equivalent to this:
94
165
 
95
- ```
96
- Mailclerk.api_key = "mc_yourprivatekey"
166
+ ```ruby
167
+ Mailclerk.api_key = "mc_live_yourprivatekey"
97
168
  Mailclerk.deliver("welcome-email", "bob@example.com")
98
169
  ```
99
170
 
100
- ## Tests
101
-
102
- Tests aren't current implemented. When they are, to test, run:
171
+ ## Gem Tests
103
172
 
104
173
  ```
105
- bundle exec rake
174
+ bundle exec rspec
106
175
  ```
107
176
 
177
+ Requires values in .env file as well
178
+
108
179
  ## Versioning
109
180
 
110
181
  Read [Semantic Versioning](https://semver.org) for details. Briefly, it means:
data/lib/client.rb ADDED
@@ -0,0 +1,62 @@
1
+ module Mailclerk
2
+ class Client
3
+ def initialize(api_key, api_url=nil)
4
+ @api_key = api_key
5
+ @api_url = api_url || ENV['MAILCLERK_API_URL'] || DEFAULT_API_URL
6
+
7
+ if @api_key.nil?
8
+ raise MailclerkError.new(
9
+ "No Mailclerk API Key provided. Set `Mailclerk.api_key`"
10
+ )
11
+ end
12
+
13
+ if @api_url.nil? || @api_url.empty?
14
+ raise MailclerkError.new("Mailclerk API URL empty")
15
+ end
16
+ end
17
+
18
+ def deliver(template, recipient, data={}, options={})
19
+ conn = Faraday.new(url: @api_url)
20
+ conn.basic_auth(@api_key, '')
21
+
22
+ if Mailclerk.outbox_enabled?
23
+ options = options.merge(
24
+ "local_outbox" => true
25
+ )
26
+ options.delete(:local_outbox)
27
+ end
28
+
29
+ params = {
30
+ 'template' => template,
31
+ 'recipient' => recipient,
32
+ 'data' => data,
33
+ 'options' => options
34
+ }
35
+
36
+ response = conn.post('deliver', params.to_json, {
37
+ 'Content-Type' => 'application/json',
38
+ 'X-Client-Version' => Identity.version_label
39
+ })
40
+
41
+ if response.status >= 400
42
+ begin
43
+ message = JSON.parse(response.body)["message"] || "Unknown"
44
+ description = "Mailclerk API Error: #{ message }"
45
+ rescue JSON::ParserError
46
+ description = "Mailclerk API Unknown Error"
47
+ end
48
+
49
+ raise MailclerkAPIError.new(
50
+ description, response.status, response
51
+ )
52
+ end
53
+
54
+ if Mailclerk.outbox_enabled?
55
+ params["options"].delete("local_outbox")
56
+ Mailclerk.outbox.add_send(params, JSON.parse(response.body)["delivery"])
57
+ end
58
+
59
+ return response
60
+ end
61
+ end
62
+ end
data/lib/errors.rb ADDED
@@ -0,0 +1,15 @@
1
+ module Mailclerk
2
+ class MailclerkError < StandardError
3
+ end
4
+
5
+ class MailclerkAPIError < MailclerkError
6
+ attr_accessor :http_status
7
+ attr_accessor :http_response
8
+
9
+ def initialize(description, http_status=nil, http_response=nil)
10
+ super(description)
11
+ self.http_status = http_status
12
+ self.http_response = http_response
13
+ end
14
+ end
15
+ end
data/lib/mailclerk.rb CHANGED
@@ -3,6 +3,10 @@
3
3
  require 'faraday'
4
4
  require 'json'
5
5
 
6
+ require "client"
7
+ require "errors"
8
+ require "outbox"
9
+
6
10
  module Mailclerk
7
11
  DEFAULT_API_URL = "https://api.mailclerk.app"
8
12
 
@@ -22,7 +26,7 @@ module Mailclerk
22
26
  end
23
27
 
24
28
  def self.version
25
- "0.1.1"
29
+ "1.1.1"
26
30
  end
27
31
 
28
32
  def self.version_label
@@ -30,47 +34,19 @@ module Mailclerk
30
34
  end
31
35
  end
32
36
 
33
- class MailclerkError < StandardError
34
- end
35
-
36
- class Client
37
- def initialize(api_key, api_url=nil)
38
- @api_key = api_key
39
- @api_url = api_url || ENV['MAILCLERK_API_URL'] || DEFAULT_API_URL
40
-
41
- if @api_key.nil?
42
- raise MailclerkError.new "No Mailclerk API Key provided. Set `Mailclerk.api_key`"
43
- end
44
-
45
- if @api_url.nil? || @api_url.empty?
46
- raise MailclerkError.new "Mailclerk API URL empty"
47
- end
48
- end
49
-
50
- def deliver(template, recipient, data={}, options={})
51
- conn = Faraday.new(url: @api_url)
52
- conn.basic_auth(@api_key, '')
53
-
54
- resp = conn.post('deliver', {
55
- 'template' => template,
56
- 'recipient' => recipient,
57
- 'data' => data,
58
- 'options' => options
59
- }.to_json, {
60
- 'Content-Type' => 'application/json',
61
- 'X-Client-Version' => Identity.version_label
62
- })
63
-
64
- return resp
65
- end
66
- end
67
-
68
37
  # Syntax intended to emulate ActionMailer
69
38
  def self.deliver(*args)
70
39
  api_key = self.api_key || ENV['MAILCLERK_API_KEY']
71
40
 
72
- client = Client.new(api_key, self.api_url)
41
+ client = Mailclerk::Client.new(api_key, self.api_url)
73
42
  return client.deliver(*args)
74
43
  end
44
+
45
+ def self.outbox
46
+ @outbox ||= Mailclerk::Outbox.new
47
+ end
75
48
 
76
- end
49
+ def self.outbox_enabled?
50
+ !!(@outbox && @outbox.enabled)
51
+ end
52
+ end
data/lib/outbox.rb ADDED
@@ -0,0 +1,91 @@
1
+ module Mailclerk
2
+ class Outbox < Array
3
+ attr_accessor :enabled
4
+
5
+ def initialize
6
+ self.enabled = false
7
+ end
8
+
9
+ def enable
10
+ self.enabled = true
11
+ end
12
+
13
+ def reset
14
+ self.clear
15
+ end
16
+
17
+ # Not just an alias for 'select'
18
+ def filter(query)
19
+ self.select do |email|
20
+ query.all? do |key, value|
21
+ email[key] == value
22
+ end
23
+ end
24
+ end
25
+
26
+ def add_send(request, response)
27
+ email = OutboxEmail.new(
28
+ OutboxEmail.recursive_init(
29
+ response.merge(request)
30
+ )
31
+ )
32
+ self << email
33
+ end
34
+ end
35
+
36
+ class OutboxEmail < OpenStruct
37
+
38
+ def self.recursive_init(data)
39
+
40
+ data.each do |key, val|
41
+ if val.is_a?(Hash)
42
+ data[key] = self.recursive_init(val)
43
+ else
44
+ data[key] = val
45
+ end
46
+ end
47
+
48
+ return OpenStruct.new(data)
49
+ end
50
+
51
+ # Custom getters
52
+
53
+ def recipient_email
54
+ return parse_recipient[:address]
55
+ end
56
+
57
+ def recipient_name
58
+ return parse_recipient[:name]
59
+ end
60
+
61
+ private
62
+
63
+ def parse_recipient
64
+ return {} unless self.recipient
65
+
66
+ if self.recipient.is_a?(OpenStruct)
67
+ return self.recipient
68
+ end
69
+
70
+ text = self.recipient.strip
71
+
72
+ if text =~ /^[^<]+<[^<]+>$/
73
+ parts = text.split("<", 2);
74
+
75
+ name = parts[0].strip.gsub('"', "")
76
+
77
+ address = parts[1].strip.gsub(">", "")
78
+
79
+ return {
80
+ name: name,
81
+ address: address
82
+ }
83
+ else
84
+ return {
85
+ name: nil,
86
+ address: text
87
+ }
88
+ end
89
+ end
90
+ end
91
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailclerk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Noah Litvin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-01-28 00:00:00.000000000 Z
12
+ date: 2021-03-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -109,6 +109,20 @@ dependencies:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
111
  version: '3.9'
112
+ - !ruby/object:Gem::Dependency
113
+ name: dotenv
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
112
126
  description:
113
127
  email:
114
128
  - developers@mailclerk.app
@@ -120,7 +134,10 @@ extra_rdoc_files:
120
134
  files:
121
135
  - LICENSE.md
122
136
  - README.md
137
+ - lib/client.rb
138
+ - lib/errors.rb
123
139
  - lib/mailclerk.rb
140
+ - lib/outbox.rb
124
141
  homepage: https://github.com/mailclerk/mailclerk-ruby
125
142
  licenses:
126
143
  - MIT
@@ -133,7 +150,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
150
  requirements:
134
151
  - - "~>"
135
152
  - !ruby/object:Gem::Version
136
- version: '2.7'
153
+ version: '2.5'
137
154
  required_rubygems_version: !ruby/object:Gem::Requirement
138
155
  requirements:
139
156
  - - ">="