Communitygithub.com

vellum-ai/vellum-assistant

Conecte um Oura Ring via OAuth2 — registro de aplicativo, troca de tokens e armazenamento de credenciais

O que é vellum-assistant?

Essa skill permite que um agente de IA conecte e autentique um Oura Ring (Gen 3 ou Ring 4) usando o fluxo OAuth2, obtendo acesso a dados de saúde como sono, frequência cardíaca, prontidão, atividade e outros via Oura Cloud API V2. Ela simplifica o processo de registro de um aplicativo no portal de desenvolvedores da Oura, executa um script Python no computador do usuário para capturar automaticamente o código de autorização e trocá-lo por tokens de acesso e atualização, armazena essas credenciais de forma segura para uso futuro e fornece endpoints para consultar dados de saúde. Suporta refresh de tokens a cada 30 dias e inclui dicas importantes sobre calibração do anel e limites de taxa. É ideal para desenvolvedores e usuários que desejam integrar dados biométricos do Oura Ring em seus fluxos de automação ou análise.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/vellum-ai/vellum-assistant/tree/HEAD/skills/oura-setup

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Integração com Oura Ring

Conecte o Oura Ring do usuário para obter dados de sono, frequência cardíaca, prontidão, atividade e outros dados de saúde por meio da Oura Cloud API V2.

Pré-requisitos

  • Um Oura Ring (Gen 3 ou Ring 4) com uma assinatura ativa do Oura Membership (US$ 6/mês necessária para acesso à API)
  • O aplicativo Oura instalado e pareado com o anel
  • Uma conta Oura Cloud em https://cloud.ouraring.com

Configuração

1. Registrar um Aplicativo de Desenvolvedor

Peça ao usuário para acessar https://developer.ouraring.com/applications e criar um novo aplicativo:

  • Nome de Exibição: O nome preferido do usuário para a integração
  • Descrição: Breve descrição da integração
  • Email de Contato: Email do usuário
  • Site: Qualquer URL válida (ex.: um site pessoal)
  • Política de Privacidade / Termos de Serviço: Qualquer URL válida (campos obrigatórios, mas não rigorosamente exigidos para aplicativos pessoais)
  • URIs de Redirecionamento: http://localhost:3000/callback
  • Escopos: Ative todos os escopos necessários. Recomendado: personal, daily, heartrate, sleep, workout, spo2, stress, heart_health, session, ring_configuration

Salve o ID do Cliente e o Segredo do Cliente.

2. Executar o Fluxo OAuth

Armazene o segredo do cliente de forma segura usando assistant credentials prompt, depois escreva e execute o script auxiliar OAuth na máquina do usuário:

#!/usr/bin/env python3
"""Auxiliar OAuth2 para Oura Ring — captura o código de autorização e troca por tokens instantaneamente."""
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>Conectado! Você pode fechar esta aba.</h1></body></html>')
                    print(f'\nTokens salvos em /tmp/oura_tokens.json')
                except Exception as e:
                    self.send_response(500)
                    self.end_headers()
                    self.wfile.write(f'Falha na troca de tokens: {e}'.encode())
    def log_message(self, *a): pass

print('Abrindo navegador para autorização Oura...')
webbrowser.open('http://localhost:3000')
HTTPServer(('localhost', 3000), Handler).serve_forever()

Execute com python3 /path/to/script.py na máquina do usuário (host_bash). O usuário autoriza no navegador, o script captura o código e o troca por tokens em menos de um segundo.

Importante: Os códigos de autorização expiram em ~30 segundos. NÃO peça ao usuário para colar códigos manualmente — use este script para capturá-los e trocá-los automaticamente.

3. Armazenar Tokens

Após o fluxo OAuth, leia os tokens de /tmp/oura_tokens.json e armazene-os:

  • access_token — armazenar no cofre de credenciais com modelo de injeção para o cabeçalho Authorization de api.ouraring.com (prefixo Bearer) e allowed_tools: ["bash"]
  • refresh_token — armazenar no cofre de credenciais para renovação de token
  • Os tokens expiram em ~30 dias. Defina um lembrete para renovar antes da expiração.

4. Verificar Conexão

Teste com o endpoint de informações pessoais:

curl -s -H "Authorization: Bearer $TOKEN" "https://api.ouraring.com/v2/usercollection/personal_info"

Endpoints Disponíveis

Todos os endpoints usam GET https://api.ouraring.com/v2/usercollection/{type} com parâmetros de consulta start_date e end_date (formato YYYY-MM-DD).

EndpointDadosObservações
/v2/usercollection/daily_sleepPontuação de sono, duração, eficiência, estágiosMelhor verificar após o horário típico de despertar
/v2/usercollection/sleepPeríodos detalhados de sono com FC, VFC, movimentoDados brutos do período de sono
/v2/usercollection/daily_readinessPontuação de prontidão, equilíbrio da VFC, recuperaçãoMétrica de verificação matinal
/v2/usercollection/daily_activityPassos, calorias, movimento, inatividadeResumo de atividade
/v2/usercollection/heartrateFC contínua (usar start_datetime/end_datetime no formato ISO)Pode ser grande — limite o intervalo de datas
/v2/usercollection/daily_spo2Níveis de oxigênio no sangueMédia noturna
/v2/usercollection/daily_stressPontuação de estresse e recuperaçãoRastreamento de estresse diurno
/v2/usercollection/workoutTreinos detectados com FC, caloriasDetectado automaticamente ou manual
/v2/usercollection/personal_infoIdade, peso, altura, emailBom teste de conexão

Renovação de Token

Os tokens expiram após 30 dias. Renove com:

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"

Armazene o novo access_token e refresh_token da resposta.

Dicas

  • Anéis novos precisam de 1 a 2 noites para calibrar antes que os dados sejam significativos
  • Os dados de sono geralmente aparecem algumas horas após o usuário acordar
  • Os dados de frequência cardíaca durante os treinos aparecem após a sincronização do treino via aplicativo Oura
  • Limite de taxa: 5000 requisições a cada 5 minutos
  • Usuários do Ring 4 e Gen 3 DEVEM ter uma assinatura ativa do Oura Membership para acesso à API

Habilidades Relacionadas