diff --git a/website/api/auth/index.js b/website/api/auth/index.js index c98514e3..dfc8200f 100644 --- a/website/api/auth/index.js +++ b/website/api/auth/index.js @@ -1,4 +1,5 @@ const strava = require('../shared/strava.js'); +const withings = require('../shared/withings.js'); module.exports = async function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); @@ -20,7 +21,10 @@ module.exports = async function (context, req) { switch (segment) { case "strava": - tokens = await strava.getStravaToken(code); + tokens = await strava.getToken(code); + break; + case "withings": + tokens = await withings.getToken(code); break; default: context.log(`Unknown segment: ${segment}`); diff --git a/website/api/refresh/index.js b/website/api/refresh/index.js index 9fdac6a5..fab97651 100644 --- a/website/api/refresh/index.js +++ b/website/api/refresh/index.js @@ -1,4 +1,5 @@ const strava = require('../shared/strava.js'); +const withings = require('../shared/withings.js'); module.exports = async function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); @@ -18,7 +19,10 @@ module.exports = async function (context, req) { let body = null; switch (segment) { case "strava": - body = await strava.refreshStravaToken(refresh_token); + body = await strava.refreshToken(refresh_token); + break; + case "withings": + body = await withings.refreshToken(refresh_token); break; default: context.res = { diff --git a/website/api/shared/strava.js b/website/api/shared/strava.js index 8ca18299..b7f7bf49 100644 --- a/website/api/shared/strava.js +++ b/website/api/shared/strava.js @@ -1,6 +1,6 @@ const axios = require('axios'); -async function getStravaToken(code) { +async function getToken(code) { const params = { client_id: process.env['STRAVA_CLIENT_ID'], client_secret: process.env['STRAVA_CLIENT_SECRET'], @@ -16,7 +16,7 @@ async function getStravaToken(code) { }; } -async function refreshStravaToken(refresh_token) { +async function refreshToken(refresh_token) { const params = { client_id: process.env['STRAVA_CLIENT_ID'], client_secret: process.env['STRAVA_CLIENT_SECRET'], @@ -33,6 +33,6 @@ async function refreshStravaToken(refresh_token) { } module.exports = { - getStravaToken: getStravaToken, - refreshStravaToken: refreshStravaToken, + getToken: getToken, + refreshToken: refreshToken, } diff --git a/website/api/shared/withings.js b/website/api/shared/withings.js new file mode 100644 index 00000000..7844eedf --- /dev/null +++ b/website/api/shared/withings.js @@ -0,0 +1,42 @@ +const axios = require('axios'); + +async function getToken(code) { + const params = { + client_id: process.env['WITHINGS_CLIENT_ID'], + client_secret: process.env['WITHINGS_CLIENT_SECRET'], + code: code, + grant_type: 'authorization_code', + action: 'requesttoken', + redirect_uri: 'https://ohmyposh.dev', + }; + const resp = await axios.post('https://wbsapi.withings.net/v2/oauth2', null, { params: params }); + + return { + access_token: resp.data.access_token, + refresh_token: resp.data.refresh_token, + expires_in: resp.data.expires_in + }; +} + +async function refreshToken(refresh_token) { + const params = { + client_id: process.env['WITHINGS_CLIENT_ID'], + client_secret: process.env['WITHINGS_CLIENT_SECRET'], + refresh_token: refresh_token, + grant_type: 'refresh_token', + action: 'requesttoken', + redirect_uri: 'https://ohmyposh.dev', + }; + const resp = await axios.post('https://wbsapi.withings.net/v2/oauth2', null, { params: params }); + + return { + access_token: resp.data.access_token, + refresh_token: resp.data.refresh_token, + expires_in: resp.data.expires_in + }; +} + +module.exports = { + getToken: getToken, + refreshToken: refreshToken, +} diff --git a/website/docs/segments/strava.mdx b/website/docs/segments/strava.mdx index cb95057f..8eacf687 100644 --- a/website/docs/segments/strava.mdx +++ b/website/docs/segments/strava.mdx @@ -8,7 +8,7 @@ import StravaConnect from '/img/strava_connect.svg'; ## What -[Strava][strava] ia a popular activity tracker for bike, run or any other training. +[Strava][strava] is a popular activity tracker for bike, run or any other training. To keep up with your training goals it is important to be reminded about it. An Oh My Posh Strava segment shows your last activity, and can also indicate by a color if it is time to get away from your computer and get active. diff --git a/website/docs/segments/withings.mdx b/website/docs/segments/withings.mdx new file mode 100644 index 00000000..e80616f6 --- /dev/null +++ b/website/docs/segments/withings.mdx @@ -0,0 +1,70 @@ +--- +id: withings +title: Withings +sidebar_label: Withings +--- + +import WithingsConnect from '/img/withings.svg'; + +## What + +The [Withings][withings] health ecosystem of connected devices & apps is designed to improve daily wellbeing +and long-term health. + +## Accessing your Withings data + +To allow Oh My Posh access your Withings data you need to grant access to read your public activities. +This will give you an access and a refresh token. Paste the tokens into your Withings segment configuration. + +Click the following link to connect with Withings: + + + + + +## Sample Configuration + +```json +{ + "type": "withings", + "style": "powerline", + "powerline_symbol": "\uE0B0", + "foreground": "#ffffff", + "background": "#000000", + "template": "{{.Name}} {{.Ago}} {{.Icon}}", + "properties": { + "access_token":"11111111111111111", + "refresh_token":"1111111111111111", + "http_timeout": 1500 + } +} +``` + +## Properties + +- access_token: `string` - token from Withings login, see login link in section above. It has the following format: `1111111111111111111111111` +- refresh_token: `string` - token from Withings login, see login link in section above. It has the following format: `1111111111111111111111111` +- expires_in: `int` - the default timeout of the token from the Withings login +- http_timeout: `int` - how long do you want to wait before you want to see your prompt more than your Withings data? - defaults to 500ms +- CacheTimeout: `int` in minutes - How long do you want your numbers cached? - defaults to 5 min + +## Template ([info][templates]) + +:::note default template + +``` template +{{ if .Error }}{{ .Error }}{{ else }}{{ .Ago }}{{ end }} +``` + +::: + +### Properties + +The properties below are available for use in your template + +- `.ID`: `time` - The id of the entry + +Now, go out and be active! + +[templates]: /docs/configuration/templates +[withings]: http://www.ithings.com/ diff --git a/website/src/css/custom.css b/website/src/css/custom.css index 1ce165b4..f4208657 100644 --- a/website/src/css/custom.css +++ b/website/src/css/custom.css @@ -124,3 +124,15 @@ iframe.youtube { border-radius: 8px; margin-top: 25px; } + +.withings { + width: 150px; +} + +[data-theme='light'] .withings path { + fill: black; +} + +[data-theme='dark'] .withings path { + fill: white; +} diff --git a/website/static/img/withings.svg b/website/static/img/withings.svg new file mode 100644 index 00000000..5ffa5713 --- /dev/null +++ b/website/static/img/withings.svg @@ -0,0 +1 @@ +Withings logo - Brandlogos.net