auto-api-client 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 93857c52418aed8a134ae9db8cb1c190452640c4628ab7763e64f385ac0d43d9
4
+ data.tar.gz: 3947a3e3b025d391ac3880efb732683b9d03e19678a20cb43707fc51e4b916b2
5
+ SHA512:
6
+ metadata.gz: 805daa1befec1aeb8155cbfeb623c4588603f293056dbc489d447cef084fa48afa9c0699b16c8d8361bc1262bdd257c77c50c996c8b731831990ffd038e294c4
7
+ data.tar.gz: 125f2750890bb0e4c2f9d70fc8e812a14587e0744109c225faeb3fdc63d72d638f7d9b4ae55d71aa75bb75c7a3afba56490a77631e552fa1ab69cee1f499b7e3
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 AUTO-API.COM
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,122 @@
1
+ # auto-api-client-ruby
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/auto-api-client.svg)](https://rubygems.org/gems/auto-api-client)
4
+ [![Ruby](https://img.shields.io/badge/Ruby-2.5%2B-red)](https://ruby-lang.org)
5
+ [![License](https://img.shields.io/github/license/autoapicom/auto-api-ruby)](LICENSE)
6
+
7
+ Ruby gem for the [auto-api.com](https://auto-api.com) car listings API — 8 marketplaces, one client.
8
+
9
+ encar, mobile.de, autoscout24, che168, dongchedi, guazi, dubicars, dubizzle. No dependencies beyond stdlib (`net/http` + `json`).
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ gem install auto-api-client
15
+ ```
16
+
17
+ Or add to your Gemfile:
18
+
19
+ ```ruby
20
+ gem "auto-api-client"
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```ruby
26
+ require "auto_api"
27
+
28
+ client = AutoApi::Client.new("your-api-key")
29
+ ```
30
+
31
+ ### Get filters
32
+
33
+ ```ruby
34
+ filters = client.get_filters("encar")
35
+ ```
36
+
37
+ ### Search offers
38
+
39
+ ```ruby
40
+ offers = client.get_offers("mobilede", page: 1, brand: "BMW", year_from: 2020)
41
+
42
+ # Pagination
43
+ puts offers["meta"]["page"]
44
+ puts offers["meta"]["next_page"]
45
+ ```
46
+
47
+ ### Get single offer
48
+
49
+ ```ruby
50
+ offer = client.get_offer("encar", "40427050")
51
+ ```
52
+
53
+ ### Track changes
54
+
55
+ ```ruby
56
+ change_id = client.get_change_id("encar", "2025-01-15")
57
+ changes = client.get_changes("encar", change_id)
58
+
59
+ # Next batch
60
+ next_batch = client.get_changes("encar", changes["meta"]["next_change_id"])
61
+ ```
62
+
63
+ ### Get offer by URL
64
+
65
+ ```ruby
66
+ info = client.get_offer_by_url("https://encar.com/dc/dc_cardetailview.do?carid=40427050")
67
+ ```
68
+
69
+ ### Decode offer data
70
+
71
+ The `data` hash structure depends on the source — each marketplace has its own set of fields:
72
+
73
+ ```ruby
74
+ offers["result"].each do |item|
75
+ data = item["data"]
76
+ puts "#{data['mark']} #{data['model']} #{data['year']} — $#{data['price']}"
77
+ end
78
+ ```
79
+
80
+ ### Error handling
81
+
82
+ ```ruby
83
+ begin
84
+ offers = client.get_offers("encar", page: 1)
85
+ rescue AutoApi::AuthError => e
86
+ # 401/403 — invalid API key
87
+ puts "#{e.status_code}: #{e.message}"
88
+ rescue AutoApi::ApiError => e
89
+ # Any other API error
90
+ puts "#{e.status_code}: #{e.message}"
91
+ puts e.response_body
92
+ end
93
+ ```
94
+
95
+ ## Supported sources
96
+
97
+ | Source | Platform | Region |
98
+ |--------|----------|--------|
99
+ | `encar` | [encar.com](https://encar.com) | South Korea |
100
+ | `mobilede` | [mobile.de](https://mobile.de) | Germany |
101
+ | `autoscout24` | [autoscout24.com](https://autoscout24.com) | Europe |
102
+ | `che168` | [che168.com](https://che168.com) | China |
103
+ | `dongchedi` | [dongchedi.com](https://dongchedi.com) | China |
104
+ | `guazi` | [guazi.com](https://guazi.com) | China |
105
+ | `dubicars` | [dubicars.com](https://dubicars.com) | UAE |
106
+ | `dubizzle` | [dubizzle.com](https://dubizzle.com) | UAE |
107
+
108
+ ## Other languages
109
+
110
+ | Language | Package |
111
+ |----------|---------|
112
+ | PHP | [auto-api/client](https://github.com/autoapicom/auto-api-php) |
113
+ | TypeScript | [@auto-api/client](https://github.com/autoapicom/auto-api-node) |
114
+ | Python | [auto-api-client](https://github.com/autoapicom/auto-api-python) |
115
+ | Go | [auto-api-go](https://github.com/autoapicom/auto-api-go) |
116
+ | C# | [AutoApi.Client](https://github.com/autoapicom/auto-api-dotnet) |
117
+ | Java | [auto-api-client](https://github.com/autoapicom/auto-api-java) |
118
+ | Rust | [auto-api-client](https://github.com/autoapicom/auto-api-rust) |
119
+
120
+ ## Documentation
121
+
122
+ [auto-api.com](https://auto-api.com)
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "uri"
5
+ require "json"
6
+
7
+ module AutoApi
8
+ # Client for the auto-api.com car listings API.
9
+ class Client
10
+ # Creates a new API client.
11
+ #
12
+ # @param api_key [String] API key from auto-api.com
13
+ # @param api_version [String] API version (default: "v2")
14
+ # @param base_url [String] base URL override (default: "https://auto-api.com")
15
+ def initialize(api_key, api_version: "v2", base_url: "https://auto-api.com")
16
+ @api_key = api_key
17
+ @api_version = api_version
18
+ @base_url = base_url.chomp("/")
19
+ end
20
+
21
+ # Returns available filters for a source (brands, models, body types, etc.)
22
+ #
23
+ # @param source [String] source platform name
24
+ # @return [Hash] available filters
25
+ def get_filters(source)
26
+ get("api/#{@api_version}/#{source}/filters")
27
+ end
28
+
29
+ # Returns a paginated list of offers with optional filters.
30
+ #
31
+ # @param source [String] source platform name
32
+ # @param params [Hash] query parameters (page, brand, model, etc.)
33
+ # @return [Hash] { "result" => [...], "meta" => { "page" => ..., "next_page" => ... } }
34
+ def get_offers(source, params = {})
35
+ get("api/#{@api_version}/#{source}/offers", params)
36
+ end
37
+
38
+ # Returns a single offer by inner_id.
39
+ #
40
+ # @param source [String] source platform name
41
+ # @param inner_id [String] offer inner ID
42
+ # @return [Hash] offer data
43
+ def get_offer(source, inner_id)
44
+ get("api/#{@api_version}/#{source}/offer", { inner_id: inner_id })
45
+ end
46
+
47
+ # Returns a change_id for the given date.
48
+ #
49
+ # @param source [String] source platform name
50
+ # @param date [String] date in yyyy-mm-dd format
51
+ # @return [Integer] change_id for the given date
52
+ def get_change_id(source, date)
53
+ result = get("api/#{@api_version}/#{source}/change_id", { date: date })
54
+ result["change_id"]
55
+ end
56
+
57
+ # Returns a changes feed (added/changed/removed) starting from change_id.
58
+ #
59
+ # @param source [String] source platform name
60
+ # @param change_id [Integer] change ID to start from
61
+ # @return [Hash] { "result" => [...], "meta" => { "cur_change_id" => ..., "next_change_id" => ... } }
62
+ def get_changes(source, change_id)
63
+ get("api/#{@api_version}/#{source}/changes", { change_id: change_id })
64
+ end
65
+
66
+ # Returns offer data by its URL on the marketplace.
67
+ # Uses POST /api/v1/offer/info with x-api-key header.
68
+ #
69
+ # @param url [String] marketplace offer URL
70
+ # @return [Hash] offer data
71
+ def get_offer_by_url(url)
72
+ post("api/v1/offer/info", { url: url })
73
+ end
74
+
75
+ private
76
+
77
+ def get(endpoint, params = {})
78
+ params[:api_key] = @api_key
79
+
80
+ uri = URI("#{@base_url}/#{endpoint}")
81
+ uri.query = URI.encode_www_form(params)
82
+
83
+ request = Net::HTTP::Get.new(uri)
84
+ execute(uri, request)
85
+ end
86
+
87
+ def post(endpoint, data)
88
+ uri = URI("#{@base_url}/#{endpoint}")
89
+
90
+ request = Net::HTTP::Post.new(uri)
91
+ request["Content-Type"] = "application/json"
92
+ request["x-api-key"] = @api_key
93
+ request.body = JSON.generate(data)
94
+
95
+ execute(uri, request)
96
+ end
97
+
98
+ def execute(uri, request)
99
+ http = Net::HTTP.new(uri.host, uri.port)
100
+ http.use_ssl = uri.scheme == "https"
101
+ http.open_timeout = 30
102
+ http.read_timeout = 30
103
+
104
+ response = http.request(request)
105
+ handle_response(response)
106
+ end
107
+
108
+ def handle_response(response)
109
+ body = response.body
110
+ status_code = response.code.to_i
111
+
112
+ unless (200...300).include?(status_code)
113
+ message = "API error: #{status_code}"
114
+
115
+ begin
116
+ parsed = JSON.parse(body)
117
+ message = parsed["message"] if parsed.is_a?(Hash) && parsed["message"]
118
+ rescue JSON::ParserError
119
+ # Use default message if response is not valid JSON
120
+ end
121
+
122
+ if status_code == 401 || status_code == 403
123
+ raise AuthError.new(status_code, message, body)
124
+ end
125
+
126
+ raise ApiError.new(status_code, message, body)
127
+ end
128
+
129
+ begin
130
+ JSON.parse(body)
131
+ rescue JSON::ParserError
132
+ raise ApiError.new(status_code, "Invalid JSON response: #{body[0, 200]}", body)
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AutoApi
4
+ # Base exception for all auto-api.com API errors.
5
+ class ApiError < StandardError
6
+ # @return [Integer] HTTP status code returned by the API
7
+ attr_reader :status_code
8
+
9
+ # @return [String, nil] raw response body from the API
10
+ attr_reader :response_body
11
+
12
+ # @param status_code [Integer] HTTP status code
13
+ # @param message [String] error message
14
+ # @param response_body [String, nil] raw response body
15
+ def initialize(status_code, message, response_body = nil)
16
+ @status_code = status_code
17
+ @response_body = response_body
18
+ super("API error #{status_code}: #{message}")
19
+ end
20
+ end
21
+
22
+ # Exception for authentication errors (HTTP 401/403).
23
+ class AuthError < ApiError
24
+ # @param status_code [Integer] HTTP status code (401 or 403)
25
+ # @param message [String] error message
26
+ # @param response_body [String, nil] raw response body
27
+ def initialize(status_code, message, response_body = nil)
28
+ @status_code = status_code
29
+ @response_body = response_body
30
+ super(status_code, message, response_body)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AutoApi
4
+ VERSION = "1.0.0"
5
+ end
data/lib/auto_api.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "auto_api/version"
4
+ require_relative "auto_api/errors"
5
+ require_relative "auto_api/client"
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: auto-api-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - AUTO-API.COM
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-02-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Access car listings from encar, mobile.de, autoscout24, che168 and other
14
+ marketplaces via auto-api.com.
15
+ email:
16
+ - support@auto-api.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - LICENSE
22
+ - README.md
23
+ - lib/auto_api.rb
24
+ - lib/auto_api/client.rb
25
+ - lib/auto_api/errors.rb
26
+ - lib/auto_api/version.rb
27
+ homepage: https://github.com/autoapicom/auto-api-ruby
28
+ licenses:
29
+ - MIT
30
+ metadata:
31
+ homepage_uri: https://github.com/autoapicom/auto-api-ruby
32
+ source_code_uri: https://github.com/autoapicom/auto-api-ruby
33
+ changelog_uri: https://github.com/autoapicom/auto-api-ruby/blob/main/CHANGELOG.md
34
+ keywords: encar api, mobile.de api, autoscout24 api, che168 api, dongchedi api,
35
+ guazi api, dubicars api, dubizzle api
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 2.5.0
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubygems_version: 3.4.1
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Ruby client for auto-api.com
55
+ test_files: []