Dashboard-Automatizase/docs/n8n-webhook-oauth-url.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

191 lines
5.1 KiB
Markdown

# 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":"..."}
```