- 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.
3.2 KiB
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:
- Lê o
state - Procura a credencial com esse ID
- 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
- Acesse n8n → Credentials
- Clique na credencial Google Calendar OAuth2
- URL será:
https://n8n.automatizase.com.br/credentials/ccTThTS9TKsejR7W - 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.