{"id":24932345,"url":"https://github.com/tbuehlmann/hots_api","last_synced_at":"2025-04-09T22:21:30.415Z","repository":{"id":56876679,"uuid":"103568960","full_name":"tbuehlmann/hots_api","owner":"tbuehlmann","description":"Client library for the Heroes of the Storm replay metadata API hotsapi.net","archived":false,"fork":false,"pushed_at":"2018-06-27T07:12:12.000Z","size":296,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-25T12:44:53.137Z","etag":null,"topics":["hotsapi","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tbuehlmann.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-14T18:44:27.000Z","updated_at":"2019-03-11T09:08:56.000Z","dependencies_parsed_at":"2022-08-20T11:30:55.259Z","dependency_job_id":null,"html_url":"https://github.com/tbuehlmann/hots_api","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tbuehlmann%2Fhots_api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tbuehlmann%2Fhots_api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tbuehlmann%2Fhots_api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tbuehlmann%2Fhots_api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tbuehlmann","download_url":"https://codeload.github.com/tbuehlmann/hots_api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248120165,"owners_count":21050903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hotsapi","ruby"],"created_at":"2025-02-02T14:21:11.879Z","updated_at":"2025-04-09T22:21:30.394Z","avatar_url":"https://github.com/tbuehlmann.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HotsApi\n\n[![Build Status](https://travis-ci.org/tbuehlmann/hots_api.svg?branch=master)](https://travis-ci.org/tbuehlmann/hots_api)\n\nHotsApi is an API client for the Heroes of the Storm replay metadata API [hotsapi.net](https://hotsapi.net/). It consumes the API and lets you retrieve information about uploaded replays.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'hots_api'\n```\n\nAnd then execute:\n\n    $ bundle install\n\nOr install it yourself as:\n\n    $ gem install hots_api\n\n## Finding Replays\n\n#### Finding a Single Replay\n\n```ruby\nreplay = HotsApi.replays.find(59) # =\u003e #\u003cHotsApi::Models::Replay\u003e\nreplay.id           # =\u003e 59\nreplay.filename     # =\u003e '04e92942-7a46-f12c-24f6-65dcf4ea409f'\nreplay.size         # =\u003e 1495665\nreplay.fingerprint  # =\u003e '04e92942-7a46-2cf1-24f6-65dcf4ea409f'\nreplay.game_date    # =\u003e 2017-08-15 23:16:28 +0200\nreplay.game_length  # =\u003e 872\nreplay.game_map     # =\u003e 'Braxis Holdout'\nreplay.game_type    # =\u003e 'HeroLeague'\nreplay.game_version # =\u003e '2.27.1.56361'\nreplay.bans         # =\u003e [['Dehaka', 'Anub'arak'], ['Sylvanas', 'Sonya']]\nreplay.region       # =\u003e 2\nreplay.processed    # =\u003e true\nreplay.url          # =\u003e 'http://hotsapi.s3-website-eu-west-1.amazonaws.com/04e92942-7a46-f12c-24f6-65dcf4ea409f.StormReplay'\nreplay.created_at   # =\u003e 2017-08-27 14:58:59 +0200\nreplay.updated_at   # =\u003e 2017-10-04 01:23:53 +0200\nreplay.players      # =\u003e [#\u003cHotsApi::Models::Player\u003e, …]\n\nplayer = replay.players[2] # =\u003e #\u003cHotsApi::Models::Player\u003e\nplayer.blizz_id   # =\u003e 215378\nplayer.battletag  # =\u003e 'Poma'\nplayer.hero       # =\u003e 'Chromie'\nplayer.hero_level # =\u003e 13\nplayer.team       # =\u003e 0\nplayer.winner     # =\u003e true\nplayer.party      # =\u003e 0\nplayer.talents    # =\u003e {'1' =\u003e 'ChromieTimewalkersPursuit', '4' =\u003e 'ChromieBronzeTalons', '7' =\u003e 'ChromieDragonsBreathDragonsEye', '10' =\u003e 'ChromieHeroicAbilityTemporalLoop', '13' =\u003e 'ChromieReachingThroughTime', '16' =\u003e 'ChromieQuantumOverdrive'}\nplayer.score      # =\u003e #\u003cHotsApi::Models::Score\u003e\n\nscore = player.score # =\u003e #\u003cHotsApi::Models::Score\u003e\nscore.level                   # =\u003e 16\nscore.kills                   # =\u003e 9\nscore.assists                 # =\u003e 14\nscore.takedowns               # =\u003e 23\nscore.deaths                  # =\u003e 1\nscore.highest_kill_streak     # =\u003e 23\nscore.hero_damage             # =\u003e 35902\nscore.siege_damage            # =\u003e 33200\nscore.structure_damage        # =\u003e 10571\nscore.minion_damage           # =\u003e 20839\nscore.creep_damage            # =\u003e 6686\nscore.summon_damage           # =\u003e 1790\nscore.time_cc_enemy_heroes    # =\u003e 5033\nscore.healing                 # =\u003e nil\nscore.self_healing            # =\u003e 0\nscore.damage_taken            # =\u003e nil\nscore.experience_contribution # =\u003e 7683\nscore.town_kills              # =\u003e 0\nscore.time_spent_dead         # =\u003e 44\nscore.merc_camp_captures      # =\u003e 3\nscore.watch_tower_captures    # =\u003e 0\nscore.meta_experience         # =\u003e 52960\n```\n\n#### Finding Replays\n\n```ruby\nreplays = HotsApi.replays.to_a # =\u003e [#\u003cHotsApi::Models::Replay\u003e, …]\n```\n\n#### Filtering Replays\n\n```ruby\n# by game date\nreplays = HotsApi.replays.where(start_date: '2017-09-01 00:00').to_a\nreplays = HotsApi.replays.where(end_date: '2017-09-01 00:00').to_a\n\n# by game map\nreplays = HotsApi.replays.where(game_map: 'Hanamura').to_a\n\n# by game type\nreplays = HotsApi.replays.where(game_type: 'HeroLeague').to_a\n\n# by id\nreplays = HotsApi.replays.where(min_id: 1000).to_a\n\n# by player\nreplays = HotsApi.replays.where(player: 'Poma').to_a\n\n# by hero\nreplays = HotsApi.replays.where(hero: 'Tassadar').to_a\n\n# conditions are chainable\nreplays = HotsApi.replays.where(start_date: '2017-09-01 00:00', end_date: '2017-09-01 23:59').where(game_type: 'HeroLeague').to_a\n```\n\nNote: Filtering hero and map is disabled on the server right now, so you cannot use it.\n\n#### Include Players\n\nReplays don't include its players and bans per default. If you want to include them, use `with_players` (which is also chainable):\n\n```ruby\nreplays = HotsApi.replays.with_players.to_a\nreplays = HotsApi.replays.where(start_date: '2017-09-01 00:00').with_players.to_a\n```\n\n#### Pagination\n\nThe API returns a maximum of 100 replays per request. If you want to retrieve the second page (or the next 100 replays) for a given query:\n\n```ruby\nfirst_page = HotsApi.replays\nsecond_page = first_page.next_page\n```\n\nInternally, this will set the appropriate `min_id` to the query. If there's no next page, calling `next_page` will return `nil`.\n\nIf you want to retrieve all replays for a given query, use `find_each`:\n\n```ruby\nHotsApi.replays.where(start_date: '2017-09-01 00:00', end_date: '2017-09-01 23:59').find_each do |replay|\n  # …\nend\n\n# or\n\nreplays = HotsApi.replays.where(start_date: '2017-09-01 00:00', end_date: '2017-09-01 23:59').find_each.to_a\n```\n\nNote that this might take some time, depending on the query's replay count.\n\n## Replay Utilities\n\n#### Uploading Replays\n\n```ruby\nuploaded_replay = HotsApi.replays.upload('/path/to/Garden of Terror.StormReplay') # =\u003e #\u003cHotsApi::Models::UploadedReplay\u003e\nuploaded_replay.id            # =\u003e 2431959\nuploaded_replay.filename      # =\u003e '1745472b-94a0-2b2d-3f14-8794717545fc'\nuploaded_replay.original_name # =\u003e 'Garden of Terror.StormReplay'\nuploaded_replay.status        # =\u003e 'duplicate'\nuploaded_replay.success       # =\u003e true\nuploaded_replay.url           # =\u003e 'http://hotsapi.s3-website-eu-west-1.amazonaws.com/1745472b-94a0-2b2d-3f14-8794717545fc.StormReplay'\n```\n\nYou can also retrieve the replay for a given uploaded replay:\n\n```ruby\nuploaded_replay.replay # =\u003e #\u003cHotsApi::Models::Replay\u003e\n```\n\n#### Checking for Replay Existence\n\nCheck whether a given replay was uploaded by its fingerprint:\n\n```ruby\nHotsApi.replays.fingerprint_uploaded?('04e92942-7a46-2cf1-24f6-65dcf4ea409f') # =\u003e true\nHotsApi.replays.fingerprint_uploaded?('non-existing-fingerprint') # =\u003e false\n```\n\nCheck whether given replays were uploaded by its fingerprints:\n\n```ruby\nfingerprints = ['04e92942-7a46-2cf1-24f6-65dcf4ea409f', 'non-existing-fingerprint']\nHotsApi.replays.fingerprints_uploaded?(fingerprints) # =\u003e {'04e92942-7a46-2cf1-24f6-65dcf4ea409f' =\u003e true, 'non-existing-fingerprint' =\u003e false}\n```\n\n#### Triggering HotsLogs Uploads\n\nIf there's a replay saved on HotsApi, you can trigger uploading it to HotsLogs usings its fingerprint:\n\n```ruby\nfingerprint = '04e92942-7a46-2cf1-24f6-65dcf4ea409f'\nupload_triggered = HotsApi.replays.trigger_hotslogs_upload(fingerprint)\n\nif upload_triggered\n  puts 'Triggered HotsLogs upload'\nelse\n  puts 'Replay for given fingerprint does not exist'\nend\n```\n\nThe actual uploading to HotsLogs happens from the HotsApi server, not your local computer.\n\n#### Getting The Minimal Supported Build Version\n\n```ruby\nHotsApi.replays.minimum_supported_build # =\u003e 43905\n```\n\n## Finding Heroes\n\n#### Finding a Single Hero\n\n```ruby\nhero = HotsApi.heroes.find('Tassadar') # =\u003e #\u003cHotsApi::Models::Hero\u003e\nhero.name         # =\u003e 'Tassadar'\nhero.short_name   # =\u003e 'tassadar'\nhero.attribute_id # =\u003e 'Tass'\nhero.role         # =\u003e 'Support'\nhero.type         # =\u003e 'Ranged'\nhero.release_date # =\u003e 2014-03-13\nhero.icon_url     # =\u003e {'92x93' =\u003e 'http://s3.hotsapi.net/img/heroes/92x93/tassadar.png'}\nhero.translations # =\u003e ['тассадар', '태사다르', '塔萨达尔', '塔薩達', 'tassadar']\nhero.abilities    # =\u003e [#\u003cHotsApi::Models::Ability\u003e, …]\n\nability = hero.abilities[0] # =\u003e #\u003cHotsApi::Models::Ability\u003e\nability.name        # =\u003e 'D1'\nability.owner       # =\u003e 'Tassadar'\nability.title       # =\u003e 'Oracle'\nability.description # =\u003e 'Activate to greatly increase Tassadar's vision radius, allow him to see over obstacles, and detect stealthed units. Lasts for 5 seconds. Passive: Tassadar's Basic Attack is a Distortion Beam that slows enemy units by 20%.'\nability.icon        # =\u003e nil\nability.hotkey      # =\u003e 'D'\nability.cooldown    # =\u003e 30\nability.mana_cost   # =\u003e nil\nability.trait       # =\u003e true\n```\n\n#### Finding Heroes\n\n```ruby\nheroes = HotsApi.heroes.to_a # =\u003e [#\u003cHotsApi::Models::Hero\u003e, …]\n```\n\n## Finding Maps\n\n#### Finding a Single Map\n\n```ruby\nmap = HotsApi.maps.find('Tomb of the Spider Queen') # =\u003e #\u003cHotsApi::Models::Map\u003e\nmap.name         # =\u003e 'Tomb of the Spider Queen'\nmap.translations # =\u003e ['tumba de la reina araña', '蛛后之墓', 'tumba da aranha rainha', '거미 여왕의 무덤', 'tombe de la reine araignée', 'grabkammer der spinnenkönigin', 'grobowiec pajęczej królowej', 'tomba della regina ragno', 'гробница королевы пауков', '蛛后墓', 'tomb of the spider queen']\n```\n\n#### Finding Maps\n\n```ruby\nmap = HotsApi.maps.to_a # =\u003e [#\u003cHotsApi::Models::Map\u003e, …]\n```\n\n## Finding Talents\n\n#### Finding a Single Talent\n\n```ruby\ntalent = HotsApi.talents.find('MalfurionRevitalizeInnervateTalent') # =\u003e #\u003cHotsApi::Models::Talent\u003e\ntalent.name        # =\u003e 'MalfurionRevitalizeInnervateTalent'\ntalent.title       # =\u003e 'Revitalize'\ntalent.description # =\u003e 'Using Innervate also grants Malfurion 50 Mana and causes his Cooldowns to refresh 50% faster for 5 seconds.'\ntalent.icon        # =\u003e 'storm_ui_icon_malfurion_innerrvate.png'\ntalent.icon_url    # =\u003e {'64x64' =\u003e 'http://s3.hotsapi.net/img/talents/64x64/storm_ui_icon_malfurion_innerrvate.png'}\ntalent.ability     # =\u003e 'D1'\ntalent.sort        # =\u003e 3\ntalent.cooldown    # =\u003e nil\ntalent.mana_cost   # =\u003e nil\ntalent.level       # =\u003e 16\ntalent.heroes      # =\u003e ['Malfurion']\n```\n\n#### Finding Talents\n\n```ruby\nmap = HotsApi.talents.to_a # =\u003e [#\u003cHotsApi::Models::Talent\u003e, …]\n```\n\n## Rate Limiting\n\nThe API uses some kind of leaky bucket algorithm for rate limiting. It allows for a certain amount of requests in a given period of time and refills this pool of available requests every other second. The number of available requests depends on the resource you're requesting.\n\nWhen the client requests the API and hits the request rate limit, it will sleep for a second and try again after that. It will retry 9 times for a given query. If it hits the rate limit on its last try, it will raise a `HotsApi::Fetcher::ApiLimitReachedError`.\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\n## Contributing\n\nBug reports and pull requests are welcome on [GitHub](https://github.com/tbuehlmann/hots_api).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftbuehlmann%2Fhots_api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftbuehlmann%2Fhots_api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftbuehlmann%2Fhots_api/lists"}