Luup : Fitbit API
-
Hi
I’m trying out the Fitbit api, not only to extract some activity data for a potential plugin, but also to learn more about OAuth 2.0. More details can be found here..
In addition to having a fitbit account, to get going with any integration, you need to register your app, via here..
With an app registered, I’ve called mine “VERA” , I’ve written chunks of Lua code to support the various steps, (completed manually) my goal now is to try and put them all together into functions to be called in sequence on my Vera and/or OpenLuup.
Where I’m getting stuck is with the
authorisation code
step, which Fitbit provides appended to the domain name I registered with them when registered my app ..Here’s an example of a redirect URL that Fitbit will redirect the user too, with their associated authorisation code, which I need in the process later on to obtain the required
access token
. (More specific details are here - https://dev.fitbit.com/build/reference/web-api/developer-guide/authorization/ )https://myapp.com/callback?code=d62d6f5bdc13df79d9a5f#_=_
And it’s the
d62d6f5bdc13df79d9a5f
part of that new page/URL which I need..How best do i capture/process the URL call Fitbit issues?
I assume this is where a
luup.register_handler
would come in, and I could register my Vera handle (using https ?, as that’s required by Fitbit) as the redirect domain/url e.g.https://veraip:3480/data_request?id=lr_fitbit&
So Fitbit would redirect to..
https://veraip:3480/data_request?id=lr_fitbit&/?code=d62d6f5bdc13df79d9a5f#_=_
But that doesn’t seem to work..
Any suggestions on how to do this would be appreciated..
function FitbitRequestHandler(lul_request, lul_parameters, lul_outputformat) for k,v in pairs(lul_parameters) do luup.log ('fitbit_Handler: parameters are: '..tostring(k)..'='..tostring(v)) end if next(lul_parameters) == nil then luup.log("lul_parameters Table is empty") end local html = "</html><head>" .. "</head>" .. "<body>" .. "PRINTING" .. "\n" .. " lul_request: " .. tostring(lul_request) .. "\n" .. " lul_parameters: " .. tostring(lul_parameters) .. "\n" .. " lul_outputformat: " .. tostring(lul_outputformat) .. "\n" .. "</body></html>" return html, "text/html" end luup.register_handler("FitbitRequestHandler", "fitbit")
Thanks is advance…
-
toggledbitswrote on Jul 28, 2022, 1:49 PM last edited by toggledbits Jul 28, 2022, 9:51 AM
I'm not aware that Vera/Luup listens on port 443, which is where an
https://
request would go. Also if your Vera IP is on a non-routable address and/or behind a firewall, you'd have to open the firewall and likely NAT to it (which IMO opens up a very weak system to potential exploit). And if you could fix all that, you'd also likely have to have a valid certificate associated with the Vera endpoint. All together seems very unlikely to bear fruit.You could consider something like an AWS lambda to be the HTTPS endpoint and proxy the response back to the Vera, but you still have the issue of the lambda being able to talk to the Vera behind your firewall, and the appurtenant risks.
This is where the advancing age and limitations of the platform really show.
-
Hi @toggledbits , many thanks for responding, and i hope all is well..
Regarding the redirect domain/URL, i was wondering if the address provided could resolve locally? What if i register the localhost as the redirect url with Fitbit ? (I found the following old entry from Vera, which said
Ports 22, 80, 443, 3480, and 49451 will be blocked on all the network interfaces , except the local loopback interface (localhost / 127.0.0.1).
)Other than that, as the redirect looks to be the result of an initial http.request I make, is there a way with Lua code that I can capture the URL returned by Fitbit ?
-
toggledbitswrote on Jul 28, 2022, 7:30 PM last edited by toggledbits Jul 28, 2022, 3:32 PM
I based my comment having done
nmap
on my Vera Plus running 7.32. I think since the old post, a lot of ports got locked down or eliminated. You may recall that 3480 was on the chopping block as well, and they were going to have everyone use/port_3480/
in their URL paths as the alternative (which does work today in 7.3x). If memory serves, this was all in an attempt to improve security on the hub, but in true form, they (a) never finished the work, and (b) were closing windows when the barn doors were still open. I'm guessing they probably realized it was going to break a lot of stuff (their own cloud services as well).If FitBit's public cloud is making a callback to your Vera, you aren't going to be successful with localhost or any non-routable (RFC1918) address -- the cloud servers will not know how to reach those addresses. The callback will have to be to the public address of your router (assuming it's routable), and your router would need to be configured to NAT the request to the Vera. And as I said, that's not likely to succeed because Vera doesn't have an HTTPS endpoint, and it would be a poor security choice for FitBit's cloud to accept a callback handling a security token to an unencrypted endpoint (that is, HTTP instead of HTTPS).
-
Thanks again @toggledbits , and just to confirm there is no way in Lua to capture/record a url that’s returned by a server/service ? (It doesn’t need to do anything with it, just record what it is as a variable i can use )? Here is a similar requirement discussed using python..
I also found this, which seem like it has potential ?
-
It has nothing to do with Lua. It has to do with the capabilities of Vera (or lack thereof) and your network configuration (which hides the Vera from the outside world).
-
Thanks so much @toggledbits ..
Oh well, another Vera/OpenLuup dream, dashed by reality
-
@parkerc if it’s oauth, it’s just a redirect. If you’re able to offer an https endpoint, you’re good to go. even ngrok or localtest.me will be enough to capture the code.
-
Hi @therealdb - many thanks for responding,
it does indeed look to just be a redirect returned, and correct, it looks like I can register any https url for it to use..
what I’m not clear on , is how I can (programmatically) make the request and also read / capture the redirect url with the authorisation code parameter they add ?
I assume part of it will be so,etching like this, but how do I capture it first ?
local code = url:match"^https://myapp%.com/callback%?code=(.-)#"
-
You’ll probably need to get it by hand. Ie, write a small page with some JavaScript hosted somewhere that will get the code and that you’ll have to copy and paste manually.
4/10