A simple automation tool that syncs Strava activities to Fitbit using Vercel serverless functions and GitHub Actions.
StravBit automatically syncs your Strava activities to your Fitbit account whenever a new activity is created on Strava. It uses:
- Vercel Serverless Functions to receive and verify Strava webhooks
- GitHub Actions as the execution environment for the sync process
- Strava API to fetch activity details
- Fitbit API to upload the activity data
- When a new activity is created on Strava, a webhook notification is sent to your Vercel serverless function
- The Vercel function verifies the webhook and triggers a GitHub repository dispatch event
- The GitHub Action workflow is triggered by this event
- The sync script fetches the activity details from Strava API using OAuth refresh tokens
- The activity data is then uploaded to Fitbit API using OAuth refresh tokens
- A Strava account with API access (client ID, client secret, and refresh token)
- A Fitbit account with API access (client ID, client secret, and refresh token)
- A GitHub repository to host this code
- A Vercel account to deploy the serverless function
-
Fork this repository
-
Deploy to Vercel:
npm run deploy -
Set up the following environment variables in Vercel:
STRAVA_VERIFY_TOKEN: A secret token you create to verify Strava webhooksGITHUB_TOKEN: A GitHub personal access token with repo scopeGITHUB_REPO: Your GitHub repository in the formatusername/repo
-
Set up the following secrets in your GitHub repository:
STRAVA_CLIENT_ID: Your Strava API client IDSTRAVA_CLIENT_SECRET: Your Strava API client secretSTRAVA_REFRESH_TOKEN: Your Strava API refresh tokenFITBIT_CLIENT_ID: Your Fitbit API client IDFITBIT_CLIENT_SECRET: Your Fitbit API client secretFITBIT_REFRESH_TOKEN: Your Fitbit API refresh token
-
Configure a Strava webhook:
- Callback URL:
https://your-vercel-app.vercel.app/api/strava - Verify token: The same value as your
STRAVA_VERIFY_TOKEN
- Callback URL:
- Node.js 18+
- Vercel CLI
- axios
- dotenv
To test locally:
-
Create a
.envfile with your API credentials:STRAVA_VERIFY_TOKEN=your_verify_token GITHUB_TOKEN=your_github_token GITHUB_REPO=your_username/your_repo # For local testing of sync.js TEST_ACTIVITY_ID=your_test_activity_id STRAVA_CLIENT_ID=your_strava_client_id STRAVA_CLIENT_SECRET=your_strava_client_secret STRAVA_REFRESH_TOKEN=your_strava_refresh_token FITBIT_CLIENT_ID=your_fitbit_client_id FITBIT_CLIENT_SECRET=your_fitbit_client_secret FITBIT_REFRESH_TOKEN=your_fitbit_refresh_token -
Run the local development server:
npm run dev -
Test the webhook with curl:
# Test verification curl "http://localhost:3000/api/strava?hub.mode=subscribe&hub.challenge=challenge123&hub.verify_token=your_verify_token" # Test webhook event curl -X POST http://localhost:3000/api/strava \ -H "Content-Type: application/json" \ -d '{"object_type":"activity","object_id":"12345678","aspect_type":"create","owner_id":"87654321"}'
See the LICENSE file for details.