# Webhook n8n para Gerar OAuth URL ## Problema O endpoint REST `/rest/oauth2-credential/auth` do n8n requer cookies de sessão (usuário logado), não aceita API Key. ## Solução Criar um workflow no n8n com webhook que gera a `oauth_url` internamente. ## Workflow n8n ### 1. Webhook (Trigger) - **Path**: `/webhook/google-calendar-oauth-url` - **Method**: `GET` ou `POST` - **Authentication**: `None` (webhook público) ### 2. Code Node (Gerar oauth_url) ```javascript // Configuração const credentialId = "ccTThTS9TKsejR7W"; // Seu credential ID const clientId = "174466774807-xxx.apps.googleusercontent.com"; // Google Client ID const callbackUrl = $json.query?.callbackUrl || "http://localhost:3000/api/google-calendar/callback"; // Gerar CSRF token (aleatório) const csrfToken = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); // Criar state (formato do n8n) const state = { token: csrfToken, cid: credentialId, createdAt: Date.now() }; // Codificar state em base64 const stateBase64 = Buffer.from(JSON.stringify(state)).toString('base64'); // Construir oauth_url const oauthUrl = new URL("https://accounts.google.com/o/oauth2/v2/auth"); oauthUrl.searchParams.set("client_id", clientId); oauthUrl.searchParams.set("redirect_uri", callbackUrl); oauthUrl.searchParams.set("response_type", "code"); oauthUrl.searchParams.set("scope", "https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events"); oauthUrl.searchParams.set("access_type", "offline"); oauthUrl.searchParams.set("prompt", "consent"); oauthUrl.searchParams.set("state", stateBase64); // Retornar return { json: { oauthUrl: oauthUrl.toString(), state: stateBase64, credentialId: credentialId } }; ``` ### 3. Respond to Webhook Retorna o resultado: ```json { "oauthUrl": "https://accounts.google.com/o/oauth2/v2/auth?...", "state": "eyJ0b2tlbiI6InhjZDExMzkyLWUyMzkiLCJjaWQiOiJjY1RUaFRTOVRLc2VqUjdXIiwiY3JlYXRlZEF0IjoxNzU5OTUzNTY1MDI0fQ==", "credentialId": "ccTThTS9TKsejR7W" } ``` ## Configuração no Dashboard Atualize `.env.local`: ```bash # Webhook do n8n para gerar oauth_url N8N_OAUTH_URL_WEBHOOK=https://n8n.automatizase.com.br/webhook/google-calendar-oauth-url ``` Remova (não é mais necessário): ```bash # N8N_API_KEY não é mais necessário ``` ## Atualizar API Route `app/api/google-calendar/auth/route.ts`: ```typescript export async function GET(_request: NextRequest) { try { const webhookUrl = process.env.N8N_OAUTH_URL_WEBHOOK; const callbackUrl = `${process.env.NEXT_PUBLIC_SITE_URL}/api/google-calendar/callback`; if (!webhookUrl) { return NextResponse.json( { error: "N8N_OAUTH_URL_WEBHOOK not configured" }, { status: 500 } ); } // Chamar webhook do n8n const response = await fetch( `${webhookUrl}?callbackUrl=${encodeURIComponent(callbackUrl)}` ); if (!response.ok) { const error = await response.text(); console.error("n8n webhook error:", error); return NextResponse.json( { error: "Failed to generate OAuth URL" }, { status: 500 } ); } const data = await response.json(); return NextResponse.json({ oauthUrl: data.oauthUrl }); } catch (error) { console.error("Error:", error); return NextResponse.json( { error: "Internal server error" }, { status: 500 } ); } } ``` ## Validação do State no n8n **IMPORTANTE:** O n8n vai validar o `state` quando receber o callback do Google. Como estamos gerando o state manualmente, precisamos **desabilitar a validação CSRF** ou **salvar o token** no n8n. ### Opção 1: Desabilitar Validação (Mais Simples) O n8n não valida CSRF token por padrão quando o callback vem pelo redirect do Google. Apenas valida o `cid` (credential ID). ### Opção 2: Salvar Token (Mais Seguro) Adicionar um nó no workflow que salva o `csrfToken` temporariamente (Redis, banco, etc) e validar no callback. ## Fluxo Completo ``` 1. Dashboard → GET /api/google-calendar/auth ↓ 2. API Route → GET https://n8n.automatizase.com.br/webhook/google-calendar-oauth-url ↓ 3. n8n Workflow gera state + oauth_url ↓ 4. Dashboard redireciona para oauth_url ↓ 5. Google → Callback http://localhost:3000/api/google-calendar/callback?code=...&state=... ↓ 6. Dashboard salva no Supabase ↓ 7. Dashboard → https://n8n.automatizase.com.br/rest/oauth2-credential/callback?code=...&state=... ↓ 8. n8n processa OAuth e salva tokens ↓ 9. Sucesso! ✅ ``` ## Vantagens ✅ Webhook público (sem autenticação) ✅ n8n controla geração do state ✅ Código simples e direto ✅ Fácil de debugar ## Alternativa: State Simplificado Se o n8n não validar o CSRF token, podemos usar um state mais simples: ```javascript const state = credentialId; // Apenas o credential ID ``` Teste primeiro para ver se o n8n aceita. ## Teste ```bash # Testar webhook curl "https://n8n.automatizase.com.br/webhook/google-calendar-oauth-url?callbackUrl=http://localhost:3000/api/google-calendar/callback" # Deve retornar: # {"oauthUrl":"https://accounts.google.com/...","state":"...","credentialId":"..."} ```