Dashboard-Automatizase/docs/qa/erro-invalid-state-format.md
Luis Erlacher 0152a2fda0 feat: add n8n API testing script for Google OAuth2 schema and existing credentials
- Implemented a bash script to test n8n API and retrieve credential schemas.
- Added types for API responses, Google Calendar, and WhatsApp instances.
- Configured Vitest for testing with React and added setup for testing-library.
2025-10-10 14:29:02 -03:00

3.2 KiB

Erro: Invalid state format

⚠️ ATUALIZAÇÃO: Este erro foi resolvido com uma nova abordagem. Veja fluxo-final-google-oauth.md para a solução final.


O Problema

Quando tentamos conectar Google Calendar, o n8n retornou:

<h4>Error: Invalid state format</h4>

Causa Raiz

O dashboard estava enviando user_id no parâmetro state:

const state = user.id; // ❌ ERRADO - UUID do user

Mas o n8n espera receber o credential_id no state:

const state = n8nCredentialId; // ✅ CORRETO - ID da credencial n8n

Por que isso acontece?

O n8n usa o state para identificar qual credencial deve ser atualizada com os tokens OAuth.

Quando o Google redireciona de volta para:

https://n8n.automatizase.com.br/rest/oauth2-credential/callback?code=...&state=...

O n8n:

  1. Lê o state
  2. Procura a credencial com esse ID
  3. Atualiza a credencial com os tokens OAuth

Se o state não for um credential_id válido do n8n, ele retorna "Invalid state format".

Solução

1. Usar credential_id no state

Dashboard (app/dashboard/page.tsx):

const n8nCredentialId = process.env.NEXT_PUBLIC_N8N_CREDENTIAL_ID;
const state = n8nCredentialId; // ID da credencial n8n

2. Pegar user_id da sessão no callback

Callback (app/api/google-calendar/callback/route.ts):

// Criar cliente Supabase com cookies
const cookieStore = await cookies();
const supabase = createServerClient(..., {
  cookies: { ... }
});

// Pegar user da sessão
const { data: { user } } = await supabase.auth.getUser();

// Salvar no banco usando user.id (não o state)
await supabase.schema("portal").from("integrations").upsert({
  user_id: user.id,
  provider: "google_calendar",
  status: "connecting",
  ...
});

Fluxo Correto

1. Dashboard:
   state = credential_id (ex: "ccTThTS9TKsejR7W")

2. Google OAuth:
   Redireciona com state=credential_id

3. Callback Dashboard:
   - Lê state (credential_id)
   - Lê user_id da sessão Supabase
   - Salva no banco: user_id + status
   - Redireciona para n8n com state=credential_id

4. n8n:
   - Lê state (credential_id)
   - Atualiza credencial com tokens OAuth
   - Sucesso!

Variáveis de Ambiente Necessárias

# Google OAuth
NEXT_PUBLIC_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com

# n8n Credential ID (IMPORTANTE!)
NEXT_PUBLIC_N8N_CREDENTIAL_ID=ccTThTS9TKsejR7W

# n8n Base URL
N8N_BASE_URL=https://n8n.automatizase.com.br

Como encontrar o Credential ID?

Opção 1: URL do n8n

  1. Acesse n8n → Credentials
  2. Clique na credencial Google Calendar OAuth2
  3. URL será: https://n8n.automatizase.com.br/credentials/ccTThTS9TKsejR7W
  4. O ID é a última parte: ccTThTS9TKsejR7W

Opção 2: API do n8n

curl https://n8n.automatizase.com.br/api/v1/credentials \
  -H "X-N8N-API-KEY: your-api-key" | jq '.[] | select(.type == "googleCalendarOAuth2Api") | .id'

Resumo

  • ERRADO: state = user_id (UUID)
  • CORRETO: state = credential_id (ID do n8n)
  • user_id: Pegar da sessão Supabase no callback

O state é para o n8n identificar a credencial. O user_id é para o dashboard salvar no banco.