resend 0.2.1 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aab8a1f078990a6a2c6e40c01f4b72771915d74e5ad8fa19fec67d9e0d00dc7e
4
- data.tar.gz: c440488de4a502b5abf3fbe79a83cd3535039fab30533308176f7b39b24477df
3
+ metadata.gz: fdc5399f47d9b5faaaa0a1406099a416bfafd29d9e07557ff8496617f1f35091
4
+ data.tar.gz: 5cfe523a3a1f8788551811de440a6e179c40802cbc6a1879180e022e8e9fc38e
5
5
  SHA512:
6
- metadata.gz: 577cb058bcada5f1cb56820c7ae1a6ba0f93da4035b1ac82d487fc3768a3c9b77a091a76b9cb5a91d5cb4a0331c8d6294f1b629ac40e86e6452e2d99c237b765
7
- data.tar.gz: 037aa163eea257ab8c8a779d58dad4bbc166d69d979d258a578843d3229a35d5a90b337d4dd0d4d8680d27707c2ead0be5b8142fa7cf190ab4bbc0674a4149ca
6
+ metadata.gz: bb127ddf8f4cfc28793690add92c1b38d84c25d54b20cbe00344dc4a72dcdeb1823eaa765a576c1ef68dd50ac27b8cb15da9d7349b71026b8522e2dc01c3c602
7
+ data.tar.gz: c5bde3db647e5fb1c7c819842a25420f4e296d9a9735e37c6415e3958e93331cc31a577e2e0fd40a7294b08c368522dadadffde1ac1d0769e6a686a9b2afdbbd
data/README.md CHANGED
@@ -25,7 +25,16 @@ First, you need to get an API key, which is available in the [Resend Dashboard](
25
25
 
26
26
  ```ruby
27
27
  require "resend"
28
- client = Resend::Client.new "re_YOUR_API_KEY"
28
+ Resend.api_key = ENV["RESEND_API_KEY"]
29
+ ```
30
+
31
+ or
32
+
33
+ ```ruby
34
+ require "resend"
35
+ Resend.configure do |config|
36
+ config.api_key = ENV["RESEND_API_KEY"]
37
+ end
29
38
  ```
30
39
 
31
40
  ## Example
@@ -33,18 +42,21 @@ client = Resend::Client.new "re_YOUR_API_KEY"
33
42
  ```rb
34
43
  require "resend"
35
44
 
36
- client = Resend::Client.new "re_YOUR_API_KEY"
45
+ Resend.api_key = ENV["RESEND_API_KEY"]
37
46
 
38
47
  params = {
39
- "from": "team@recomendo.io",
40
- "to": "carlosderich@gmail.com",
48
+ "from": "from@email.io",
49
+ "to": ["to@email.com", "to1@gmail.com"],
41
50
  "html": "<h1>Hello World</h1>",
42
51
  "subject": "Hey"
43
52
  }
44
- r = client.send_email(params)
53
+ r = Resend::Emails.send(params)
45
54
  puts r
46
55
  ```
47
56
 
57
+ You can view all the examples in the [examples folder](https://github.com/drish/resend-ruby/tree/main/examples)
58
+
59
+
48
60
  # Rails and ActiveMailer support
49
61
 
50
62
  This gem can be used as an ActionMailer delivery method, add this to your `config/environments/environment.rb` file and replace with your api key.
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "resend/request"
4
+ require "resend/errors"
5
+
6
+ module Resend
7
+ # api keys api wrapper
8
+ module ApiKeys
9
+ class << self
10
+ # https://resend.com/docs/api-reference/api-keys/create-api-key
11
+ def create(params)
12
+ path = "/api-keys"
13
+ Resend::Request.new(path, params, "post").perform
14
+ end
15
+
16
+ # https://resend.com/docs/api-reference/api-keys/list-api-keys
17
+ def list
18
+ path = "/api-keys"
19
+ Resend::Request.new(path, {}, "get").perform
20
+ end
21
+
22
+ # https://resend.com/docs/api-reference/api-keys/delete-api-key
23
+ def remove(api_key_id = "")
24
+ path = "/api-keys/#{api_key_id}"
25
+ Resend::Request.new(path, {}, "delete").perform
26
+ end
27
+ end
28
+ end
29
+ end
data/lib/resend/client.rb CHANGED
@@ -1,62 +1,21 @@
1
- require_relative "./version"
2
- require_relative "./errors"
1
+ # frozen_string_literal: true
2
+
3
+ require "resend/api_keys"
4
+ require "resend/domains"
5
+ require "resend/emails"
3
6
  require "httparty"
4
7
 
5
8
  module Resend
6
-
9
+ # Client class.
7
10
  class Client
8
- BASE_URL = "https://api.klotty.com/".freeze
11
+ include Resend::Emails
9
12
 
10
- attr_reader :api_key, :base_url, :timeout
13
+ attr_reader :api_key
11
14
 
12
15
  def initialize(api_key)
13
- raise ArgumentError.new("API Key is not a string") unless api_key.is_a?(String)
14
- @api_key = api_key
15
- @timeout = nil
16
- end
17
-
18
- def send_email(params)
19
- validate!(params)
20
-
21
- options = {
22
- headers: {
23
- 'Content-Type' => 'application/json',
24
- "Accept" => "application/json",
25
- "User-Agent" => "ruby:#{Resend::VERSION}",
26
- "Authorization" => "Bearer #{@api_key}",
27
- },
28
- body: params.to_json
29
- }
30
-
31
- resp = HTTParty.post("#{BASE_URL}/email", options)
32
- resp.transform_keys!(&:to_sym)
33
- if not resp[:error].nil?
34
- handle_error!(resp[:error])
35
- end
36
- resp
37
- end
16
+ raise ArgumentError, "API Key is not a string" unless api_key.is_a?(String)
38
17
 
39
- private
40
-
41
- def validate!(params)
42
- raise ArgumentError.new("'to' should be an Array or String") unless params[:to].is_a?(String) or params[:to].is_a?(Array)
43
- raise ArgumentError.new("Argument 'to' is missing") if params[:to].nil?
44
- raise ArgumentError.new("'to' can not be empty") if params[:to].empty?
45
-
46
- raise ArgumentError.new("'from' should be a String") unless params[:from].is_a?(String)
47
- raise ArgumentError.new("Argument 'from' is missing") if params[:from].nil?
48
- raise ArgumentError.new("'from' can not be empty") if params[:from].empty?
49
-
50
- raise ArgumentError.new("'from' should be a String") unless params[:from].is_a?(String)
51
- raise ArgumentError.new("Argument 'subject' is missing") if params[:subject].nil?
52
- raise ArgumentError.new("'subject' can not be empty") if params[:subject].empty?
53
-
54
- raise ArgumentError.new("Argument 'text' and 'html' are missing") if params[:text].nil? and params[:html].nil?
55
- end
56
-
57
- def handle_error!(error)
58
- err = error.transform_keys(&:to_sym)
59
- raise Resend::ResendError.new(err[:message])
18
+ @api_key = api_key
60
19
  end
61
20
  end
62
- end
21
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "resend/request"
4
+ require "resend/errors"
5
+
6
+ module Resend
7
+ # domains api wrapper
8
+ module Domains
9
+ class << self
10
+ # https://resend.com/docs/api-reference/domains/create-domain
11
+ def create(params)
12
+ path = "/domains"
13
+ Resend::Request.new(path, params, "post").perform
14
+ end
15
+
16
+ # https://resend.com/docs/api-reference/api-keys/list-api-keys
17
+ def list
18
+ path = "/domains"
19
+ Resend::Request.new(path, {}, "get").perform
20
+ end
21
+
22
+ # https://resend.com/docs/api-reference/domains/delete-domain
23
+ def remove(domain_id = "")
24
+ path = "/domains/#{domain_id}"
25
+ Resend::Request.new(path, {}, "delete").perform
26
+ end
27
+
28
+ # https://resend.com/docs/api-reference/domains/verify-domain
29
+ def verify(domain_id = "")
30
+ path = "/domains/#{domain_id}/verify"
31
+ Resend::Request.new(path, {}, "post").perform
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "resend/request"
4
+
5
+ module Resend
6
+ # Module responsible for wrapping email sending API
7
+ module Emails
8
+ class << self
9
+ # send email functionality
10
+ # https://resend.com/docs/api-reference/send-email
11
+ def send(params)
12
+ path = "emails"
13
+ Resend::Request.new(path, params, "post").perform
14
+ end
15
+
16
+ def get(email_id = "")
17
+ path = "emails/#{email_id}"
18
+ Resend::Request.new(path, {}, "get").perform
19
+ end
20
+ end
21
+
22
+ # This method is kept here for backwards compatibility
23
+ # Use Resend::Emails.send instead.
24
+ def send_email(params)
25
+ warn "[DEPRECATION] `send_email` is deprecated. Please use `Resend::Emails.send` instead."
26
+ Resend::Emails.send(params)
27
+ end
28
+ end
29
+ end
data/lib/resend/errors.rb CHANGED
@@ -1,5 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Resend
2
- class ResendError < StandardError
4
+ # Errors wrapper class
5
+ # For more info: https://resend.com/docs/api-reference/error-codes
6
+ class Error < StandardError
7
+
8
+ # 4xx HTTP status code
9
+ ClientError = Class.new(self)
10
+
11
+ # 5xx HTTP status code
12
+ ServerError = Class.new(self)
13
+
14
+ # code 500
15
+ InternalServerError = Class.new(ServerError)
16
+
17
+ # code 422
18
+ InvalidRequestError = Class.new(ServerError)
19
+
20
+ # code 404
21
+ NotFoundError = Class.new(ServerError)
22
+
23
+ ERRORS = {
24
+ 404 => Resend::Error::InvalidRequestError,
25
+ 422 => Resend::Error::InvalidRequestError,
26
+ 400 => Resend::Error::InvalidRequestError,
27
+ 500 => Resend::Error::InternalServerError
28
+ }.freeze
29
+
30
+ def initialize(msg, code = nil)
31
+ super(msg)
32
+ @code = code
33
+ end
3
34
  end
4
35
  end
5
-
data/lib/resend/mailer.rb CHANGED
@@ -1,39 +1,42 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "resend"
2
4
 
3
5
  module Resend
6
+ # Mailer class used by railtie
4
7
  class Mailer
5
-
6
8
  attr_accessor :config, :settings
7
9
 
8
10
  def initialize(config)
9
11
  @config = config
10
- raise Resend::ResendError.new("Config requires api_key", @config) unless @config.has_key?(:api_key)
12
+ raise Resend::ResendError.new("Config requires api_key", @config) unless @config.key?(:api_key)
13
+
11
14
  @settings = { return_response: true } # avoids NilError exception
12
15
  @resend_client = Resend::Client.new config[:api_key]
13
16
  end
14
17
 
15
18
  def deliver!(mail)
19
+ params = build_resend_params(mail)
20
+ resp = @resend_client.send_email(params)
21
+ mail.message_id = resp[:id] if resp[:error].nil?
22
+ resp
23
+ end
24
+
25
+ # rubocop:disable Metrics/AbcSize
26
+ def build_resend_params(mail)
16
27
  params = {
17
28
  from: mail[:from].to_s,
18
29
  to: mail.to,
19
- subject: mail.subject,
30
+ subject: mail.subject
20
31
  }
21
32
  params[:cc] = mail[:cc].to_s if mail[:cc].present?
22
33
  params[:bcc] = mail[:bcc].to_s if mail[:bcc].present?
23
34
  params[:reply_to] = mail[:reply_to].to_s if mail[:reply_to].present?
24
35
  params[:html] = mail.body.decoded
25
-
26
- resp = @resend_client.send_email(params)
27
-
28
- if resp[:error].nil? then
29
- mail.message_id = resp[:id]
30
- end
31
-
32
- resp
36
+ params
33
37
  end
38
+ # rubocop:enable Metrics/AbcSize
34
39
 
35
- def resend_client
36
- @resend_client
37
- end
40
+ attr_reader :resend_client
38
41
  end
39
- end
42
+ end
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "resend"
2
4
  require "resend/mailer"
3
5
 
4
6
  module Resend
7
+ # Main railtime class
5
8
  class Railtie < ::Rails::Railtie
6
9
  ActiveSupport.on_load(:action_mailer) do
7
10
  add_delivery_method :resend, Resend::Mailer
8
11
  ActiveSupport.run_load_hooks(:resend_mailer, Resend::Mailer)
9
12
  end
10
13
  end
11
- end
14
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "resend/version"
4
+ require "resend/errors"
5
+ require "httparty"
6
+
7
+ module Resend
8
+ # This class is responsible for making the appropriate HTTP calls
9
+ # and raising the specific errors based on the response.
10
+ class Request
11
+ BASE_URL = "https://api.resend.com/"
12
+
13
+ attr_accessor :body, :verb
14
+
15
+ def initialize(path = "", body = {}, verb = "POST")
16
+ raise if Resend.api_key.nil?
17
+
18
+ @path = path
19
+ @body = body
20
+ @verb = verb
21
+ @headers = {
22
+ "Content-Type" => "application/json",
23
+ "Accept" => "application/json",
24
+ "User-Agent" => "ruby:#{Resend::VERSION}",
25
+ "Authorization" => "Bearer #{Resend.api_key}"
26
+ }
27
+ end
28
+
29
+ # Performs the HTTP call
30
+ def perform
31
+ options = {
32
+ headers: @headers
33
+ }
34
+ options[:body] = @body.to_json unless @body.empty?
35
+ resp = HTTParty.send(@verb.to_sym, "#{BASE_URL}#{@path}", options)
36
+ resp.transform_keys!(&:to_sym) unless resp.body.empty?
37
+ handle_error!(resp) if resp[:statusCode] && resp[:statusCode] != 200
38
+ resp
39
+ end
40
+
41
+ def handle_error!(resp)
42
+ code = resp[:statusCode]
43
+ body = resp[:message]
44
+ error = Resend::Error::ERRORS[code]
45
+ raise(error.new(body, code)) if error
46
+ end
47
+ end
48
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Resend
4
- VERSION = "0.2.1"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/resend.rb CHANGED
@@ -3,15 +3,17 @@
3
3
  require "resend/version"
4
4
  require "resend/client"
5
5
 
6
- require 'resend/railtie' if defined?(Rails) && defined?(ActionMailer)
6
+ require "resend/railtie" if defined?(Rails) && defined?(ActionMailer)
7
7
 
8
+ # Main Resend module
8
9
  module Resend
9
10
  class << self
10
- attr_accessor :api_key,
11
+ attr_accessor :api_key
12
+
11
13
  def configure
12
14
  yield self if block_given?
13
15
  true
14
16
  end
15
- alias_method :config, :configure
17
+ alias config configure
16
18
  end
17
- end
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resend
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derich Pacheco
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-02 00:00:00.000000000 Z
11
+ date: 2023-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.20.0
19
+ version: 0.19.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.20.0
26
+ version: 0.19.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rails
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -46,12 +46,16 @@ extra_rdoc_files: []
46
46
  files:
47
47
  - README.md
48
48
  - lib/resend.rb
49
+ - lib/resend/api_keys.rb
49
50
  - lib/resend/client.rb
51
+ - lib/resend/domains.rb
52
+ - lib/resend/emails.rb
50
53
  - lib/resend/errors.rb
51
54
  - lib/resend/mailer.rb
52
55
  - lib/resend/railtie.rb
56
+ - lib/resend/request.rb
53
57
  - lib/resend/version.rb
54
- homepage: https://github.com/drish/resend-ruby
58
+ homepage: https://github.com/resendlabs/resend-ruby
55
59
  licenses:
56
60
  - MIT
57
61
  metadata: {}