proxy-cheap-client 1.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 72af370a7a949355facabddfef0d1bf5ec5221303ce4314e287f66cb96b1750c
4
+ data.tar.gz: bd3e0d5c6cc1bfd9adbf66abe2e01dc4fd0e2156fd0fe3c3f5544692effdf7a5
5
+ SHA512:
6
+ metadata.gz: 1f51ba931aa10bfe72a7604c6681b3c63812053353ba01a6056c8854aba7904237506faea69ac0ac3739798e87bfa6284848733125fbb376e9f1d16f009b212d
7
+ data.tar.gz: 1f01a397a39b39380014d66bddcdf4289d508b23cb5adbce4557e39bae33745959ef43b6cb9ce96169b6d6242b485dc28c2ba79116163ee7b510d2fac5580d6a
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 MassProspecting
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,166 @@
1
+ # proxy-cheap-client
2
+
3
+ Ruby client for the Proxy-Cheap.com API.
4
+
5
+ [![Gem Version](https://img.shields.io/gem/v/proxy-cheap-client.svg)](https://rubygems.org/gems/proxy-cheap-client) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE.txt)
6
+
7
+ ## Features
8
+
9
+ * Retrieve account balance
10
+ * List proxies
11
+ * Enable/disable auto-extend on proxies
12
+ * Order new residential proxies
13
+
14
+ ## Requirements
15
+
16
+ * Ruby 2.7+
17
+ * Internet access to Proxy-Cheap.com API
18
+ * API key and API secret from Proxy-Cheap.com
19
+
20
+ ## Installation
21
+
22
+ Install from RubyGems:
23
+
24
+ ```bash
25
+ gem install proxy-cheap-client
26
+ ```
27
+
28
+ Or add to your `Gemfile`:
29
+
30
+ ```ruby
31
+ gem "proxy-cheap-client"
32
+ ```
33
+
34
+ Then run:
35
+
36
+ ```bash
37
+ bundle install
38
+ ```
39
+
40
+ ## Configuration
41
+
42
+ The client requires both an API key and API secret.
43
+
44
+ You have to pass them explicitly when initializing the client:
45
+
46
+ ```ruby
47
+ client = ProxyCheapClient::Client.new(
48
+ api_key: "your_api_key_here",
49
+ api_secret: "your_api_secret_here"
50
+ )
51
+ ```
52
+
53
+ ## Usage Example
54
+
55
+ ```ruby
56
+ require "proxy_cheap_client"
57
+
58
+ client = ProxyCheapClient::Client.new(
59
+ api_key: "your_api_key_here",
60
+ api_secret: "your_api_secret_here"
61
+ )
62
+
63
+ # 1. Get balance
64
+ balance = client.balance
65
+ puts "Balance: #{balance.amount} #{balance.currency}"
66
+ ```
67
+
68
+ ## Load Proxies
69
+
70
+ ```ruby
71
+ proxies = client.proxies
72
+ proxies.each do |p|
73
+ puts "Proxy #{p.id}: #{p.ip}:#{p.port}, auto_extend=#{p.auto_extend}"
74
+ end
75
+ ```
76
+
77
+ ## Load Specific Proxy
78
+
79
+ ```ruby
80
+ proxy = ProxyCheapClient::Proxy.load(12345)
81
+ puts "Proxy details: #{proxy.to_h}"
82
+ ```
83
+
84
+ ## Enable auto-extend for a proxy
85
+
86
+ ```ruby
87
+ proxy.enable_auto_extend
88
+ puts "Auto-extend enabled"
89
+ ```
90
+
91
+ ## Disable auto-extend
92
+
93
+ ```ruby
94
+ proxy.disable_auto_extend
95
+ puts "Auto-extend disabled"
96
+ ```
97
+
98
+ ## Supported Countries
99
+
100
+ ```ruby
101
+ arr = client.countries
102
+ puts "Supported Countries: #{arr}"
103
+ ```
104
+
105
+ ## Order Residential Proxies
106
+
107
+ ```ruby
108
+ order = client.order_static_residential_proxy(
109
+ country: "US",
110
+ proxyProtocol: "HTTP",
111
+ authenticationType: "USERNAME_PASSWORD"
112
+ )
113
+ ```
114
+
115
+ ## Order Proxies
116
+
117
+ ```ruby
118
+ order.proxies
119
+ ```
120
+
121
+ ## Error Handling
122
+
123
+ The client raises specific exceptions for failure modes:
124
+
125
+ * `ProxyCheapClient::AuthenticationError` - API key or secret is missing or invalid (HTTP 401)
126
+ * `ProxyCheapClient::NotFoundError` - Resource does not exist (HTTP 404)
127
+ * `ProxyCheapClient::BadRequestError` - Invalid request parameters (HTTP 400)
128
+ * `ProxyCheapClient::ServerError` - Server-side error (HTTP 5xx)
129
+ * `ProxyCheapClient::RequestError` - General request failure
130
+ * `ProxyCheapClient::InvalidResponseError` - Malformed or non-JSON response
131
+
132
+ All errors inherit from `ProxyCheapClient::Error` and include `status_code` and `response_body` attributes for debugging:
133
+
134
+ ```ruby
135
+ begin
136
+ client.balance
137
+ rescue ProxyCheapClient::NotFoundError => e
138
+ puts "Not found: #{e.message}"
139
+ puts "Status: #{e.status_code}"
140
+ puts "Body: #{e.response_body}"
141
+ rescue ProxyCheapClient::Error => e
142
+ puts "API failure: #{e.message}"
143
+ end
144
+ ```
145
+
146
+ ## Publishing
147
+
148
+ Build and push to RubyGems:
149
+
150
+ ```bash
151
+ gem build proxy-cheap-client.gemspec
152
+ gem push proxy-cheap-client-#{ProxyCheapClient::VERSION}.gem
153
+ ```
154
+
155
+ Make sure you have an account on RubyGems.org and appropriate credentials configured in `~/.gem/credentials`.
156
+
157
+ ## Contributing
158
+
159
+ 1. Fork the repository.
160
+ 2. Create a feature branch: `git checkout -b feature/xyz`
161
+ 3. Run tests (add test suite if missing).
162
+ 4. Open a pull request with a clear description.
163
+
164
+ ## License
165
+
166
+ This project is licensed under the MIT License. See `LICENSE.txt` for details.
@@ -0,0 +1,4 @@
1
+ gem 'faraday', '2.3.0'
2
+ gem 'faraday-net_http', '2.1.0'
3
+ require_relative "proxy_cheap_client/client"
4
+
@@ -0,0 +1,132 @@
1
+ require "faraday"
2
+ require "json"
3
+ require_relative "version"
4
+ require_relative "errors"
5
+ require_relative "models/base"
6
+ require_relative "models/balance"
7
+ require_relative "models/proxy"
8
+ require_relative "models/order"
9
+ require_relative "models/configuration"
10
+
11
+ module ProxyCheapClient
12
+ class Client < Base
13
+ API_BASE = "https://api.proxy-cheap.com"
14
+
15
+ # Initialize the client with API credentials.
16
+ # @param api_key [String] API key (or set PROXY_CHEAP_API_KEY env var)
17
+ # @param api_secret [String] API secret (or set PROXY_CHEAP_API_SECRET env var)
18
+ # @param timeout [Integer] Request timeout in seconds (default: 10)
19
+ def initialize(
20
+ api_key:,
21
+ api_secret:,
22
+ timeout: 10
23
+ )
24
+ @api_key = api_key
25
+ @api_secret = api_secret
26
+
27
+ raise AuthenticationError, "API key missing" unless @api_key && !@api_key.strip.empty?
28
+ raise AuthenticationError, "API secret missing" unless @api_secret && !@api_secret.strip.empty?
29
+
30
+ @conn = Faraday.new(url: API_BASE) do |f|
31
+ f.request :json
32
+ f.response :raise_error
33
+ f.options.timeout = timeout
34
+ f.headers["X-Api-Key"] = @api_key
35
+ f.headers["X-Api-Secret"] = @api_secret
36
+ f.headers["Content-Type"] = "application/json"
37
+ f.adapter Faraday.default_adapter
38
+ end
39
+ rescue Faraday::Error => e
40
+ raise RequestError, "Connection failure: #{e.message}"
41
+ end
42
+
43
+ def conn
44
+ @conn
45
+ end
46
+
47
+ # retrieve the array of countries with number of available proxies per country
48
+ def countries
49
+ config = self.configuration(
50
+ networkType: "RESIDENTIAL_STATIC",
51
+ ipVersion: "IPv4",
52
+ country: "US",
53
+ proxyProtocol: "HTTP",
54
+ authenticationType: "USERNAME_PASSWORD",
55
+ quantity: 1
56
+ )
57
+ config.data["supportedCountries"]
58
+ end
59
+
60
+ # Get user balance.
61
+ # @return [Balance]
62
+ def balance
63
+ resp = request(:get, "account/balance")
64
+ Balance.new(resp, self)
65
+ end
66
+
67
+ # Get all user proxies.
68
+ # @return [Array<Proxy>]
69
+ def proxies
70
+ resp = request(:get, "proxies")
71
+ # API may return proxies directly as an array or wrapped in a "data" key
72
+ proxy_list = resp.is_a?(Hash) && resp.key?("data") ? resp["data"] : resp
73
+ proxy_list = resp.is_a?(Hash) && resp.key?("proxies") ? resp["proxies"] : resp
74
+ Array(proxy_list).map { |p| Proxy.new(p, self) }
75
+ end
76
+
77
+ # Convenience method to order a static residential proxy.
78
+ # @param params [Hash] Order parameters
79
+ # @option params [String] :country 2 letter country code (required)
80
+ # @option params [String] :isp ISP id
81
+ # @option params [String] :proxyProtocol HTTP, HTTPS, SOCKS5 (default: HTTP)
82
+ # @option params [String] :authenticationType USERNAME_PASSWORD or IP_WHITELIST
83
+ # @option params [Integer] :quantity number of proxies (default: 1)
84
+ # @return [Order]
85
+ def order_static_residential_proxy(params = {})
86
+ order_params = {
87
+ networkType: "RESIDENTIAL_STATIC",
88
+ ipVersion: "IPv4"
89
+ }.merge(params)
90
+ order(order_params)
91
+ end # def order_static_residential_proxy
92
+
93
+ private
94
+
95
+ # Get configuration/pricing according to filter parameters.
96
+ # Use this to preview an order before executing it.
97
+ # @param params [Hash] Configuration parameters
98
+ # @option params [String] :networkType MOBILE, DATACENTER, RESIDENTIAL, RESIDENTIAL_STATIC
99
+ # @option params [String] :ipVersion IPv4, IPv6, MOBILE
100
+ # @option params [String] :country 2 letter country code
101
+ # @option params [String] :region 2 letter region code
102
+ # @option params [String] :isp ISP id
103
+ # @option params [String] :proxyProtocol HTTP, HTTPS, SOCKS5
104
+ # @option params [String] :authenticationType USERNAME_PASSWORD, IP_WHITELIST
105
+ # @option params [Array<String>] :ipWhitelist whitelisted IPs
106
+ # @option params [String] :package package id
107
+ # @option params [Integer] :quantity proxies amount
108
+ # @option params [String] :couponCode order promo code
109
+ # @option params [Integer] :bandwidth amount in GB
110
+ # @option params [Boolean] :isAutoExtendEnabled enables auto extend
111
+ # @option params [Integer] :autoExtendBandwidth how many GB to extend
112
+ # @return [Configuration]
113
+ def configuration(params = {})
114
+ resp = request(:post, "order/configuration", params)
115
+ Configuration.new(resp, self)
116
+ end # def configuration
117
+
118
+ # Execute an order with the given configuration.
119
+ # Use `configuration` first to preview the order.
120
+ # @param params [Hash] Same parameters as `configuration`
121
+ # @return [Order]
122
+ def order(params = {})
123
+ resp = request(:post, "order/execute", params)
124
+ # {"id"=>"019aebab-7635-79e1-ba1f-95118dc12695",
125
+ # "periodInMonths"=>"1",
126
+ # "totalPrice"=>"3.39"}
127
+
128
+ # Return order model (API returns order descriptor including id/status)
129
+ Order.new(resp, self)
130
+ end # def order
131
+ end # class Client
132
+ end # module ProxyCheapClient
@@ -0,0 +1,18 @@
1
+ module ProxyCheapClient
2
+ class Error < StandardError
3
+ attr_reader :status_code, :response_body
4
+
5
+ def initialize(message = nil, status_code: nil, response_body: nil)
6
+ @status_code = status_code
7
+ @response_body = response_body
8
+ super(message)
9
+ end
10
+ end
11
+
12
+ class AuthenticationError < Error; end
13
+ class RequestError < Error; end
14
+ class NotFoundError < Error; end
15
+ class BadRequestError < Error; end
16
+ class ServerError < Error; end
17
+ class InvalidResponseError < Error; end
18
+ end
@@ -0,0 +1,17 @@
1
+ module ProxyCheapClient
2
+ #module Models
3
+ class Balance < Base
4
+ attr_reader :amount, :currency, :conn
5
+
6
+ def initialize(attrs = {}, client)
7
+ @amount = attrs["balance"] || attrs["amount"]
8
+ @currency = attrs["currency"] || "USD"
9
+ @conn = client.conn
10
+ end
11
+
12
+ def to_h
13
+ { amount: amount, currency: currency }
14
+ end
15
+ end
16
+ #end
17
+ end
@@ -0,0 +1,87 @@
1
+ module ProxyCheapClient
2
+ class Base
3
+ # Make an HTTP request to the API.
4
+ # @note Some API endpoints (whitelist, extend-period, buy-bandwidth) use GET
5
+ # requests with JSON body, which is non-standard but matches the official API behavior.
6
+ def request(method, path, body = nil)
7
+ response = case method.to_s.downcase.to_sym
8
+ when :get
9
+ if body
10
+ @conn.get(path) { |r| r.body = body.to_json }
11
+ else
12
+ @conn.get(path)
13
+ end
14
+ when :post
15
+ @conn.post(path) { |r| r.body = body.to_json if body }
16
+ when :patch
17
+ @conn.patch(path) { |r| r.body = body.to_json if body }
18
+ else
19
+ raise RequestError, "Unsupported HTTP method: #{method}"
20
+ end
21
+
22
+ parse_response(response)
23
+ rescue Faraday::UnauthorizedError => e
24
+ raise AuthenticationError.new(
25
+ "Unauthorized - check API key and secret",
26
+ status_code: 401,
27
+ response_body: extract_error_body(e)
28
+ )
29
+ rescue Faraday::ResourceNotFound => e
30
+ raise NotFoundError.new(
31
+ "Resource not found: #{path}",
32
+ status_code: 404,
33
+ response_body: extract_error_body(e)
34
+ )
35
+ rescue Faraday::BadRequestError => e
36
+ raise BadRequestError.new(
37
+ "Bad request: #{extract_error_message(e)}",
38
+ status_code: 400,
39
+ response_body: extract_error_body(e)
40
+ )
41
+ rescue Faraday::ServerError => e
42
+ raise ServerError.new(
43
+ "Server error: #{extract_error_message(e)}",
44
+ status_code: e.response&.dig(:status) || 500,
45
+ response_body: extract_error_body(e)
46
+ )
47
+ rescue Faraday::ClientError => e
48
+ raise RequestError.new(
49
+ "API request failed: #{extract_error_message(e)}",
50
+ status_code: e.response&.dig(:status),
51
+ response_body: extract_error_body(e)
52
+ )
53
+ end # request
54
+
55
+ def extract_error_body(error)
56
+ error.response&.dig(:body)
57
+ end # extract_error_body
58
+
59
+ def extract_error_message(error)
60
+ body = extract_error_body(error)
61
+ return error.message unless body
62
+
63
+ begin
64
+ parsed = JSON.parse(body)
65
+ parsed["message"] || parsed["error"] || body
66
+ rescue JSON::ParserError
67
+ body
68
+ end
69
+ end # extract_error_message
70
+
71
+ def parse_response(response)
72
+ return {} if response.body.nil? || response.body.empty?
73
+
74
+ begin
75
+ data = JSON.parse(response.body)
76
+ rescue JSON::ParserError
77
+ raise InvalidResponseError, "Response is not valid JSON"
78
+ end
79
+
80
+ if response.status >= 400
81
+ raise RequestError, "API error: #{data}"
82
+ end
83
+
84
+ data
85
+ end # parse_response
86
+ end # class Base
87
+ end # module ProxyCheapClient
@@ -0,0 +1,20 @@
1
+ module ProxyCheapClient
2
+ #module Models
3
+ class Configuration < Base
4
+ attr_reader :data, :price, :currency, :packages, :available, :conn
5
+
6
+ def initialize(attrs = {}, client)
7
+ @data = attrs
8
+ @price = attrs["price"] || attrs["totalPrice"]
9
+ @currency = attrs["currency"] || "USD"
10
+ @packages = attrs["packages"]
11
+ @available = attrs["available"]
12
+ @conn = client.conn
13
+ end
14
+
15
+ def to_h
16
+ data
17
+ end
18
+ end
19
+ #end
20
+ end
@@ -0,0 +1,57 @@
1
+ module ProxyCheapClient
2
+ #module Models
3
+ class Order < Base
4
+ attr_reader :data,
5
+ :id,
6
+ #:status,
7
+ #:proxies,
8
+ #:created_at,
9
+ :total_price,
10
+ #:currency,
11
+ :conn
12
+
13
+ def initialize(attrs = {}, client)
14
+ @data = attrs
15
+ @id = attrs["id"] || attrs["orderId"]
16
+ #@status = attrs["status"]
17
+ #@proxies = attrs["proxies"]
18
+ #@created_at = attrs["createdAt"] || attrs["created_at"]
19
+ @total_price = attrs["totalPrice"] || attrs["total_price"]
20
+ #@currency = attrs["currency"]
21
+ @conn = client.conn
22
+ end # initialize
23
+
24
+ def to_h
25
+ {
26
+ id: id,
27
+ #status: status,
28
+ #proxies: proxies,
29
+ #created_at: created_at,
30
+ total_price: total_price,
31
+ #currency: currency
32
+ }
33
+ end # to_h
34
+
35
+ # Get proxies of an order
36
+ # @param order_id [String] Order ID
37
+ # @return [Order]
38
+ def proxies()
39
+ order_id = self.id
40
+ resp = request(:get, "orders/#{order_id}/proxies")
41
+
42
+ # The response may be an array or wrapped in a key (e.g. "proxies" or "data").
43
+ proxy_data = if resp.is_a?(Hash) && resp.key?("proxies")
44
+ resp["proxies"]
45
+ elsif resp.is_a?(Hash) && resp.key?("data")
46
+ resp["data"]
47
+ else
48
+ resp
49
+ end
50
+
51
+ Array(proxy_data).map { |p| ProxyCheapClient::Proxy.new(p) }
52
+ end # proxies
53
+
54
+
55
+ end # class
56
+ #end # module
57
+ end # module
@@ -0,0 +1,124 @@
1
+ module ProxyCheapClient
2
+ #module Models
3
+ class Proxy < Base
4
+ attr_reader :data, :id, :ip, :port, :type, :expires_at,
5
+ #:auto_renew, :auto_extend,
6
+ :country, :isp, :username, :password, :protocol, :bandwidth_limit,
7
+ :bandwidth_used, :status, :conn
8
+
9
+ def initialize(attrs = {}, client)
10
+ @data = attrs
11
+ @id = attrs["id"]
12
+ @ip = attrs["ip"] || attrs["host"] || (attrs["connection"] && attrs["connection"]['connectIp'])
13
+ @port = attrs["port"] || (attrs["connection"] && attrs["connection"]['httpPort'])
14
+ @type = attrs["type"] || attrs["networkType"] || (attrs["connection"] && attrs["connection"]['ipVersion'])
15
+ @expires_at = attrs["expiresAt"] || attrs["expires_at"]
16
+ #@auto_renew = attrs["autoRenew"] || attrs["auto_renew"] || attrs["isAutoExtendEnabled"]
17
+ #@auto_extend = attrs["isAutoExtendEnabled"] || attrs["autoExtend"]
18
+ @country = attrs["countryCode"]
19
+ isp = attrs["metadata"]['ispName']
20
+ @username = attrs["username"] || (attrs["authentication"] && attrs["authentication"]['username'])
21
+ @password = attrs["password"] || (attrs["authentication"] && attrs["authentication"]['password'])
22
+ @protocol = attrs["protocol"] || attrs["proxyProtocol"] || attrs["proxyType"]
23
+ @bandwidth_limit = attrs["bandwidthLimit"] || attrs["bandwidth_limit"] || (attrs["bandwidth"] && attrs["bandwidth"]['total'])
24
+ @bandwidth_used = attrs["bandwidthUsed"] || attrs["bandwidth_used"] || (attrs["bandwidth"] && attrs["bandwidth"]['used'])
25
+ @status = attrs["status"]
26
+ @conn = client.conn
27
+ end # def initialize
28
+
29
+ def to_h
30
+ {
31
+ id: id,
32
+ ip: ip,
33
+ port: port,
34
+ type: type,
35
+ expires_at: expires_at,
36
+ #auto_renew: auto_renew,
37
+ #auto_extend: auto_extend,
38
+ country: country,
39
+ isp: isp,
40
+ username: username,
41
+ password: password,
42
+ protocol: protocol,
43
+ bandwidth_limit: bandwidth_limit,
44
+ bandwidth_used: bandwidth_used,
45
+ status: status
46
+ }
47
+ end # to_h
48
+ =begin
49
+ # Change whitelisted IPs for a proxy.
50
+ # @note The official API uses GET with request body for this operation.
51
+ # @param proxy_id [Integer] Proxy ID
52
+ # @param ips [Array<String>] List of IPs to whitelist
53
+ # @return [Hash] API response
54
+ def whitelist(proxy_id, ips = [])
55
+ request(:get, "proxies/#{proxy_id}/whitelist-ip", { ips: ips })
56
+ end
57
+
58
+ # Extend a proxy period.
59
+ # @note The official API uses GET with request body for this operation.
60
+ # @param proxy_id [Integer] Proxy ID
61
+ # @param months [Integer] Number of months to extend (minimum 1)
62
+ # @return [Hash] API response
63
+ def extend_period(proxy_id, months)
64
+ raise ArgumentError, "You must extend for at least 1 month" unless months && months >= 1
65
+ request(:get, "proxies/#{proxy_id}/extend-period", { periodInMonths: months })
66
+ end
67
+
68
+ # Buy additional bandwidth for a proxy.
69
+ # @note The official API uses GET with request body for this operation.
70
+ # @param proxy_id [Integer] Proxy ID
71
+ # @param bandwidth_gb [Integer] Amount of bandwidth in GB (minimum 1)
72
+ # @return [Hash] API response
73
+ def buy_bandwidth(proxy_id, bandwidth_gb)
74
+ raise ArgumentError, "You must buy at least 1 GB" unless bandwidth_gb && bandwidth_gb >= 1
75
+ request(:get, "proxies/#{proxy_id}/buy-bandwidth", { bandwidth: bandwidth_gb })
76
+ end
77
+ =end
78
+ # Get info on a specific proxy.
79
+ # @param proxy_id [Integer] Proxy ID
80
+ # @return [Proxy]
81
+ def self.load(proxy_id)
82
+ resp = request(:get, "proxies/#{proxy_id}")
83
+ Proxy.new(resp)
84
+ end # proxy
85
+ =begin
86
+ def auto_extend?
87
+ !!@data.dig("autoExtend", "isEnabled")
88
+ end
89
+
90
+ def get_name
91
+ @data["name"]
92
+ end
93
+
94
+ def set_name(name)
95
+ response = @conn.patch("proxies/#{@data['id']}") do |req|
96
+ req.headers['Content-Type'] = 'application/json'
97
+ req.body = { name: name }.to_json
98
+ end
99
+ if response.success?
100
+ @data["name"] = name
101
+ else
102
+ raise "Failed to set proxy name (HTTP #{response.status})"
103
+ end
104
+ end
105
+ =end
106
+ # Enable auto-extend for a proxy.
107
+ # @param proxy_id [Integer] Proxy ID
108
+ # @return [Hash] API response
109
+ def enable_auto_extend()
110
+ proxy_id = self.id
111
+ request(:post, "proxies/#{proxy_id}/auto-extend/enable")
112
+ end # enable_auto_extend
113
+
114
+ # Disable auto-extend for a proxy.
115
+ # @param proxy_id [Integer] Proxy ID
116
+ # @return [Hash] API response
117
+ def disable_auto_extend()
118
+ proxy_id = self.id
119
+ request(:post, "proxies/#{proxy_id}/auto-extend/disable")
120
+ end # disable_auto_extend
121
+
122
+ end # Proxy
123
+ #end # Model
124
+ end
@@ -0,0 +1,3 @@
1
+ module ProxyCheapClient
2
+ VERSION = "1.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: proxy-cheap-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Leandro Sardi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-12-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.3.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.3.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Manage balance, proxies, auto-extend, and order proxies via the Proxy-Cheap
42
+ API.
43
+ email:
44
+ - leandro@massprospecting.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - LICENSE
50
+ - README.md
51
+ - lib/proxy-cheap-client.rb
52
+ - lib/proxy_cheap_client/client.rb
53
+ - lib/proxy_cheap_client/errors.rb
54
+ - lib/proxy_cheap_client/models/balance.rb
55
+ - lib/proxy_cheap_client/models/base.rb
56
+ - lib/proxy_cheap_client/models/configuration.rb
57
+ - lib/proxy_cheap_client/models/order.rb
58
+ - lib/proxy_cheap_client/models/proxy.rb
59
+ - lib/proxy_cheap_client/version.rb
60
+ homepage: https://github.com/massprospecting/proxy-cheap-client
61
+ licenses:
62
+ - MIT
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '2.7'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubygems_version: 3.3.7
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Ruby client for Proxy-Cheap.com API
83
+ test_files: []