He hecho exactamente esto antes. La recomendación de achamm sobre n8n-nodes-azure-openai-ms-oauth2 es la referencia más limpia si estás construyendo un nodo personalizado — gestiona el ciclo de vida completo del token en el hook preSend del nodo y agrega el parámetro del cuerpo del recurso en la actualización exactamente como lo necesitas. El código fuente está en npm y GitHub, fácil de hacer fork.
Si quieres una plantilla de inicio aún más simple para consultar, el nodo Google Drive integrado de n8n tiene lógica OAuth2 personalizada en su definición de credencial que maneja la actualización del token con parámetros adicionales (está en el repositorio principal de n8n bajo packages/nodes-base/credentials/GoogleOAuth2Api.credentials.ts). El patrón es casi idéntico: almacena tokens, verifica la expiración, hace POST al endpoint del token con los campos de cuerpo adicionales que necesites, actualiza el token de acceso antes de que se envíe la solicitud real.
Para tu caso específico — servidor OAuth personalizado, necesitas recurso en el cuerpo — la lógica de preSend se vería algo así (dentro del método execute o preSend de tu nodo personalizado):
async preSend(request, options) {
const credentials = await this.getCredentials(‘myCustomOAuth2Api’);
// Verificar si el token ha expirado
if (Date.now() > credentials.expiresAt) {
const refreshParams = new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: credentials.refreshToken,
client_id: credentials.clientId,
client_secret: credentials.clientSecret,
resource: credentials.resource, // el parámetro de cuerpo crucial
});
const tokenResponse = await this.helpers.httpRequest({
method: 'POST',
url: credentials.accessTokenUrl,
body: refreshParams.toString(),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
});
// Actualizar caché de credenciales
credentials.accessToken = tokenResponse.access_token;
credentials.refreshToken = tokenResponse.refresh_token;
credentials.expiresAt = Date.now() + (tokenResponse.expires_in * 1000);
await this.setCredentials('myCustomOAuth2Api', credentials);
}
// Adjuntar token de acceso a la solicitud original
request.headers.Authorization = Bearer ${credentials.accessToken};
return request;
}
Ese es esencialmente el plano. Para producción, agregarías manejo de errores y almacenamiento de tokens adecuadamente (el objeto de credenciales de n8n persiste automáticamente a través de la base de datos).
Pero antes de que escribas una sola línea de código — intenta primero el truco del parámetro de consulta. Solo añade ?resource=https://your-target a tu accessTokenUrl. Si el servidor lo acepta como parámetro de consulta, ¡terminaste en 10 segundos! Muchos servidores OAuth personalizados lo hacen, porque analizan ambos. Si es estrictamente solo cuerpo, entonces la ruta del nodo personalizado es sólida y mantenible a largo plazo.
Cuéntame qué camino terminas eligiendo — encantado de ayudarte a depurar el hook preSend si te quedas atascado.