Class: Sendeez::Client
- Inherits:
-
Object
- Object
- Sendeez::Client
- Defined in:
- lib/sendeez/client.rb
Overview
Client for the Sendeez transactional email API.
Zero runtime dependencies: HTTP is done with Net::HTTP. Pass transport
to substitute a fake transport in tests (same role as injecting +fetch+/
opener in the Node and Python SDKs).
Constant Summary collapse
- DEFAULT_BASE_URL =
"https://api.sendeez.com"
Instance Attribute Summary collapse
-
#admin ⇒ Object
readonly
Returns the value of attribute admin.
-
#api_keys ⇒ Object
readonly
Returns the value of attribute api_keys.
-
#domains ⇒ Object
readonly
Returns the value of attribute domains.
-
#emails ⇒ Object
readonly
Returns the value of attribute emails.
-
#suppressions ⇒ Object
readonly
Returns the value of attribute suppressions.
-
#webhooks ⇒ Object
readonly
Returns the value of attribute webhooks.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(api_key, base_url: DEFAULT_BASE_URL, max_retries: 2, timeout: 30, transport: nil) ⇒ Client
constructor
A new instance of Client.
- #request(method, path, body: nil, query: nil, idempotency_key: nil, timeout: nil) ⇒ Object
Constructor Details
#initialize(api_key, base_url: DEFAULT_BASE_URL, max_retries: 2, timeout: 30, transport: nil) ⇒ Client
Returns a new instance of Client.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/sendeez/client.rb', line 14 def initialize(api_key, base_url: DEFAULT_BASE_URL, max_retries: 2, timeout: 30, transport: nil) raise ArgumentError, "Sendeez api_key is required" if api_key.nil? || api_key.empty? @api_key = api_key @base_url = base_url.chomp("/") @max_retries = max_retries @timeout = timeout @transport = transport || method(:default_transport) @emails = Emails.new(self) @domains = Domains.new(self) @suppressions = Suppressions.new(self) @webhooks = Webhooks.new(self) @api_keys = ApiKeys.new(self) @admin = Admin.new(self) end |
Instance Attribute Details
#admin ⇒ Object (readonly)
Returns the value of attribute admin.
12 13 14 |
# File 'lib/sendeez/client.rb', line 12 def admin @admin end |
#api_keys ⇒ Object (readonly)
Returns the value of attribute api_keys.
12 13 14 |
# File 'lib/sendeez/client.rb', line 12 def api_keys @api_keys end |
#domains ⇒ Object (readonly)
Returns the value of attribute domains.
12 13 14 |
# File 'lib/sendeez/client.rb', line 12 def domains @domains end |
#emails ⇒ Object (readonly)
Returns the value of attribute emails.
12 13 14 |
# File 'lib/sendeez/client.rb', line 12 def emails @emails end |
#suppressions ⇒ Object (readonly)
Returns the value of attribute suppressions.
12 13 14 |
# File 'lib/sendeez/client.rb', line 12 def suppressions @suppressions end |
#webhooks ⇒ Object (readonly)
Returns the value of attribute webhooks.
12 13 14 |
# File 'lib/sendeez/client.rb', line 12 def webhooks @webhooks end |
Class Method Details
.new_idempotency_key ⇒ Object
31 32 33 |
# File 'lib/sendeez/client.rb', line 31 def self.new_idempotency_key "sdk_#{SecureRandom.uuid}" end |
Instance Method Details
#request(method, path, body: nil, query: nil, idempotency_key: nil, timeout: nil) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/sendeez/client.rb', line 36 def request(method, path, body: nil, query: nil, idempotency_key: nil, timeout: nil) url = "#{@base_url}#{path}" if query filtered = query.reject { |_, v| v.nil? } url += "?#{URI.encode_www_form(filtered)}" unless filtered.empty? end headers = { "Authorization" => "Bearer #{@api_key}", "Accept" => "application/json" } payload = nil unless body.nil? payload = JSON.generate(body) headers["Content-Type"] = "application/json" end headers["Idempotency-Key"] = idempotency_key if idempotency_key effective_timeout = timeout || @timeout attempt = 0 loop do begin response = @transport.call(method, url, headers, payload, effective_timeout) rescue StandardError => e raise e if attempt >= @max_retries || (method != "GET" && idempotency_key.nil?) sleep(backoff(attempt)) attempt += 1 next end status = response[:status] if status >= 200 && status < 300 body_str = response[:body] return nil if status == 204 || body_str.nil? || body_str.empty? return JSON.parse(body_str) end error_payload = parse_error_body(response[:body]) retry_after = parse_retry_after(response[:headers]) if attempt < @max_retries && retryable?(method, idempotency_key, status) sleep(retry_after || backoff(attempt)) attempt += 1 next end raise Sendeez::Error.new(status, error_payload["error"] || {}, retry_after: retry_after) end end |