Webhooks: Listar Producto por ID
Descripción General
El webhook Listar Producto por ID proporciona un enfoque optimizado de dos etapas para recuperar productos. Esto es útil para optimización de rendimiento cuando tienes un catálogo de productos grande.
En lugar de devolver detalles completos del producto con cada solicitud, puedes devolver una lista ligera de IDs de productos y sus timestamps de last_updated. Talk2sync utiliza esta información para determinar qué productos han cambiado y solo solicita detalles completos para aquellos que necesitan actualización.
Proceso de Recuperación de Dos Etapas
Etapa 1: Listar IDs de Productos (Índice Ligero)
Solicitud:
Talk2sync primero solicita un índice ligero de todos tus productos:
Paginación por Offset Numérico
GET https://www.example.com/your/endpoint/url?offset=0&sortorder=desc&jobid=123
T2SKey: {{API_KEY}}
Paginación por Cursor
GET https://www.example.com/your/endpoint/url?next=YXNkaWhhc3BvZGhpYXM&sortorder=desc&jobid=123
T2SKey: {{API_KEY}}
Respuesta:
Devuelve una lista ligera con solo información esencial:
{
"paging": {
"pageSize": 20,
"itemsTotal": 2,
"offset": 0
},
"products": [
{
"_id": "100004777",
"sku": "100004777",
"last_updated": 1517360038797
},
{
"_id": "100004778",
"sku": "100004778",
"last_updated": 1517360038800
}
]
}
Campos de Respuesta:
| Campo | Tipo | Descripción |
|---|---|---|
_id | string | Identificador único del producto (requerido) |
sku | string | SKU/código del producto |
last_updated | integer | Timestamp Unix (milisegundos) de la última modificación |
Etapa 2: Recuperar Detalles Completos del Producto (Bajo Demanda)
Solicitud:
Cuando Talk2sync determina que un producto necesita actualización, solicita los detalles completos del producto usando el ID del producto:
GET https://www.example.com/your/endpoint/url?id=100004777&jobid=123
T2SKey: {{API_KEY}}
Parámetros de Solicitud:
| Parámetro | Tipo | Descripción | Obligatorio |
|---|---|---|---|
id | string | ID del producto para recuperar detalles completos | ✓ Sí |
jobid | integer | Identificador único para este trabajo de sincronización | ✓ Sí |
T2SKey | header | Tu clave de seguridad | ✓ Sí |
Respuesta:
Devuelve los detalles completos del producto:
{
"_id": "100004777",
"sku": "100004777",
"last_updated": 1517360038797,
"title": "EON618S JBL SUBWOOFER 18\" AMPLIFICADO",
"url": "",
"brand": "",
"mpn": "",
"model": "",
"description": "JBL Premium Transducers",
"variations": [
{
"availabilities": [
{
"tag": "default",
"quantity": 50
}
],
"prices": [
{
"tag": "default",
"currency": "USD",
"number": 1060.51
}
],
"images": [
{
"url": "https://www.example.com/13080-thickbox_default/eon618s-jbl-subwoofer-18-amplificado-.jpg"
}
],
"videos": [
{
"url": ""
}
],
"barcode": "",
"size": "",
"color": "",
"variationid": ""
}
],
"properties": [
{
"extraattributes": {
"promociones": "",
"status": "",
"condicion_venta": "",
"peso": "",
"relacionados": "",
"custom_01": "",
"custom_02": "1",
"custom_03": ""
}
}
]
}
Referencia Completa de Campos
Objeto de Producto Ligero (Etapa 1)
| Campo | Tipo | Descripción |
|---|---|---|
_id | string | Identificador único del producto (requerido) |
sku | string | SKU/código del producto |
last_updated | integer | Timestamp Unix (milisegundos) de la última modificación |
Objeto de Producto Completo (Etapa 2)
| Campo | Tipo | Descripción |
|---|---|---|
_id | string | Identificador único del producto (requerido) |
sku | string | SKU/código del producto |
last_updated | integer | Timestamp Unix (milisegundos) de la última modificación |
title | string | Nombre/título del producto |
url | string | URL del producto en tu tienda |
brand | string | Marca del producto |
mpn | string | Número de Parte del Fabricante |
model | string | Modelo del producto |
description | string | Descripción detallada del producto |
variations | array | Array de variaciones del producto |
properties | array | Array de propiedades/atributos personalizados |
Objeto de Variación (Solo Etapa 2)
| Campo | Tipo | Descripción |
|---|---|---|
variationid | string | Identificador único de la variación |
size | string | Atributo de tamaño |
color | string | Atributo de color |
barcode | string | Código de barras/EAN |
availabilities | array | Información de inventario por ubicación |
prices | array | Información de precios |
images | array | Imágenes del producto |
videos | array | Videos del producto |
Objeto de Disponibilidad
| Campo | Tipo | Descripción |
|---|---|---|
tag | string | Identificador de ubicación (p.ej., "default", "warehouse_1") |
quantity | integer | Cantidad disponible |
Objeto de Precio
| Campo | Tipo | Descripción |
|---|---|---|
tag | string | Identificador de nivel de precio (p.ej., "default", "wholesale") |
currency | string | Código de moneda ISO 4217 (p.ej., "USD", "MXN") |
number | number | Valor del precio |
Ejemplo de Implementación (Node.js/Express)
// Etapa 1: Listar IDs de productos con timestamps de last_updated
app.get('/api/products', (req, res) => {
const { offset = 0, next, sortorder = 'desc', jobid } = req.query;
const apiKey = req.headers['t2skey'];
// Validar clave de API
if (apiKey !== process.env.TALK2SYNC_KEY) {
return res.status(401).json({ error: 'No autorizado' });
}
try {
// Obtener datos de productos ligeros (solo IDs y timestamps)
const allProducts = fetchProductsLightweight(sortorder);
const pageSize = 20;
const startIndex = parseInt(offset) || 0;
const paginatedProducts = allProducts.slice(startIndex, startIndex + pageSize);
const response = {
paging: {
pageSize: paginatedProducts.length,
itemsTotal: allProducts.length,
offset: startIndex
},
products: paginatedProducts.map(product => ({
_id: product.id,
sku: product.sku,
last_updated: new Date(product.updatedAt).getTime()
}))
};
res.json(response);
} catch (error) {
console.error('Error al obtener productos:', error);
res.status(500).json({ error: 'Error Interno del Servidor' });
}
});
// Etapa 2: Recuperar detalles completos del producto por ID
app.get('/api/products', (req, res) => {
const { id, jobid } = req.query;
const apiKey = req.headers['t2skey'];
// Validar clave de API
if (apiKey !== process.env.TALK2SYNC_KEY) {
return res.status(401).json({ error: 'No autorizado' });
}
try {
// Si el parámetro ID está presente, devuelve detalles completos del producto
if (id) {
const product = fetchProductById(id);
if (!product) {
return res.status(404).json({ error: 'Producto no encontrado' });
}
const response = {
_id: product.id,
sku: product.sku,
last_updated: new Date(product.updatedAt).getTime(),
title: product.name,
url: product.url,
brand: product.brand,
mpn: product.mpn,
model: product.model,
description: product.description,
variations: product.variations.map(v => ({
variationid: v.id,
size: v.size || "",
color: v.color || "",
barcode: v.barcode || "",
availabilities: v.stocks.map(s => ({
tag: s.location || "default",
quantity: s.quantity
})),
prices: v.prices.map(p => ({
tag: p.tier || "default",
currency: p.currency || "USD",
number: p.value
})),
images: v.images.map(img => ({ url: img })),
videos: v.videos.map(vid => ({ url: vid }))
})),
properties: [{
extraattributes: product.customFields || {}
}]
};
res.json(response);
}
} catch (error) {
console.error('Error al obtener producto:', error);
res.status(500).json({ error: 'Error Interno del Servidor' });
}
});
Cómo Talk2sync Utiliza Este Enfoque
- Primera Solicitud: Talk2sync llama a tu endpoint sin parámetro
idpara obtener el índice ligero - Comparación: Talk2sync compara el timestamp
last_updatedcon lo que tiene almacenado - Solicitudes Selectivas: Para productos con valores de
last_updatedmás nuevos, Talk2sync realiza solicitudes individuales con el parámetroid - Optimización de Ancho de Banda: Solo los productos que han cambiado realmente generan solicitudes de datos completos
Beneficios de Rendimiento
| Aspecto | Beneficio |
|---|---|
| Ancho de Banda | Reducido al obtener solo detalles completos para productos cambiados |
| Velocidad de Sincronización | Mucho más rápida la comparación inicial del índice |
| Carga de Base de Datos | Carga más baja de menos búsquedas completas de productos |
| Escalabilidad | Maneja catálogos grandes eficientemente |
Cuándo Usar Este Enfoque
✓ Úsalo cuando:
- Tu catálogo tiene 10,000+ productos
- Los productos se actualizan con poca frecuencia
- Quieres minimizar el uso de ancho de banda
- El tiempo de respuesta es crítico
✗ Evítalo cuando:
- Tu catálogo es pequeño (< 1,000 productos)
- La mayoría de productos cambian frecuentemente
- El ancho de banda no es una preocupación
- La simplicidad es más importante que la optimización
Códigos de Estado de Respuesta
| Estado | Significado | Acción |
|---|---|---|
200 OK | Datos recuperados exitosamente | Talk2sync procesa la respuesta |
400 Bad Request | Parámetros inválidos | Verifica tus parámetros de solicitud |
401 Unauthorized | Clave de API inválida o faltante | Verifica tu clave de seguridad |
404 Not Found | ID de producto no existe | Verifica el ID del producto |
500 Internal Server Error | Error del servidor | Revisa los registros de tu servidor |
Guías de Paginación
Etapa 1: Endpoints de Lista
Usa las mismas estrategias de paginación que Listar Productos:
- Offset Numérico: Para conjuntos de datos pequeños a medianos
- Basada en Cursor: Para conjuntos de datos grandes o que cambian frecuentemente
Etapa 2: Solicitud de Producto Único
Sin paginación necesaria—este endpoint siempre devuelve un único producto completo.
Buenas Prácticas
✓ Haz:
- Devuelve datos ligeros en Etapa 1 (solo IDs y timestamps)
- Mantén timestamps de
last_updatedprecisos y actualizados - Valida la clave de API en cada solicitud
- Devuelve 404 si un ID de producto solicitado no existe
- Cachea detalles completos del producto cuando sea posible
✗ No hagas:
- Devuelvas detalles completos del producto en Etapa 1 (anula el propósito)
- Devuelvas datos incompletos en Etapa 2
- Incluyas información sensible en respuestas
- Ignores el parámetro de ordenamiento en Etapa 1
Comparación: Listar Productos vs Listar Producto por ID
| Característica | Listar Productos | Listar Producto por ID |
|---|---|---|
| Caso de Uso | Catálogos pequeños, integraciones simples | Catálogos grandes, optimización de rendimiento |
| Respuesta Etapa 1 | Detalles completos del producto | Ligero (ID + timestamp) |
| Respuesta Etapa 2 | N/A | Detalles completos del producto (bajo demanda) |
| Uso de Ancho de Banda | Alto (todos los detalles siempre enviados) | Bajo (solo productos cambiados obtenidos) |
| Complejidad | Simple | Más compleja (dos endpoints) |
| Mejor Para | < 1,000 productos | 10,000+ productos |