class FitgemOauth2::Client

Constants

ACTIVITY_PERIODS
ACTIVITY_RESOURCES
API_VERSION
BODY_GOALS
BODY_TIME_SERIES_PERIODS
DEFAULT_USER_ID
FAT_PERIODS
FOOD_SERIES_PERIODS
FOOD_SERIES_RESOURCES
HR_DETAIL_LEVELS
HR_PERIODS
SLEEP_PERIODS
SLEEP_RESOURCES
SUBSCRIBABLE_TYPES
WEIGHT_PERIODS

Attributes

client_id[R]
client_secret[R]
connection[R]
token[R]
unit_system[R]
user_id[R]

Public Class Methods

new(opts) click to toggle source
# File lib/fitgem_oauth2/client.rb, line 30
def initialize(opts)
  missing = %i[client_id client_secret token] - opts.keys
  raise FitgemOauth2::InvalidArgumentError, "Missing required options: #{missing.join(',')}" unless missing.empty?

  @client_id = opts[:client_id]
  @client_secret = opts[:client_secret]
  @token = opts[:token]
  @user_id = (opts[:user_id] || DEFAULT_USER_ID)
  @unit_system = opts[:unit_system]
  @connection = Faraday.new('https://api.fitbit.com')
end

Public Instance Methods

activities() click to toggle source

Get a tree of all valid Fitbit public activities from the activities catalog as well as private custom activities the user created in the format requested. If the activity has levels, also get a list of activity level details

# File lib/fitgem_oauth2/activity.rb, line 141
def activities
  get_call('activities.json')
end
activity(id) click to toggle source

Returns the details of a specific activity in the Fitbit activities database in the format requested. @param id id of the activity for which the details need to be retrieved

# File lib/fitgem_oauth2/activity.rb, line 147
def activity(id)
  get_call("activities/#{id}.json")
end
activity_list(date, sort, limit) click to toggle source

retrieves activity list for the user

# File lib/fitgem_oauth2/activity.rb, line 117
def activity_list(date, sort, limit)
  date_param = format_date(date)
  if sort == 'asc'
    date_param = "afterDate=#{date_param}"
  elsif sort == 'desc'
    date_param = "beforeDate=#{date_param}"
  else
    raise FitgemOauth2::InvalidArgumentError, 'sort can either be asc or desc'
  end
  get_call("user/#{user_id}/activities/list.json?offset=0&limit=#{limit}&sort=#{sort}&#{date_param}")
end
activity_tcx(id) click to toggle source

retrieves activity list in the tcx format

# File lib/fitgem_oauth2/activity.rb, line 130
def activity_tcx(id)
  get_call("user/#{user_id}/activities/#{id}.tcx")
end
activity_time_series(resource: nil, start_date: nil, end_date: nil, period: nil) click to toggle source

retrieves activity time series, based on the arguments provided @param resource the resource for which the series needs to be retrieved. one of ALLOWED_RESOURCES @param start_date the start date for the series @param end_date the end date for the series. If specifying end_date, do not specify period @param period the period starting from start_date for which the series needs to be retrieved. If specifying period,

do not use end_date
# File lib/fitgem_oauth2/activity.rb, line 32
def activity_time_series(resource: nil, start_date: nil, end_date: nil, period: nil)
  unless resource && ACTIVITY_RESOURCES.include?(resource)
    raise FitgemOauth2::InvalidArgumentError, "Invalid resource: #{resource}. Valid resources are #{ACTIVITY_RESOURCES}."
  end

  raise FitgemOauth2::InvalidArgumentError, 'Start date must be specified.' unless start_date

  if period && end_date
    raise FitgemOauth2::InvalidArgumentError, 'Both period and end_date are specified. Please specify only one.'
  end

  if period && !ACTIVITY_PERIODS.include?(period)
    raise FitgemOauth2::InvalidArgumentError, "Invalid period: #{period}. Valid periods are #{ACTIVITY_PERIODS}."
  end

  first = format_date(start_date)
  second = period || format_date(end_date)
  url = ['user', user_id, 'activities', resource, 'date', first, second].join('/')
  get_call(url + '.json')
end
add_alarm(tracker_id, params) click to toggle source

adds an alaram @param tracker_id ID of the tracker to which the alaram needs to be added @param params POST parameters for adding the alarm

# File lib/fitgem_oauth2/devices.rb, line 27
def add_alarm(tracker_id, params)
  post_call("user/#{user_id}/devices/tracker/#{tracker_id}/alarms.json", params)
end
add_favorite_activity(activity_id) click to toggle source

adds the activity with the given ID to user's list of favorite activities. @param activity_id ID of the activity to be added to the list of favorite activities

# File lib/fitgem_oauth2/activity.rb, line 168
def add_favorite_activity(activity_id)
  post_call("user/#{user_id}/activities/log/favorite/#{activity_id}.json")
end
add_favorite_food(food_id) click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 5
def add_favorite_food(food_id)
  post_call("user/#{user_id}/foods/log/favorite/#{food_id}.json")
end
alarms(tracker_id) click to toggle source

returns list of alarams for the tracker ID @param tracker_id ID for the tracker for which alarams need to be retrieved

# File lib/fitgem_oauth2/devices.rb, line 20
def alarms(tracker_id)
  get_call("user/#{user_id}/devices/tracker/#{tracker_id}/alarms.json")
end
badges() click to toggle source

retrieve badges for the user

# File lib/fitgem_oauth2/friends.rb, line 42
def badges
  get_call("user/#{user_id}/badges.json")
end
body_fat_logs(start_date: nil, end_date: nil, period: nil) click to toggle source

retrieves a list of all user's body fat log entries note: provide either end_date or period @param start_date start date for the logs @param end_date (optional)end date for the logs @param period (optional) period for the logs

# File lib/fitgem_oauth2/body_measurements.rb, line 19
def body_fat_logs(start_date: nil, end_date: nil, period: nil)
  raise FitgemOauth2::InvalidArgumentError, 'must specify start_date' unless start_date

  url = ['user', user_id, 'body/log/fat/date', format_date(start_date)].join('/')
  url = [url, format_date(end_date)].join('/') if end_date

  if period
    if FAT_PERIODS.include?(period)
      url = [url, period].join('/')
    else
      raise FitgemOauth2::InvalidArgumentError, "period must be one in #{FAT_PERIODS}"
    end
  end

  url += '.json'

  get_call(url)
end
body_goals(type) click to toggle source

retrieves body goals based on the type specified @param type 'fat' or 'weight'

# File lib/fitgem_oauth2/body_measurements.rb, line 92
def body_goals(type)
  if type && BODY_GOALS.include?(type)
    get_call("user/#{user_id}/body/log/#{type}/goal.json")
  else
    raise FitgemOauth2::InvalidArgumentError, "invalid goal type : #{type}. must be one of #{BODY_GOALS}"
  end
end
body_time_series(resource: nil, start_date: nil, end_date: nil, period: nil) click to toggle source

retrieve body time series for the user; provide at least one of end_date and period @param resource (required)the resource requested ['bmi', 'fat', or 'weight'] @param start_date (required)the start date for the series @param end_date (optional)the end date for the series @param period (optional)period for the time series. valid periods are BODY_TIME_SERIES_PERIODS

# File lib/fitgem_oauth2/body_measurements.rb, line 59
def body_time_series(resource: nil, start_date: nil, end_date: nil, period: nil)
  unless resource && start_date
    raise FitgemOauth2::InvalidArgumentError, 'resource and start_date are required parameters. Please specify both.'
  end

  url = ['user', user_id, 'body', resource, 'date', format_date(start_date)].join('/')

  second = ''
  if end_date && period
    raise FitgemOauth2::InvalidArgumentError, 'Please specify either period or end date, not both.'
  end

  if period
    if BODY_TIME_SERIES_PERIODS.include?(period)
      second = period
    else
      raise FitgemOauth2::InvalidArgumentError, "Invalid Period. Body time series period must be in #{BODY_TIME_SERIES_PERIODS}"
    end
  end

  second = format_date(end_date) if end_date

  url = [url, second].join('/')

  get_call(url + '.json')
end
create_food(params) click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 45
def create_food(params)
  post_call("user/#{user_id}/foods.json", params)
end
create_meal(params) click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 29
def create_meal(params)
  post_call("user/#{user_id}/meals.json", params)
end
create_subscription(opts) click to toggle source
# File lib/fitgem_oauth2/subscriptions.rb, line 11
def create_subscription(opts)
  post_call(subscription_url(opts))
end
daily_activity_summary(date) click to toggle source

retrieves daily activity summary for a date @param date the date for which the summary is retrieved

# File lib/fitgem_oauth2/activity.rb, line 18
def daily_activity_summary(date)
  get_call("user/#{user_id}/activities/date/#{format_date(date)}.json")
end
delete_call(url) click to toggle source
# File lib/fitgem_oauth2/client.rb, line 80
def delete_call(url)
  url = "#{API_VERSION}/#{url}"
  response = connection.delete(url) {|request| set_headers(request) }
  parse_response(response)
end
delete_favorite_food(food_id) click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 9
def delete_favorite_food(food_id)
  delete_call("user/#{user_id}/foods/log/favorite/#{food_id}.json")
end
delete_food(food_id) click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 49
def delete_food(food_id)
  delete_call("user/#{user_id}/foods/#{food_id}.json")
end
delete_food_log(food_log_id) click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 41
def delete_food_log(food_log_id)
  delete_call("user/#{user_id}/foods/log/#{food_log_id}.json")
end
delete_logged_activity(id) click to toggle source

deletes a logged activity @param id id of the activity log to be deleted

# File lib/fitgem_oauth2/activity.rb, line 112
def delete_logged_activity(id)
  delete_call("user/#{user_id}/activities/#{id}.json")
end
delete_logged_body_fat(id) click to toggle source

delete logged body fat @param id ID of the log to be deleted.

# File lib/fitgem_oauth2/body_measurements.rb, line 46
def delete_logged_body_fat(id)
  delete_call("user/#{user_id}/body/log/fat/#{id}.json")
end
delete_logged_sleep(log_id) click to toggle source

deleted sleep log @param log_id ID of the sleep log that needs to be removed.

# File lib/fitgem_oauth2/sleep.rb, line 80
def delete_logged_sleep(log_id)
  delete_call("user/#{user_id}/sleep/#{log_id}.json")
end
delete_logged_weight(id) click to toggle source

delete logged weight @param id ID of the weight log to be deleted

# File lib/fitgem_oauth2/body_measurements.rb, line 151
def delete_logged_weight(id)
  delete_call("user/#{user_id}/body/log/weight/#{id}.json")
end
delete_meal(meal_id) click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 41
def delete_meal(meal_id)
  delete_call("user/#{user_id}/meals/#{meal_id}.json")
end
delete_water_log(water_log_id) click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 49
def delete_water_log(water_log_id)
  delete_call("user/#{user_id}/foods/log/water/#{water_log_id}.json")
end
devices() click to toggle source

return list of Fitbit devices linked to the account

# File lib/fitgem_oauth2/devices.rb, line 10
def devices
  get_call("user/#{user_id}/devices.json")
end
favorite_activities() click to toggle source

gets favorite activities

# File lib/fitgem_oauth2/activity.rb, line 162
def favorite_activities
  get_call("user/#{user_id}/activities/favorite.json")
end
favorite_foods() click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 17
def favorite_foods
  get_call("user/#{user_id}/foods/log/favorite.json")
end
food(id) click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 53
def food(id)
  get_call("foods/#{id}.json")
end
food_goals() click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 5
def food_goals
  get_call("user/#{user_id}/foods/log/goal.json")
end
food_logs(date) click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 9
def food_logs(date)
  get_call("user/#{user_id}/foods/log/date/#{format_date(date)}.json")
end
food_series_for_date_range(start_date, end_date) click to toggle source
# File lib/fitgem_oauth2/food/series.rb, line 5
def food_series_for_date_range(start_date, end_date)
  validate_start_date(start_date)
  validate_end_date(end_date)
  get_call(food_series_url(user_id, format_date(start_date), format_date(end_date)))
end
food_series_for_period(start_date, period) click to toggle source
# File lib/fitgem_oauth2/food/series.rb, line 11
def food_series_for_period(start_date, period)
  validate_start_date(start_date)
  validate_food_series_period(period)
  get_call(food_series_url(user_id, format_date(start_date), period))
end
food_units() click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 57
def food_units
  get_call('foods/units.json')
end
format_date(date) click to toggle source
# File lib/fitgem_oauth2/utils.rb, line 5
def format_date(date)
  return nil if date.nil?

  valid_semantic_date = %w[today yesterday].include? date
  valid_date_string = (date =~ /\d{4}\-\d{2}\-\d{2}/) == 0
  if valid_date_string
    date
  elsif valid_semantic_date
    date_from_semantic(date)
  elsif date.is_a?(Date) || date.is_a?(Time) || date.is_a?(DateTime)
    date.strftime('%Y-%m-%d')
  else
    raise FitgemOauth2::InvalidDateArgument, "Date used must be a date/time object or a string in the format YYYY-MM-DD; supplied argument is a #{date.class}"
  end
end
format_time(time) click to toggle source
# File lib/fitgem_oauth2/utils.rb, line 21
def format_time(time)
  if (time =~ /\d{2}:\d{2}/) == 0
    time
  elsif time.is_a?(DateTime) || time.is_a?(Time)
    time.strftime('%H:%M')
  else
    raise FitgemOauth2::InvalidTimeArgument, "Time used must be a DateTime/Time object or a string in the format hh:mm; supplied argument is a #{time.class}"
  end
end
frequent_activities() click to toggle source

gets frequent activities

# File lib/fitgem_oauth2/activity.rb, line 152
def frequent_activities
  get_call("user/#{user_id}/activities/frequent.json")
end
frequent_foods() click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 21
def frequent_foods
  get_call("user/#{user_id}/foods/log/frequent.json")
end
friend_invitations() click to toggle source

retrieve list of friend invitations

# File lib/fitgem_oauth2/friends.rb, line 26
def friend_invitations
  get_call("user/#{user_id}/friends/invitations.json")
end
friends() click to toggle source

retrieves list of friends for the current user

# File lib/fitgem_oauth2/friends.rb, line 6
def friends
  get_call("user/#{user_id}/friends.json")
end
friends_leaderboard() click to toggle source

retrieves leaderboard for the user

# File lib/fitgem_oauth2/friends.rb, line 11
def friends_leaderboard
  get_call("user/#{user_id}/friends/leaderboard.json")
end
get_call(url) click to toggle source
# File lib/fitgem_oauth2/client.rb, line 53
def get_call(url)
  url = "#{API_VERSION}/#{url}"
  response = connection.get(url) {|request| set_headers(request) }
  parse_response(response)
end
get_call_1_2(url) click to toggle source

This method is a helper method (like get_call) for 1.2 version of the API_VERSION This method is needed because Fitbit API supports both versions as of current date (Nov 5, 2017)

# File lib/fitgem_oauth2/client.rb, line 62
def get_call_1_2(url)
  url = "1.2/#{url}"
  response = connection.get(url) {|request| set_headers(request) }
  parse_response(response)
end
goals(period) click to toggle source

retrieve activity goals for a period @period the period for which the goals need to be retrieved. either 'weekly' or 'daily'

# File lib/fitgem_oauth2/activity.rb, line 184
def goals(period)
  unless period && %w[daily weekly].include?(period)
    raise FitgemOauth2::InvalidArgumentError, "Goal period should either be 'daily' or 'weekly'"
  end

  get_call("user/#{user_id}/activities/goals/#{period}.json")
end
hr_series_for_date_range(start_date, end_date) click to toggle source
# File lib/fitgem_oauth2/heartrate.rb, line 8
def hr_series_for_date_range(start_date, end_date)
  validate_start_date(start_date)
  validate_end_date(end_date)

  url = ['user', user_id, 'activities/heart/date', format_date(start_date), format_date(end_date)].join('/')
  get_call(url + '.json')
end
hr_series_for_period(start_date, period) click to toggle source
# File lib/fitgem_oauth2/heartrate.rb, line 16
def hr_series_for_period(start_date, period)
  validate_start_date(start_date)
  validate_hr_period(period)

  url = ['user', user_id, 'activities/heart/date', format_date(start_date), period].join('/')
  get_call(url + '.json')
end
intraday_activity_time_series(resource: nil, start_date: nil, end_date: nil, detail_level: nil, start_time: nil, end_time: nil) click to toggle source

retrieves intraday activity time series. @param resource (required) for which the intrady series is retrieved. one of 'calories', 'steps', 'distance', 'floors', 'elevation' @param start_date (required) start date for the series @param end_date (optional) end date for the series, if not specified, the series is for 1 day @param detail_level (required) level of detail for the series @param start_time (optional)start time for the series @param end_time the (optional)end time for the series. specify both start_time and end_time, if using either

# File lib/fitgem_oauth2/activity.rb, line 60
def intraday_activity_time_series(resource: nil, start_date: nil, end_date: nil, detail_level: nil,
                                  start_time: nil, end_time: nil)

  # converting to symbol to allow developer to use either 'calories' or :calories
  resource = resource.to_sym

  unless %i[calories steps distance floors elevation].include?(resource)
    raise FitgemOauth2::InvalidArgumentError,
          'Must specify resource to fetch intraday time series data for.'\
          ' One of (:calories, :steps, :distance, :floors, or :elevation) is required.'
  end

  unless start_date
    raise FitgemOauth2::InvalidArgumentError,
          'Must specify the start_date to fetch intraday time series data'
  end

  end_date ||= '1d'

  unless detail_level && %w[1min 15min].include?(detail_level)
    raise FitgemOauth2::InvalidArgumentError,
          'Must specify the data resolution to fetch intraday time series data for.'\
          ' One of (\"1d\" or \"15min\") is required.'
  end

  resource_path = [
    'user', @user_id,
    'activities', resource,
    'date', format_date(start_date),
    end_date, detail_level
  ].join('/')

  if start_time || end_time
    resource_path =
      [resource_path, 'time', format_time(start_time), format_time(end_time)].join('/')
  end
  get_call("#{resource_path}.json")
end
intraday_heartrate_time_series(start_date: nil, end_date: nil, detail_level: nil, start_time: nil, end_time: nil) click to toggle source

retrieve intraday series for heartrate

# File lib/fitgem_oauth2/heartrate.rb, line 25
def intraday_heartrate_time_series(start_date: nil, end_date: nil, detail_level: nil, start_time: nil, end_time: nil)
  intraday_series_guard(
    start_date: start_date,
    end_date: end_date,
    detail_level: detail_level,
    start_time: start_time,
    end_time: end_time
  )

  end_date = format_date(end_date) || '1d'

  url = ['user', user_id, 'activities/heart/date', format_date(start_date), end_date, detail_level].join('/')

  url = [url, 'time', format_time(start_time), format_time(end_time)].join('/') if start_time && end_time

  get_call(url + '.json')
end
invite_friend(params) click to toggle source

send an invitation to a friend @param params POST parameters for sending friend invite.

# File lib/fitgem_oauth2/friends.rb, line 21
def invite_friend(params)
  post_call("user/#{user_id}/friends/invitations.json", params)
end
lifetime_stats() click to toggle source

retrieves lifetime statistics for the user

# File lib/fitgem_oauth2/activity.rb, line 204
def lifetime_stats
  get_call("user/#{user_id}/activities.json")
end
log_activity(params) click to toggle source

logs activity using the params. @param params Hash to be posted. Refer dev.fitbit.com/docs/activity/#activity-logging for accepted

POST parameters
# File lib/fitgem_oauth2/activity.rb, line 106
def log_activity(params)
  post_call("user/#{user_id}/activities.json", params)
end
log_body_fat(params) click to toggle source

logs body fat @param params POST parameters for logging body fat

# File lib/fitgem_oauth2/body_measurements.rb, line 40
def log_body_fat(params)
  post_call("user/#{user_id}/body/log/fat.json", params)
end
log_food(params) click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 21
def log_food(params)
  post_call("user/#{user_id}/foods/log.json", params)
end
log_sleep(params) click to toggle source

log sleep @param params POST params for creating sleep log

# File lib/fitgem_oauth2/sleep.rb, line 74
def log_sleep(params)
  post_call_1_2("user/#{user_id}/sleep.json", params)
end
log_water(params) click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 29
def log_water(params)
  post_call("user/#{user_id}/foods/log/water.json", params)
end
log_weight(params) click to toggle source

logs weight for the user @param params POST message for logging weight

# File lib/fitgem_oauth2/body_measurements.rb, line 145
def log_weight(params)
  post_call("user/#{user_id}/body/log/weight.json", params)
end
meal(meal_id) click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 33
def meal(meal_id)
  get_call("user/#{user_id}/meals/#{meal_id}.json")
end
meals() click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 25
def meals
  get_call("user/#{user_id}/meals.json")
end
post_call(url, params={}) click to toggle source
# File lib/fitgem_oauth2/client.rb, line 68
def post_call(url, params={})
  url = "#{API_VERSION}/#{url}"
  response = connection.post(url, params) {|request| set_headers(request) }
  parse_response(response)
end
post_call_1_2(url, params={}) click to toggle source
# File lib/fitgem_oauth2/client.rb, line 74
def post_call_1_2(url, params={})
  url = "1.2/#{url}"
  response = connection.post(url, params) {|request| set_headers(request) }
  parse_response(response)
end
recent_activities() click to toggle source

gets recent activities

# File lib/fitgem_oauth2/activity.rb, line 157
def recent_activities
  get_call("user/#{user_id}/activities/recent.json")
end
recent_foods() click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 13
def recent_foods
  get_call("user/#{user_id}/foods/recent.json")
end
refresh_access_token(refresh_token) click to toggle source
# File lib/fitgem_oauth2/client.rb, line 42
def refresh_access_token(refresh_token)
  response = connection.post('/oauth2/token') do |request|
    encoded = Base64.strict_encode64("#{@client_id}:#{@client_secret}")
    request.headers['Authorization'] = "Basic #{encoded}"
    request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
    request.params['grant_type'] = 'refresh_token'
    request.params['refresh_token'] = refresh_token
  end
  JSON.parse(response.body)
end
remove_alarm(tracker_id, alarm_id) click to toggle source

removes an existing alaram @param tracker_id ID of the tracker from which alaram needs to be removed @params alarm_id ID of the alaram that needs to be removed

# File lib/fitgem_oauth2/devices.rb, line 42
def remove_alarm(tracker_id, alarm_id)
  delete_call("user/#{user_id}/devices/tracker/#{tracker_id}/alarms/#{alarm_id}.json")
end
remove_favorite_activity(activity_id) click to toggle source

removes the activity with given ID from list of favorite activities. @param activity_id ID of the activity to be removed from favorite activity

# File lib/fitgem_oauth2/activity.rb, line 174
def remove_favorite_activity(activity_id)
  delete_call("user/#{user_id}/activities/log/favorite/#{activity_id}.json")
end
remove_subscription(opts) click to toggle source
# File lib/fitgem_oauth2/subscriptions.rb, line 15
def remove_subscription(opts)
  delete_call(subscription_url(opts))
end
respond_to_invitation(from_user_id, params) click to toggle source

respond to a friend invite @param from_user_id the ID of the friend @param params POST parameters for responding to the invite.

# File lib/fitgem_oauth2/friends.rb, line 33
def respond_to_invitation(from_user_id, params)
  post_call("user/#{user_id}/friends/invitations/#{from_user_id}.json", params)
end
search_foods(params) click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 61
def search_foods(params)
  post_call('foods/search.json', params)
end
sleep_goal() click to toggle source

retrieve sleep goal for the user

# File lib/fitgem_oauth2/sleep.rb, line 35
def sleep_goal
  get_call("user/#{user_id}/sleep/goal.json")
end
sleep_logs(date) click to toggle source

retrieve sleep logs for a date @param date date for which sleep logs needs to be accessed

# File lib/fitgem_oauth2/sleep.rb, line 14
def sleep_logs(date)
  get_call_1_2("user/#{user_id}/sleep/date/#{format_date(date)}.json")
end
sleep_logs_by_date_range(start_date, end_date) click to toggle source
# File lib/fitgem_oauth2/sleep.rb, line 18
def sleep_logs_by_date_range(start_date, end_date)
  get_call_1_2("user/#{user_id}/sleep/date/#{format_date(start_date)}/#{format_date(end_date)}.json")
end
sleep_logs_list(date, sort, limit) click to toggle source
# File lib/fitgem_oauth2/sleep.rb, line 22
def sleep_logs_list(date, sort, limit)
  date_param = format_date(date)
  if sort == 'asc'
    date_param = "afterDate=#{date_param}"
  elsif sort == 'desc'
    date_param = "beforeDate=#{date_param}"
  else
    raise FitgemOauth2::InvalidArgumentError, 'sort can either be asc or desc'
  end
  get_call_1_2("user/#{user_id}/sleep/list.json?#{date_param}&offset=0&sort=#{sort}&limit=#{limit}")
end
sleep_time_series(resource: nil, start_date: nil, end_date: nil, period: nil) click to toggle source

retrieve time series data for sleep @param resource sleep resource to be requested @param start_date starting date for sleep time series @param end_date ending date for sleep time series @param period period for sleep time series

# File lib/fitgem_oauth2/sleep.rb, line 50
def sleep_time_series(resource: nil, start_date: nil, end_date: nil, period: nil)
  raise FitgemOauth2::InvalidArgumentError, 'Start date not provided.' unless start_date

  unless resource && SLEEP_RESOURCES.include?(resource)
    raise FitgemOauth2::InvalidArgumentError, "Invalid resource: #{resource}. Valid resources are #{SLEEP_RESOURCES}."
  end

  if period && end_date
    raise FitgemOauth2::InvalidArgumentError, 'Both end_date and period specified. Specify only one.'
  end

  if period && !SLEEP_PERIODS.include?(period)
    raise FitgemOauth2::InvalidArgumentError, "Invalid period: #{period}. Valid periods are #{SLEEP_PERIODS}."
  end

  second = period || format_date(end_date)

  url = ['user', user_id, 'sleep', resource, 'date', format_date(start_date), second].join('/')

  get_call(url + '.json')
end
subscriptions(opts) click to toggle source
# File lib/fitgem_oauth2/subscriptions.rb, line 7
def subscriptions(opts)
  get_call(subscription_url(opts))
end
update_activity_goals(period, params) click to toggle source

update activity goals @param period period for the goal ('weekly' or 'daily') @param params the POST params for the request. Refer to Fitbit documentation for accepted format

# File lib/fitgem_oauth2/activity.rb, line 195
def update_activity_goals(period, params)
  unless period && %w[daily weekly].include?(period)
    raise FitgemOauth2::InvalidArgumentError, "Goal period should either be 'daily' or 'weekly'"
  end

  post_call("user/#{user_id}/activities/goals/#{period}.json", params)
end
update_alarm(tracker_id, alarm_id, params) click to toggle source

update an existing alarm @param tracker_id ID of the tracker to which alaram needs to be added. @param alarm_id ID of the alarm that needs to be updated @param params POST parameters for updating the alarm

# File lib/fitgem_oauth2/devices.rb, line 35
def update_alarm(tracker_id, alarm_id, params)
  post_call("user/#{user_id}/devices/tracker/#{tracker_id}/alarms/#{alarm_id}.json", params)
end
update_body_fat_goal(params) click to toggle source

update body fat goal @param params POST params for updating body fat goal

# File lib/fitgem_oauth2/body_measurements.rb, line 102
def update_body_fat_goal(params)
  post_call("user/#{user_id}/body/log/fat/goal.json", params)
end
update_food_goal(params) click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 33
def update_food_goal(params)
  post_call("user/#{user_id}/foods/log/goal.json", params)
end
update_food_log(food_log_id, params) click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 25
def update_food_log(food_log_id, params)
  post_call("user/#{user_id}/foods/log/#{food_log_id}.json", params)
end
update_meal(meal_id, params) click to toggle source
# File lib/fitgem_oauth2/food/metadata.rb, line 37
def update_meal(meal_id, params)
  post_call("user/#{user_id}/meals/#{meal_id}.json", params)
end
update_sleep_goal(params) click to toggle source

update sleep goal @param params POST parameters for updating sleep goal

# File lib/fitgem_oauth2/sleep.rb, line 41
def update_sleep_goal(params)
  post_call("user/#{user_id}/sleep/goal.json", params)
end
update_water_goal(params) click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 37
def update_water_goal(params)
  post_call("user/#{user_id}/foods/log/water/goal.json", params)
end
update_water_log(water_log_id, params) click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 45
def update_water_log(water_log_id, params)
  post_call("user/#{user_id}/foods/log/water/#{water_log_id}.json", params)
end
update_weight_goal(params) click to toggle source

update weight goal @param params POST params for updating weight goal

# File lib/fitgem_oauth2/body_measurements.rb, line 108
def update_weight_goal(params)
  post_call("user/#{user_id}/body/log/weight/goal.json", params)
end
user_info() click to toggle source
# File lib/fitgem_oauth2/users.rb, line 5
def user_info
  get_call("user/#{user_id}/profile.json")
end
validate_end_date(end_date) click to toggle source
# File lib/fitgem_oauth2/utils.rb, line 35
def validate_end_date(end_date)
  raise FitgemOauth2::InvalidArgumentError, 'Please specify a valid end date.' unless end_date
end
validate_start_date(start_date) click to toggle source
# File lib/fitgem_oauth2/utils.rb, line 31
def validate_start_date(start_date)
  raise FitgemOauth2::InvalidArgumentError, 'Please specify a valid start date.' unless start_date
end
water_goal() click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 17
def water_goal
  get_call("user/#{user_id}/foods/log/water/goal.json")
end
water_logs(date) click to toggle source
# File lib/fitgem_oauth2/food/collection.rb, line 13
def water_logs(date)
  get_call("user/#{user_id}/foods/log/water/date/#{format_date(date)}.json")
end
water_series_for_date_range(start_date, end_date) click to toggle source
# File lib/fitgem_oauth2/food/series.rb, line 17
def water_series_for_date_range(start_date, end_date)
  validate_start_date(start_date)
  validate_end_date(end_date)
  get_call(water_series_url(user_id, format_date(start_date), format_date(end_date)))
end
water_series_for_period(start_date, period) click to toggle source
# File lib/fitgem_oauth2/food/series.rb, line 23
def water_series_for_period(start_date, period)
  validate_start_date(start_date)
  validate_food_series_period(period)
  get_call(water_series_url(user_id, format_date(start_date), period))
end
weight_logs(start_date: nil, end_date: nil, period: nil) click to toggle source

retrieve weight logs; specify either the end_date or period @param start_date start date for the logs @param end_date (optional)end_date for the logs @param period (optional)period for the logs

# File lib/fitgem_oauth2/body_measurements.rb, line 120
def weight_logs(start_date: nil, end_date: nil, period: nil)
  raise FitgemOauth2::InvalidArgumentError, 'start_date not specified.' unless start_date

  if period && end_date
    raise FitgemOauth2::InvalidArgumentError, 'both end_date and period specified. please provide only one.'
  end

  if period
    unless WEIGHT_PERIODS.include?(period)
      raise FitgemOauth2::InvalidArgumentError, "valid period not specified. please choose a period from #{WEIGHT_PERIODS}"
    end
  end

  first = format_date(start_date)
  url = ['user', user_id, 'body/log/weight/date', first].join('/')
  if period || end_date
    second = period || format_date(end_date)
    url = [url, second].join('/')
  end

  get_call(url + '.json')
end

Protected Instance Methods

subscription_url(opts) click to toggle source
# File lib/fitgem_oauth2/subscriptions.rb, line 21
def subscription_url(opts)
  type = opts[:type] || :all
  subscription_id = opts[:subscription_id]

  url = ['user', user_id]
  url << type unless type == :all
  url << 'apiSubscriptions'
  url << subscription_id if subscription_id

  url.join('/') + '.json'
end

Private Instance Methods

date_from_semantic(semantic) click to toggle source
# File lib/fitgem_oauth2/utils.rb, line 41
def date_from_semantic(semantic)
  if semantic === 'yesterday'
    (Date.today - 1).strftime('%Y-%m-%d')
  elsif semantic == 'today'
    Date.today.strftime('%Y-%m-%d')
  end
end
food_series_url(user_id, start_date, end_date_or_period) click to toggle source
# File lib/fitgem_oauth2/food.rb, line 20
def food_series_url(user_id, start_date, end_date_or_period)
  ['user', user_id, 'foods/log/caloriesIn', 'date', start_date, end_date_or_period].join('/') + '.json'
end
intraday_series_guard(start_date:, end_date:, detail_level:, start_time:, end_time:) click to toggle source
# File lib/fitgem_oauth2/heartrate.rb, line 51
def intraday_series_guard(start_date:, end_date:, detail_level:, start_time:, end_time:)
  raise FitgemOauth2::InvalidArgumentError, 'Start date not provided.' unless start_date

  unless detail_level && HR_DETAIL_LEVELS.include?(detail_level)
    raise FitgemOauth2::InvalidArgumentError, "Please specify the defail level. Detail level should be one of #{HR_DETAIL_LEVELS}."
  end

  if (start_time && !end_time) || (end_time && !start_time)
    raise FitgemOauth2::InvalidArgumentError, 'Either specify both the start_time and end_time or specify neither.'
  end
end
parse_response(response) click to toggle source
# File lib/fitgem_oauth2/client.rb, line 96
def parse_response(response)
  headers_to_keep = %w[fitbit-rate-limit-limit fitbit-rate-limit-remaining fitbit-rate-limit-reset]

  error_handler = {
    200 => lambda {
      body = JSON.parse(response.body)
      body = {body: body} if body.is_a?(Array)
      headers = response.headers.to_hash.keep_if do |k, _v|
        headers_to_keep.include? k
      end
      body.merge!(headers)
    },
    201 => -> {},
    204 => -> {},
    400 => -> { raise FitgemOauth2::BadRequestError },
    401 => -> { raise FitgemOauth2::UnauthorizedError },
    403 => -> { raise FitgemOauth2::ForbiddenError },
    404 => -> { raise FitgemOauth2::NotFoundError },
    429 => -> { raise FitgemOauth2::ApiLimitError },
    500..599 => -> { raise FitgemOauth2::ServerError }
  }

  fn = error_handler.find {|k, _| k === response.status }
  if fn.nil?
    raise StandardError, "Unexpected response status #{response.status}"
  else
    fn.last.call
  end
end
set_headers(request) click to toggle source
# File lib/fitgem_oauth2/client.rb, line 90
def set_headers(request)
  request.headers['Authorization'] = "Bearer #{token}"
  request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
  request.headers['Accept-Language'] = unit_system unless unit_system.nil?
end
validate_food_series_period(period) click to toggle source
# File lib/fitgem_oauth2/food.rb, line 14
def validate_food_series_period(period)
  unless FOOD_SERIES_PERIODS.include?(period)
    raise FitgemOauth2::InvalidArgumentError, "Invalid period: #{period}. Specify a valid period from #{FOOD_SERIES_PERIODS}"
  end
end
validate_hr_period(period) click to toggle source
# File lib/fitgem_oauth2/heartrate.rb, line 45
def validate_hr_period(period)
  unless period && HR_PERIODS.include?(period)
    raise FitgemOauth2::InvalidArgumentError, "Invalid period: #{period}. Valid periods are #{HR_PERIODS}."
  end
end
water_series_url(user_id, start_date, end_date_or_period) click to toggle source
# File lib/fitgem_oauth2/food.rb, line 24
def water_series_url(user_id, start_date, end_date_or_period)
  ['user', user_id, 'foods/log/water', 'date', start_date, end_date_or_period].join('/') + '.json'
end