Class: FitbitAPI::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/fitbit_api/body.rb,
lib/fitbit_api/food.rb,
lib/fitbit_api/user.rb,
lib/fitbit_api/goals.rb,
lib/fitbit_api/sleep.rb,
lib/fitbit_api/water.rb,
lib/fitbit_api/alarms.rb,
lib/fitbit_api/client.rb,
lib/fitbit_api/devices.rb,
lib/fitbit_api/friends.rb,
lib/fitbit_api/activities.rb,
lib/fitbit_api/heart_rate.rb,
lib/fitbit_api/helpers/utils.rb

Constant Summary collapse

BODY_RESOURCES =
%w(bmi fat weight)
FOOD_RESOURCES =
%w(caloriesIn water)
SLEEP_RESOURCES =
%w(startTime timeInBed minutesAsleep awakeningsCount
minutesAwake minutesToFallAsleep minutesAfterWakeup efficiency)
ACTIVITY_RESOURCES =
%w(calories caloriesBMR steps distance floors elevation
minutesSedentary minutesLightlyActive minutesFairlyActive
minutesVeryActive activityCalories tracker/calories
tracker/steps tracker/distance tracker/floors
tracker/elevation tracker/minutesSedentary
tracker/minutesLightlyActive tracker/minutesFairlyActive
tracker/minutesVeryActive tracker/activityCalories)
ACTIVITY_INTRADAY_RESOURCES =
%w(calories steps distance floors elevation)
PERIODS =
%w(1d 7d 30d 1w 1m 3m 6m 1y max).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Client

Returns a new instance of Client.



20
21
22
23
24
25
# File 'lib/fitbit_api/client.rb', line 20

def initialize(opts={})
  validate_args(opts)
  assign_attrs(opts)
  set_client
  establish_token(opts)
end

Instance Attribute Details

#api_versionObject

Returns the value of attribute api_version.



16
17
18
# File 'lib/fitbit_api/client.rb', line 16

def api_version
  @api_version
end

#localeObject

Returns the value of attribute locale.



16
17
18
# File 'lib/fitbit_api/client.rb', line 16

def locale
  @locale
end

#scopeObject

Returns the value of attribute scope.



16
17
18
# File 'lib/fitbit_api/client.rb', line 16

def scope
  @scope
end

#snake_case_keysObject

Returns the value of attribute snake_case_keys.



16
17
18
# File 'lib/fitbit_api/client.rb', line 16

def snake_case_keys
  @snake_case_keys
end

#symbolize_keysObject

Returns the value of attribute symbolize_keys.



16
17
18
# File 'lib/fitbit_api/client.rb', line 16

def symbolize_keys
  @symbolize_keys
end

#unit_systemObject

Returns the value of attribute unit_system.



16
17
18
# File 'lib/fitbit_api/client.rb', line 16

def unit_system
  @unit_system
end

#user_idObject (readonly)

Returns the value of attribute user_id.



18
19
20
# File 'lib/fitbit_api/client.rb', line 18

def user_id
  @user_id
end

Instance Method Details

#activity(activity_id) ⇒ Object

Returns the details of a specific activity in the Fitbit activities database in the format requested.

If activity has levels, also returns a list of activity level details.


73
74
75
# File 'lib/fitbit_api/activities.rb', line 73

def activity(activity_id)
  get("activities/#{activity_id}.json")
end

#activity_intraday_time_series(resource, opts = {}) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/fitbit_api/activities.rb', line 112

def activity_intraday_time_series(resource, opts={})
  date         = opts[:date] || Date.today
  detail_level = opts[:detail_level]
  start_time   = opts[:start_time]
  end_time     = opts[:end_time]

  unless ACTIVITY_INTRADAY_RESOURCES.include?(resource)
    raise FitbitAPI::InvalidArgumentError, "Invalid resource: \"#{resource}\". Please provide one of the following: #{ACTIVITY_RESOURCES}."
  end

  if [date, detail_level].any?(&:nil?)
    raise FitbitAPI::InvalidArgumentError, 'A date and detail_level are required.'
  end

  unless %(1min 15min).include? detail_level
    raise FitbitAPI::InvalidArgumentError, "Invalid detail_level: \"#{detail_level}\". Please provide one of the following: \"1min\" or \"15min\"."
  end

  if (start_time || end_time) && !(start_time && end_time)
    raise FitbitAPI::InvalidArgumentError, 'Both start_time and end_time are required if time is being specified.'
  end

  if (start_time && end_time)
    get("user/-/activities/#{resource}/date/#{format_date(date)}/1d/#{detail_level}/time/#{format_time(start_time)}/#{format_time(end_time)}.json")
  else
    get("user/-/activities/#{resource}/date/#{format_date(date)}/1d/#{detail_level}.json")
  end
end

#activity_logs_list(opts = {}) ⇒ Object

URL Parameters

  • :beforeDate - the date; formatted in yyyy-MM-ddTHH:mm:ss

  • :afterDate - the date; formatted in yyyy-MM-ddTHH:mm:ss

  • :sort - the sort order of entries by date (asc or desc)

  • :offset - the offset number of entries. Must always be 0

  • :limit - the max of the number of entries returned (max: 20)



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/fitbit_api/activities.rb', line 58

def activity_logs_list(opts={})
  opts[:params] = {}
  param_defaults = { before_date: Date.today, after_date: nil, sort: 'desc', limit: 20, offset: 0 }

  # move param values from top-level opts into :params sub-hash
  param_defaults.each do |key, default_val|
    opts[:params][key] = opts.delete(key) || default_val
  end

  get("user/#{user_id}/activities/list.json", opts)
end

#activity_time_series(resource, opts = {}) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/fitbit_api/activities.rb', line 86

def activity_time_series(resource, opts={})
  start_date = opts[:start_date]
  end_date   = opts[:end_date] || Date.today
  period     = opts[:period]

  unless ACTIVITY_RESOURCES.include?(resource)
    raise FitbitAPI::InvalidArgumentError, "Invalid resource: \"#{resource}\". Please provide one of the following: #{ACTIVITY_RESOURCES}."
  end

  if [start_date, period].none?
    raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.'
  end

  if period && !PERIODS.include?(period)
    raise FitbitAPI::InvalidArgumentError, "Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
  end

  if period
    result = get("user/#{user_id}/activities/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
  else
    result = get("user/#{user_id}/activities/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
  end
  # remove root key from response
  result.values[0]
end

#add_alarm(tracker_id, opts = {}) ⇒ Object

POST Parameters

  • :time - time of day that the alarm vibrates with a UTC timezone offset, e.g. 07:15-08:00

  • :enabled - boolean; if false, alarm does not vibrate until enabled is set to true

  • :recurring - boolean; if false, the alarm is a single event

  • :weekDays - comma separated list of days of the week on which the alarm vibrates (MONDAY,TUESDAY)



23
24
25
# File 'lib/fitbit_api/alarms.rb', line 23

def add_alarm(tracker_id, opts={})
  post("user/#{user_id}/devices/tracker/#{tracker_id}/alarms.json", opts)
end

#add_favorite_activity(activity_id) ⇒ Object

Adds the activity with the given ID to user’s list of favorite activities.



163
164
165
# File 'lib/fitbit_api/activities.rb', line 163

def add_favorite_activity(activity_id)
  post("user/#{user_id}/activities/favorite/#{activity_id}.json")
end

#alarms(tracker_id, opts = {}) ⇒ Object

Returns a list of the set alarms connected to a user’s account.



8
9
10
# File 'lib/fitbit_api/alarms.rb', line 8

def alarms(tracker_id, opts={})
  get("user/#{user_id}/devices/tracker/#{tracker_id}/alarms.json", opts)
end

#all_activities(opts = {}) ⇒ Object

Gets a tree of all valid Fitbit public activities from

the activities catalog as well as private custom activities the user created.


44
45
46
# File 'lib/fitbit_api/activities.rb', line 44

def all_activities(opts={})
  get('activities.json', opts)
end

#auth_headerObject



51
52
53
# File 'lib/fitbit_api/client.rb', line 51

def auth_header
  { 'Authorization' => ('Basic ' + Base64.encode64(@client_id + ':' + @client_secret)) }
end

#auth_urlObject



27
28
29
# File 'lib/fitbit_api/client.rb', line 27

def auth_url
  @client.auth_code.authorize_url(redirect_uri: @redirect_uri, scope: @scope)
end

#badges(opts = {}) ⇒ Object



7
8
9
# File 'lib/fitbit_api/user.rb', line 7

def badges(opts={})
  get("user/#{user_id}/badges.json", opts)
end

#body_fat_goal(opts = {}) ⇒ Object

Retrieves a user’s current body fat percentage goal.



14
15
16
# File 'lib/fitbit_api/goals.rb', line 14

def body_fat_goal(opts={})
  get("user/-/body/log/fat/goal.json", opts)
end

#body_fat_logs(date = Date.today, opts = {}) ⇒ Object



9
10
11
# File 'lib/fitbit_api/body.rb', line 9

def body_fat_logs(date=Date.today, opts={})
  get("user/-/body/log/fat/date/#{format_date(date)}.json", opts)
end

#body_time_series(resource, opts = {}) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/fitbit_api/body.rb', line 13

def body_time_series(resource, opts={})
  start_date = opts[:start_date]
  end_date   = opts[:end_date] || Date.today
  period     = opts[:period]

  unless BODY_RESOURCES.include?(resource)
    raise FitbitAPI::InvalidArgumentError, "Invalid resource: \"#{resource}\". Please provide one of the following: #{BODY_RESOURCES}."
  end

  if [period, start_date].none?
    raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.'
  end

  if period && !PERIODS.include?(period)
    raise FitbitAPI::InvalidArgumentError, "Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
  end

  if period
    result = get("user/#{user_id}/body/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
  else
    result = get("user/#{user_id}/body/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
  end
  # remove root key from response
  result.values[0]
end

#create_or_update_daily_goals(opts = {}) ⇒ Object

POST Parameters

  • :caloriesOut - calories output goal value; integer

  • :activeMinutes - active minutes goal value; integer

  • :floors - floor goal value; integer

  • :distance - distance goal value; X.XX or integer

  • :steps - steps goal value; integer



43
44
45
# File 'lib/fitbit_api/goals.rb', line 43

def create_or_update_daily_goals(opts={})
  post("user/#{user_id}/activities/goals/daily.json", opts)
end

#create_or_update_weekly_goals(opts = {}) ⇒ Object

POST Parameters

  • :caloriesOut - calories output goal value; integer

  • :activeMinutes - active minutes goal value; integer

  • :floors - floor goal value; integer

  • :distance - distance goal value; X.XX or integer

  • :steps - steps goal value; integer



57
58
59
# File 'lib/fitbit_api/goals.rb', line 57

def create_or_update_weekly_goals(opts={})
  post("user/#{user_id}/activities/goals/weekly.json", opts)
end

#daily_activity_summary(date = Date.today, opts = {}) ⇒ Object

Retrieves a summary and list of a user’s activities and activity log entries for a given day

in the format requested using units in the unit system which corresponds to the Accept-Language header provided.


20
21
22
# File 'lib/fitbit_api/activities.rb', line 20

def daily_activity_summary(date=Date.today, opts={})
  get("user/#{user_id}/activities/date/#{format_date(date)}.json", opts)
end

#daily_goals(opts = {}) ⇒ Object

Retrieves a user’s current daily activity goals.



20
21
22
# File 'lib/fitbit_api/goals.rb', line 20

def daily_goals(opts={})
  get("user/#{user_id}/activities/goals/daily.json", opts)
end

#deep_keys_to_camel_case!(object) ⇒ Object



42
43
44
# File 'lib/fitbit_api/helpers/utils.rb', line 42

def deep_keys_to_camel_case!(object)
  deep_transform_keys!(object) { |key| to_camel_case(key, lower: true) }
end

#deep_keys_to_snake_case!(object) ⇒ Object



38
39
40
# File 'lib/fitbit_api/helpers/utils.rb', line 38

def deep_keys_to_snake_case!(object)
  deep_transform_keys!(object) { |key| to_snake_case(key, replace_dashes: true) }
end

#deep_symbolize_keys!(object) ⇒ Object



46
47
48
# File 'lib/fitbit_api/helpers/utils.rb', line 46

def deep_symbolize_keys!(object)
  deep_transform_keys!(object) { |key| key.to_sym rescue key }
end

#deep_transform_keys!(object, &block) ⇒ Object

Inspired by ActiveSupport’s implementation



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/fitbit_api/helpers/utils.rb', line 51

def deep_transform_keys!(object, &block)
  case object
  when Hash
    object.keys.each do |key|
      value = object.delete(key)
      object[yield(key)] = deep_transform_keys!(value) { |key| yield(key) }
    end
    object
  when Array
    object.map! { |e| deep_transform_keys!(e) { |key| yield(key) } }
  else
    object
  end
end

#delete(path, opts = {}) ⇒ Object



76
77
78
79
80
# File 'lib/fitbit_api/client.rb', line 76

def delete(path, opts={})
  response = token.delete(("#{@api_version}/" + path), headers: request_headers).response
  object = MultiJson.load(response.body) unless response.status == 204
  process_keys!(object, opts)
end

#delete_activity(activity_log_id) ⇒ Object

Deletes a user’s activity log entry with the given ID.



172
173
174
# File 'lib/fitbit_api/activities.rb', line 172

def delete_activity(activity_log_id)
  delete("user/#{user_id}/activities/#{activity_log_id}.json")
end

#delete_alarm(tracker_id, alarm_id, opts = {}) ⇒ Object

Deletes the user’s device alarm entry with the given ID for a given device.



48
49
50
# File 'lib/fitbit_api/alarms.rb', line 48

def delete_alarm(tracker_id, alarm_id, opts={})
  delete("user/#{user_id}/devices/tracker/#{tracker_id}/alarms/#{alarm_id}.json", opts)
end

#delete_body_fat_log(body_fat_log_id, opts = {}) ⇒ Object



51
52
53
# File 'lib/fitbit_api/body.rb', line 51

def delete_body_fat_log(body_fat_log_id, opts={})
  delete("user/#{user_id}/body/log/fat/#{body_fat_log_id}.json", opts)
end

#delete_favorite_activity(activity_id) ⇒ Object

Removes the activity with the given ID from a user’s list of favorite activities.



178
179
180
# File 'lib/fitbit_api/activities.rb', line 178

def delete_favorite_activity(activity_id)
  delete("user/#{user_id}/activities/favorite/#{activity_id}.json")
end

#delete_weight_log(weight_log_id, opts = {}) ⇒ Object



43
44
45
# File 'lib/fitbit_api/body.rb', line 43

def delete_weight_log(weight_log_id, opts={})
  delete("user/#{user_id}/body/log/weight/#{weight_log_id}.json", opts)
end

#devices(opts = {}) ⇒ Object



3
4
5
# File 'lib/fitbit_api/devices.rb', line 3

def devices(opts={})
  get("user/#{user_id}/devices.json", opts)
end

#favorite_activities(opts = {}) ⇒ Object

Returns a list of a user’s favorite activities.



37
38
39
# File 'lib/fitbit_api/activities.rb', line 37

def favorite_activities(opts={})
  get("user/#{user_id}/activities/favorite.json", opts)
end

#favorite_foods(opts = {}) ⇒ Object



17
18
19
# File 'lib/fitbit_api/food.rb', line 17

def favorite_foods(opts={})
  get("user/#{user_id}/foods/log/favorite.json", opts)
end

#food_goals(opts = {}) ⇒ Object



21
22
23
# File 'lib/fitbit_api/food.rb', line 21

def food_goals(opts={})
  get("user/#{user_id}/foods/log/goal.json", opts)
end

#food_logs(date = Date.today, opts = {}) ⇒ Object



5
6
7
# File 'lib/fitbit_api/food.rb', line 5

def food_logs(date=Date.today, opts={})
  get("user/#{user_id}/foods/log/date/#{format_date(date)}.json", opts)
end

#food_time_series(resource, opts = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/fitbit_api/food.rb', line 25

def food_time_series(resource, opts={})
  start_date = opts[:start_date]
  end_date   = opts[:end_date] || Date.today
  period     = opts[:period]

  unless FOOD_RESOURCES.include?(resource)
    raise FitbitAPI::InvalidArgumentError, "Invalid resource: \"#{resource}\". Please provide one of the following: #{FOOD_RESOURCES}."
  end

  if [period, start_date].none?
    raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.'
  end

  if period && !PERIODS.include?(period)
    raise FitbitAPI::InvalidArgumentError, "Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
  end

  if period
    result = get("user/#{user_id}/foods/log/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
  else
    result = get("user/#{user_id}/foods/log/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
  end
  # remove root key from response
  result.values[0]
end

#format_date(date) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/fitbit_api/helpers/utils.rb', line 6

def format_date(date)
  if [Date, Time, DateTime].include?(date.class)
    date.strftime('%Y-%m-%d')
  elsif date.is_a? String
    if date =~ /\d{4}\-\d{2}\-\d{2}/
      date
    else
      raise FitbitAPI::InvalidArgumentError, "Invalid argument [\"#{date}\"] - string must follow yyyy-MM-dd format."
    end
  else
    raise FitbitAPI::InvalidArgumentError, "Invalid type [#{date.class}] - provide a Date/Time/DateTime or a String(yyyy-MM-dd format)."
  end
end

#format_scope(scope) ⇒ Object



34
35
36
# File 'lib/fitbit_api/helpers/utils.rb', line 34

def format_scope(scope)
  scope.is_a?(Array) ? scope.join(' ') : scope
end

#format_time(time) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/fitbit_api/helpers/utils.rb', line 20

def format_time(time)
  if [Time, DateTime].include?(time.class)
    time.strftime('%H:%M')
  elsif time.is_a? String
    if time =~ /\d{2}\:\d{2}/
      time
    else
      raise FitbitAPI::InvalidArgumentError, "Invalid argument [\"#{time}\"] - string must follow HH:mm format."
    end
  else
    raise FitbitAPI::InvalidArgumentError, "Invalid type [#{time.class}] - provide a Time/DateTime or a String(HH:mm format)."
  end
end

#frequent_activities(opts = {}) ⇒ Object

Retrieves a list of a user’s frequent activities in the format requested using units

in the unit system which corresponds to the Accept-Language header provided.


27
28
29
# File 'lib/fitbit_api/activities.rb', line 27

def frequent_activities(opts={})
  get("user/#{user_id}/activities/frequent.json", opts)
end

#frequent_foods(opts = {}) ⇒ Object



13
14
15
# File 'lib/fitbit_api/food.rb', line 13

def frequent_foods(opts={})
  get("user/#{user_id}/foods/log/frequent.json", opts)
end

#friends(opts = {}) ⇒ Object



3
4
5
# File 'lib/fitbit_api/friends.rb', line 3

def friends(opts={})
  get("user/#{user_id}/friends.json", opts)
end

#friends_leaderboard(opts = {}) ⇒ Object



7
8
9
# File 'lib/fitbit_api/friends.rb', line 7

def friends_leaderboard(opts={})
  get("user/#{user_id}/friends/leaderboard.json", opts)
end

#get(path, opts = {}) ⇒ Object



63
64
65
66
67
68
# File 'lib/fitbit_api/client.rb', line 63

def get(path, opts={})
  params = opts.delete(:params) || {}
  response = token.get(("#{@api_version}/" + path), params: deep_keys_to_camel_case!(params), headers: request_headers).response
  object = MultiJson.load(response.body) unless response.status == 204
  process_keys!(object, opts)
end

#get_token(auth_code) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'lib/fitbit_api/client.rb', line 31

def get_token(auth_code)
  @token = @client.auth_code.get_token(
    auth_code,
    redirect_uri: @redirect_uri,
    headers: auth_header
  )
  @user_id = @token.params['user_id']
  @token
end

#heart_rate_intraday_time_series(opts = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/fitbit_api/heart_rate.rb', line 25

def heart_rate_intraday_time_series(opts={})
  date         = opts[:date] || Date.today
  detail_level = opts[:detail_level]
  start_time   = opts[:start_time]
  end_time     = opts[:end_time]

  if [date, detail_level].any?(&:nil?)
    raise FitbitAPI::InvalidArgumentError, 'A date and detail_level are required.'
  end

  unless %(1sec 1min).include? detail_level
    raise FitbitAPI::InvalidArgumentError, "Invalid detail_level: \"#{detail_level}\". Please provide one of the following: \"1sec\" or \"1min\"."
  end

  if (start_time || end_time) && !(start_time && end_time)
    raise FitbitAPI::InvalidArgumentError, 'Both start_time and end_time are required if time is being specified.'
  end

  if (start_time && end_time)
    get("user/-/activities/heart/date/#{format_date(date)}/1d/#{detail_level}/time/#{format_time(start_time)}/#{format_time(end_time)}.json")
  else
    get("user/-/activities/heart/date/#{format_date(date)}/1d/#{detail_level}.json")
  end
end

#heart_rate_time_series(opts = {}) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/fitbit_api/heart_rate.rb', line 3

def heart_rate_time_series(opts={})
  start_date = opts[:start_date]
  end_date   = opts[:end_date] || Date.today
  period     = opts[:period]

  if [period, start_date].none?
    raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.'
  end

  if period && !PERIODS.include?(period)
    raise FitbitAPI::InvalidArgumentError, "Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
  end

  if period
    result = get("user/#{user_id}/activities/heart/date/#{format_date(end_date)}/#{period}.json", opts)
  else
    result = get("user/#{user_id}/activities/heart/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
  end
  # remove root key from response
  result.values[0]
end

#lifetime_stats(opts = {}) ⇒ Object

Retrieves the user’s activity statistics in the format requested using units

in the unit system which corresponds to the Accept-Language header provided.
Activity statistics includes Lifetime and Best achievement values from the
My Achievements tile on the website dashboard.


82
83
84
# File 'lib/fitbit_api/activities.rb', line 82

def lifetime_stats(opts={})
  get("user/#{user_id}/activities.json", opts)
end

#log_activity(opts) ⇒ Object

POST Parameters

  • :activityId - activity id

  • :activityName - custom activity name. Either activity ID or activityName must be provided

  • :manualCalories - calories burned, specified manually. Required with activityName, otherwise optional

  • :startTime - activity start time; formatted in HH:mm:ss

  • :durationMillis - duration in milliseconds

  • :date - log entry date; formatted in yyyy-MM-dd

  • :distance - distance; required for logging directory activity; formatted in X.XX

  • :distanceUnit - distance measurement unit



157
158
159
# File 'lib/fitbit_api/activities.rb', line 157

def log_activity(opts)
  post("user/#{user_id}/activities.json", opts)
end

#log_body_fat(opts) ⇒ Object



47
48
49
# File 'lib/fitbit_api/body.rb', line 47

def log_body_fat(opts)
  post("user/#{user_id}/body/log/fat.json", opts)
end

#log_weight(opts) ⇒ Object



39
40
41
# File 'lib/fitbit_api/body.rb', line 39

def log_weight(opts)
  post("user/#{user_id}/body/log/weight.json", opts)
end

#post(path, opts = {}) ⇒ Object



70
71
72
73
74
# File 'lib/fitbit_api/client.rb', line 70

def post(path, opts={})
  response = token.post(("#{@api_version}/" + path), body: deep_keys_to_camel_case!(opts), headers: request_headers).response
  object = MultiJson.load(response.body) unless response.status == 204
  process_keys!(object, opts)
end

#process_keys!(object, opts = {}) ⇒ Object



82
83
84
85
86
# File 'lib/fitbit_api/client.rb', line 82

def process_keys!(object, opts={})
  deep_keys_to_snake_case!(object) if (opts[:snake_case_keys] || snake_case_keys)
  deep_symbolize_keys!(object) if (opts[:symbolize_keys] || symbolize_keys)
  return object
end

#profile(opts = {}) ⇒ Object



3
4
5
# File 'lib/fitbit_api/user.rb', line 3

def profile(opts={})
  get("user/#{user_id}/profile.json", opts)
end

#recent_activities(opts = {}) ⇒ Object



31
32
33
# File 'lib/fitbit_api/activities.rb', line 31

def recent_activities(opts={})
  get("user/#{user_id}/activities/recent.json", opts)
end

#recent_foods(opts = {}) ⇒ Object



9
10
11
# File 'lib/fitbit_api/food.rb', line 9

def recent_foods(opts={})
  get("user/#{user_id}/foods/log/recent.json", opts)
end

#refresh_token!Object



45
46
47
48
49
# File 'lib/fitbit_api/client.rb', line 45

def refresh_token!
  @token = @token.refresh!(headers: auth_header)
  @user_id ||= @token.params['user_id']
  @token
end

#request_headersObject



55
56
57
58
59
60
61
# File 'lib/fitbit_api/client.rb', line 55

def request_headers
  {
    'User-Agent' => "fitbit_api-#{FitbitAPI::VERSION} gem (#{FitbitAPI::REPO_URL})",
    'Accept-Language' => @unit_system,
    'Accept-Locale' => @locale
  }
end

#sleep_logs(date = Date.today, opts = {}) ⇒ Object



6
7
8
# File 'lib/fitbit_api/sleep.rb', line 6

def sleep_logs(date=Date.today, opts={})
  get("user/#{user_id}/sleep/date/#{format_date(date)}.json", opts)
end

#sleep_time_series(resource, opts = {}) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/fitbit_api/sleep.rb', line 10

def sleep_time_series(resource, opts={})
  start_date = opts[:start_date]
  end_date   = opts[:end_date] || Date.today
  period     = opts[:period]

  unless SLEEP_RESOURCES.include?(resource)
    raise FitbitAPI::InvalidArgumentError, "Invalid resource: \"#{resource}\". Please provide one of the following: #{SLEEP_RESOURCES}."
  end

  if [period, start_date].none?
    raise FitbitAPI::InvalidArgumentError, 'A start_date or period is required.'
  end

  if period && !PERIODS.include?(period)
    raise FitbitAPI::InvalidArgumentError, "Invalid period: \"#{period}\". Please provide one of the following: #{PERIODS}."
  end

  if period
    result = get("user/#{user_id}/activities/#{resource}/date/#{format_date(end_date)}/#{period}.json", opts)
  else
    result = get("user/#{user_id}/activities/#{resource}/date/#{format_date(start_date)}/#{format_date(end_date)}.json", opts)
  end
  # remove root key from response
  result.values[0]
end

#to_camel_case(word, opts = {}) ⇒ Object



75
76
77
78
79
80
81
# File 'lib/fitbit_api/helpers/utils.rb', line 75

def to_camel_case(word, opts={})
  string = word.to_s
  return string if string.match(/[A-Z]|[a-z]([A-Z0-9]*[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*/)
  string = word.to_s.split('_').collect(&:capitalize).join
  string.gsub!(/^\w{1}/) { |word| word.downcase } if opts[:lower]
  return string
end

#to_snake_case(word, opts = {}) ⇒ Object



66
67
68
69
70
71
72
73
# File 'lib/fitbit_api/helpers/utils.rb', line 66

def to_snake_case(word, opts={})
  string = word.to_s.dup
  return string.downcase if string.match(/\A[A-Z]+\z/)
  string.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
  string.gsub!(/([a-z])([A-Z])/, '\1_\2')
  string.gsub!('-', '_') if opts[:replace_dashes]
  string.downcase
end

#tokenObject



41
42
43
# File 'lib/fitbit_api/client.rb', line 41

def token
  @token.expired? ? refresh_token! : @token
end

#update_alarm(tracker_id, alarm_id, opts = {}) ⇒ Object

POST Parameters

  • :time - time of day that the alarm vibrates with a UTC timezone offset, e.g. 07:15-08:00

  • :enabled - boolean; if false, alarm does not vibrate until enabled is set to true

  • :recurring - boolean; if false, the alarm is a single event

  • :weekDays - comma separated list of days of the week on which the alarm vibrates (MONDAY,TUESDAY)

  • :snoozeLength - integer; minutes between alarms

  • :snoozeCount - integer; maximum snooze count

  • :label - string; label for alarm

  • :vibe - vibe pattern; only one value for now (DEFAULT)



39
40
41
# File 'lib/fitbit_api/alarms.rb', line 39

def update_alarm(tracker_id, alarm_id, opts={})
  post("user/#{user_id}/devices/tracker/#{tracker_id}/alarms/#{alarm_id}.json", opts)
end

#update_profile(opts) ⇒ Object



11
12
13
# File 'lib/fitbit_api/user.rb', line 11

def update_profile(opts)
  post("user/#{user_id}/profile.json", opts)
end

#water_logs(date = Date.today, opts = {}) ⇒ Object



3
4
5
# File 'lib/fitbit_api/water.rb', line 3

def water_logs(date=Date.today, opts={})
  get("user/#{user_id}/foods/log/water/date/#{format_date(date)}.json", opts)
end

#weekly_goals(opts = {}) ⇒ Object

Retrieves a user’s current weekly activity goals.



26
27
28
# File 'lib/fitbit_api/goals.rb', line 26

def weekly_goals(opts={})
  get("user/#{user_id}/activities/goals/weekly.json", opts)
end

#weight_goal(opts = {}) ⇒ Object

Retrieves a user’s current weight goal.



8
9
10
# File 'lib/fitbit_api/goals.rb', line 8

def weight_goal(opts={})
  get("user/-/body/log/weight/goal.json", opts)
end

#weight_logs(date = Date.today, opts = {}) ⇒ Object



5
6
7
# File 'lib/fitbit_api/body.rb', line 5

def weight_logs(date=Date.today, opts={})
  get("user/-/body/log/weight/date/#{format_date(date)}.json", opts)
end