Volver a Inicio

Ejemplo Node.js

Integra la API de ReciGo en tu aplicación Node.js o TypeScript.

Instalación

No necesitas ninguna librería especial. Solo usa fetch (Node.js 18+) o axios:

# Opción 1: Node.js 18+ (fetch nativo)
# No necesitas instalar nada

# Opción 2: Axios (cualquier versión de Node.js)
npm install axios

Cliente de API

Crea un cliente reutilizable para interactuar con la API de ReciGo:

recigo-client.ts
// recigo-client.ts
const RECIGO_API_URL = 'https://api.recigo.es/v1';

export class ReciGoClient {
  private apiKey: string;

  constructor(apiKey: string) {
    this.apiKey = apiKey;
  }

  private async request(method: string, endpoint: string, body?: any) {
    const response = await fetch(`${RECIGO_API_URL}${endpoint}`, {
      method,
      headers: {
        'X-API-Key': this.apiKey,
        'Content-Type': 'application/json',
      },
      body: body ? JSON.stringify(body) : undefined,
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`ReciGo API Error: ${error.message}`);
    }

    return response.json();
  }

  // Estimar precio
  async estimatePrice(data: {
    size: 'S' | 'M' | 'L' | 'XL';
    pickup: { address: string; floor?: number; has_elevator?: boolean };
    dropoff: { address: string; floor?: number; has_elevator?: boolean };
  }) {
    return this.request('POST', '/pricing/estimate', data);
  }

  // Crear trabajo
  async createJob(data: {
    external_reference?: string;
    title: string;
    description: string;
    size: 'S' | 'M' | 'L' | 'XL';
    pickup: { address: string; floor?: number; has_elevator?: boolean };
    dropoff: { address: string; floor?: number; has_elevator?: boolean };
    customer_phone: string;
    photos?: string[];
  }) {
    return this.request('POST', '/jobs', data);
  }

  // Consultar estado del trabajo
  async getJobStatus(jobId: string) {
    return this.request('GET', `/jobs/${jobId}`);
  }
}

// Exportar instancia configurada
export const recigoClient = new ReciGoClient(
  process.env.RECIGO_API_KEY || ''
);

Ejemplo 1: Estimación de Precio

estimate-price.ts
import { recigoClient } from './recigo-client';

async function estimatePrice() {
  try {
    const estimate = await recigoClient.estimatePrice({
      size: 'L',
      pickup: {
        address: 'Calle Gran Vía 1, Madrid',
        floor: 3,
        has_elevator: false,
      },
      dropoff: {
        address: 'Calle Alcalá 100, Madrid',
        floor: 1,
        has_elevator: true,
      },
    });

    console.log('Precio estimado:', estimate);
    console.log(`Total: €${estimate.total_customer_pays_eur}`);
    console.log(`Distancia: ${estimate.calculation_breakdown.distance_km} km`);

    return estimate;
  } catch (error) {
    console.error('Error al estimar precio:', error);
    throw error;
  }
}

// Ejecutar
estimatePrice();

Ejemplo 2: Crear Trabajo Completo

create-job.ts
import { recigoClient } from './recigo-client';

async function createDeliveryJob() {
  try {
    // Paso 1: Estimar precio (opcional pero recomendado)
    const estimate = await recigoClient.estimatePrice({
      size: 'L',
      pickup: { address: 'Calle Gran Vía 1, Madrid' },
      dropoff: { address: 'Calle Alcalá 100, Madrid' },
    });

    console.log(`Precio estimado: €${estimate.total_customer_pays_eur}`);

    // Paso 2: Crear el trabajo
    const job = await recigoClient.createJob({
      external_reference: 'listing-12345', // Tu referencia interna
      title: 'Mover sofá de 2 plazas',
      description: 'Sofá gris en buen estado, necesita 2 personas para cargar',
      size: 'L',
      pickup: {
        address: 'Calle Gran Vía 1, Madrid',
        floor: 3,
        has_elevator: false,
      },
      dropoff: {
        address: 'Calle Alcalá 100, Madrid',
        floor: 1,
        has_elevator: true,
      },
      customer_phone: '+34612345678',
      photos: [
        'https://mi-plataforma.com/images/sofa1.jpg',
        'https://mi-plataforma.com/images/sofa2.jpg',
      ],
    });

    console.log('Trabajo creado:', job);
    console.log(`Job ID: ${job.job_id}`);
    console.log(`Estado: ${job.status}`);
    console.log(`Deep Link: ${job.deep_link_url}`);
    console.log(`SMS enviado: ${job.sms_sent ? 'Sí' : 'No'}`);

    return job;
  } catch (error) {
    console.error('Error al crear trabajo:', error);
    throw error;
  }
}

// Ejecutar
createDeliveryJob();

Ejemplo 3: Consultar Estado del Trabajo

check-status.ts
import { recigoClient } from './recigo-client';

async function checkJobStatus(jobId: string) {
  try {
    const status = await recigoClient.getJobStatus(jobId);

    console.log('Estado del trabajo:', status);

    switch (status.status) {
      case 'draft':
        console.log('⏳ El cliente aún no ha completado el pago');
        break;
      case 'posted':
        console.log('✅ El trabajo está publicado y visible para transportistas');
        break;
      case 'accepted':
        console.log('🚗 Un transportista ha aceptado el trabajo');
        break;
      case 'completed':
        console.log('🎉 El trabajo ha sido completado');
        break;
      case 'cancelled':
        console.log('❌ El trabajo ha sido cancelado');
        break;
    }

    return status;
  } catch (error) {
    console.error('Error al consultar estado:', error);
    throw error;
  }
}

// Ejecutar
checkJobStatus('550e8400-e29b-41d4-a716-446655440000');

Ejemplo 4: Integración con Express.js

Ejemplo de cómo integrar la API de ReciGo en un servidor Express.js:

server.ts
import express from 'express';
import { recigoClient } from './recigo-client';

const app = express();
app.use(express.json());

// Endpoint para estimar precio
app.post('/api/delivery/estimate', async (req, res) => {
  try {
    const { size, pickup_address, dropoff_address } = req.body;

    const estimate = await recigoClient.estimatePrice({
      size,
      pickup: { address: pickup_address },
      dropoff: { address: dropoff_address },
    });

    res.json({
      success: true,
      estimate,
    });
  } catch (error: any) {
    res.status(500).json({
      success: false,
      error: error.message,
    });
  }
});

// Endpoint para crear trabajo de entrega
app.post('/api/delivery/create', async (req, res) => {
  try {
    const {
      listing_id,
      title,
      description,
      size,
      pickup_address,
      dropoff_address,
      customer_phone,
      photo_urls,
    } = req.body;

    const job = await recigoClient.createJob({
      external_reference: listing_id,
      title,
      description,
      size,
      pickup: { address: pickup_address },
      dropoff: { address: dropoff_address },
      customer_phone,
      photos: photo_urls,
    });

    // Guardar en tu base de datos
    await saveJobToDatabase({
      listing_id,
      recigo_job_id: job.job_id,
      status: job.status,
      deep_link: job.deep_link_url,
    });

    res.json({
      success: true,
      job_id: job.job_id,
      deep_link: job.deep_link_url,
      sms_sent: job.sms_sent,
    });
  } catch (error: any) {
    res.status(500).json({
      success: false,
      error: error.message,
    });
  }
});

// Endpoint para consultar estado
app.get('/api/delivery/:jobId/status', async (req, res) => {
  try {
    const { jobId } = req.params;

    const status = await recigoClient.getJobStatus(jobId);

    res.json({
      success: true,
      status,
    });
  } catch (error: any) {
    res.status(500).json({
      success: false,
      error: error.message,
    });
  }
});

// Función helper para guardar en DB (ejemplo)
async function saveJobToDatabase(data: any) {
  // Implementa tu lógica de base de datos aquí
  console.log('Guardando en DB:', data);
}

// Iniciar servidor
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Servidor corriendo en puerto ${PORT}`);
});

Manejo de Errores

error-handling.ts
import { recigoClient } from './recigo-client';

async function createJobWithErrorHandling() {
  try {
    const job = await recigoClient.createJob({
      title: 'Mover sofá',
      description: 'Sofá de 2 plazas',
      size: 'L',
      pickup: { address: 'Calle Gran Vía 1, Madrid' },
      dropoff: { address: 'Calle Alcalá 100, Madrid' },
      customer_phone: '+34612345678',
    });

    return { success: true, job };
  } catch (error: any) {
    // Manejo específico de errores de la API
    if (error.message.includes('validation_error')) {
      console.error('Error de validación:', error);
      return {
        success: false,
        error: 'Los datos proporcionados son inválidos',
      };
    }

    if (error.message.includes('unauthorized')) {
      console.error('API key inválida');
      return {
        success: false,
        error: 'Error de autenticación con ReciGo',
      };
    }

    if (error.message.includes('rate_limit_exceeded')) {
      console.error('Límite de tasa excedido');
      return {
        success: false,
        error: 'Demasiadas solicitudes, intenta de nuevo más tarde',
      };
    }

    if (error.message.includes('geocoding_failed')) {
      console.error('No se pudo geocodificar la dirección');
      return {
        success: false,
        error: 'Una o más direcciones no son válidas',
      };
    }

    // Error genérico
    console.error('Error desconocido:', error);
    return {
      success: false,
      error: 'Ocurrió un error al crear el trabajo',
    };
  }
}

Variables de Entorno

Crea un archivo .env para guardar tu API key de forma segura:

.env
# ReciGo API Configuration
RECIGO_API_KEY=recigo_live_abc123...

# Node.js Environment
NODE_ENV=production
PORT=3000

Importante: Nunca subas tu archivo .env a control de versiones. Añade .env a tu .gitignore.

Más Ejemplos