{"id":28219887,"url":"https://github.com/phoffer/strava","last_synced_at":"2025-07-01T02:36:45.808Z","repository":{"id":59156562,"uuid":"96054064","full_name":"phoffer/strava","owner":"phoffer","description":"Object oriented wrapper for Strava's v3 API","archived":false,"fork":false,"pushed_at":"2018-08-13T16:40:56.000Z","size":24,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-11T09:47:49.929Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/phoffer.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-07-02T23:20:32.000Z","updated_at":"2018-09-29T08:46:40.000Z","dependencies_parsed_at":"2022-09-13T20:10:54.579Z","dependency_job_id":null,"html_url":"https://github.com/phoffer/strava","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/phoffer/strava","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoffer%2Fstrava","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoffer%2Fstrava/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoffer%2Fstrava/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoffer%2Fstrava/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phoffer","download_url":"https://codeload.github.com/phoffer/strava/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoffer%2Fstrava/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262884194,"owners_count":23379349,"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":[],"created_at":"2025-05-18T03:11:40.452Z","updated_at":"2025-07-01T02:36:45.786Z","avatar_url":"https://github.com/phoffer.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Strava\n\nInteract with [Strava's v3 API](https://strava.github.io/api/). This gem is designed to be fully object oriented, so most interaction is with Strava objects. There is an existing gem [strava-api-v3](https://github.com/jaredholdcroft/strava-api-v3), which has been around much longer and has some extra functionality. It is more functional and typically deals with JSON data. \n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'strava'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install strava\n\n## API Notes\n\n### Detail Level\n\nAll Strava resources have a detail level, `{1 =\u003e meta, 2 =\u003e summary, 3 =\u003e detailed}`. Objects will have a `#get_details` method which retrieves the full object details, if supported and not already fetched.\n\n### Pagination\n\nMany Strava endpoints support optional pagination. All of these endpoints accept `:page` and `:per_page` options. These can be used like `athlete.activities(page: 3)`. Refer to the [API Coverage](#api-coverage) section for a list of endpoints supporting pagination.\n\nAll method calls including pagination will trigger an API call and return the items from that call. Any calls without pagination will return all previously downloaded items. If no requests have been made, a request without pagination will be made.\n\n## Functionality\n\n### Configuration\n\nThis is not necessary, as only the webhooks API requires application information. The values shown below are used by default if not configured manually.\n\n```ruby\nStrava.client_id = ENV['STRAVA_CLIENT_ID']\nStrava.client_secret = ENV['STRAVA_CLIENT_SECRET']\n```\n\n### Current Athlete\n\nGenerally, most of the Strava API is based off the authenticated user. Thus, most of the gem's functionality flows from the athlete class (either authenticated user or another).\n\nThe quickest way to get started is with the currently authenticated athlete:\n\n```ruby\nca = Strava::Athlete.current_athlete(access_token) # =\u003e Strava::Athlete\n```\n\nThere is also a mixin for existing classes (i.e. models). It is agnostic to DBs/adapters/etc, and only requires a method for the access token.\n\n```ruby\nclass Account \u003c ApplicationRecord\n  include Strava.model as: :athlete, via: :token, id: :strava_id\nend\nca = Account.find(1).athlete # =\u003e Strava::Athlete\n```\n\nThis will add an instance method `#athlete` to the `User` class. This returns a `Strava::Athlete`, populating the access token with `User#token` and the user ID with `User#strava_id`. All 3 parameters are optional, and the default parameters are `{ via: :access_token, as: :strava_athlete, id: nil }`.\n\nIt can also be used to go through another method, for instance, if you have separate user and account models:\n\n```ruby\nclass User \u003c ApplicationRecord\n  has_one :account\n  include Strava.model as: :athlete, via: 'account.token', id: 'account.strava_id'\nend\nca = User.find(1).athlete # =\u003e Strava::Athlete\n```\n\n### Classes\n\nMost use cases won't include manually instantiating classes. Instead, interaction starts with a user and then flows through related objects. If desired, classes can be instantiated, with two requirements:\n\n1. First argument must be either the object ID (string or integer accepted), or a hash with an `'id'` key.\n1. Either the `token` or `client` keyword argument must be passed. All API interaction requires an access_token, so instantiation does too.\n\n```ruby\nact = Strava::Activity.new(321934, token: '83ebeabdec09f6670863766f792ead24d61fe3f9')\nact = Strava::Activity.new({'id' =\u003e 321934}, client: Strava::Client.new('83ebeabdec09f6670863766f792ead24d61fe3f9'))\n```\n\n## Usage\n\n### Athlete\n\n[Strava Docs](https://strava.github.io/api/v3/athlete/)\n\nStrava uses the phrase _currently authenticated athlete_ throughout their docs, so we'll use the term _current_ to represent that athlete. With the current athlete from above, we can request data for that athlete. Some APIs can only be made on behalf of the current athlete. See Strava docs for further information.\n\n```ruby\nca.get_details              # =\u003e retrieves full representation of the athlete\nca.email                    # =\u003e \"john@applestrava.com\"\nca.firstname                # =\u003e \"John\"\nca.lastname                 # =\u003e \"Applestrava\"\nca.stats                    # =\u003e Hash of athlete stats\nca.zones                    # =\u003e Array of HR/power zones (hash)\nca.koms                     # =\u003e [Strava::SegmentEffort]\nca.friends                  # =\u003e [Strava::Athlete]\nca.followers                # =\u003e [Strava::Athlete]\nca.both_following(other_id) # =\u003e [Strava::Athlete]\n\n# listed in docs other than athlete docs\nca.clubs            # =\u003e [Strava::Club]\nca.routes           # =\u003e [Strava::Route]\nca.starred_segments # =\u003e [Strava::Segment]\n```\n\n### Activity\n\n[Strava Docs](https://strava.github.io/api/v3/activities/)\n\nStrava provides extensive data on activities. \n\n```ruby\nactivity = ca.activities.first # =\u003e Strava::Activity\nactivity.get_details           # =\u003e retrieves full representation of the activity\nactivity.comments              # =\u003e [Strava::Comment]\nactivity.kudos                 # =\u003e [Strava::Kudo]\nactivity.photos                # =\u003e [Strava::Photo]\nactivity.related               # =\u003e [Strava::Activity] activities that were matched as “with this group”\nactivity.zones                 # =\u003e Array of HR/Power zones\nactivity.laps                  # =\u003e [Strava::Lap]\nactivity.streams               # =\u003e [Strava::StreamSet] Without args, will retrieve time, distance, latlng streams\n\n# Strava Partner APIs\nactivity.comment(message)      # =\u003e Create a comment on an activity\nactivity.kudo                  # =\u003e Kudo an activity\n```\n\n### Club\n\n[Strava Docs](https://strava.github.io/api/v3/clubs/)\n\n```ruby\nclub = ca.clubs.first # =\u003e Strava::Club\nclub.get_details      # =\u003e retrieves full representation of the club\nclub.activities       # =\u003e [Strava::Activity]\nclub.group_events     # =\u003e [Strava::GroupEvent]\nclub.announcements    # =\u003e [Strava::ClubAnnouncment]\nclub.members          # =\u003e [Strava::Athlete]\nclub.admins           # =\u003e [Strava::Athlete]\nclub.join             # =\u003e Join the club as current athlete. Returns hash for success or failure\nclub.leave            # =\u003e Leave the club as current athlete. Returns hash for success or failure\n```\n\n### Group Event\n\n[Strava Docs](https://strava.github.io/api/v3/club_group_events/)\n\n```ruby\nge = club.group_events.first  # =\u003e Strava::GroupEvent\nge.get_details                # =\u003e retrieves full representation of the group event\nge.athletes                   # =\u003e [Strava::Athlete]\nge.delete                     # =\u003e Delete group event. Must have edit permissions. Returns hash of success/failure\nge.join                       # =\u003e Join the event as current athlete. Returns hash of success/failure\nge.leave                      # =\u003e Leave the event as current athlete. Returns hash of success/failure\n```\n\n### Gear\n\n[Strava Docs](https://strava.github.io/api/v3/gear/)\n\n```ruby\ngear = ca.gear.first  # =\u003e Strava::Gear\ngear.get_details      # =\u003e retrieves full representation of the gear\n```\n\n### Route\n\n[Strava Docs](https://strava.github.io/api/v3/routes/)\n\n```ruby\nroute = ca.routes.first # =\u003e Strava::Route\nroute.get_details       # =\u003e retrieves full representation of the route\nroute.streams           # =\u003e [Strava::StreamSet] Retrieves distance, altitude, latlng streams (no other streams available).\n```\n\n### Running Race\n\n[Strava Docs](https://strava.github.io/api/v3/running_races/)\n\nRaces are different, as they don't flow from the current athlete. However, the Race APIs still require authentication. As such, there are a couple ways to retrieve races:\n\n```ruby\n# List races via the current athlete. Probably the simplest way.\nraces = ca.list_races\n\n# List races via the `RunningRace` class. Must provide an API client.\nclient = Strava::Client.new('83ebeabdec09f6670863766f792ead24d61fe3f9')\nraces = RunningRace.list_races(client)\n\n# List races via a client. The gem is designed to minimize interaction with the Client class, but it's available if desired.\nclient = Strava::Client.new('83ebeabdec09f6670863766f792ead24d61fe3f9')\nraces = client.list_races\n\n# All methods accept an optional argument for the year:\nraces = ca.list_races(2016)\nraces = RunningRace.list_races(client, 2016)\nraces = client.list_races(2016)\n\n# The only API interaction available for a race is to retrieve more details.\nraces.first.get_details # Returns the race, with full representation.\n```\n\n### Segment\n\n[Strava Docs](https://strava.github.io/api/v3/segments/)\n\n```ruby\nsegment = ca.starred_segments.first # =\u003e Strava::Segment\nsegment.get_details                 # =\u003e retrieves full representation of the segment\nsegment.efforts                     # =\u003e [Strava::SegmentEffort] Segment efforts for the current athlete\nsegment.streams                     # =\u003e [Strava::StreamSet] Retrieves distance, altitude, latlng streams (no other streams available).\nsegment.star                        # =\u003e Star the segment, on behalf of current athlete. Returns hash of success/failure.\nsegment.unstar                      # =\u003e Unstar the segment, on behalf of current athlete. Returns hash of success/failure.\n\n# segment explorer is similar to the running races API. It can be called via a user:\nbounds = '37.821362,-122.505373,37.842038,-122.465977' # =\u003e ‘south,west,north,east\nca.segment_explorer(bounds)\n\n# Or via the `Segment` class. Must provide an API client.\nsegments = Segment.explorer(client, bounds)\n\n# or via a client (discouraged)\nclient.segment_explorer(bounds)\n```\n\n\n### Segment Effort\n\n[Strava Docs](https://strava.github.io/api/v3/efforts/)\n\n```ruby\neffort = segment.efforts.first  # =\u003e Strava::SegmentEffort\neffort.get_details              # =\u003e retrieves full representation of the segment\neffort.streams                  # =\u003e [Strava::StreamSet] Retrieves distance, altitude, latlng streams (no other streams available).\n```\n\n### StreamSet\n\n[Strava Docs](https://strava.github.io/api/v3/streams/)\n\n```ruby\nactivity.streams\nactivity.streams.all\n```\n\n### Uploads\n\n[Strava Docs](https://strava.github.io/api/v3/uploads/)\n\nUploads haven't been implemented yet :( It will be soon though!\n\n### Auth\n\n[Strava Docs](https://strava.github.io/api/v3/oauth/)\n\nAuth hasn't been implemented yet :( However, most apps are probably using omniauth, so this is a bit lower on the priority list.\n\n### Webhooks\n\n[Strava Docs](https://strava.github.io/api/v3/events/)\n\nWebhooks haven't been implemented yet :( It will be soon though!\n\n## TODO\n\n1. Continue adding YARD Documentation\n1. Add tests\n1. Submit PRs to existing gem\n\n## Why\n\nQ. Why aren't there tests?\nA. Tests are in progress. Unfortunately, there is no test environment for Strava, and virtually everything is based on hitting their API.\n\nQ. Why not contribute to the existing gem?\nA. I'm planning on it! But I also wanted something a bit more OO, and wanted to see what I could come up with.\n\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/phoffer/strava.\n\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoffer%2Fstrava","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphoffer%2Fstrava","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoffer%2Fstrava/lists"}