Repository navigation
Expand file tree
/
Copy pathconfig-healthsync.example
More file actions
136 lines (124 loc) · 8.04 KB
/
Copy pathconfig-healthsync.example
File metadata and controls
136 lines (124 loc) · 8.04 KB
1
2
3
4
5
6
7
8
9
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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
111
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
# HealthSync / Google Drive activities config
# Copy to /etc/healthsync-activities.conf and chmod 600 it.
# SOURCE this file (KEY="value", no spaces around =).
# --- Google OAuth credentials -----------------------------------------------
# One-time setup. Do this on your PC, not on the router.
# You need your own Google Cloud OAuth client (Desktop app type).
#
# STEP A — Create a Google Cloud project and enable the Drive API (free tier is sufficient)
# a) https://console.cloud.google.com/ → project dropdown → New Project → Create
# b) Search "Google Drive API" → Enable
#
# STEP B — Configure the OAuth consent screen
# APIs & Services → OAuth consent screen → External → Create
# Fill in app name, support email, developer contact → Save and Continue
# Scopes → Add or Remove Scopes → add https://www.googleapis.com/auth/drive.readonly → Save
# Publishing status: click "Publish App" → confirm.
# (If you leave it as "Testing", refresh tokens expire after 7 days and you must
# repeat Step E weekly. Publishing removes this limit — the token lasts as long
# as the script runs at least once every 6 months, which cron guarantees.)
#
# STEP C — Create a Desktop app OAuth 2.0 credential
# APIs & Services → Credentials → + Create Credentials → OAuth client ID
# Application type: Desktop app
# Copy Client ID and Client Secret → paste into GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET
#
# STEP D — Get the refresh token via PowerShell (one-time, on your dev PC)
# Run the block below in PowerShell. It opens a browser, captures the redirect,
# and exchanges the code for tokens. Copy the refresh_token value.
#
# $CLIENT_ID = "YOUR_CLIENT_ID"
# $CLIENT_SECRET = "YOUR_CLIENT_SECRET"
# $PORT = 8765; $redirect = "http://localhost:$PORT"
# $scope = [uri]::EscapeDataString("https://www.googleapis.com/auth/drive.readonly")
# $url = "https://accounts.google.com/o/oauth2/v2/auth?client_id=$CLIENT_ID&redirect_uri=$([uri]::EscapeDataString($redirect))&response_type=code&scope=$scope&access_type=offline&prompt=consent"
# $listener = [System.Net.HttpListener]::new(); $listener.Prefixes.Add("http://localhost:$PORT/"); $listener.Start()
# Start-Process $url
# $ctx = $listener.GetContext(); $code = [System.Web.HttpUtility]::ParseQueryString($ctx.Request.Url.Query)["code"]
# $buf = [System.Text.Encoding]::UTF8.GetBytes("<html><body>Done — close this tab.</body></html>")
# $ctx.Response.OutputStream.Write($buf, 0, $buf.Length); $ctx.Response.Close(); $listener.Stop()
# curl -s https://oauth2.googleapis.com/token -d "code=$code" -d "client_id=$CLIENT_ID" -d "client_secret=$CLIENT_SECRET" -d "redirect_uri=$redirect" -d "grant_type=authorization_code" | ConvertFrom-Json | Select-Object refresh_token
#
# NOTE: Google does not support the device authorization flow for Drive scopes.
# Do not use device/code endpoint — it returns "invalid_scope".
# NOTE: The OOB redirect (urn:ietf:wg:oauth:2.0:oob) was removed by Google in 2022.
# The localhost listener approach above is the only supported desktop flow.
#
# RE-AUTHORIZATION ON THE ROUTER: Google no longer supports the device
# authorization flow for Drive scopes, so the router's /cgi-bin/drive-auth
# CGI cannot complete a re-auth by itself. When the token expires, repeat
# Step E on your PC to get a new refresh token, then update the config:
# ssh root@<router-ip> "sed -i 's/GOOGLE_REFRESH_TOKEN=.*/GOOGLE_REFRESH_TOKEN=\"<new_token>\"/' /etc/healthsync-activities.conf"
# Or just edit /etc/healthsync-activities.conf manually over SSH.
GOOGLE_CLIENT_ID="YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET="YOUR_GOOGLE_CLIENT_SECRET"
GOOGLE_REFRESH_TOKEN="YOUR_GOOGLE_REFRESH_TOKEN"
# --- Google Drive folder ----------------------------------------------------
# The ID of the Drive folder where healthsync.app exports activity files.
# Find it in the URL when you open the folder in Drive:
# https://drive.google.com/drive/folders/FOLDER_ID_HERE
DRIVE_FOLDER_ID="YOUR_DRIVE_FOLDER_ID"
# --- Paths (defaults shown; uncomment to override) --------------------------
#HEALTHSYNC_STATE_DIR="/usr/lib/healthsync" # persistent store (not tmpfs)
#HEALTHSYNC_WEB_DIR="/www/strava/me" # uhttpd web root output dir
#HEALTHSYNC_BIKE_DATA="/usr/lib/healthsync/bike-service.json"
#HEALTHSYNC_BIKE_ASSIGN="/usr/lib/healthsync/bike-assignments.json"
#HEALTHSYNC_CGI_DIR="/www/cgi-bin"
# Annual ride-goal data file. If you also run strava-my-activities, set
# RIDE_GOALS_DATA in BOTH configs to the same path so neither script clobbers
# the other's CGI pointer. Example (pick any persistent path):
#RIDE_GOALS_DATA="/mnt/sda5/healthsync/ride-goals.json"
# --- Default bike name -------------------------------------------------------
# Ride-type activities are attributed to this bike until manually reassigned
# on the dashboard. Must match a bike name in the Bike Service page.
HEALTHSYNC_DEFAULT_BIKE="Kross"
# Your birth year. Used to compute age (current year − birth year) → theoretical
# max heart rate (220 − age) for zone thresholds on the per-activity detail page.
# Leave blank to fall back to the activity's recorded max_heartrate instead.
#HEALTHSYNC_BIRTH_YEAR="1990"
# --- Weather temperature backfill (optional) ----------------------------------
# When average_temp is not in the exported data, the script looks up the
# historical mean temperature for the activity's date via Open-Meteo (free, no
# API key required). GPS coordinates are extracted from the cached GPX file
# automatically. Set these as a fallback for activities without a GPX file.
# Leave blank to skip weather lookup when no coordinates are available.
#WEATHER_LAT="51.11" # decimal degrees, e.g. latitude of Wroclaw
#WEATHER_LON="17.03"
# --- Token refresh margin (seconds before expiry to refresh) ----------------
#HEALTHSYNC_TOKEN_REFRESH_MARGIN="300"
# Set to 0 to skip the Google Drive download/sync step and just re-render the
# HTML from the existing local store. Useful while debugging the dashboard or
# when temporarily blocking outbound requests. The local store and cached GPX
# files are not touched; only the HTML/JSON output files are regenerated.
#HEALTHSYNC_IMPORT_ENABLED="1"
# Run mode: "full" (default) or "keepalive".
# Set to "keepalive" while Strava is still your active source. The script will
# only refresh the Google OAuth token and verify Drive folder access, then exit —
# no files are downloaded, no store is touched, no HTML is written.
# Switch to "full" (or remove this line) in September when you disable Strava.
#HEALTHSYNC_MODE="keepalive"
# --- Network retry (optional) -----------------------------------------------
# On OpenWrt, dnsmasq restarts (e.g. during WAN reconnect) can cause a brief
# DNS gap. curl_retry in strava-lib.sh retries any network-level failure.
# STRAVA_CURL_RETRIES: number of retries after the first attempt (default 3)
# STRAVA_CURL_RETRY_DELAY: seconds to wait between retries (default 15)
#STRAVA_CURL_RETRIES="3"
#STRAVA_CURL_RETRY_DELAY="15"
# --- Strava history migration -----------------------------------------------
# HealthSync only keeps ~30 days of exports on Google Drive, so switching cold
# from Strava would lose all your history. Point this at your existing Strava
# NDJSON store to carry it over.
#
# On each run, records whose ID is not yet in the HealthSync store are appended.
# Idempotent: safe to leave in place permanently — Strava IDs are numeric while
# HealthSync IDs are date strings, so they never collide. After the initial
# migration you can set this to "" to stop reading the old store (once Strava
# API stops working the file won't change anyway).
#
# Typical path on OpenWrt (default STRAVA_MY_STATE_DIR):
#HEALTHSYNC_IMPORT_STRAVA_STORE="/usr/lib/strava-my-activities/activities.ndjson"
#
# Bike-service migration: when HEALTHSYNC_IMPORT_STRAVA_STORE is set, the script
# also copies bike-service.json and bike-assignments.json from the same directory
# on the first run (if the HealthSync files do not exist yet). No extra config
# needed — your bike history and per-activity assignments carry over automatically.