fitbit_api 0.10.1 → 0.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 767484bcfc76da3df543118553915957931085d397929a10a4ab044aa2a0ccf8
4
- data.tar.gz: 58c722470d69043d9bed70e0234471d76f1156612c7222d1a2725a73b2acdb4e
3
+ metadata.gz: d49f9a31d98fa1fddb1ccffd11d15cbd197ccf9847e0170f2db23410b5cd6eff
4
+ data.tar.gz: b7d731600647e16ee1dad3e84371ae83fc2d38b6dd53d3ba88a796191d85e832
5
5
  SHA512:
6
- metadata.gz: febd698371e86ef605756827d51cd5d2fd669df5ac0737254b842cb15ec6912f3675578479596f0fac7eed6e02cf1fce85336b83777d01e108700763559086de
7
- data.tar.gz: 170fc85f95423adbf6179087a9912c40ed5d830bc333a6a897f40ca808188721e314f44a241811644c30243421c388af64b780fcfb9b18bd20e117ce5ac9d89d
6
+ metadata.gz: 56ebf6e543e9c1c3bc7b7aa78018151e40fb3929447af8778adb0c7f65628e9d1ef9e17b2b2f11bd7c07c5f79c81018f8a27b25fa87a4f53a5e6ad20f79c9b54
7
+ data.tar.gz: 1b5c912d4e7d80e9c0b01f0e9c5346e0d8c7c506943d03df0c6ebd5fd33b5f1239c73b78b97b4f1036fc29def97037faa549fd41f25b93883113ffaeef4ffe4d
@@ -0,0 +1,29 @@
1
+ name: Test
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ ruby-version:
16
+ - 2.6
17
+ - 2.7
18
+ - 3.0
19
+ - 3.1
20
+
21
+ steps:
22
+ - uses: actions/checkout@v3
23
+ - name: Set up Ruby
24
+ uses: ruby/setup-ruby@v1
25
+ with:
26
+ ruby-version: ${{ matrix.ruby-version }}
27
+ bundler-cache: true
28
+ - name: Run tests
29
+ run: bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ 0.12.0
2
+ ------
3
+ - Expand endpont support for foods (searching foods, creating custom foods, updating/deleting logs).
4
+ - Expand endpoint support for water logging (create, update, delete water logs).
5
+ - Expand endpoint support for sleep (list sleep logs, create/delete sleep logs).
6
+ - Expand endpoint support for goals (food, sleep, water goals).
7
+ - Add endpoint support for meals.
8
+ - Allow `get`, `post`, and `delete` methods to accept blocks.
9
+ - Switch to Github Actions for CI.
10
+ - Rename a few methods for better accuracy/clarity:
11
+ - daily_goals -> daily_activity_goals
12
+ - weekly_goals -> weekly_activity_goals
13
+ - create_or_update_daily_goals -> update_daily_activity_goals
14
+ - create_or_update_weekly_goals -> update_weekly_activity_goals
15
+
16
+ 0.11.0
17
+ ------
18
+ - Add support for subscriptions endpoints.
19
+ - Make `get` and `post` methods more ergonomic (can pass params & body directly instead of via nested object).
20
+ - Allow `delete` request method to specify query params.
21
+ - Remove per-request response payload transformations (can be set per-client).
22
+
23
+ 0.10.2
24
+ ------
25
+ - Fix docs for examples
26
+
1
27
  0.10.1
2
28
  ------
3
29
  - Fix docs for listed options
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # FitbitAPI
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/fitbit_api.svg)](https://badge.fury.io/rb/fitbit_api)
4
- [![Build Status](https://travis-ci.org/zokioki/fitbit_api.svg?branch=master)](https://travis-ci.org/zokioki/fitbit_api)
4
+ [![Test Workflow](https://github.com/zokioki/fitbit_api/actions/workflows/test.yml/badge.svg)](https://github.com/zokioki/fitbit_api/actions/workflows/test.yml)
5
5
 
6
6
  FitbitAPI provides a Ruby interface to the [Fitbit Web API](https://dev.fitbit.com/reference/web-api).
7
7
 
data/fitbit_api.gemspec CHANGED
@@ -21,8 +21,8 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_runtime_dependency 'oauth2', '~> 1.0'
23
23
 
24
- spec.add_development_dependency 'byebug'
24
+ spec.add_development_dependency 'byebug', '~> 11.0'
25
25
  spec.add_development_dependency 'bundler', '~> 2.3'
26
- spec.add_development_dependency 'rake', '>= 12.3.3'
27
- spec.add_development_dependency 'rspec'
26
+ spec.add_development_dependency 'rake', '~> 13.0'
27
+ spec.add_development_dependency 'rspec', '~> 3.11'
28
28
  end
@@ -20,32 +20,32 @@ module FitbitAPI
20
20
  #
21
21
  # @param date [Date] The date for which to retrieve the activity data.
22
22
 
23
- def daily_activity_summary(date=Date.today, opts={})
24
- get("user/#{user_id}/activities/date/#{format_date(date)}.json", opts)
23
+ def daily_activity_summary(date=Date.today)
24
+ get("user/#{user_id}/activities/date/#{format_date(date)}.json")
25
25
  end
26
26
 
27
27
  # Retrieves a list of a user's frequent activities in the format requested using
28
28
  # units in the unit system which corresponds to the Accept-Language header provided.
29
29
 
30
- def frequent_activities(opts={})
31
- get("user/#{user_id}/activities/frequent.json", opts)
30
+ def frequent_activities
31
+ get("user/#{user_id}/activities/frequent.json")
32
32
  end
33
33
 
34
- def recent_activities(opts={})
35
- get("user/#{user_id}/activities/recent.json", opts)
34
+ def recent_activities
35
+ get("user/#{user_id}/activities/recent.json")
36
36
  end
37
37
 
38
38
  # Returns a list of a user's favorite activities.
39
39
 
40
- def favorite_activities(opts={})
41
- get("user/#{user_id}/activities/favorite.json", opts)
40
+ def favorite_activities
41
+ get("user/#{user_id}/activities/favorite.json")
42
42
  end
43
43
 
44
- # Gets a tree of all valid Fitbit public activities from the activities catalog
44
+ # Gets a list of all valid Fitbit public activities from the activities catalog
45
45
  # as well as private custom activities the user created.
46
46
 
47
- def all_activities(opts={})
48
- get('activities.json', opts)
47
+ def all_activities
48
+ get('activities.json')
49
49
  end
50
50
 
51
51
  # Retrieves a list of a user's activity log entries before or after a given day
@@ -60,16 +60,9 @@ module FitbitAPI
60
60
  # @param offset [Integer] The offset number of entries. Must always be 0
61
61
  # @param limit [Integer] The max of the number of entries returned (max: 20)
62
62
 
63
- def activity_logs_list(opts={})
64
- opts[:params] = {}
65
- param_defaults = { before_date: Date.today, after_date: nil, sort: 'desc', limit: 20, offset: 0 }
66
-
67
- # move param values from top-level opts into :params sub-hash
68
- param_defaults.each do |key, default_val|
69
- opts[:params][key] = opts.delete(key) || default_val
70
- end
71
-
72
- get("user/#{user_id}/activities/list.json", opts)
63
+ def activity_logs_list(params={})
64
+ default_params = { before_date: Date.today, after_date: nil, sort: 'desc', limit: 20, offset: 0 }
65
+ get("user/#{user_id}/activities/list.json", default_params.merge(params))
73
66
  end
74
67
 
75
68
  # Returns the details of a specific activity in the Fitbit activities database in the format requested.
@@ -86,8 +79,8 @@ module FitbitAPI
86
79
  # Activity statistics includes Lifetime and Best achievement values from the
87
80
  # My Achievements tile on the website dashboard.
88
81
 
89
- def lifetime_stats(opts={})
90
- get("user/#{user_id}/activities.json", opts)
82
+ def lifetime_stats
83
+ get("user/#{user_id}/activities.json")
91
84
  end
92
85
 
93
86
  def activity_time_series(resource, opts={})
@@ -108,10 +101,11 @@ module FitbitAPI
108
101
  end
109
102
 
110
103
  if period
111
- result = get("user/#{user_id}/activities/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
104
+ result = get("user/#{user_id}/activities/#{resource}/date/#{format_date(end_date)}/#{period}.json")
112
105
  else
113
- result = get("user/#{user_id}/activities/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
106
+ result = get("user/#{user_id}/activities/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
114
107
  end
108
+
115
109
  # remove root key from response
116
110
  result.values[0]
117
111
  end
@@ -139,9 +133,9 @@ module FitbitAPI
139
133
  end
140
134
 
141
135
  if (start_time && end_time)
142
- get("user/-/activities/#{resource}/date/#{format_date(date)}/1d/#{detail_level}/time/#{format_time(start_time)}/#{format_time(end_time)}.json")
136
+ get("user/#{user_id}/activities/#{resource}/date/#{format_date(date)}/1d/#{detail_level}/time/#{format_time(start_time)}/#{format_time(end_time)}.json")
143
137
  else
144
- get("user/-/activities/#{resource}/date/#{format_date(date)}/1d/#{detail_level}.json")
138
+ get("user/#{user_id}/activities/#{resource}/date/#{format_date(date)}/1d/#{detail_level}.json")
145
139
  end
146
140
  end
147
141
 
@@ -151,7 +145,7 @@ module FitbitAPI
151
145
  # Creates log entry for an activity or user's private custom activity using units
152
146
  # in the unit system which corresponds to the Accept-Language header provided.
153
147
  #
154
- # log_activity(body: { activity_id: 90013, manual_calories: 300, duration_millis: 6000000 })
148
+ # log_activity(activity_id: 90013, manual_calories: 300, duration_millis: 6000000)
155
149
  #
156
150
  # @param activity_id [Integer, String] The activity ID
157
151
  # @param activity_name [String] Custom activity name. Either activity ID or activity_name must be provided
@@ -162,8 +156,8 @@ module FitbitAPI
162
156
  # @param distance [Integer] Distance; required for logging directory activity
163
157
  # @param distance_unit [String] Distance measurement unit
164
158
 
165
- def log_activity(opts)
166
- post("user/#{user_id}/activities.json", opts)
159
+ def log_activity(body)
160
+ post("user/#{user_id}/activities.json", body)
167
161
  end
168
162
 
169
163
  # Adds the activity with the given ID to user's list of favorite activities.
@@ -7,8 +7,8 @@ module FitbitAPI
7
7
  #
8
8
  # @params tracker_id [Integer] The ID of the tracker for which the data is returned
9
9
 
10
- def alarms(tracker_id, opts={})
11
- get("user/#{user_id}/devices/tracker/#{tracker_id}/alarms.json", opts)
10
+ def alarms(tracker_id)
11
+ get("user/#{user_id}/devices/tracker/#{tracker_id}/alarms.json")
12
12
  end
13
13
 
14
14
  # POST Alarms
@@ -16,7 +16,7 @@ module FitbitAPI
16
16
 
17
17
  # Adds the alarm settings to a given ID for a given device.
18
18
  #
19
- # add_alarm(body: { time: "07:15-08:00", enabled: true, recurring: true, week_days: "MONDAY,FRIDAY,SATURDAY" })
19
+ # add_alarm(123, time: "07:15-08:00", recurring: true, week_days: "MONDAY,FRIDAY,SATURDAY")
20
20
  #
21
21
  # @param tracker_id [Integer] The ID of the tracker for which the alarm is created
22
22
  #
@@ -25,12 +25,14 @@ module FitbitAPI
25
25
  # @param recurring [Boolean] If false, the alarm is a single event
26
26
  # @param week_days [String] Comma separated list of days of the week on which the alarm vibrates (MONDAY,TUESDAY)
27
27
 
28
- def add_alarm(tracker_id, opts={})
29
- post("user/#{user_id}/devices/tracker/#{tracker_id}/alarms.json", opts)
28
+ def add_alarm(tracker_id, body={})
29
+ post("user/#{user_id}/devices/tracker/#{tracker_id}/alarms.json", body)
30
30
  end
31
31
 
32
32
  # Updates the alarm entry with a given ID for a given device.
33
33
  #
34
+ # update_alarm(123, 987, week_days: "TUESDAY,SUNDAY")
35
+ #
34
36
  # @param tracker_id [Integer] The ID of the tracker for which the alarm is created
35
37
  # @param alarm_id [Integer] The ID of the alarm to be updated
36
38
  #
@@ -43,8 +45,8 @@ module FitbitAPI
43
45
  # @param label [String] Label for alarm
44
46
  # @param vibe [String] Vibe pattern; only one value for now (DEFAULT)
45
47
 
46
- def update_alarm(tracker_id, alarm_id, opts={})
47
- post("user/#{user_id}/devices/tracker/#{tracker_id}/alarms/#{alarm_id}.json", opts)
48
+ def update_alarm(tracker_id, alarm_id, body={})
49
+ post("user/#{user_id}/devices/tracker/#{tracker_id}/alarms/#{alarm_id}.json", body)
48
50
  end
49
51
 
50
52
  # DELETE Alarms
@@ -52,11 +54,13 @@ module FitbitAPI
52
54
 
53
55
  # Deletes the user's device alarm entry with the given ID for a given device.
54
56
  #
57
+ # delete_alarm(123, 987)
58
+ #
55
59
  # @param tracker_id [Integer] The ID of the tracker for which the alarm is to be deleted
56
60
  # @param alarm_id [Integer] The ID of the alarm to be deleted
57
61
 
58
- def delete_alarm(tracker_id, alarm_id, opts={})
59
- delete("user/#{user_id}/devices/tracker/#{tracker_id}/alarms/#{alarm_id}.json", opts)
62
+ def delete_alarm(tracker_id, alarm_id)
63
+ delete("user/#{user_id}/devices/tracker/#{tracker_id}/alarms/#{alarm_id}.json")
60
64
  end
61
65
  end
62
66
  end
@@ -2,12 +2,12 @@ module FitbitAPI
2
2
  class Client
3
3
  BODY_RESOURCES = %w(bmi fat weight)
4
4
 
5
- def weight_logs(date=Date.today, opts={})
6
- get("user/-/body/log/weight/date/#{format_date(date)}.json", opts)
5
+ def weight_logs(date=Date.today)
6
+ get("user/#{user_id}/body/log/weight/date/#{format_date(date)}.json")
7
7
  end
8
8
 
9
- def body_fat_logs(date=Date.today, opts={})
10
- get("user/-/body/log/fat/date/#{format_date(date)}.json", opts)
9
+ def body_fat_logs(date=Date.today)
10
+ get("user/#{user_id}/body/log/fat/date/#{format_date(date)}.json")
11
11
  end
12
12
 
13
13
  def body_time_series(resource, opts={})
@@ -28,28 +28,29 @@ module FitbitAPI
28
28
  end
29
29
 
30
30
  if period
31
- result = get("user/#{user_id}/body/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
31
+ result = get("user/#{user_id}/body/#{resource}/date/#{format_date(end_date)}/#{period}.json")
32
32
  else
33
- result = get("user/#{user_id}/body/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
33
+ result = get("user/#{user_id}/body/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
34
34
  end
35
+
35
36
  # remove root key from response
36
37
  result.values[0]
37
38
  end
38
39
 
39
- def log_weight(opts)
40
- post("user/#{user_id}/body/log/weight.json", opts)
40
+ def log_weight(body)
41
+ post("user/#{user_id}/body/log/weight.json", body)
41
42
  end
42
43
 
43
- def delete_weight_log(weight_log_id, opts={})
44
- delete("user/#{user_id}/body/log/weight/#{weight_log_id}.json", opts)
44
+ def delete_weight_log(weight_log_id)
45
+ delete("user/#{user_id}/body/log/weight/#{weight_log_id}.json")
45
46
  end
46
47
 
47
- def log_body_fat(opts)
48
- post("user/#{user_id}/body/log/fat.json", opts)
48
+ def log_body_fat(body)
49
+ post("user/#{user_id}/body/log/fat.json", body)
49
50
  end
50
51
 
51
- def delete_body_fat_log(body_fat_log_id, opts={})
52
- delete("user/#{user_id}/body/log/fat/#{body_fat_log_id}.json", opts)
52
+ def delete_body_fat_log(body_fat_log_id)
53
+ delete("user/#{user_id}/body/log/fat/#{body_fat_log_id}.json")
53
54
  end
54
55
  end
55
56
  end
@@ -7,7 +7,9 @@ require 'fitbit_api/body'
7
7
  require 'fitbit_api/devices'
8
8
  require 'fitbit_api/food'
9
9
  require 'fitbit_api/friends'
10
+ require 'fitbit_api/meals'
10
11
  require 'fitbit_api/sleep'
12
+ require 'fitbit_api/subscriptions'
11
13
  require 'fitbit_api/user'
12
14
  require 'fitbit_api/water'
13
15
 
@@ -46,16 +48,16 @@ module FitbitAPI
46
48
  @token
47
49
  end
48
50
 
49
- def get(path, opts={})
50
- request(:get, path, opts)
51
+ def get(path, params={}, opts={}, &block)
52
+ request(:get, path, opts.merge(params: params), &block)
51
53
  end
52
54
 
53
- def post(path, opts={})
54
- request(:post, path, opts)
55
+ def post(path, body={}, opts={}, &block)
56
+ request(:post, path, opts.merge(body: body), &block)
55
57
  end
56
58
 
57
- def delete(path, opts={})
58
- request(:delete, path, opts)
59
+ def delete(path, params={}, opts={}, &block)
60
+ request(:delete, path, opts.merge(params: params), &block)
59
61
  end
60
62
 
61
63
  private
@@ -114,8 +116,9 @@ module FitbitAPI
114
116
  refresh_token! if @token.token.empty?
115
117
  end
116
118
 
117
- def request(verb, path, opts={})
119
+ def request(verb, path, opts={}, &block)
118
120
  request_path = "#{@api_version}/#{path}"
121
+ request_headers = default_request_headers.merge(opts[:headers] || {})
119
122
  request_options = opts.merge(headers: request_headers)
120
123
 
121
124
  deep_keys_to_camel_case!(request_options[:params])
@@ -123,17 +126,17 @@ module FitbitAPI
123
126
 
124
127
  refresh_token! if auto_refresh_token && token.expired?
125
128
 
126
- response = token.public_send(verb, request_path, request_options).response
127
- object = MultiJson.load(response.body) unless response.status == 204
129
+ response = token.public_send(verb, request_path, request_options, &block).response
130
+ response_body = MultiJson.load(response.body) unless response.status == 204
128
131
 
129
- process_keys!(object, opts)
132
+ process_keys!(response_body)
130
133
  end
131
134
 
132
135
  def auth_headers
133
136
  { 'Authorization' => ('Basic ' + Base64.encode64(@client_id + ':' + @client_secret)) }
134
137
  end
135
138
 
136
- def request_headers
139
+ def default_request_headers
137
140
  {
138
141
  'User-Agent' => "fitbit_api gem (v#{FitbitAPI::VERSION})",
139
142
  'Accept-Language' => @unit_system,
@@ -141,10 +144,11 @@ module FitbitAPI
141
144
  }
142
145
  end
143
146
 
144
- def process_keys!(object, opts={})
145
- deep_keys_to_snake_case!(object) if (opts[:snake_case_keys] || snake_case_keys)
146
- deep_symbolize_keys!(object) if (opts[:symbolize_keys] || symbolize_keys)
147
- return object
147
+ def process_keys!(object)
148
+ deep_keys_to_snake_case!(object) if snake_case_keys
149
+ deep_symbolize_keys!(object) if symbolize_keys
150
+
151
+ object
148
152
  end
149
153
  end
150
154
  end
@@ -1,7 +1,7 @@
1
1
  module FitbitAPI
2
2
  class Client
3
- def devices(opts={})
4
- get("user/#{user_id}/devices.json", opts)
3
+ def devices
4
+ get("user/#{user_id}/devices.json")
5
5
  end
6
6
  end
7
7
  end
@@ -2,24 +2,83 @@ module FitbitAPI
2
2
  class Client
3
3
  FOOD_RESOURCES = %w(caloriesIn water)
4
4
 
5
- def food_logs(date=Date.today, opts={})
6
- get("user/#{user_id}/foods/log/date/#{format_date(date)}.json", opts)
5
+ def food_logs(date=Date.today)
6
+ get("user/#{user_id}/foods/log/date/#{format_date(date)}.json")
7
7
  end
8
8
 
9
- def recent_foods(opts={})
10
- get("user/#{user_id}/foods/log/recent.json", opts)
9
+ # Retrieves a list of public foods from the Fitbit foods database and private foods the user created
10
+ #
11
+ # @params query [String] The search query
12
+
13
+ def search_foods(params)
14
+ get("foods/search.json", params)
15
+ end
16
+
17
+ def recent_foods
18
+ get("user/#{user_id}/foods/log/recent.json")
19
+ end
20
+
21
+ def frequent_foods
22
+ get("user/#{user_id}/foods/log/frequent.json")
11
23
  end
12
24
 
13
- def frequent_foods(opts={})
14
- get("user/#{user_id}/foods/log/frequent.json", opts)
25
+ def favorite_foods
26
+ get("user/#{user_id}/foods/log/favorite.json")
15
27
  end
16
28
 
17
- def favorite_foods(opts={})
18
- get("user/#{user_id}/foods/log/favorite.json", opts)
29
+ # Creates a new private food for a user
30
+ #
31
+ # @params body [Hash] The POST request body
32
+
33
+ def create_food(body)
34
+ post("user/#{user_id}/foods.json", body)
19
35
  end
20
36
 
21
- def food_goals(opts={})
22
- get("user/#{user_id}/foods/log/goal.json", opts)
37
+ # Deletes a custom food created by the user
38
+ #
39
+ # @params food_id [Integer] The ID of the food to be deleted
40
+
41
+ def delete_food(food_id)
42
+ delete("user/#{user_id}/foods/#{food_id}.json")
43
+ end
44
+
45
+ # Creates a food log entry
46
+ #
47
+ # @params body [Hash] The POST request body
48
+
49
+ def create_food_log(body)
50
+ post("user/#{user_id}/foods/log.json", body)
51
+ end
52
+
53
+ # Updates the quantity or calories consumed for a user's food log entry with the given Food Log ID
54
+ #
55
+ # @params food_log_id [Integer] The ID of the food log to edit
56
+ # @params body [Hash] The POST request body
57
+
58
+ def update_food_log(food_log_id, body)
59
+ post("user/#{user_id}/foods/log/#{food_log_id}.json", body)
60
+ end
61
+
62
+ # Deletes a user's food log entry using the given log ID
63
+ #
64
+ # @params food_log_id [Integer] The id of the food log entry
65
+
66
+ def delete_food_log(food_log_id)
67
+ delete("user/#{user_id}/foods/log/#{food_log_id}.json")
68
+ end
69
+
70
+ # Adds a food with the given ID to the user's list of favorite foods
71
+
72
+ def add_favorite_food(food_id)
73
+ post("user/#{user_id}/foods/log/favorite/#{food_id}.json")
74
+ end
75
+
76
+ # Deletes a food with the given ID from the user's list of favorite foods
77
+ #
78
+ # @params food_id [Integer] The ID of the food to delete from the user's favorites
79
+
80
+ def delete_favorite_food(food_id)
81
+ delete("user/#{user_id}/foods/log/favorite/#{food_id}.json")
23
82
  end
24
83
 
25
84
  def food_time_series(resource, opts={})
@@ -40,12 +99,25 @@ module FitbitAPI
40
99
  end
41
100
 
42
101
  if period
43
- result = get("user/#{user_id}/foods/log/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
102
+ result = get("user/#{user_id}/foods/log/#{resource}/date/#{format_date(end_date)}/#{period}.json")
44
103
  else
45
- result = get("user/#{user_id}/foods/log/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
104
+ result = get("user/#{user_id}/foods/log/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
46
105
  end
106
+
47
107
  # remove root key from response
48
108
  result.values[0]
49
109
  end
110
+
111
+ # Retrieves the food locales used to search, log or create food
112
+
113
+ def food_locales
114
+ get("foods/locales.json")
115
+ end
116
+
117
+ # Retrieves a list of all valid Fitbit food units
118
+
119
+ def food_units
120
+ get("foods/units.json")
121
+ end
50
122
  end
51
123
  end
@@ -1,11 +1,11 @@
1
1
  module FitbitAPI
2
2
  class Client
3
- def friends(opts={})
4
- get("user/#{user_id}/friends.json", opts)
3
+ def friends
4
+ get("user/#{user_id}/friends.json")
5
5
  end
6
6
 
7
- def friends_leaderboard(opts={})
8
- get("user/#{user_id}/friends/leaderboard.json", opts)
7
+ def friends_leaderboard
8
+ get("user/#{user_id}/friends/leaderboard.json")
9
9
  end
10
10
  end
11
11
  end
@@ -5,26 +5,44 @@ module FitbitAPI
5
5
 
6
6
  # Retrieves a user's current weight goal.
7
7
 
8
- def weight_goal(opts={})
9
- get("user/-/body/log/weight/goal.json", opts)
8
+ def weight_goal
9
+ get("user/#{user_id}/body/log/weight/goal.json")
10
10
  end
11
11
 
12
12
  # Retrieves a user's current body fat percentage goal.
13
13
 
14
- def body_fat_goal(opts={})
15
- get("user/-/body/log/fat/goal.json", opts)
14
+ def body_fat_goal
15
+ get("user/#{user_id}/body/log/fat/goal.json")
16
16
  end
17
17
 
18
18
  # Retrieves a user's current daily activity goals.
19
19
 
20
- def daily_goals(opts={})
21
- get("user/#{user_id}/activities/goals/daily.json", opts)
20
+ def daily_activity_goals
21
+ get("user/#{user_id}/activities/goals/daily.json")
22
22
  end
23
23
 
24
24
  # Retrieves a user's current weekly activity goals.
25
25
 
26
- def weekly_goals(opts={})
27
- get("user/#{user_id}/activities/goals/weekly.json", opts)
26
+ def weekly_activity_goals
27
+ get("user/#{user_id}/activities/goals/weekly.json")
28
+ end
29
+
30
+ # Retrieves a user's current sleep goal.
31
+
32
+ def sleep_goal
33
+ get("user/#{user_id}/sleep/goal.json")
34
+ end
35
+
36
+ # Retrieves the user's current daily calorie consumption goal and/or food plan.
37
+
38
+ def food_goals
39
+ get("user/#{user_id}/foods/log/goal.json")
40
+ end
41
+
42
+ # Retrieves a user's daily water consumption goal.
43
+
44
+ def water_goal
45
+ get("user/#{user_id}/foods/log/water/goal.json")
28
46
  end
29
47
 
30
48
  # POST Goals
@@ -33,7 +51,7 @@ module FitbitAPI
33
51
  # Creates or updates a user's daily activity goals and returns a response using units
34
52
  # in the unit system which corresponds to the Accept-Language header provided.
35
53
  #
36
- # create_or_update_daily_goals(body: {calories_out: 2000, active_minutes: 90, floors: 5})
54
+ # update_daily_activity_goals(calories_out: 2000, active_minutes: 90, floors: 5)
37
55
  #
38
56
  # @param calories_out [Integer] Calories output goal value
39
57
  # @param active_minutes [Integer] Active minutes goal value
@@ -41,14 +59,14 @@ module FitbitAPI
41
59
  # @param distance [Integer, Float] Distance goal value
42
60
  # @param steps [Integer] Steps goal value
43
61
 
44
- def create_or_update_daily_goals(opts={})
45
- post("user/#{user_id}/activities/goals/daily.json", opts)
62
+ def update_daily_activity_goals(body={})
63
+ post("user/#{user_id}/activities/goals/daily.json", body)
46
64
  end
47
65
 
48
66
  # Creates or updates a user's weekly activity goals and returns a response using units
49
67
  # in the unit system which corresponds to the Accept-Language header provided.
50
68
  #
51
- # create_or_update_weekly_goals(body: { active_minutes: 300, floors: 20 })
69
+ # update_weekly_activity_goals(active_minutes: 300, floors: 20)
52
70
  #
53
71
  # @param calories_out [Integer] Calories output goal value
54
72
  # @param active_minutes [Integer] Active minutes goal value
@@ -56,8 +74,47 @@ module FitbitAPI
56
74
  # @param distance [Integer, Float] Distance goal value
57
75
  # @param steps [Integer] Steps goal value
58
76
 
59
- def create_or_update_weekly_goals(opts={})
60
- post("user/#{user_id}/activities/goals/weekly.json", opts)
77
+ def update_weekly_activity_goals(body={})
78
+ post("user/#{user_id}/activities/goals/weekly.json", body)
79
+ end
80
+
81
+ # Creates or updates a user's weight goal.
82
+ #
83
+ # @param body [Hash] the POST request body
84
+ def update_weight_goal(body)
85
+ post("user/#{user_id}/body/log/weight/goal.json", body)
86
+ end
87
+
88
+ # Creates or updates a user's body fat goal.
89
+ #
90
+ # @param body [Hash] the POST request body
91
+
92
+ def update_body_fat_goal(body)
93
+ post("user/#{user_id}/body/log/fat/goal.json", body)
94
+ end
95
+
96
+ # Create or update a user's sleep goal.
97
+ #
98
+ # @param body [Hash] the POST request body
99
+
100
+ def update_sleep_goal(body)
101
+ post("user/#{user_id}/sleep/goal.json", body)
102
+ end
103
+
104
+ # Creates or updates a user's daily calorie consumption or food plan goals.
105
+ #
106
+ # @param body [Hash] the POST request body
107
+
108
+ def update_food_goals(body)
109
+ post("user/#{user_id}/foods/log/goal.json", body)
110
+ end
111
+
112
+ # Creates or updates a user's daily water consumption goal.
113
+ #
114
+ # @param body [Hash] the POST request body
115
+
116
+ def update_water_goal(body)
117
+ post("user/#{user_id}/foods/log/water/goal.json", body)
61
118
  end
62
119
  end
63
120
  end
@@ -14,10 +14,11 @@ module FitbitAPI
14
14
  end
15
15
 
16
16
  if period
17
- result = get("user/#{user_id}/activities/heart/date/#{format_date(end_date)}/#{period}.json", opts)
17
+ result = get("user/#{user_id}/activities/heart/date/#{format_date(end_date)}/#{period}.json")
18
18
  else
19
- result = get("user/#{user_id}/activities/heart/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
19
+ result = get("user/#{user_id}/activities/heart/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
20
20
  end
21
+
21
22
  # remove root key from response
22
23
  result.values[0]
23
24
  end
@@ -41,9 +42,9 @@ module FitbitAPI
41
42
  end
42
43
 
43
44
  if (start_time && end_time)
44
- get("user/-/activities/heart/date/#{format_date(date)}/1d/#{detail_level}/time/#{format_time(start_time)}/#{format_time(end_time)}.json")
45
+ get("user/#{user_id}/activities/heart/date/#{format_date(date)}/1d/#{detail_level}/time/#{format_time(start_time)}/#{format_time(end_time)}.json")
45
46
  else
46
- get("user/-/activities/heart/date/#{format_date(date)}/1d/#{detail_level}.json")
47
+ get("user/#{user_id}/activities/heart/date/#{format_date(date)}/1d/#{detail_level}.json")
47
48
  end
48
49
  end
49
50
  end
@@ -0,0 +1,42 @@
1
+ module FitbitAPI
2
+ class Client
3
+ # Retrieves a list of meals created by the user from their food log
4
+
5
+ def meals
6
+ get("user/#{user_id}/meals.json")
7
+ end
8
+
9
+ # Retrieves a single meal created by the user from their food log given the meal id
10
+ #
11
+ # @params meal_id [Integer] The ID of the meal
12
+
13
+ def meal(meal_id)
14
+ get("user/#{user_id}/meals/#{meal_id}.json")
15
+ end
16
+
17
+ # Creates a meal with the given food
18
+ #
19
+ # @params body [Hash] The POST request body
20
+
21
+ def create_meal(body)
22
+ post("user/#{user_id}/meals.json", body)
23
+ end
24
+
25
+ # Updates an existing meal with the contents of the request
26
+ #
27
+ # @params meal_id [Integer] The ID of the meal
28
+ # @params body [Hash] The POST request body
29
+
30
+ def update_meal(meal_id, body)
31
+ post("user/#{user_id}/meals/#{meal_id}.json", body)
32
+ end
33
+
34
+ # Deletes an existing meal of the given meal ID
35
+ #
36
+ # @params meal_id [Integer] The ID of the meal
37
+
38
+ def delete_meal(meal_id)
39
+ delete("user/#{user_id}/meals/#{meal_id}.json")
40
+ end
41
+ end
42
+ end
@@ -3,8 +3,43 @@ module FitbitAPI
3
3
  SLEEP_RESOURCES = %w(startTime timeInBed minutesAsleep awakeningsCount
4
4
  minutesAwake minutesToFallAsleep minutesAfterWakeup efficiency)
5
5
 
6
- def sleep_logs(date=Date.today, opts={})
7
- get("user/#{user_id}/sleep/date/#{format_date(date)}.json", opts)
6
+ # Returns a list of a user's sleep log entries for a given date. The data returned can include sleep
7
+ # periods that began on the previous date. For example, if you request a Sleep Log for 2021-12-22,
8
+ # it may return a log entry that began the previous night on 2021-12-21, but ended on 2021-12-22.
9
+ #
10
+ # @params date [Date, String] The date for the sleep log to be returned in the format yyyy-MM-dd
11
+
12
+ def sleep_logs(date=Date.today)
13
+ get("user/#{user_id}/sleep/date/#{format_date(date)}.json")
14
+ end
15
+
16
+ # Returns a list of a user's sleep log entries before or after a given date, and specifying offset,
17
+ # limit and sort order. The data returned for different dates can include sleep periods that began
18
+ # on the previous date. For example, a sleep log entry for 2018-10-21 may have ended that day but
19
+ # started the previous night on 2018-10-20.
20
+ #
21
+ # sleep_logs_list(before_date: Date.parse('2021-05-24'), limit: 5)
22
+ #
23
+ # @param before_date [Date] Specify when filtering entries that occured before the given date
24
+ # @param after_date [Date] Specify when filtering entries that occured after the given date
25
+ # @param sort [String] the Sort order of entries by date (asc or desc)
26
+ # @param offset [Integer] The offset number of entries. Must always be 0
27
+ # @param limit [Integer] The max of the number of entries returned (max: 100)
28
+
29
+ def sleep_logs_list(params={})
30
+ default_params = { before_date: Date.today, after_date: nil, sort: 'desc', limit: 20, offset: 0 }
31
+ get("user/#{user_id}/sleep/list.json", default_params.merge(params))
32
+ end
33
+
34
+ # Creates a log entry for a sleep event
35
+
36
+ def create_sleep_log(body)
37
+ post("user/#{user_id}/sleep.json", body)
38
+ end
39
+
40
+ # Deletes a sleep log with the given log ID
41
+ def delete_sleep_log(sleep_log_id)
42
+ delete("user/#{user_id}/sleep/#{sleep_log_id}.json")
8
43
  end
9
44
 
10
45
  def sleep_time_series(resource, opts={})
@@ -25,10 +60,11 @@ module FitbitAPI
25
60
  end
26
61
 
27
62
  if period
28
- result = get("user/#{user_id}/sleep/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
63
+ result = get("user/#{user_id}/sleep/#{resource}/date/#{format_date(end_date)}/#{period}.json")
29
64
  else
30
- result = get("user/#{user_id}/sleep/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
65
+ result = get("user/#{user_id}/sleep/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
31
66
  end
67
+
32
68
  # remove root key from response
33
69
  result.values[0]
34
70
  end
@@ -0,0 +1,38 @@
1
+ module FitbitAPI
2
+ class Client
3
+ # Retrieves a list of subscriptions created by your application for a specific user.
4
+ # You can either fetch subscriptions for a specific collection or the entire list
5
+ # of subscriptions for the user.
6
+ #
7
+ # @param collection_path [String] Collection of data to retrieve notifications
8
+
9
+ def subscriptions(collection_path=nil)
10
+ get("#{subscriptions_path(collection_path)}.json")
11
+ end
12
+
13
+ # Creates a subscription to notify the application when a user has new data available.
14
+ #
15
+ # @param collection_path [String] Collection of data to retrieve notifications
16
+ # @param subscription_id [Integer] The unique ID of the subscription created by the API client application
17
+
18
+ def create_subscription(collection_path=nil, subscription_id)
19
+ post("#{subscriptions_path(collection_path)}/#{subscription_id}.json")
20
+ end
21
+
22
+ # Deletes a subscription for a specific user.
23
+ #
24
+ # @param collection_path [String] Collection of data to retrieve notifications
25
+ # @param subscription_id [Integer] The unique ID of the subscription created by the API client application
26
+
27
+ def delete_subscription(collection_path=nil, subscription_id)
28
+ delete("#{subscriptions_path(collection_path)}/#{subscription_id}.json")
29
+ end
30
+
31
+ private
32
+
33
+ def subscriptions_path(collection_path=nil)
34
+ collection_path = "#{collection_path}/" if collection_path
35
+ "user/#{user_id}/#{collection_path}apiSubscriptions"
36
+ end
37
+ end
38
+ end
@@ -1,15 +1,15 @@
1
1
  module FitbitAPI
2
2
  class Client
3
- def profile(opts={})
4
- get("user/#{user_id}/profile.json", opts)
3
+ def profile
4
+ get("user/#{user_id}/profile.json")
5
5
  end
6
6
 
7
- def badges(opts={})
8
- get("user/#{user_id}/badges.json", opts)
7
+ def badges
8
+ get("user/#{user_id}/badges.json")
9
9
  end
10
10
 
11
- def update_profile(opts)
12
- post("user/#{user_id}/profile.json", opts)
11
+ def update_profile(body)
12
+ post("user/#{user_id}/profile.json", body)
13
13
  end
14
14
  end
15
15
  end
@@ -1,3 +1,3 @@
1
1
  module FitbitAPI
2
- VERSION = '0.10.1'
2
+ VERSION = '0.12.0'
3
3
  end
@@ -1,7 +1,32 @@
1
1
  module FitbitAPI
2
2
  class Client
3
- def water_logs(date=Date.today, opts={})
4
- get("user/#{user_id}/foods/log/water/date/#{format_date(date)}.json", opts)
3
+ # Retrieves a summary and list of a user's water log entries for a given day
4
+ #
5
+ # @param date [Date] The date for which entries are to be returned
6
+ def water_logs(date=Date.today)
7
+ get("user/#{user_id}/foods/log/water/date/#{format_date(date)}.json")
8
+ end
9
+
10
+ # Create a user's water log entry
11
+ #
12
+ # @param body [Hash] The POST request body for creating the water log entry
13
+ def log_water(body)
14
+ post("user/#{user_id}/foods/log/water.json", body)
15
+ end
16
+
17
+ # Updates the quantity consumed for a user's water log entry with the given log ID
18
+ #
19
+ # @params water_log_id [Integer] The ID of the water log to be updated
20
+ # @params body [Hash] The POST request body for updating the water log
21
+ def update_water_log(water_log_id, body)
22
+ post("user/#{user_id}/foods/log/water/#{water_log_id}.json", body)
23
+ end
24
+
25
+ # Deleted a user's water log entry using the given log ID
26
+ #
27
+ # @param water_log_id [Integer] The id of the water log entry
28
+ def delete_water_log(water_log_id)
29
+ delete("user/#{user_id}/foods/log/water/#{water_log_id}.json")
5
30
  end
6
31
  end
7
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fitbit_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zoran
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-05 00:00:00.000000000 Z
11
+ date: 2022-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oauth2
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '11.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '11.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -56,39 +56,39 @@ dependencies:
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 12.3.3
61
+ version: '13.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 12.3.3
68
+ version: '13.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '3.11'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '3.11'
83
83
  description:
84
84
  email:
85
85
  executables: []
86
86
  extensions: []
87
87
  extra_rdoc_files: []
88
88
  files:
89
+ - ".github/workflows/test.yml"
89
90
  - ".gitignore"
90
91
  - ".rspec"
91
- - ".travis.yml"
92
92
  - CHANGELOG.md
93
93
  - Gemfile
94
94
  - LICENSE.txt
@@ -109,7 +109,9 @@ files:
109
109
  - lib/fitbit_api/helpers/configuration.rb
110
110
  - lib/fitbit_api/helpers/exceptions.rb
111
111
  - lib/fitbit_api/helpers/utils.rb
112
+ - lib/fitbit_api/meals.rb
112
113
  - lib/fitbit_api/sleep.rb
114
+ - lib/fitbit_api/subscriptions.rb
113
115
  - lib/fitbit_api/user.rb
114
116
  - lib/fitbit_api/version.rb
115
117
  - lib/fitbit_api/water.rb
data/.travis.yml DELETED
@@ -1,8 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.7.2
4
- - 2.6.6
5
- - 2.5.1
6
- - 2.4.2
7
- - 2.3.5
8
- before_install: gem install bundler -v 1.10.3