resend 0.2.1 → 0.4.0

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: aab8a1f078990a6a2c6e40c01f4b72771915d74e5ad8fa19fec67d9e0d00dc7e
4
- data.tar.gz: c440488de4a502b5abf3fbe79a83cd3535039fab30533308176f7b39b24477df
3
+ metadata.gz: e3e46d09490b1ad19c59f04e55fd16b0da3d3c2573ed5c9dcba3297f0f92f5fc
4
+ data.tar.gz: 6c9dfb7910fd6199bc9c75aa9f3c2e9200677ce9e2ba1e9a29e124908489e714
5
5
  SHA512:
6
- metadata.gz: 577cb058bcada5f1cb56820c7ae1a6ba0f93da4035b1ac82d487fc3768a3c9b77a091a76b9cb5a91d5cb4a0331c8d6294f1b629ac40e86e6452e2d99c237b765
7
- data.tar.gz: 037aa163eea257ab8c8a779d58dad4bbc166d69d979d258a578843d3229a35d5a90b337d4dd0d4d8680d27707c2ead0be5b8142fa7cf190ab4bbc0674a4149ca
6
+ metadata.gz: 58e0cdd7ae1d48654ff33761b1fcb8a4e96061142d154232f85bac348c38956505d11ee3a0cdf6d86592389d2d8c69eba48941d7d97e1c4de904d0c8b5b6d7a6
7
+ data.tar.gz: 2069dfd99a67245da05ebf8e58658c2771de51cd6999d8d824116174b0aeba38dcc4f4423f05cb73e63388f5497377dba4c4b98eebddba2b2205864530790d3a
data/README.md CHANGED
@@ -16,7 +16,7 @@ gem install resend
16
16
 
17
17
  Via Gemfile:
18
18
  ```
19
- gem 'resend', '~>0.2.1'
19
+ gem 'resend', '~>0.3.0'
20
20
  ```
21
21
 
22
22
  ## Setup
@@ -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,36 @@
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
+ 401 => Resend::Error::InvalidRequestError,
25
+ 404 => Resend::Error::InvalidRequestError,
26
+ 422 => Resend::Error::InvalidRequestError,
27
+ 400 => Resend::Error::InvalidRequestError,
28
+ 500 => Resend::Error::InternalServerError
29
+ }.freeze
30
+
31
+ def initialize(msg, code = nil)
32
+ super(msg)
33
+ @code = code
34
+ end
3
35
  end
4
36
  end
5
-
data/lib/resend/mailer.rb CHANGED
@@ -1,39 +1,76 @@
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
- @resend_client = Resend::Client.new config[:api_key]
13
15
  end
14
16
 
15
17
  def deliver!(mail)
18
+ params = build_resend_params(mail)
19
+ resp = Resend::Emails.send(params)
20
+ mail.message_id = resp[:id] if resp[:error].nil?
21
+ resp
22
+ end
23
+
24
+ def build_resend_params(mail)
16
25
  params = {
17
- from: mail[:from].to_s,
26
+ from: get_from(mail.from),
18
27
  to: mail.to,
19
- subject: mail.subject,
28
+ subject: mail.subject
20
29
  }
21
- params[:cc] = mail[:cc].to_s if mail[:cc].present?
22
- params[:bcc] = mail[:bcc].to_s if mail[:bcc].present?
23
- params[:reply_to] = mail[:reply_to].to_s if mail[:reply_to].present?
24
- params[:html] = mail.body.decoded
30
+ params.merge!(get_addons(mail))
31
+ params[:attachments] = get_attachments(mail) if mail.attachments.present?
32
+ params.merge!(get_contents(mail))
33
+ params
34
+ end
25
35
 
26
- resp = @resend_client.send_email(params)
36
+ def get_addons(mail)
37
+ params = {}
38
+ params[:cc] = mail.cc if mail.cc.present?
39
+ params[:bcc] = mail.bcc if mail.bcc.present?
40
+ params[:reply_to] = mail.reply_to if mail.reply_to.present?
41
+ params
42
+ end
27
43
 
28
- if resp[:error].nil? then
29
- mail.message_id = resp[:id]
44
+ def get_contents(mail)
45
+ params = {}
46
+ case mail.mime_type
47
+ when "text/plain"
48
+ params[:text] = mail.body.decoded
49
+ when "text/html"
50
+ params[:html] = mail.body.decoded
51
+ when "multipart/alternative", "multipart/mixed", "multipart/related"
52
+ params[:text] = mail.text_part.decoded if mail.text_part
53
+ params[:html] = mail.html_part.decoded if mail.html_part
30
54
  end
55
+ params
56
+ end
31
57
 
32
- resp
58
+ def get_from(input)
59
+ return input.first if input.is_a? Array
60
+
61
+ input
33
62
  end
34
63
 
35
- def resend_client
36
- @resend_client
64
+ def get_attachments(mail)
65
+ attachments = []
66
+ mail.attachments.each do |part|
67
+ attachment = {
68
+ filename: part.filename,
69
+ content: part.body.decoded.bytes
70
+ }
71
+ attachments.append(attachment)
72
+ end
73
+ attachments
37
74
  end
38
75
  end
39
- end
76
+ 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.4.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.4.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-05-20 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: {}