Fetch latest data from your Garmin Connect account and share (tweet) results
I was looking for a way to automatically share (primarily tweet, actually) my runs upon completion of a running activity. I could do it from the Garmin Connect app on my phone, but I didn't like the process of selecting a nice image, ensuring proper blending of colours, etc. So I thought automating this would be a fun thing to do!
The result is this project – a python tool that
- Connects to your Garmin Connect account and obtains the last activity (via python-garminconnect)
- Uses the data from the last activity to create an image (via Pillow)
- Sends a tweet with the image above (via tweepy)
For this to work, it needs to run periodically, based on your foreseen run days, perhaps as a cron job.
-
You need to have a Twitter developer acount, and a Garmin Connect account.
-
You need to have Docker and Docker Compose on your machine:
# check that you have docker on your machine docker -v # check that you have docker-compose on your machine docker-compose -v
If you don't have Docker and Docker Compose, then click the respective links above for installation instructions for your platform.
-
Install dev dependencies in your vitual environment
# development pip install -r requirements-dev.txt
-
build and spin up docker containers (there are only 2 containers, the
bot
container and theredis
container. Redis is used to store the retrieved data so that we can make comparisons whenever we fetch data from Garmin Connect. This ensures that we do not share the same result multiple times)docker-compose up -d --build
-
Setup environment variables. See
env.sample
for details. Copyenv.sample
to.env
and update the new file. -
access the
bot
container:inv exec bot "bash"
. This is a shortcut fordocker-compose exec bot bash
-
Inside the container, run
inv tweet
.
Assuming you already have a Dokku machine, all you need to do is
- create an app
- install redis and link your app
- set environment variables
- remove ports (this isn't a web app)
- set up persistent storage
The BASH commands below illustrate the above steps.
# create app
sudo dokku apps:create garmin-activity-share
# setup redis | https://github.com/dokku/dokku-redis
sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis
sudo dokku redis:create redis-garmin-activity-share
sudo dokku redis:link redis-garmin-activity-share garmin-activity-share
# set env variables
sudo dokku config:set --no-restart garmin-activity-share API_KEY=xxxxx && \
sudo dokku config:set --no-restart garmin-activity-share API_KEY_SECRET=xxxxx && \
sudo dokku config:set --no-restart garmin-activity-share BEARER_TOKEN=xxxxx && \
sudo dokku config:set --no-restart garmin-activity-share ACCESS_TOKEN=xxxxx && \
sudo dokku config:set --no-restart garmin-activity-share ACCESS_TOKEN_SECRET=xxxxx && \
sudo dokku config:set --no-restart garmin-activity-share CLIENT_ID=xxxxx && \
sudo dokku config:set --no-restart garmin-activity-share CLIENT_SECRET=xxxxx && \
sudo dokku config:set --no-restart garmin-activity-share GARMIN_CONNECT_EMAIL=xxxxx && \
sudo dokku config:set --no-restart garmin-activity-share GARMIN_CONNECT_AUTH=xxxxx && \
sudo dokku config:set --no-restart garmin-activity-share MODE=production
# customize Docker Build-time configuration variables
# https://dokku.com/docs/deployment/builders/dockerfiles/#build-time-configuration-variables
sudo dokku docker-options:add garmin-activity-share build '--build-arg MODE=production'
# persistent storage
sudo dokku storage:ensure-directory --chown heroku garmin-activity-share
sudo dokku storage:mount garmin-activity-share /var/lib/dokku/data/storage/garmin-activity-share:/home/tweepy/assets/dist
# remove ports
sudo dokku proxy:ports-remove garmin-activity-share http:80:5000
sudo dokku proxy:ports-remove garmin-activity-share https:443:5000
You can adjust the cron schedule in app.json
to suit your preferences. The default setup is as follows
# At minute 30 past hour 8 and 20 on every day-of-week from Monday through Saturday.
30 8,20 * * 1-6
- Save session to REDIS, instead of a JSON file
- instead of showing the time as UTC on share image, use local time
- Fix the PYTHONPATH problem
- Write tests
- Share to other platforms
- Use unsplash API for background images
- use an API for random quotes
- improve
Dockerfile
configuration. See https://stackoverflow.com/questions/43654656/dockerfile-if-else-condition-with-external-arguments - incorporate cron monitoring
- setup sentry
- Running person icon: https://www.svgrepo.com/svg/342791/running
- Garmin logo: https://creative.garmin.com/styleguide/resources/logos/
andrew-slifkin-tL50RgKdn3Q-unsplash.jpg
by Andrew Slifkin on Unsplashjohn-t-rPKKiHzLFiY-unsplash.jpg
by John T on Unsplashjoshua-sortino-XMcoTHgNcQA-unsplash.jpg
by Joshua Sortino on Unsplashlucas-favre-JnoNcfFwrNA-unsplash.jpg
by lucas Favre on Unsplashtara-glaser-WodC5zEcSLQ-unsplash.jpg
by Tara Glaser on Unsplashwill-suddreth-NRA25SWe71o-unsplash.jpg
by Will Suddreth on Unsplashandrea-leopardi-QVD3Xht9txA-unsplash.jpg
by Andrea Leopardi on Unsplashgary-butterfield-XGKSeGYGP0A-unsplash.jpg
by Gary Butterfield on Unsplashzac-ong-RYvOI54rmPw-unsplash.jpg
by Zac Ong on Unsplashmalik-skydsgaard-zZoE-CCid3g-unsplash.jpg
by Malik Skydsgaard on Unsplashkevin-andre-M2k-Kd4n-S0-unsplash.jpg
by Kevin Andre on Unsplasharek-adeoye-gGZ8ZynljWk-unsplash.jpg
by Arek Adeoye on Unsplashjim-makos-bYy09RkQW8w-unsplash.jpg
by Jim Makos on Unsplashmike-cox-NrhgewTdfF8-unsplash.jpg
by Mike Cox on Unsplashmaxwell-nelson-UvN7K8MM-8k-unsplash.jpg
by Maxwell Nelson on Unsplashwill-suddreth-1pjRN2kphIs-unsplash.jpg
by Will Suddreth on Unsplash