buchida 0.1.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 +7 -0
- data/lib/buchida/client.rb +81 -0
- data/lib/buchida/errors.rb +37 -0
- data/lib/buchida/resources/api_keys.rb +23 -0
- data/lib/buchida/resources/domains.rb +27 -0
- data/lib/buchida/resources/emails.rb +47 -0
- data/lib/buchida/resources/metrics.rb +18 -0
- data/lib/buchida/resources/templates.rb +19 -0
- data/lib/buchida/resources/webhooks.rb +23 -0
- data/lib/buchida/version.rb +5 -0
- data/lib/buchida.rb +14 -0
- metadata +80 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: d609f12cc9ce58b4802a97f2b0bdb1e37150472571d7bb4f7165eab82a884eba
|
|
4
|
+
data.tar.gz: e6db0119d1dce466a631cbb23b99629a38038e5c72d8d58d49865bccd8ec6232
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 0bf53456137333f4e788a172820ad8995beba3d1a8b1233ed20107348d3a0b055410846d80756c7259764ffebcc1616b625d15e9fe973bec93af51d0a9cfe902
|
|
7
|
+
data.tar.gz: 9c06e7301bcb567579664b876a626f3e13f3e0eec85a981c2d4be49d19a81bffa1b7079d130a3f1b7a2346e4f7cda94e82041160b26bcb35d04686c72d33f4d7
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "uri"
|
|
5
|
+
require "json"
|
|
6
|
+
|
|
7
|
+
module Buchida
|
|
8
|
+
class Client
|
|
9
|
+
DEFAULT_BASE_URL = "https://api.buchida.com"
|
|
10
|
+
DEFAULT_TIMEOUT = 30
|
|
11
|
+
|
|
12
|
+
attr_reader :emails, :domains, :api_keys, :webhooks, :templates, :metrics
|
|
13
|
+
|
|
14
|
+
def initialize(api_key, base_url: DEFAULT_BASE_URL, timeout: DEFAULT_TIMEOUT)
|
|
15
|
+
raise ArgumentError, "API key is required" if api_key.nil? || api_key.empty?
|
|
16
|
+
|
|
17
|
+
@api_key = api_key
|
|
18
|
+
@base_url = base_url.chomp("/")
|
|
19
|
+
@timeout = timeout
|
|
20
|
+
|
|
21
|
+
@emails = Resources::Emails.new(self)
|
|
22
|
+
@domains = Resources::Domains.new(self)
|
|
23
|
+
@api_keys = Resources::ApiKeys.new(self)
|
|
24
|
+
@webhooks = Resources::Webhooks.new(self)
|
|
25
|
+
@templates = Resources::Templates.new(self)
|
|
26
|
+
@metrics = Resources::Metrics.new(self)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def request(method, path, body = nil)
|
|
30
|
+
uri = URI("#{@base_url}#{path}")
|
|
31
|
+
|
|
32
|
+
req = case method
|
|
33
|
+
when :get then Net::HTTP::Get.new(uri)
|
|
34
|
+
when :post then Net::HTTP::Post.new(uri)
|
|
35
|
+
when :delete then Net::HTTP::Delete.new(uri)
|
|
36
|
+
else raise ArgumentError, "Unsupported method: #{method}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
req["Authorization"] = "Bearer #{@api_key}"
|
|
40
|
+
req["Content-Type"] = "application/json"
|
|
41
|
+
req["User-Agent"] = "buchida-ruby/#{VERSION}"
|
|
42
|
+
req.body = JSON.generate(body) if body
|
|
43
|
+
|
|
44
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
45
|
+
http.use_ssl = uri.scheme == "https"
|
|
46
|
+
http.open_timeout = @timeout
|
|
47
|
+
http.read_timeout = @timeout
|
|
48
|
+
|
|
49
|
+
response = http.request(req)
|
|
50
|
+
|
|
51
|
+
unless response.is_a?(Net::HTTPSuccess) || response.code == "204"
|
|
52
|
+
handle_error(response)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
return nil if response.code == "204" || response.body.nil? || response.body.empty?
|
|
56
|
+
|
|
57
|
+
JSON.parse(response.body)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def handle_error(response)
|
|
63
|
+
body = begin
|
|
64
|
+
JSON.parse(response.body)
|
|
65
|
+
rescue
|
|
66
|
+
{ "message" => response.message }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
message = body["message"] || response.message
|
|
70
|
+
status = response.code.to_i
|
|
71
|
+
|
|
72
|
+
case status
|
|
73
|
+
when 401 then raise AuthenticationError, message
|
|
74
|
+
when 404 then raise NotFoundError, message
|
|
75
|
+
when 422 then raise ValidationError, message
|
|
76
|
+
when 429 then raise RateLimitError, message
|
|
77
|
+
else raise Error.new(message, status, body["code"])
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Buchida
|
|
4
|
+
class Error < StandardError
|
|
5
|
+
attr_reader :status_code, :code
|
|
6
|
+
|
|
7
|
+
def initialize(message, status_code, code = nil)
|
|
8
|
+
super(message)
|
|
9
|
+
@status_code = status_code
|
|
10
|
+
@code = code
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class AuthenticationError < Error
|
|
15
|
+
def initialize(message = "Invalid API key")
|
|
16
|
+
super(message, 401, "authentication_error")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class RateLimitError < Error
|
|
21
|
+
def initialize(message = "Rate limit exceeded")
|
|
22
|
+
super(message, 429, "rate_limit_error")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class NotFoundError < Error
|
|
27
|
+
def initialize(message = "Resource not found")
|
|
28
|
+
super(message, 404, "not_found")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class ValidationError < Error
|
|
33
|
+
def initialize(message = "Validation failed")
|
|
34
|
+
super(message, 422, "validation_error")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Buchida
|
|
4
|
+
module Resources
|
|
5
|
+
class ApiKeys
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create(name:, permission:)
|
|
11
|
+
@client.request(:post, "/api-keys", { name: name, permission: permission })
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def list
|
|
15
|
+
@client.request(:get, "/api-keys")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def delete(id)
|
|
19
|
+
@client.request(:delete, "/api-keys/#{id}")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Buchida
|
|
4
|
+
module Resources
|
|
5
|
+
class Domains
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create(name:)
|
|
11
|
+
@client.request(:post, "/domains", { name: name })
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def list
|
|
15
|
+
@client.request(:get, "/domains")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def get(id)
|
|
19
|
+
@client.request(:get, "/domains/#{id}")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def verify(id)
|
|
23
|
+
@client.request(:post, "/domains/#{id}/verify")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Buchida
|
|
4
|
+
module Resources
|
|
5
|
+
class Emails
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def send(from:, to:, subject:, html: nil, text: nil, reply_to: nil, cc: nil, bcc: nil, tags: nil, scheduled_at: nil)
|
|
11
|
+
body = { from: from, to: to, subject: subject }
|
|
12
|
+
body[:html] = html if html
|
|
13
|
+
body[:text] = text if text
|
|
14
|
+
body[:replyTo] = reply_to if reply_to
|
|
15
|
+
body[:cc] = cc if cc
|
|
16
|
+
body[:bcc] = bcc if bcc
|
|
17
|
+
body[:tags] = tags if tags
|
|
18
|
+
body[:scheduledAt] = scheduled_at if scheduled_at
|
|
19
|
+
@client.request(:post, "/emails", body)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get(id)
|
|
23
|
+
@client.request(:get, "/emails/#{id}")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def list(cursor: nil, limit: nil, status: nil, from: nil, to: nil)
|
|
27
|
+
params = {}
|
|
28
|
+
params[:cursor] = cursor if cursor
|
|
29
|
+
params[:limit] = limit if limit
|
|
30
|
+
params[:status] = status if status
|
|
31
|
+
params[:from] = from if from
|
|
32
|
+
params[:to] = to if to
|
|
33
|
+
qs = URI.encode_www_form(params) unless params.empty?
|
|
34
|
+
path = qs ? "/emails?#{qs}" : "/emails"
|
|
35
|
+
@client.request(:get, path)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def cancel(id)
|
|
39
|
+
@client.request(:post, "/emails/#{id}/cancel")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def send_batch(emails)
|
|
43
|
+
@client.request(:post, "/emails/batch", emails)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Buchida
|
|
4
|
+
module Resources
|
|
5
|
+
class Metrics
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def get(from:, to:, granularity: nil)
|
|
11
|
+
params = { from: from, to: to }
|
|
12
|
+
params[:granularity] = granularity if granularity
|
|
13
|
+
qs = URI.encode_www_form(params)
|
|
14
|
+
@client.request(:get, "/metrics?#{qs}")
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Buchida
|
|
4
|
+
module Resources
|
|
5
|
+
class Templates
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def list
|
|
11
|
+
@client.request(:get, "/templates")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get(id)
|
|
15
|
+
@client.request(:get, "/templates/#{id}")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Buchida
|
|
4
|
+
module Resources
|
|
5
|
+
class Webhooks
|
|
6
|
+
def initialize(client)
|
|
7
|
+
@client = client
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create(url:, events:)
|
|
11
|
+
@client.request(:post, "/webhooks", { url: url, events: events })
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def list
|
|
15
|
+
@client.request(:get, "/webhooks")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def delete(id)
|
|
19
|
+
@client.request(:delete, "/webhooks/#{id}")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/lib/buchida.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "buchida/version"
|
|
4
|
+
require_relative "buchida/errors"
|
|
5
|
+
require_relative "buchida/client"
|
|
6
|
+
require_relative "buchida/resources/emails"
|
|
7
|
+
require_relative "buchida/resources/domains"
|
|
8
|
+
require_relative "buchida/resources/api_keys"
|
|
9
|
+
require_relative "buchida/resources/webhooks"
|
|
10
|
+
require_relative "buchida/resources/templates"
|
|
11
|
+
require_relative "buchida/resources/metrics"
|
|
12
|
+
|
|
13
|
+
module Buchida
|
|
14
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: buchida
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- buchida
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-04-02 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: minitest
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '5.0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '5.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: webmock
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '3.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '3.0'
|
|
41
|
+
description: Ruby client for the buchida email API with CJK-first template support.
|
|
42
|
+
email: hello@buchida.com
|
|
43
|
+
executables: []
|
|
44
|
+
extensions: []
|
|
45
|
+
extra_rdoc_files: []
|
|
46
|
+
files:
|
|
47
|
+
- lib/buchida.rb
|
|
48
|
+
- lib/buchida/client.rb
|
|
49
|
+
- lib/buchida/errors.rb
|
|
50
|
+
- lib/buchida/resources/api_keys.rb
|
|
51
|
+
- lib/buchida/resources/domains.rb
|
|
52
|
+
- lib/buchida/resources/emails.rb
|
|
53
|
+
- lib/buchida/resources/metrics.rb
|
|
54
|
+
- lib/buchida/resources/templates.rb
|
|
55
|
+
- lib/buchida/resources/webhooks.rb
|
|
56
|
+
- lib/buchida/version.rb
|
|
57
|
+
homepage: https://github.com/Vyblor/buchida-ruby
|
|
58
|
+
licenses:
|
|
59
|
+
- MIT
|
|
60
|
+
metadata: {}
|
|
61
|
+
post_install_message:
|
|
62
|
+
rdoc_options: []
|
|
63
|
+
require_paths:
|
|
64
|
+
- lib
|
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: 3.2.0
|
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
requirements: []
|
|
76
|
+
rubygems_version: 3.5.3
|
|
77
|
+
signing_key:
|
|
78
|
+
specification_version: 4
|
|
79
|
+
summary: Official Ruby SDK for buchida email API
|
|
80
|
+
test_files: []
|