Skip to content

Instantly share code, notes, and snippets.

@judy-zz
Last active December 11, 2015 17:08
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save judy-zz/4631988 to your computer and use it in GitHub Desktop.
Save judy-zz/4631988 to your computer and use it in GitHub Desktop.
Load data from Livestrong MyPlate (or any other source) into FitBit.

Couple bonuses here:

  • There are two different source code files. I separate authentication from data loading. You can just as well use authenticate_fitbit.rb as a shortcut to authenticate into FitBit using OAuth, for your own purposes. Maybe loading in your other body measurements or calorie counts. Then copy the first half of load_livestrong for cues on setting up the access token, and then using it to manipulate the API.
  • Your access token is stored in a created file, auth.yml. You can then play with load_livestrong at will, without having to go through the entire OAuth process for each run.
  • Here's the API documentation. I'm only using the endpoint for creating body weight measurements.

IMPORTANT: You MUST set FITBIT_KEY and FITBIT_SECRET environment variables before running these scripts. Make sure you don't share those with anyone if forking these scripts. You can request keys here.

License: GPLv3, all the way. If you extend my code, I want to see your edits. I'm willing to hear if you want to negotiate on the license for business reasons; I just like sharing my code, that's all. :-)

require 'oauth'
require 'launchy'
require 'yaml'
require_relative 'weights'
@consumer = OAuth::Consumer.new ENV['FITBIT_KEY'], ENV['FITBIT_SECRET'],
{:site=>"https://api.fitbit.com"}
@request_token = @consumer.get_request_token
@auth = {}
puts "Launching browser..."
Launchy.open @request_token.authorize_url
puts "Enter the token you just received:"
verifier = gets.strip
@access_token = @request_token.get_access_token(:oauth_verifier => verifier)
@auth[:token] = @access_token.token
@auth[:token_secret] = @access_token.secret
File.open('auth.yml', 'w') {|f| YAML.dump(@auth, f)}
puts "Authentication done!"
puts "Continue with data dump?"
require_relative "load_livestrong" if gets.strip.downcase == "y"
require 'yaml'
require 'oauth'
require 'json'
require 'ruby-progressbar'
require_relative 'weights'
@auth = YAML.load(File.open('auth.yml')) if @auth.nil?
@consumer = OAuth::Consumer.new ENV['FITBIT_KEY'], ENV['FITBIT_SECRET'],
{:site=>"https://api.fitbit.com"} if @consumer.nil?
@access_token = OAuth::AccessToken.new(@consumer, @auth[:token], @auth[:token_secret])
measurements = JSON.parse(@access_token.get("/1/user/-/body/date/2013-01-24.json", {"Accept-Language" => "en_US"}).body)
puts "Your current weight is: #{measurements["body"]["weight"]}"
$weights.each_with_index do |w, i|
weight = sprintf("%.2f", w[:weight])
num = sprintf('%4.0f', i + 1)
result = @access_token.post(
"/1/user/-/body/log/weight.json",
{'weight' => weight, 'date' => w[:datestamp]},
{"Accept-Language" => "en_US"}
)
puts "Weight: #{weight} Date: #{w[:datestamp]} Num: #{num} of #{$weights.count}"
# # The FitBit API is supposed to be rate-limited, at 150 requests per hour. This *should*
# # sleep for 65 minutes every 140 posts; there's some buffer in case. Completely untested though!
# sleep 60*61 if i % 140 == 0
end
# This file, you'll have to build yourself. Sorry. There's no public API for getting your data
# off of Livestrong. Do this:
#
# 1. Go to the graph of your weights.
# 2. Change the date range so you get ALL of your weight measurements. Be generous.
# 3. View source, find the json that looks similar to the below data, and copy it.
# 4. Massage it into a format like the one seen below.
#
# In retrospect, knowing I wanted to turn this source code into a gist later, I would have made
# it easier to just paste the data here and parsed it with the json gem. I suppose you can still
# do that. In any case, you need a hash with the :weight and :datestamp keys, exactly as they
# are. To be honest, you could theoretically grab weight data from ANY source to import it into
# FitBit, as long as it's in the below format.
$weights = [
{weight: 264.2, weight_date: "Jan 23 2013", datestamp: "2013-01-23", unixTimestamp: 1358928000000, display: "Jan 23 2013"},
{weight: 264, weight_date: "Jan 21 2013", datestamp: "2013-01-21", unixTimestamp: 1358755200000, display: "Jan 21 2013"}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment