GitScrum / Docs

Buenas Prácticas

Manejo de webhooks listo para producción: responde rápido, maneja duplicados, usa cola de procesamiento, manejo de errores y monitoreo.

Sigue estas prácticas para construir handlers de webhook confiables y listos para producción.

Responde Rápidamente

Devuelve un código de estado 2xx lo más rápido posible. GitScrum espera una respuesta dentro de 30 segundos. Si tu procesamiento tarda más, confirma la recepción inmediatamente y procesa de forma asíncrona.

Procesamiento Basado en Cola

Desacopla la recepción del procesamiento usando una cola de mensajes:

const Queue = require('bull');
const webhookQueue = new Queue('webhooks');

app.post('/webhooks/gitscrum', (req, res) => {
  // Acknowledge immediately
  res.status(200).json({ received: true });

  // Queue for async processing
  webhookQueue.add(req.body);
});

webhookQueue.process(async (job) => {
  const event = job.data;
  // Heavy processing here: database writes, API calls, notifications
  await processWebhook(event);
});
from celery import Celery

celery_app = Celery('webhooks', broker='redis://localhost:6379')

@app.route('/webhooks/gitscrum', methods=['POST'])
def webhook():
    event = request.get_json()

    # Acknowledge immediately
    process_webhook.delay(event)

    return jsonify({"received": True}), 200

@celery_app.task
def process_webhook(event):
    # Heavy processing here
    pass

Maneja Duplicados

El mismo evento puede ser entregado más de una vez. Diseña tu handler para ser idempotente — procesar el mismo evento dos veces debe producir el mismo resultado.

Usa el UUID como Clave de Idempotencia

const processedEvents = new Set(); // Use Redis in production

webhookQueue.process(async (job) => {
  const { data } = job.data;
  const eventId = data.uuid;

  // Skip if already processed
  if (processedEvents.has(eventId)) {
    console.log(`Skipping duplicate: ${eventId}`);
    return;
  }

  processedEvents.add(eventId);
  await processWebhook(job.data);
});

Manejo de Errores

Captura Todas las Excepciones

Nunca dejes que tu handler de webhook falle. Envuelve el procesamiento en manejo de errores:

app.post('/webhooks/gitscrum', async (req, res) => {
  try {
    // Always respond 200 first
    res.status(200).json({ received: true });

    await processWebhook(req.body);
  } catch (error) {
    console.error('Webhook processing error:', error);
    // Log the error but don't crash the server
  }
});

Registra Todo

Registra todos los webhooks recibidos para depuración y auditoría:

app.post('/webhooks/gitscrum', (req, res) => {
  const timestamp = new Date().toISOString();
  const headers = {
    'x-header': req.headers['x-header'],
    'user-agent': req.headers['user-agent'],
  };

  console.log(JSON.stringify({
    timestamp,
    headers,
    body: req.body,
  }));

  res.status(200).json({ received: true });
});

Monitoreo

Rastrea Tasas de Éxito de Entrega

Monitorea tu endpoint de webhook para:

  • Tiempo de respuesta (mantén por debajo de 5 segundos)
  • Tasas de error (respuestas 5xx)
  • Tamaño del payload
  • Profundidad de la cola de procesamiento

Endpoint de Health Check

Agrega un health check junto a tu endpoint de webhook:

app.get('/webhooks/health', (req, res) => {
  res.status(200).json({
    status: 'healthy',
    queue_depth: webhookQueue.getJobCount(),
    uptime: process.uptime(),
  });
});

Filtrado de Eventos

Si usas la misma URL de endpoint para múltiples eventos, filtra verificando la estructura del payload:

app.post('/webhooks/gitscrum', (req, res) => {
  res.status(200).json({ received: true });

  const { data } = req.body;

  // Route based on payload structure
  if (data.workflow) {
    handleTaskEvent(data);
  } else if (data.time_box) {
    handleSprintEvent(data);
  } else if (data.acceptance_criteria) {
    handleUserStoryEvent(data);
  }
});

Separación de Ambientes

Usa endpoints de webhook diferentes para ambientes diferentes:

AmbienteEndpoint
Desarrollohttps://dev.your-server.com/webhooks/gitscrum
Staginghttps://staging.your-server.com/webhooks/gitscrum
Producciónhttps://your-server.com/webhooks/gitscrum

Configura proyectos GitScrum separados para cada ambiente y apunta los webhooks al endpoint correspondiente.

Pruebas con ngrok

Durante el desarrollo, usa una herramienta de tunelización como ngrok para exponer tu servidor local:

# Start your local server on port 3000
node server.js

# In another terminal, start ngrok
ngrok http 3000

Copia la URL HTTPS de ngrok y pégala en la configuración de webhook de GitScrum. Esto permite probar webhooks contra tu servidor de desarrollo local.

Relacionado