buchida 0.1.2 → 0.2.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 +4 -4
- data/lib/buchida/client.rb +34 -3
- data/lib/buchida/resources/api_keys.rb +2 -2
- data/lib/buchida/resources/domains.rb +4 -4
- data/lib/buchida/resources/emails.rb +9 -8
- data/lib/buchida/resources/metrics.rb +3 -2
- data/lib/buchida/resources/templates.rb +2 -2
- data/lib/buchida/resources/webhooks.rb +2 -2
- data/lib/buchida/response.rb +120 -0
- data/lib/buchida/version.rb +1 -1
- data/lib/buchida.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1fcf69caf904b7e44acd3566606f5f1ade948dfc6d01d094437067ae72310cbf
|
|
4
|
+
data.tar.gz: 7f7c9892d7b633081b75d464fe775406a33d34f6d351fdd434a32a08a1bd0cdb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc088609542a0c45a81021a4e8bcc6861893c09df6483dbf0ae26c7f3f5906dd3c05c221b2d284c13577c2a087838591331ba48212f9502d3f50c19438b98fba
|
|
7
|
+
data.tar.gz: 2f269621f280e5b4320be5d3d7b8079192c4686d09740db87186b51291f743c77f11c19bbd111b0c59fc0d2cbdb2f2112500d8f5b12317301044b77db4fea479
|
data/lib/buchida/client.rb
CHANGED
|
@@ -6,7 +6,7 @@ require "json"
|
|
|
6
6
|
|
|
7
7
|
module Buchida
|
|
8
8
|
class Client
|
|
9
|
-
DEFAULT_BASE_URL = "https://api.buchida.com"
|
|
9
|
+
DEFAULT_BASE_URL = "https://api.buchida.com/v1"
|
|
10
10
|
DEFAULT_TIMEOUT = 30
|
|
11
11
|
|
|
12
12
|
attr_reader :emails, :domains, :api_keys, :webhooks, :templates, :metrics
|
|
@@ -57,8 +57,32 @@ module Buchida
|
|
|
57
57
|
JSON.parse(response.body)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
# Request returning a single object: unwraps `{ "data" => {...} }` (204 => nil).
|
|
61
|
+
def request_object(method, path, body = nil)
|
|
62
|
+
unwrap_object(request(method, path, body))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Request returning a list: unwraps `{ "data" => [...], "cursor" =>, "hasMore" => }`.
|
|
66
|
+
def request_list(method, path, body = nil)
|
|
67
|
+
resp = request(method, path, body)
|
|
68
|
+
if resp.is_a?(Hash)
|
|
69
|
+
ListResult.new(resp["data"] || [], cursor: resp["cursor"], has_more: resp["hasMore"] || resp["has_more"] || false)
|
|
70
|
+
elsif resp.is_a?(Array)
|
|
71
|
+
ListResult.new(resp)
|
|
72
|
+
else
|
|
73
|
+
resp
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
60
77
|
private
|
|
61
78
|
|
|
79
|
+
def unwrap_object(resp)
|
|
80
|
+
return resp unless resp.is_a?(Hash)
|
|
81
|
+
|
|
82
|
+
inner = resp.key?("data") ? resp["data"] : resp
|
|
83
|
+
inner.is_a?(Hash) ? Result[inner] : inner
|
|
84
|
+
end
|
|
85
|
+
|
|
62
86
|
def handle_error(response)
|
|
63
87
|
body = begin
|
|
64
88
|
JSON.parse(response.body)
|
|
@@ -66,7 +90,14 @@ module Buchida
|
|
|
66
90
|
{ "message" => response.message }
|
|
67
91
|
end
|
|
68
92
|
|
|
69
|
-
|
|
93
|
+
err = body["error"]
|
|
94
|
+
if err.is_a?(Hash)
|
|
95
|
+
message = err["message"] || response.message
|
|
96
|
+
error_code = err["code"]
|
|
97
|
+
else
|
|
98
|
+
message = body["message"] || response.message
|
|
99
|
+
error_code = body["code"]
|
|
100
|
+
end
|
|
70
101
|
status = response.code.to_i
|
|
71
102
|
|
|
72
103
|
case status
|
|
@@ -74,7 +105,7 @@ module Buchida
|
|
|
74
105
|
when 404 then raise NotFoundError, message
|
|
75
106
|
when 422 then raise ValidationError, message
|
|
76
107
|
when 429 then raise RateLimitError, message
|
|
77
|
-
else raise Error.new(message, status,
|
|
108
|
+
else raise Error.new(message, status, error_code)
|
|
78
109
|
end
|
|
79
110
|
end
|
|
80
111
|
end
|
|
@@ -8,11 +8,11 @@ module Buchida
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def create(name:, permission:)
|
|
11
|
-
@client.
|
|
11
|
+
@client.request_object(:post, "/api-keys", { name: name, permission: permission })
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def list
|
|
15
|
-
@client.
|
|
15
|
+
@client.request_list(:get, "/api-keys")
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def delete(id)
|
|
@@ -8,19 +8,19 @@ module Buchida
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def create(name:)
|
|
11
|
-
@client.
|
|
11
|
+
@client.request_object(:post, "/domains", { name: name })
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def list
|
|
15
|
-
@client.
|
|
15
|
+
@client.request_list(:get, "/domains")
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def get(id)
|
|
19
|
-
@client.
|
|
19
|
+
@client.request_object(:get, "/domains/#{id}")
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def verify(id)
|
|
23
|
-
@client.
|
|
23
|
+
@client.request_object(:post, "/domains/#{id}/verify")
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -7,20 +7,21 @@ module Buchida
|
|
|
7
7
|
@client = client
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def send(from:, to:, subject:, html: nil, text: nil, reply_to: nil, cc: nil, bcc: nil, tags: nil, scheduled_at: nil)
|
|
10
|
+
def send(from:, to:, subject:, html: nil, text: nil, reply_to: nil, cc: nil, bcc: nil, tags: nil, scheduled_at: nil, from_name: nil)
|
|
11
11
|
body = { from: from, to: to, subject: subject }
|
|
12
|
+
body[:from_name] = from_name if from_name
|
|
12
13
|
body[:html] = html if html
|
|
13
14
|
body[:text] = text if text
|
|
14
|
-
body[:
|
|
15
|
+
body[:reply_to] = reply_to if reply_to
|
|
15
16
|
body[:cc] = cc if cc
|
|
16
17
|
body[:bcc] = bcc if bcc
|
|
17
18
|
body[:tags] = tags if tags
|
|
18
|
-
body[:
|
|
19
|
-
@client.
|
|
19
|
+
body[:scheduled_at] = scheduled_at if scheduled_at
|
|
20
|
+
@client.request_object(:post, "/emails", body)
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
def get(id)
|
|
23
|
-
@client.
|
|
24
|
+
@client.request_object(:get, "/emails/#{id}")
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
def list(cursor: nil, limit: nil, status: nil, from: nil, to: nil)
|
|
@@ -32,15 +33,15 @@ module Buchida
|
|
|
32
33
|
params[:to] = to if to
|
|
33
34
|
qs = URI.encode_www_form(params) unless params.empty?
|
|
34
35
|
path = qs ? "/emails?#{qs}" : "/emails"
|
|
35
|
-
@client.
|
|
36
|
+
@client.request_list(:get, path)
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
def cancel(id)
|
|
39
|
-
@client.
|
|
40
|
+
@client.request_object(:post, "/emails/#{id}/cancel")
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
def send_batch(emails)
|
|
43
|
-
@client.
|
|
44
|
+
@client.request_list(:post, "/emails/batch", emails)
|
|
44
45
|
end
|
|
45
46
|
end
|
|
46
47
|
end
|
|
@@ -8,10 +8,11 @@ module Buchida
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def get(from:, to:, granularity: nil)
|
|
11
|
-
|
|
11
|
+
# The API filters on from_date/to_date; plain from/to were silently ignored.
|
|
12
|
+
params = { from_date: from, to_date: to }
|
|
12
13
|
params[:granularity] = granularity if granularity
|
|
13
14
|
qs = URI.encode_www_form(params)
|
|
14
|
-
@client.
|
|
15
|
+
@client.request_object(:get, "/metrics?#{qs}")
|
|
15
16
|
end
|
|
16
17
|
end
|
|
17
18
|
end
|
|
@@ -8,11 +8,11 @@ module Buchida
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def list
|
|
11
|
-
@client.
|
|
11
|
+
@client.request_list(:get, "/templates")
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def get(id)
|
|
15
|
-
@client.
|
|
15
|
+
@client.request_object(:get, "/templates/#{id}")
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
end
|
|
@@ -8,11 +8,11 @@ module Buchida
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def create(url:, events:)
|
|
11
|
-
@client.
|
|
11
|
+
@client.request_object(:post, "/webhooks", { url: url, events: events })
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def list
|
|
15
|
-
@client.
|
|
15
|
+
@client.request_list(:get, "/webhooks")
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def delete(id)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Buchida
|
|
4
|
+
# Deprecation helper for the pre-0.2 raw-envelope access (`res["data"]`).
|
|
5
|
+
module Legacy
|
|
6
|
+
@warned = false
|
|
7
|
+
|
|
8
|
+
def self.warn_once(what)
|
|
9
|
+
return if @warned
|
|
10
|
+
|
|
11
|
+
@warned = true
|
|
12
|
+
Kernel.warn("[buchida] DEPRECATION: #{what} is deprecated. Since buchida 0.2 the SDK " \
|
|
13
|
+
"returns the unwrapped payload; use the result directly.")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.data_key?(key)
|
|
17
|
+
key == "data" || key == :data
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# An unwrapped single-object response (a Hash with String keys, as before).
|
|
22
|
+
# `result["data"]` / `result[:data]` still return the same object, with a one-time
|
|
23
|
+
# deprecation warning, so code written against the raw `{ "data" => {...} }` envelope keeps working.
|
|
24
|
+
# No self-reference is stored, so `to_json` / `JSON.generate` are unaffected.
|
|
25
|
+
class Result < Hash
|
|
26
|
+
REAL_KEY = Hash.instance_method(:key?)
|
|
27
|
+
|
|
28
|
+
def [](key)
|
|
29
|
+
if Legacy.data_key?(key) && !REAL_KEY.bind(self).call("data")
|
|
30
|
+
Legacy.warn_once("result[\"data\"]")
|
|
31
|
+
return self
|
|
32
|
+
end
|
|
33
|
+
super
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def key?(key)
|
|
37
|
+
Legacy.data_key?(key) || super
|
|
38
|
+
end
|
|
39
|
+
alias_method :has_key?, :key?
|
|
40
|
+
alias_method :include?, :key?
|
|
41
|
+
alias_method :member?, :key?
|
|
42
|
+
|
|
43
|
+
def fetch(key, *args, &block)
|
|
44
|
+
if Legacy.data_key?(key) && !REAL_KEY.bind(self).call("data")
|
|
45
|
+
Legacy.warn_once("result.fetch(\"data\")")
|
|
46
|
+
return self
|
|
47
|
+
end
|
|
48
|
+
super
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def dig(key, *rest)
|
|
52
|
+
value = self[key]
|
|
53
|
+
rest.empty? || value.nil? ? value : value.dig(*rest)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# An unwrapped list response: an Array of items plus `cursor` and `has_more`.
|
|
58
|
+
# The old envelope keys (`res["data"]`, `res["cursor"]`, `res["hasMore"]`) still work, with a
|
|
59
|
+
# one-time deprecation warning.
|
|
60
|
+
class ListResult < Array
|
|
61
|
+
attr_reader :cursor, :has_more
|
|
62
|
+
|
|
63
|
+
def initialize(items = [], cursor: nil, has_more: false)
|
|
64
|
+
super(items)
|
|
65
|
+
@cursor = cursor
|
|
66
|
+
@has_more = has_more
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def data
|
|
70
|
+
self
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def has_more?
|
|
74
|
+
@has_more ? true : false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
LEGACY_KEYS = %w[data cursor hasMore has_more].freeze
|
|
78
|
+
|
|
79
|
+
def self.legacy_key?(key)
|
|
80
|
+
(key.is_a?(String) || key.is_a?(Symbol)) && LEGACY_KEYS.include?(key.to_s)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def key?(key)
|
|
84
|
+
ListResult.legacy_key?(key)
|
|
85
|
+
end
|
|
86
|
+
alias_method :has_key?, :key?
|
|
87
|
+
|
|
88
|
+
def include?(item)
|
|
89
|
+
ListResult.legacy_key?(item) || super
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def fetch(key, *args, &block)
|
|
93
|
+
return self[key] if ListResult.legacy_key?(key)
|
|
94
|
+
|
|
95
|
+
super
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def dig(key, *rest)
|
|
99
|
+
if ListResult.legacy_key?(key)
|
|
100
|
+
value = self[key]
|
|
101
|
+
return rest.empty? || value.nil? ? value : value.dig(*rest)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
super
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def [](*args)
|
|
108
|
+
key = args.first
|
|
109
|
+
if args.length == 1 && (key.is_a?(String) || key.is_a?(Symbol))
|
|
110
|
+
case key.to_s
|
|
111
|
+
when "data" then (Legacy.warn_once("list[\"data\"]"); return self)
|
|
112
|
+
when "cursor" then (Legacy.warn_once("list[\"cursor\"]"); return @cursor)
|
|
113
|
+
when "hasMore", "has_more" then (Legacy.warn_once("list[\"hasMore\"]"); return @has_more)
|
|
114
|
+
end
|
|
115
|
+
return nil
|
|
116
|
+
end
|
|
117
|
+
super
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
data/lib/buchida/version.rb
CHANGED
data/lib/buchida.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: buchida
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- buchida
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-10-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|
|
@@ -54,6 +54,7 @@ files:
|
|
|
54
54
|
- lib/buchida/resources/metrics.rb
|
|
55
55
|
- lib/buchida/resources/templates.rb
|
|
56
56
|
- lib/buchida/resources/webhooks.rb
|
|
57
|
+
- lib/buchida/response.rb
|
|
57
58
|
- lib/buchida/version.rb
|
|
58
59
|
homepage: https://github.com/Vyblor/buchida-ruby
|
|
59
60
|
licenses:
|