keplars 2.8.0 → 2.9.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: 34db333b47bda0dbd67ccd1173e40bba96006f5760ea039f909cff188f2baedf
4
- data.tar.gz: abd282d486bd30dbed467b4f458c59cefadb5e466824c3e524840a1bb7db9483
3
+ metadata.gz: 3c9f27c62fc254b42974354edc4e138d253a05b0367eb1276f9999125810e7e9
4
+ data.tar.gz: 1cc364a65c48a1676b3d0fc82a511cf671efe84aae50127b7017907917ef1bbd
5
5
  SHA512:
6
- metadata.gz: 4555943f4670d58e9ecaa4d9b1c54ceb3fc91fac339f81956554252d253c517acab48f875d6b107ad3e852cecb5a84a91ce13b11e0fcc1b1edf68f3192273f41
7
- data.tar.gz: 921934717da2466ac5c74f2c39e9cf61394d85e42c83eb1ff47c5b6a766c5a8baa160e960b29c4dcc08c09021a96ed905bd62677e4416ecf338abdb770ac7f84
6
+ metadata.gz: 2bb04146d158a84e30a28220d06c6ab4308c37aabc4391cd8e9ad3871198e40ea71a92254ef827b1c466237613eee519884217fbfc6f61b8a412aeb5411ddaa9
7
+ data.tar.gz: 9fd4acb85ed648d3bf8babd7a5f2d345599bcfa9db8091fb1da3e710cd5377e52c7f804d3708468475414de7e45de28e03d440d3fb509b9d08b9d8389518142c
data/README.md CHANGED
@@ -46,6 +46,26 @@ puts result[:data][:job_id]
46
46
  | Regular | `kms_<id>.live_<secret>` | Email sending |
47
47
  | Admin | `kms_<id>.adm_<secret>` | Contacts, audiences, automations, domains |
48
48
 
49
+ ### Using Both Send and Admin Operations
50
+
51
+ Pass `admin_key:` alongside a live `api_key:` to use a single client for both:
52
+
53
+ ```ruby
54
+ client = Keplars::Client.new(
55
+ api_key: 'kms_<id>.live_<secret>',
56
+ admin_key: 'kms_<id>.adm_<secret>'
57
+ )
58
+
59
+ client.emails.send_instant(...) # uses api_key
60
+ client.audiences.list # uses admin_key
61
+ ```
62
+
63
+ If you only have an admin key, pass it as `api_key:` directly:
64
+
65
+ ```ruby
66
+ client = Keplars::Client.new(api_key: 'kms_<id>.adm_<secret>')
67
+ ```
68
+
49
69
  ## Email Sending
50
70
 
51
71
  ### Priority Levels
@@ -4,7 +4,7 @@ module Keplars
4
4
  def create(name:, description: nil)
5
5
  body = { name: name }
6
6
  body[:description] = description if description
7
- @client.request('POST', '/api/v1/public/audiences/add-audience', body: body)[:data]
7
+ @client.request('POST', '/api/v1/public/audiences/add-audience', body: body, is_admin: true)[:data]
8
8
  end
9
9
 
10
10
  def list(page: nil, limit: nil, sort_by: nil, sort_dir: nil)
@@ -15,15 +15,15 @@ module Keplars
15
15
  params[:sortDir] = sort_dir if sort_dir
16
16
 
17
17
  query = @client.send(:build_query_string, params)
18
- @client.request('GET', "/api/v1/public/audiences/get-audiences#{query}")[:data]
18
+ @client.request('GET', "/api/v1/public/audiences/get-audiences#{query}", is_admin: true)[:data]
19
19
  end
20
20
 
21
21
  def get(id)
22
- @client.request('GET', "/api/v1/public/audiences/get-audience?id=#{URI.encode_www_form_component(id)}")[:data]
22
+ @client.request('GET', "/api/v1/public/audiences/get-audience?id=#{URI.encode_www_form_component(id)}", is_admin: true)[:data]
23
23
  end
24
24
 
25
25
  def delete(id)
26
- @client.request('DELETE', "/api/v1/public/audiences/delete-audience?id=#{URI.encode_www_form_component(id)}")[:data]
26
+ @client.request('DELETE', "/api/v1/public/audiences/delete-audience?id=#{URI.encode_www_form_component(id)}", is_admin: true)[:data]
27
27
  end
28
28
  end
29
29
  end
@@ -7,27 +7,27 @@ module Keplars
7
7
  params[:limit] = limit if limit
8
8
 
9
9
  query = @client.send(:build_query_string, params)
10
- @client.request('GET', "/api/v1/public/automations/get-all#{query}")[:data]
10
+ @client.request('GET', "/api/v1/public/automations/get-all#{query}", is_admin: true)[:data]
11
11
  end
12
12
 
13
13
  def get(id)
14
- @client.request('GET', "/api/v1/public/automations/get-automation/#{id}")[:data]
14
+ @client.request('GET', "/api/v1/public/automations/get-automation/#{id}", is_admin: true)[:data]
15
15
  end
16
16
 
17
17
  def enroll(id, email:, properties: nil)
18
18
  body = { email: email }
19
19
  body[:properties] = properties if properties
20
- @client.request('POST', "/api/v1/public/automations/add-automation/#{id}/enroll", body: body)[:data]
20
+ @client.request('POST', "/api/v1/public/automations/add-automation/#{id}/enroll", body: body, is_admin: true)[:data]
21
21
  end
22
22
 
23
23
  def unenroll(id, email:)
24
- @client.request('DELETE', "/api/v1/public/automations/delete-automation/#{id}/subscribers", body: { email: email })[:data]
24
+ @client.request('DELETE', "/api/v1/public/automations/delete-automation/#{id}/subscribers", body: { email: email }, is_admin: true)[:data]
25
25
  end
26
26
 
27
27
  def track_event(email, event_name, event_properties: nil)
28
28
  body = { email: email, event_name: event_name }
29
29
  body[:event_properties] = event_properties if event_properties
30
- @client.request('POST', '/api/v1/public/automations/events/track', body: body)[:data]
30
+ @client.request('POST', '/api/v1/public/automations/events/track', body: body, is_admin: true)[:data]
31
31
  end
32
32
  end
33
33
  end
@@ -11,7 +11,7 @@ module Keplars
11
11
 
12
12
  attr_reader :emails, :contacts, :audiences, :automations, :domains
13
13
 
14
- def initialize(api_key: nil, base_url: nil, timeout: DEFAULT_TIMEOUT, max_retries: DEFAULT_MAX_RETRIES, retry_delay: DEFAULT_RETRY_DELAY)
14
+ def initialize(api_key: nil, admin_key: nil, base_url: nil, timeout: DEFAULT_TIMEOUT, max_retries: DEFAULT_MAX_RETRIES, retry_delay: DEFAULT_RETRY_DELAY)
15
15
  @api_key = api_key || ENV['KEPLARS_API_KEY']
16
16
  raise ArgumentError, 'API key is required. Set KEPLARS_API_KEY or pass api_key parameter' if @api_key.nil? || @api_key.empty?
17
17
 
@@ -19,6 +19,11 @@ module Keplars
19
19
  raise ArgumentError, 'Invalid API key format. Expected: kms_<id>.live_<secret> or kms_<id>.adm_<secret>'
20
20
  end
21
21
 
22
+ if admin_key
23
+ raise ArgumentError, 'Invalid adminKey format. Expected: kms_<id>.adm_<secret>' unless admin_key.match?(/\Akms_[a-f0-9]+\.adm_[a-f0-9]+\z/)
24
+ @admin_key = admin_key
25
+ end
26
+
22
27
  resolved_base_url = base_url || ENV['KEPLARS_BASE_URL'] || DEFAULT_BASE_URL
23
28
  @base_url = resolved_base_url.sub(/\/$/, '')
24
29
  @timeout = timeout
@@ -32,7 +37,7 @@ module Keplars
32
37
  @domains = Resources::Domains.new(self)
33
38
  end
34
39
 
35
- def request(method, path, body: nil, retry_count: 0)
40
+ def request(method, path, body: nil, retry_count: 0, is_admin: false)
36
41
  uri = URI("#{@base_url}#{path}")
37
42
 
38
43
  http = Net::HTTP.new(uri.host, uri.port)
@@ -50,7 +55,7 @@ module Keplars
50
55
  end
51
56
 
52
57
  request = request_class.new(uri.request_uri)
53
- request['Authorization'] = "Bearer #{@api_key}"
58
+ request['Authorization'] = "Bearer #{get_auth_key(is_admin)}"
54
59
  request['Content-Type'] = 'application/json'
55
60
  request['User-Agent'] = "keplars-ruby/#{VERSION}"
56
61
 
@@ -72,7 +77,7 @@ module Keplars
72
77
  if retryable_error?(e) && retry_count < @max_retries
73
78
  delay = calculate_backoff(retry_count)
74
79
  sleep(delay)
75
- request(method, path, body: body, retry_count: retry_count + 1)
80
+ request(method, path, body: body, retry_count: retry_count + 1, is_admin: is_admin)
76
81
  else
77
82
  raise NetworkError.new("Request failed: #{e.message}", original_error: e)
78
83
  end
@@ -81,6 +86,14 @@ module Keplars
81
86
 
82
87
  private
83
88
 
89
+ def get_auth_key(is_admin)
90
+ return @api_key unless is_admin
91
+ return @admin_key if @admin_key
92
+ return @api_key if @api_key.match?(/\Akms_[a-f0-9]+\.adm_[a-f0-9]+\z/)
93
+
94
+ raise AuthorizationError.new('Admin key required for this operation. Provide admin_key in config.', request_id: nil)
95
+ end
96
+
84
97
  def extract_rate_limit_info(response)
85
98
  limit = response['X-RateLimit-Limit']
86
99
  remaining = response['X-RateLimit-Remaining']
@@ -2,12 +2,12 @@ module Keplars
2
2
  module Resources
3
3
  class Contacts < Base
4
4
  def add(**params)
5
- @client.request('POST', '/api/v1/public/contacts/add-contact', body: params.compact)[:data]
5
+ @client.request('POST', '/api/v1/public/contacts/add-contact', body: params.compact, is_admin: true)[:data]
6
6
  end
7
7
 
8
8
  def get(email_or_id)
9
9
  param = email_or_id.include?('@') ? 'email' : 'id'
10
- @client.request('GET', "/api/v1/public/contacts/get-contact?#{param}=#{URI.encode_www_form_component(email_or_id)}")[:data]
10
+ @client.request('GET', "/api/v1/public/contacts/get-contact?#{param}=#{URI.encode_www_form_component(email_or_id)}", is_admin: true)[:data]
11
11
  end
12
12
 
13
13
  def list(audience_id: nil, page: nil, limit: nil, sort_by: nil, sort_dir: nil, subscribed_only: nil)
@@ -20,7 +20,7 @@ module Keplars
20
20
  params[:subscribedOnly] = subscribed_only.to_s if !subscribed_only.nil?
21
21
 
22
22
  query = @client.send(:build_query_string, params)
23
- @client.request('GET', "/api/v1/public/contacts/get-contacts#{query}")[:data]
23
+ @client.request('GET', "/api/v1/public/contacts/get-contacts#{query}", is_admin: true)[:data]
24
24
  end
25
25
 
26
26
  def update(id_or_email, **params)
@@ -30,7 +30,7 @@ module Keplars
30
30
  else
31
31
  param = 'id'
32
32
  end
33
- @client.request('PATCH', "/api/v1/public/contacts/update-contact?#{param}=#{URI.encode_www_form_component(id_or_email)}", body: params.compact)[:data]
33
+ @client.request('PATCH', "/api/v1/public/contacts/update-contact?#{param}=#{URI.encode_www_form_component(id_or_email)}", body: params.compact, is_admin: true)[:data]
34
34
  end
35
35
 
36
36
  def delete(id_or_email)
@@ -40,7 +40,7 @@ module Keplars
40
40
  else
41
41
  param = 'id'
42
42
  end
43
- @client.request('DELETE', "/api/v1/public/contacts/delete-contact?#{param}=#{URI.encode_www_form_component(id_or_email)}")[:data]
43
+ @client.request('DELETE', "/api/v1/public/contacts/delete-contact?#{param}=#{URI.encode_www_form_component(id_or_email)}", is_admin: true)[:data]
44
44
  end
45
45
  end
46
46
  end
@@ -4,23 +4,23 @@ module Keplars
4
4
  def add(domain, region: nil)
5
5
  body = { domain: domain }
6
6
  body[:region] = region if region
7
- @client.request('POST', '/api/v1/public/domains/add-domain', body: body)[:data]
7
+ @client.request('POST', '/api/v1/public/domains/add-domain', body: body, is_admin: true)[:data]
8
8
  end
9
9
 
10
10
  def list
11
- @client.request('GET', '/api/v1/public/domains/get-domains')[:data]
11
+ @client.request('GET', '/api/v1/public/domains/get-domains', is_admin: true)[:data]
12
12
  end
13
13
 
14
14
  def get_status(domain_id)
15
- @client.request('GET', "/api/v1/public/domains/domain-status/#{domain_id}")[:data]
15
+ @client.request('GET', "/api/v1/public/domains/domain-status/#{domain_id}", is_admin: true)[:data]
16
16
  end
17
17
 
18
18
  def verify(domain_id)
19
- @client.request('POST', "/api/v1/public/domains/verify-domain/#{domain_id}")[:data]
19
+ @client.request('POST', "/api/v1/public/domains/verify-domain/#{domain_id}", is_admin: true)[:data]
20
20
  end
21
21
 
22
22
  def delete(domain_id)
23
- @client.request('DELETE', "/api/v1/public/domains/delete-domain/#{domain_id}")[:data]
23
+ @client.request('DELETE', "/api/v1/public/domains/delete-domain/#{domain_id}", is_admin: true)[:data]
24
24
  end
25
25
 
26
26
  def create_api_key(**params)
@@ -29,7 +29,7 @@ module Keplars
29
29
  warn '[Keplars] Deprecated: :domain_id is deprecated since v2.7.0. Use :custom_domain_id instead.'
30
30
  body[:custom_domain_id] = body.delete(:domain_id)
31
31
  end
32
- @client.request('POST', '/api/v1/public/domains/api-keys/create', body: body.compact)[:data]
32
+ @client.request('POST', '/api/v1/public/domains/api-keys/create', body: body.compact, is_admin: true)[:data]
33
33
  end
34
34
  end
35
35
  end
@@ -1,3 +1,3 @@
1
1
  module Keplars
2
- VERSION = "2.8.0"
2
+ VERSION = "2.9.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keplars
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.0
4
+ version: 2.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keplars
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-08-13 00:00:00.000000000 Z
11
+ date: 2026-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday