Intégration de la bague Oura
Connectez la bague Oura de l'utilisateur pour récupérer les données de sommeil, fréquence cardiaque, état de préparation, activité et autres données de santé via l'API Cloud Oura V2.
Prérequis
- Une bague Oura (Gen 3 ou Ring 4) avec un abonnement Oura actif (6 $/mois requis pour l'accès API)
- L'application Oura installée et couplée avec la bague
- Un compte Oura Cloud sur https://cloud.ouraring.com
Configuration
1. Enregistrer une application développeur
Demandez à l'utilisateur d'aller sur https://developer.ouraring.com/applications et de créer une nouvelle application :
- Nom d'affichage : Le nom préféré de l'utilisateur pour l'intégration
- Description : Brève description de l'intégration
- Email de contact : L'email de l'utilisateur
- Site Web : N'importe quelle URL valide (ex. un site personnel)
- Politique de confidentialité / Conditions de service : N'importe quelles URL valides (champs obligatoires mais non vérifiés pour les applications personnelles)
- URI de redirection :
http://localhost:3000/callback - Portées (scopes) : Activez toutes les portées nécessaires. Recommandé :
personal,daily,heartrate,sleep,workout,spo2,stress,heart_health,session,ring_configuration
Enregistrez le Client ID et le Client Secret.
2. Exécuter le flux OAuth
Stockez le secret client de manière sécurisée en utilisant assistant credentials prompt, puis écrivez et exécutez le script d'aide OAuth sur la machine de l'utilisateur :
#!/usr/bin/env python3
"""Oura Ring OAuth2 helper — catches auth code and exchanges for tokens instantly."""
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs, urlencode
import urllib.request, json, webbrowser, ssl
CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
REDIRECT_URI = 'http://localhost:3000/callback'
SCOPES = 'email personal daily heartrate workout tag session spo2 ring_configuration stress heart_health'
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
parsed = urlparse(self.path)
if parsed.path == '/':
params = urlencode({
'response_type': 'code', 'client_id': CLIENT_ID,
'redirect_uri': REDIRECT_URI, 'scope': SCOPES, 'state': 'assistant'
})
self.send_response(302)
self.send_header('Location', f'https://cloud.ouraring.com/oauth/authorize?{params}')
self.end_headers()
elif parsed.path == '/callback':
code = parse_qs(parsed.query).get('code', [''])[0]
if code:
token_data = urlencode({
'grant_type': 'authorization_code', 'code': code,
'redirect_uri': REDIRECT_URI, 'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
}).encode()
try:
req = urllib.request.Request('https://api.ouraring.com/oauth/token',
data=token_data,
headers={'Content-Type': 'application/x-www-form-urlencoded'},
method='POST')
resp = urllib.request.urlopen(req, context=ssl.create_default_context())
result = json.loads(resp.read())
with open('/tmp/oura_tokens.json', 'w') as f:
json.dump(result, f, indent=2)
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
self.wfile.write(b'<html><body><h1>Connecté ! Vous pouvez fermer cet onglet.</h1></body></html>')
print(f'\nJetons sauvegardés dans /tmp/oura_tokens.json')
except Exception as e:
self.send_response(500)
self.end_headers()
self.wfile.write(f'Échec de l\'échange des jetons : {e}'.encode())
def log_message(self, *a): pass
print('Ouverture du navigateur pour l\'autorisation Oura...')
webbrowser.open('http://localhost:3000')
HTTPServer(('localhost', 3000), Handler).serve_forever()
Exécutez avec python3 /chemin/vers/script.py sur la machine de l'utilisateur (host_bash). L'utilisateur autorise dans son navigateur, le script capture le code et l'échange contre des jetons en moins d'une seconde.
Important : Les codes d'autorisation expirent en ~30 secondes. Ne demandez PAS à l'utilisateur de coller des codes manuellement — utilisez ce script pour les capturer et les échanger automatiquement.
3. Stocker les jetons
Après le flux OAuth, lisez les jetons depuis /tmp/oura_tokens.json et stockez-les :
access_token— stockez dans le coffre d'identifiants avec un modèle d'injection pour l'en-tête Authorization deapi.ouraring.com(préfixe Bearer) etallowed_tools: ["bash"]refresh_token— stockez dans le coffre d'identifiants pour le rafraîchissement des jetons- Les jetons expirent dans ~30 jours. Définissez un rappel pour les rafraîchir avant l'expiration.
4. Vérifier la connexion
Testez avec le point de terminaison des informations personnelles :
curl -s -H "Authorization: Bearer $TOKEN" "https://api.ouraring.com/v2/usercollection/personal_info"
Points de terminaison disponibles
Tous les points de terminaison utilisent GET https://api.ouraring.com/v2/usercollection/{type} avec les paramètres de requête start_date et end_date (format AAAA-MM-JJ).
| Point de terminaison | Données | Notes |
|---|---|---|
/v2/usercollection/daily_sleep | Score de sommeil, durée, efficacité, phases | Idéal après l'heure de réveil habituelle |
/v2/usercollection/sleep | Périodes de sommeil détaillées avec FC, VRC, mouvement | Données brutes des périodes de sommeil |
/v2/usercollection/daily_readiness | Score de préparation, équilibre VRC, récupération | Métrique de vérification matinale |
/v2/usercollection/daily_activity | Pas, calories, mouvements, inactivité | Résumé de l'activité |
/v2/usercollection/heartrate | FC continue (utilisez start_datetime/end_datetime au format ISO) | Peut être volumineux — limitez la plage de dates |
/v2/usercollection/daily_spo2 | Niveaux d'oxygène dans le sang | Moyenne nocturne |
/v2/usercollection/daily_stress | Score de stress et récupération | Suivi du stress diurne |
/v2/usercollection/workout | Séances détectées avec FC, calories | Détection automatique ou manuelle |
/v2/usercollection/personal_info | Âge, poids, taille, email | Bon test de connexion |
Rafraîchissement des jetons
Les jetons expirent après 30 jours. Rafraîchissez-les avec :
curl -s -X POST "https://api.ouraring.com/oauth/token" \
-d "grant_type=refresh_token&refresh_token=$REFRESH_TOKEN&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET"
Stockez le nouveau access_token et refresh_token depuis la réponse.
Conseils
- Les nouvelles bagues ont besoin de 1 à 2 nuits pour se calibrer avant que les données soient significatives
- Les données de sommeil apparaissent généralement quelques heures après le réveil de l'utilisateur
- Les données de fréquence cardiaque pendant les séances apparaissent après la synchronisation via l'application Oura
- Limite de débit : 5000 requêtes toutes les 5 minutes
- Les utilisateurs de Ring 4 et Gen 3 DOIVENT avoir un abonnement Oura actif pour l'accès API