--- name: garmin-auth description: Manage Garmin Connect authentication, proactive OAuth token keepalives, and interactive 2-turn MFA login over Telegram. Use when Garmin authentication fails (HTTP 401, expired tokens) or when the user asks to log into Garmin. --- # 🔐 Garmin Connect Authentication & MFA Manager Headless authentication lifecycle manager for Garmin Connect, allowing OpenClaw to initiate logins, keep tokens perpetually fresh, and verify 6-digit MFA codes directly via Telegram. ## 🎯 When to Use - **Authentication Errors**: Whenever a `garmin` MCP tool call fails with `Garmin authentication failed`, `Tokens expired`, `401 Unauthorized`, or `Failed to retrieve social profile`. - **User Request**: Whenever the user explicitly asks: *"Logge dich bei Garmin ein"*, *"Garmin MFA Code eingeben"*, *"Garmin Re-Auth"*, *"Verbinde Garmin"*. - **Keepalive / Watchdog**: During morning briefings or background checks to ensure tokens are proactively refreshed before expiring. - **Status Checks**: Whenever asked about Garmin token health or expiration: *"Ist Garmin eingeloggt?"*, *"Wie lange ist der Garmin-Token noch gültig?"*. --- ## 🕹️ Interactive Telegram MFA Login Flow (Protocol) Because Garmin requires Multi-Factor Authentication (OTP sent via SMS/email), login operates in **two conversation turns**: ### Turn 1: Request Code (Initiate Login) 1. Execute the `request-code` command: ```bash uv run /home/node/mop-skills/mop-skills/skills/garmin-auth/scripts/garmin_auth.py request-code ``` 2. The command spawns a background authentication daemon and triggers Garmin to dispatch the 6-digit code to the user's email/SMS. 3. Immediately send a clear, friendly prompt to the user on Telegram: > 🔑 **Garmin-Authentifizierung erforderlich** > Ich habe einen neuen Login bei Garmin gestartet. Garmin hat dir soeben einen 6-stelligen Sicherheitscode per SMS oder E-Mail gesendet. > > Bitte antworte mir einfach kurz mit dem **6-stelligen Code**! ### Turn 2: Verify Code (Complete Login) 1. When the user sends a 6-digit message (e.g. `538291`, `538 291`): 2. Execute the `verify` command: ```bash uv run /home/node/mop-skills/mop-skills/skills/garmin-auth/scripts/garmin_auth.py verify "" ``` 3. If successful: - The tokens are automatically dumped to `/home/node/.openclaw/garmin_tokens/garmin_tokens.json` and base64 exported. - Reply to the user: > ✅ **Garmin-Login erfolgreich!** > Angemeldet als **Moritz Graf**. Alle Garmin-Tools und Workouts sind wieder voll einsatzbereit. 4. If the code was incorrect: - The daemon remains alive for 5 minutes. Inform the user and allow them to retry: > ⚠️ Der eingegebene Code war leider ungültig oder abgelaufen. Bitte prüfe den Code und sende ihn erneut. --- ## 🛠️ CLI Operations Reference ### 1. Check Token Health & Validity ```bash uv run /home/node/mop-skills/mop-skills/skills/garmin-auth/scripts/garmin_auth.py status ``` Outputs JSON with `valid`, `user`, `exp_utc`, `pending_mfa`. ### 2. Proactive Keepalive (Refresh Token before Expiry) ```bash uv run /home/node/mop-skills/mop-skills/skills/garmin-auth/scripts/garmin_auth.py keepalive ``` Touches the API, triggering `python-garminconnect`'s automatic token refresh and persisting the newly rotated refresh token to `/home/node/.openclaw/garmin_tokens/garmin_tokens.json`. --- ## 🔒 Security & Environment - Requires `GARMIN_EMAIL` and `GARMIN_PASSWORD` (already injected via `openclaw-secrets`). - Persistent storage: `/home/node/.openclaw/garmin_tokens/garmin_tokens.json` (on PVC `openclaw-data`). - Directory permissions are automatically set to `0700` and files to `0600`.