Garmin Daily Report – 10pm Email

Overview

All n8n workflows running on the Raspberry Pi 2 (strider-pi2). n8n runs as a Docker container on the Pi, accessible at n8n.adventuretube.net.


1. Garmin Daily Report – 10pm Email

Workflow ID: CPON4buQtcg4mV8p

Status: Published (Active)

Schedule: Every day at 10:00 PM (Australia/Sydney)

Recipients: strider.lee@gmail.com, yehwanlee0405@gmail.com


Workflow Diagram

Schedule Trigger → SSH (Run Docker) → Format Report → Send Gmail
   10pm daily        Pi host            Set node        2 recipients

What Happens at Each Step

Step 1: Every Day at 10pm (Schedule Trigger)

  • n8n’s internal clock checks: is it 10pm in Australia/Sydney?
  • If yes, it fires and passes a timestamp to the next node

Step 2: Run Daily Report via SSH (SSH Node)

  • n8n (inside its Docker container on the Pi) opens an SSH connection to the Pi host at 192.168.1.199
  • Logs in as strider using the private key
  • Runs: cd ~/garminconnector && docker compose run --rm garmin-report
  • This spins up a fresh Python container, which:
    • Logs into Garmin Connect API with your credentials
    • Fetches sleep, activity, heart rate, stress, and workout data
    • Compares today vs the best of the last 7 days
    • Prints the formatted report to stdout
    • Container exits and gets removed (--rm)
  • The SSH node captures all the stdout output and passes it to the next node as $json.stdout

Step 3: Format Report for Email (Set Node)

  • Takes the raw text output from SSH
  • Creates 3 variables:
    • emailSubject = “Garmin Daily Report – 2026-02-12”
    • emailBody = HTML version (newlines → <br>, spaces → &nbsp;)
    • plainText = raw stdout as-is
  • Passes these to the Gmail node

Step 4: Send Email via Gmail (Gmail Node)

  • Connects to Gmail API using OAuth2 token
  • Sends an HTML email with the report wrapped in a dark monospace-styled <pre> block
  • To: strider.lee@gmail.com and yehwanlee0405@gmail.com
  • Subject: “Garmin Daily Report – 2026-02-12”

The whole thing takes about 30-60 seconds end to end.


Infrastructure

┌─────────────────────────────────────────┐
│         Raspberry Pi 2 (strider-pi2)   │
│                                         │
│  ┌───────────────┐  SSH   ┌───────────┐│
│  │ n8n (Docker) │ ────▶ │ Pi Host   ││
│  │ port 5678    │       │ (strider) ││
│  └───────────────┘       └─────┬─────┘│
│                              │        │
│                       docker compose  │
│                        run --rm       │
│                              │        │
│                  ┌───────────▼─────┐  │
│                  │ garmin-report   │  │
│                  │ (Python 3.11)   │  │
│                  │ Runs script,    │  │
│                  │ exits, removed  │  │
│                  └─────────────────┘  │
└─────────────────────────────────────────┘
  • Why SSH? n8n runs inside Docker and can’t access the host’s Docker daemon directly. SSH from n8n container → Pi host bridges this gap.
  • Why --rm? Container spins up, runs, exits cleanly. No leftover containers piling up.
  • Garth tokens persist in a Docker named volume so you don’t re-authenticate every run.

Leave a Comment

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

Scroll to Top