Garmin Daily Report: Step 4 – n8n Workflow (Scheduled Email)

Overview

Create an n8n workflow that runs the Garmin daily report every day at 10pm via Docker on the Raspberry Pi, then emails the report to you and your son.

Workflow ID: CPON4buQtcg4mV8p


Architecture

┌──────────────┐    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│  Schedule     │    │  SSH into    │    │  Format      │    │  Send Gmail  │
│  Trigger      │───▶│  Pi Host     │───▶│  Report      │───▶│  to 2        │
│  10pm daily   │    │  Run Docker  │    │  for Email   │    │  recipients  │
└──────────────┘    └──────────────┘    └──────────────┘    └──────────────┘

All 4 nodes run on n8n (Docker on Pi) → SSHs to Pi host → runs garmin-report container → formats output → emails via Gmail.


The 4 Nodes

1. Schedule Trigger — Every Day at 10pm

  • Type: n8n-nodes-base.scheduleTrigger
  • Config: Daily at 22:00
  • Timezone: Australia/Sydney

2. SSH — Run Daily Report via SSH

  • Type: n8n-nodes-base.ssh
  • Authentication: Private Key
  • Command:
cd ~/garminconnector && docker compose run --rm garmin-report

Command Breakdown:

Part What it does
cd ~/garminconnector Navigate to the project directory where docker-compose.yml lives
&& Only proceed if the cd succeeded (prevents running in the wrong directory)
docker compose run Spins up a new temporary container from the garmin-report service defined in docker-compose.yml
--rm Auto-remove the container after it exits — prevents orphaned containers piling up
garmin-report The service name defined in docker-compose.yml that runs the Python report script

Container Lifecycle:

  1. Spin up — Docker creates a fresh container from the garmin-report image
  2. Run — The container executes the report script (fetches Garmin data, generates report)
  3. Output — stdout is captured by the SSH node and passed to the next n8n node
  4. Cleanup — The --rm flag automatically destroys the container once the script finishes

Unlike docker compose up, which starts long-running services, docker compose run is designed for one-off tasks. The container exists only for the duration of the report generation, then is removed. No manual cleanup needed.

  • Why SSH? n8n runs in Docker, so it can’t directly access the host’s Docker daemon. SSH bridges this gap.

3. Set — Format Report for Email

  • Type: n8n-nodes-base.set
  • Creates 3 fields:
    • emailSubject: “Garmin Daily Report – 2026-02-12”
    • emailBody: HTML formatted version
    • plainText: Raw stdout from the script

4. Gmail — Send Email

  • Type: n8n-nodes-base.gmail
  • To: strider.lee@gmail.com, yehwanlee0405@gmail.com
  • Email Type: HTML
  • Template: Dark monospace theme with <pre> block

SSH Credential Setup

Since n8n runs in Docker on the Pi, it needs SSH access to the Pi host to run docker compose.

Generate SSH Key (inside n8n container)

docker exec -it n8n sh
ssh-keygen -t ed25519 -f /home/node/.ssh/n8n_key -N ""
cat /home/node/.ssh/n8n_key
# Copy the private key output
exit

Authorize on Pi Host

docker exec n8n cat /home/node/.ssh/n8n_key.pub >> ~/.ssh/authorized_keys

Test Connection

docker exec -it n8n sh
ssh -i /home/node/.ssh/n8n_key strider@192.168.1.199
# Should connect without password
exit

n8n Credential Config

  • Host: 192.168.1.199 (Pi’s LAN IP)
  • Port: 22
  • Username: strider
  • Private Key: Paste the key from step 1

Gmail OAuth2 Setup

To send emails from n8n via Gmail:

1. Google Cloud Console

  • Go to Google Cloud Console
  • Create or select a project
  • Go to APIs & Services > Library → Enable Gmail API

2. OAuth Consent Screen

  • Go to Google Auth Platform > Audience
  • Configure consent screen (External, app name: “n8n”)
  • Add test user: strider.lee@gmail.com

3. Create OAuth Client

  • Go to Clients > Create OAuth Client
  • Application type: Web application
  • Authorized redirect URI: https://n8n.adventuretube.net/rest/oauth2-credential/callback
  • Copy Client ID and Client Secret

4. Configure in n8n

  • In the Gmail node, create new credential
  • Paste Client ID and Client Secret
  • Click Sign In → Continue through “unverified app” warning → Select all permissions

Tip: The “Google hasn’t verified this app” warning is normal for personal/testing apps. Just click Continue.


Publish & Activate

  1. Click Publish in the top right of the workflow editor
  2. The workflow is now live — green “Published” badge appears
  3. The schedule trigger activates and will fire every day at 10pm

Testing

You can test each node individually:

  1. Click a node → Execute step to run just that node
  2. Or click Execute Workflow to run the full pipeline
  3. Check your Gmail inbox for the report email

Adding More Reports

To create a new scheduled report (e.g. weekly), duplicate this workflow and change:

  1. The schedule (e.g. every Sunday at 10pm)
  2. The SSH command: docker compose run --rm garmin-report python3 custom_scripts/weekly_report.py
  3. The email subject prefix

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top