steam_api_client 1.0.0 → 1.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/CHANGELOG.md +15 -1
- data/docs/USAGE.md +73 -3
- data/lib/steam_api_client/endpoints.rb +55 -0
- data/lib/steam_api_client/models/app_details.rb +5 -3
- data/lib/steam_api_client/models/app_dlc.rb +44 -0
- data/lib/steam_api_client/models/package_details.rb +45 -0
- data/lib/steam_api_client/models/store_search_result.rb +34 -0
- data/lib/steam_api_client/models/wishlist_item.rb +11 -0
- data/lib/steam_api_client/version.rb +1 -1
- data/lib/steam_api_client.rb +4 -0
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '09f9edc74aff7de3fa4975dca173fd7a3388ea4a732671b67db45e09de6a06e5'
|
|
4
|
+
data.tar.gz: 92bbc4d8b4214e32fb2c8d5e8e5a18a3e6844712b4cf916552f02a46a96ec82b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 87a2e53bcd76c574b6f6389071a5156073ad893734ef79377fb34c48406f120652dd93e0a4d8f79b2bd54b5984c6415a5a55e618839ba330d7febb6415c76af8
|
|
7
|
+
data.tar.gz: 3ee3b3c3059e76060a40f63a14bfabd9881983f077f438c8ea90a239d6efeb89602cfed40c7022dfec6225b8b6578508f8821abecae7b4e7287ba0dd261fc60b
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.2.0] - 2026-11-02
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `package_details`, `app_dlc` and `store_search` from the Storefront API: a package's apps and price, an app's DLC, and a search of the store by name. No API key needed (#107).
|
|
14
|
+
|
|
15
|
+
## [1.1.0] - 2026-11-02
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- `player_wishlist`, `player_wishlist_count` and `player_followed_games`: a player's wishlist and the apps they follow in the store. No API key needed (#104).
|
|
20
|
+
|
|
9
21
|
## [1.0.0] - 2026-10-24
|
|
10
22
|
|
|
11
23
|
### Added
|
|
@@ -198,7 +210,9 @@ The versions below were bumped in `version.rb` during development but **never pu
|
|
|
198
210
|
|
|
199
211
|
- Initial gem skeleton.
|
|
200
212
|
|
|
201
|
-
[Unreleased]: https://github.com/jpechaves/steam_api/compare/v1.
|
|
213
|
+
[Unreleased]: https://github.com/jpechaves/steam_api/compare/v1.2.0...HEAD
|
|
214
|
+
[1.2.0]: https://github.com/jpechaves/steam_api/compare/v1.1.0...v1.2.0
|
|
215
|
+
[1.1.0]: https://github.com/jpechaves/steam_api/compare/v1.0.0...v1.1.0
|
|
202
216
|
[1.0.0]: https://github.com/jpechaves/steam_api/compare/v0.10.0...v1.0.0
|
|
203
217
|
[0.11.0]: https://github.com/jpechaves/steam_api/compare/v0.10.0...v0.11.0
|
|
204
218
|
[0.10.0]: https://github.com/jpechaves/steam_api/compare/v0.9.1...v0.10.0
|
data/docs/USAGE.md
CHANGED
|
@@ -191,6 +191,33 @@ stats.achievements.first # => #<data SteamApiClient::PlayerGameStats::Achievemen
|
|
|
191
191
|
|
|
192
192
|
Stat values are Integers or Floats, as the game defines them. A private profile, or a game without stats, raises `Errors::HttpBadRequest`.
|
|
193
193
|
|
|
194
|
+
#### `player_wishlist`
|
|
195
|
+
|
|
196
|
+
The apps on a player's wishlist. No key needed.
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
client.player_wishlist.retrieve(steamid: 76561198000000001).first
|
|
200
|
+
# => #<data SteamApiClient::WishlistItem app_id=202350, priority=3, date_added=1403384867>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`priority` is the player's ranking of the app, and `date_added` a unix timestamp. A private or empty wishlist is `[]`. An ID that isn't a valid SteamID (e.g. `1`) raises `Errors::HttpBadRequest`, here and in the two endpoints below.
|
|
204
|
+
|
|
205
|
+
#### `player_wishlist_count`
|
|
206
|
+
|
|
207
|
+
The number of apps on a player's wishlist, or `nil` when it's private or empty. No key needed.
|
|
208
|
+
|
|
209
|
+
```ruby
|
|
210
|
+
client.player_wishlist_count.retrieve(steamid: 76561198000000001) # => 19
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### `player_followed_games`
|
|
214
|
+
|
|
215
|
+
The app IDs a player follows in the store, or `[]` when the profile is private. No key needed.
|
|
216
|
+
|
|
217
|
+
```ruby
|
|
218
|
+
client.player_followed_games.retrieve(steamid: 76561198000000001) # => [400, 440, 620, ...]
|
|
219
|
+
```
|
|
220
|
+
|
|
194
221
|
### Apps
|
|
195
222
|
|
|
196
223
|
#### `app_details`
|
|
@@ -211,6 +238,49 @@ client.app_details.retrieve(appid: 440).platforms
|
|
|
211
238
|
|
|
212
239
|
`SteamApiClient::AppDetails` fields: `app_id`, `type`, `name`, `required_age`, `is_free`, `dlc`, `detailed_description`, `about_the_game`, `short_description`, `supported_languages`, `header_image`, `website`, `pc_requirements` / `mac_requirements` / `linux_requirements` (`AppDetails::Requirements`: `minimum`, `recommended`, as HTML), `developers`, `publishers`, `price_overview` (`AppDetails::Price`, in cents; `nil` for free apps), `packages`, `package_groups` (`AppDetails::PackageGroup` with `subs`: `AppDetails::Package`), `platforms`, `metacritic` (`score`, `url`), `categories` and `genres` (`id`, `description`), `screenshots`, `movies` (`AppDetails::Movie` with DASH and HLS streams), `recommendations` (the number of user reviews), `achievements` (`total`, `highlighted`), `release_date` (`coming_soon`, `date`), `support_info` (`url`, `email`), `background`, `background_raw`, `content_descriptors` (`ids`, `notes`).
|
|
213
240
|
|
|
241
|
+
#### `package_details`
|
|
242
|
+
|
|
243
|
+
A package (a bundle, or a "sub" such as an edition or a license) in the store, or `nil` when it's unavailable. Storefront API, no key needed. Takes one `packageid:` (Steam rejects several at once), and `country_code:` / `locale:` like `app_details`. Package IDs are in `app_details`' `packages` and `package_groups`.
|
|
244
|
+
|
|
245
|
+
```ruby
|
|
246
|
+
package = client.package_details.retrieve(packageid: 469)
|
|
247
|
+
package.name # => "The Orange Box"
|
|
248
|
+
package.apps # => [#<data SteamApiClient::PackageDetails::App id=220, name="Half-Life 2">, ...]
|
|
249
|
+
package.price # => #<data SteamApiClient::PackageDetails::Price currency="USD", initial=1999, final=1999, discount_percent=0, individual=1998>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
`SteamApiClient::PackageDetails` fields: `package_id`, `name`, `page_content` (HTML), `purchase_text`, `page_image`, `header_image`, `small_logo`, `apps` (`id`, `name`), `price` (in cents; `individual` is what the apps cost on their own; `nil` for free packages), `platforms` and `release_date` (as in `AppDetails`), `controller` (`full_gamepad`). An invalid ID such as `0` raises `Errors::HttpBadRequest`.
|
|
253
|
+
|
|
254
|
+
#### `app_dlc`
|
|
255
|
+
|
|
256
|
+
An app's DLC, or `nil` when the app is unknown. Storefront API, no key needed. Takes `appid:`, `country_code:` and `locale:`.
|
|
257
|
+
|
|
258
|
+
```ruby
|
|
259
|
+
result = client.app_dlc.retrieve(appid: 292030)
|
|
260
|
+
result.name # => "The Witcher 3: Wild Hunt — Remastered"
|
|
261
|
+
result.dlc.last
|
|
262
|
+
# => #<data SteamApiClient::AppDlc::Dlc id=1229320, name="The Witcher 3: Wild Hunt — Remastered Soundtrack", header_image="https://...",
|
|
263
|
+
# price_overview=#<data SteamApiClient::AppDlc::Price currency="USD", initial=1099, final=1099, discount_percent=0>,
|
|
264
|
+
# platforms=#<data SteamApiClient::AppDetails::Platforms windows=true, mac=true, linux=true>,
|
|
265
|
+
# release_date=#<data SteamApiClient::AppDlc::ReleaseDates steam=1581374766, mac=1581374752, linux=1581374752>, controller_support="full">
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
`price_overview` is `nil` for free DLC and DLC not sold on its own. `release_date` has a unix time per platform (`steam`, `mac`, `linux`), each `nil` when Steam doesn't know it. Steam sometimes adds milliseconds, and the time is then a Float.
|
|
269
|
+
|
|
270
|
+
#### `store_search`
|
|
271
|
+
|
|
272
|
+
Apps in the store matching a search term, at most 10 (Steam's limit, with no paging). Storefront API, no key needed. Takes `term:`, `country_code:` and `locale:`.
|
|
273
|
+
|
|
274
|
+
```ruby
|
|
275
|
+
client.store_search.retrieve(term: "portal").first
|
|
276
|
+
# => #<data SteamApiClient::StoreSearchResult id=620, type="app", name="Portal 2",
|
|
277
|
+
# price=#<data SteamApiClient::StoreSearchResult::Price currency="USD", initial=999, final=999>, tiny_image="https://...",
|
|
278
|
+
# metascore=95, platforms=#<data SteamApiClient::AppDetails::Platforms windows=true, mac=false, linux=true>,
|
|
279
|
+
# streaming_video=false, controller_support="full">
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
`price` is `nil` for free apps, `metascore` when the app has no Metacritic score. No match is `[]`.
|
|
283
|
+
|
|
214
284
|
#### `app_news`
|
|
215
285
|
|
|
216
286
|
The latest news of an app. `count:` is required, `maxlength:` (default 300) shortens each item's contents.
|
|
@@ -319,8 +389,8 @@ Don't retry other 4xx errors: they won't succeed on their own.
|
|
|
319
389
|
|
|
320
390
|
## Limits and caveats
|
|
321
391
|
|
|
322
|
-
- **Rate limits.** Steam's [Web API terms](https://steamcommunity.com/dev/apiterms) allow 100,000 calls per day per key. The Storefront API (`app_details`) is rate limited per IP address, commonly reported at about 200 requests per 5 minutes. Both answer `429` when you go over. Cache what you can.
|
|
323
|
-
- **The Storefront API is unofficial.**
|
|
324
|
-
- **Private profiles.** What a player hides depends on their privacy settings. Depending on the endpoint, Steam answers with an error (`player_achievements`: 403, `player_game_stats`: 400, `player_friends`: 401) or with empty data, which the gem returns as `nil` (`player_owned_games`, `player_recent_games`, `player_level`). `player_summaries` still returns the public part of the profile.
|
|
392
|
+
- **Rate limits.** Steam's [Web API terms](https://steamcommunity.com/dev/apiterms) allow 100,000 calls per day per key. The Storefront API (`app_details`, `package_details`, `app_dlc`, `store_search`) is rate limited per IP address, commonly reported at about 200 requests per 5 minutes. Both answer `429` when you go over. Cache what you can.
|
|
393
|
+
- **The Storefront API is unofficial.** The Storefront endpoints use the API behind Steam's store and Big Picture mode. Valve doesn't document it, and its fields change without notice.
|
|
394
|
+
- **Private profiles.** What a player hides depends on their privacy settings. Depending on the endpoint, Steam answers with an error (`player_achievements`: 403, `player_game_stats`: 400, `player_friends`: 401) or with empty data, which the gem returns as `nil` or `[]` (`player_owned_games`, `player_recent_games`, `player_level`, `player_wishlist`, `player_wishlist_count`, `player_followed_games`). Steam answers the same way for an empty wishlist, so the wishlist endpoints can't tell the two apart. `player_summaries` still returns the public part of the profile.
|
|
325
395
|
- **The key is in the URL.** Steam requires `?key=...` in the query string. Treat logs of request URLs as secrets (see [Configuration](#configuration)), and [rotate your key](https://steamcommunity.com/dev/apikey) if it leaks.
|
|
326
396
|
- **SteamIDs are 64 bit Integers** (e.g. `76561197960435530`). Use `player_steamid` to get one from a vanity URL.
|
|
@@ -26,6 +26,16 @@ module SteamApiClient
|
|
|
26
26
|
}
|
|
27
27
|
),
|
|
28
28
|
|
|
29
|
+
# An app's DLC => AppDlc, or nil when the app is unknown
|
|
30
|
+
Endpoint.new(
|
|
31
|
+
:app_dlc, "dlcforapp/", api: :store, key: false, returns: AppDlc, at: AppDlc.method(:unwrap),
|
|
32
|
+
params: {
|
|
33
|
+
appid: param.integer,
|
|
34
|
+
country_code: param.string(as: :cc, default: "US"),
|
|
35
|
+
locale: param.string(as: :l, default: "en")
|
|
36
|
+
}
|
|
37
|
+
),
|
|
38
|
+
|
|
29
39
|
# Global achievement unlock percentages of an app => [GlobalAchievement]
|
|
30
40
|
# @see https://developer.valvesoftware.com/wiki/Steam_Web_API#GetGlobalAchievementPercentagesForApp_.28v0002.29
|
|
31
41
|
Endpoint.new(
|
|
@@ -55,6 +65,19 @@ module SteamApiClient
|
|
|
55
65
|
params: {appid: param.integer}
|
|
56
66
|
),
|
|
57
67
|
|
|
68
|
+
# Details of a package (a bundle or a sub) in the store => PackageDetails, or nil when unavailable
|
|
69
|
+
# @see https://wiki.teamfortress.com/wiki/User:RJackson/StorefrontAPI#packagedetails
|
|
70
|
+
Endpoint.new(
|
|
71
|
+
:package_details, "packagedetails/", api: :store, key: false, returns: PackageDetails,
|
|
72
|
+
at: PackageDetails.method(:unwrap),
|
|
73
|
+
params: {
|
|
74
|
+
# Steam rejects several IDs at once
|
|
75
|
+
packageid: param.integer(as: :packageids),
|
|
76
|
+
country_code: param.string(as: :cc, default: "US"),
|
|
77
|
+
locale: param.string(as: :l, default: "en")
|
|
78
|
+
}
|
|
79
|
+
),
|
|
80
|
+
|
|
58
81
|
# A player's achievements in an app => PlayerAchievements
|
|
59
82
|
# @see https://developer.valvesoftware.com/wiki/Steam_Web_API#GetPlayerAchievements_.28v0001.29
|
|
60
83
|
Endpoint.new(
|
|
@@ -62,6 +85,13 @@ module SteamApiClient
|
|
|
62
85
|
params: {appid: param.integer, steamid: param.integer}
|
|
63
86
|
),
|
|
64
87
|
|
|
88
|
+
# The apps a player follows in the store => [Integer] app IDs ([] when not public)
|
|
89
|
+
# @see https://steamapi.xpaw.me/#IStoreService/GetGamesFollowed
|
|
90
|
+
Endpoint.new(
|
|
91
|
+
:player_followed_games, "IStoreService/GetGamesFollowed/v1/", key: false, returns: [:integer], at: %i[response appids],
|
|
92
|
+
params: {steamid: param.integer}
|
|
93
|
+
),
|
|
94
|
+
|
|
65
95
|
# A player's friend list, if public => [Friend]
|
|
66
96
|
# @see https://developer.valvesoftware.com/wiki/Steam_Web_API#GetFriendList_.28v0001.29
|
|
67
97
|
Endpoint.new(
|
|
@@ -116,6 +146,31 @@ module SteamApiClient
|
|
|
116
146
|
Endpoint.new(
|
|
117
147
|
:player_summaries, "ISteamUser/GetPlayerSummaries/v0002/", returns: [PlayerSummary], at: %i[response players],
|
|
118
148
|
params: {steamids: param.integer_list}
|
|
149
|
+
),
|
|
150
|
+
|
|
151
|
+
# A player's wishlist => [WishlistItem] ([] when empty or not public)
|
|
152
|
+
# @see https://steamapi.xpaw.me/#IWishlistService/GetWishlist
|
|
153
|
+
Endpoint.new(
|
|
154
|
+
:player_wishlist, "IWishlistService/GetWishlist/v1/", key: false, returns: [WishlistItem], at: %i[response items],
|
|
155
|
+
params: {steamid: param.integer}
|
|
156
|
+
),
|
|
157
|
+
|
|
158
|
+
# The number of apps on a player's wishlist => Integer, or nil when empty or not public
|
|
159
|
+
# @see https://steamapi.xpaw.me/#IWishlistService/GetWishlistItemCount
|
|
160
|
+
Endpoint.new(
|
|
161
|
+
:player_wishlist_count, "IWishlistService/GetWishlistItemCount/v1/", key: false, returns: :integer, at: %i[response count],
|
|
162
|
+
params: {steamid: param.integer}
|
|
163
|
+
),
|
|
164
|
+
|
|
165
|
+
# Apps in the store matching a search term => [StoreSearchResult] (at most 10)
|
|
166
|
+
Endpoint.new(
|
|
167
|
+
:store_search, "storesearch/", api: :store, key: false, returns: [StoreSearchResult],
|
|
168
|
+
at: StoreSearchResult.method(:unwrap),
|
|
169
|
+
params: {
|
|
170
|
+
term: param.string,
|
|
171
|
+
country_code: param.string(as: :cc, default: "US"),
|
|
172
|
+
locale: param.string(as: :l, default: "en")
|
|
173
|
+
}
|
|
119
174
|
)
|
|
120
175
|
].to_h { |endpoint| [endpoint.name, endpoint] }.freeze
|
|
121
176
|
end
|
|
@@ -105,13 +105,15 @@ module SteamApiClient
|
|
|
105
105
|
) do
|
|
106
106
|
# Steam keys the response by app ID: {"570": {"success": true, "data": {...}}}.
|
|
107
107
|
# Returns the data, or nil when the app is unavailable (success: false).
|
|
108
|
+
# The Storefront's other details endpoints (packagedetails) answer the same way.
|
|
108
109
|
# @param [Hash] json
|
|
110
|
+
# @param [Symbol] id_key the key the ID is added under
|
|
109
111
|
# @return [Hash, nil]
|
|
110
|
-
def self.unwrap(json)
|
|
111
|
-
|
|
112
|
+
def self.unwrap(json, id_key: :steam_appid)
|
|
113
|
+
id, entry = json.first
|
|
112
114
|
return unless entry.is_a?(Hash) && entry[:success]
|
|
113
115
|
|
|
114
|
-
{
|
|
116
|
+
{id_key => id.to_s}.merge(entry.fetch(:data, {}))
|
|
115
117
|
end
|
|
116
118
|
end
|
|
117
119
|
parts.each { |name, model| AppDetails.const_set(name, model) }
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module SteamApiClient
|
|
2
|
+
# The parts of AppDlc, built first, then named under it below (e.g. AppDlc::Dlc)
|
|
3
|
+
parts = {
|
|
4
|
+
Price: Model.define(
|
|
5
|
+
currency: :string,
|
|
6
|
+
# In cents
|
|
7
|
+
initial: :integer,
|
|
8
|
+
final: :integer,
|
|
9
|
+
discount_percent: :integer
|
|
10
|
+
),
|
|
11
|
+
# Unix times, per platform. Steam sometimes adds milliseconds, which makes them Floats.
|
|
12
|
+
ReleaseDates: Model.define(
|
|
13
|
+
steam: [:number, optional: true],
|
|
14
|
+
mac: [:number, optional: true],
|
|
15
|
+
linux: [:number, optional: true]
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
parts[:Dlc] = Model.define(
|
|
19
|
+
id: :integer,
|
|
20
|
+
name: :string,
|
|
21
|
+
header_image: [:string, optional: true],
|
|
22
|
+
# Not sent for free DLC, or DLC not sold on its own
|
|
23
|
+
price_overview: [parts[:Price], optional: true],
|
|
24
|
+
platforms: [AppDetails::Platforms, optional: true],
|
|
25
|
+
release_date: [parts[:ReleaseDates], optional: true],
|
|
26
|
+
# "full", "partial", or nil
|
|
27
|
+
controller_support: [:string, optional: true]
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# An app's DLC, from `app_dlc`
|
|
31
|
+
AppDlc = Model.define(
|
|
32
|
+
app_id: [:integer, from: :appid],
|
|
33
|
+
name: :string,
|
|
34
|
+
dlc: [[parts[:Dlc]], default: []]
|
|
35
|
+
) do
|
|
36
|
+
# Steam answers {"status": 2} for an unknown app
|
|
37
|
+
# @param [Hash] json
|
|
38
|
+
# @return [Hash, nil] the JSON, or nil when the app is unknown
|
|
39
|
+
def self.unwrap(json)
|
|
40
|
+
json if json[:status] == 1
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
parts.each { |name, model| AppDlc.const_set(name, model) }
|
|
44
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module SteamApiClient
|
|
2
|
+
# The parts of PackageDetails, built first, then named under it below
|
|
3
|
+
# (e.g. PackageDetails::App)
|
|
4
|
+
parts = {
|
|
5
|
+
App: Model.define(id: :integer, name: :string),
|
|
6
|
+
Price: Model.define(
|
|
7
|
+
currency: :string,
|
|
8
|
+
# In cents
|
|
9
|
+
initial: :integer,
|
|
10
|
+
final: :integer,
|
|
11
|
+
discount_percent: :integer,
|
|
12
|
+
# The sum of the apps' own prices, in cents (0 when they aren't sold separately)
|
|
13
|
+
individual: [:integer, optional: true]
|
|
14
|
+
),
|
|
15
|
+
Controller: Model.define(full_gamepad: :boolean)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
# A package (a bundle or a sub) in the store, from `package_details`. Every
|
|
19
|
+
# field is nil when Steam leaves it out.
|
|
20
|
+
# @see https://wiki.teamfortress.com/wiki/User:RJackson/StorefrontAPI#packagedetails
|
|
21
|
+
PackageDetails = Model.define(
|
|
22
|
+
package_id: [:integer, from: :packageid],
|
|
23
|
+
name: [:string, optional: true],
|
|
24
|
+
# HTML
|
|
25
|
+
page_content: [:string, optional: true],
|
|
26
|
+
purchase_text: [:string, optional: true],
|
|
27
|
+
page_image: [:string, optional: true],
|
|
28
|
+
header_image: [:string, optional: true],
|
|
29
|
+
small_logo: [:string, optional: true],
|
|
30
|
+
apps: [[parts[:App]], default: []],
|
|
31
|
+
# Not sent for free packages
|
|
32
|
+
price: [parts[:Price], optional: true],
|
|
33
|
+
platforms: [AppDetails::Platforms, optional: true],
|
|
34
|
+
controller: [parts[:Controller], optional: true],
|
|
35
|
+
release_date: [AppDetails::ReleaseDate, optional: true]
|
|
36
|
+
) do
|
|
37
|
+
# The package's data, or nil when it's unavailable (see AppDetails.unwrap)
|
|
38
|
+
# @param [Hash] json
|
|
39
|
+
# @return [Hash, nil]
|
|
40
|
+
def self.unwrap(json)
|
|
41
|
+
AppDetails.unwrap(json, id_key: :packageid)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
parts.each { |name, model| PackageDetails.const_set(name, model) }
|
|
45
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module SteamApiClient
|
|
2
|
+
# Built first, then named StoreSearchResult::Price below
|
|
3
|
+
price = Model.define(
|
|
4
|
+
currency: :string,
|
|
5
|
+
# In cents
|
|
6
|
+
initial: :integer,
|
|
7
|
+
final: :integer
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
# One result of a store search, from `store_search`
|
|
11
|
+
StoreSearchResult = Model.define(
|
|
12
|
+
id: :integer,
|
|
13
|
+
# "app"
|
|
14
|
+
type: :string,
|
|
15
|
+
name: :string,
|
|
16
|
+
# Not sent for free apps
|
|
17
|
+
price: [price, optional: true],
|
|
18
|
+
tiny_image: [:string, optional: true],
|
|
19
|
+
# nil when the app has no Metacritic score
|
|
20
|
+
metascore: [:integer, optional: true],
|
|
21
|
+
platforms: [AppDetails::Platforms, optional: true],
|
|
22
|
+
streaming_video: [:boolean, from: :streamingvideo, optional: true],
|
|
23
|
+
# "full", "partial", or nil
|
|
24
|
+
controller_support: [:string, optional: true]
|
|
25
|
+
) do
|
|
26
|
+
# The results. Steam sends "" as the metascore of apps without one.
|
|
27
|
+
# @param [Hash] json
|
|
28
|
+
# @return [Array<Hash>, nil]
|
|
29
|
+
def self.unwrap(json)
|
|
30
|
+
json[:items]&.map { |item| (item[:metascore] == "") ? item.merge(metascore: nil) : item }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
StoreSearchResult.const_set(:Price, price)
|
|
34
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module SteamApiClient
|
|
2
|
+
# An app on a player's wishlist, from `player_wishlist`
|
|
3
|
+
# @see https://steamapi.xpaw.me/#IWishlistService/GetWishlist
|
|
4
|
+
WishlistItem = Model.define(
|
|
5
|
+
app_id: [:integer, from: :appid],
|
|
6
|
+
# The player's ranking of the app in their wishlist
|
|
7
|
+
priority: :integer,
|
|
8
|
+
# In unix time
|
|
9
|
+
date_added: :integer
|
|
10
|
+
)
|
|
11
|
+
end
|
data/lib/steam_api_client.rb
CHANGED
|
@@ -30,6 +30,10 @@ require_relative "steam_api_client/models/player_game_stats"
|
|
|
30
30
|
require_relative "steam_api_client/models/news_item"
|
|
31
31
|
require_relative "steam_api_client/models/global_achievement"
|
|
32
32
|
require_relative "steam_api_client/models/app_details"
|
|
33
|
+
require_relative "steam_api_client/models/package_details"
|
|
34
|
+
require_relative "steam_api_client/models/app_dlc"
|
|
35
|
+
require_relative "steam_api_client/models/store_search_result"
|
|
36
|
+
require_relative "steam_api_client/models/wishlist_item"
|
|
33
37
|
|
|
34
38
|
require_relative "steam_api_client/endpoints"
|
|
35
39
|
require_relative "steam_api_client/client"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: steam_api_client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- João Pedro
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-11-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -54,13 +54,17 @@ files:
|
|
|
54
54
|
- lib/steam_api_client/model/field.rb
|
|
55
55
|
- lib/steam_api_client/model/scalars.rb
|
|
56
56
|
- lib/steam_api_client/models/app_details.rb
|
|
57
|
+
- lib/steam_api_client/models/app_dlc.rb
|
|
57
58
|
- lib/steam_api_client/models/friend.rb
|
|
58
59
|
- lib/steam_api_client/models/game.rb
|
|
59
60
|
- lib/steam_api_client/models/global_achievement.rb
|
|
60
61
|
- lib/steam_api_client/models/news_item.rb
|
|
62
|
+
- lib/steam_api_client/models/package_details.rb
|
|
61
63
|
- lib/steam_api_client/models/player_achievements.rb
|
|
62
64
|
- lib/steam_api_client/models/player_game_stats.rb
|
|
63
65
|
- lib/steam_api_client/models/player_summary.rb
|
|
66
|
+
- lib/steam_api_client/models/store_search_result.rb
|
|
67
|
+
- lib/steam_api_client/models/wishlist_item.rb
|
|
64
68
|
- lib/steam_api_client/request.rb
|
|
65
69
|
- lib/steam_api_client/requestor.rb
|
|
66
70
|
- lib/steam_api_client/response.rb
|