
Introduccion
En el competitivo mundo del e-commerce, la comunicacion efectiva con los clientes puede marcar la diferencia entre una venta exitosa y un carrito abandonado. Las notificaciones multicanal permiten llegar a los clientes por su canal preferido en el momento adecuado.
Por Que Notificaciones Multicanal?
Estadisticas Clave
- 73% de los clientes prefieren recibir notificaciones por multiples canales
- 48% de los carritos abandonados pueden recuperarse con recordatorios oportunos
- 90% espera actualizaciones de envio en tiempo real
- 3x mas engagement con notificaciones personalizadas
Canales Principales
| Canal |
Mejor Para |
Tasa de Apertura |
| SMS |
Alertas urgentes |
98% |
| WhatsApp |
Conversaciones |
95% |
| Email |
Contenido detallado |
20-30% |
| Push |
Usuarios activos |
40-60% |
Arquitectura de Notificaciones
Evento (pedido, envio, etc.)
|
v
Motor de Reglas
|
┌─────┴─────┐
| |
Seleccion Personalizacion
de Canal de Contenido
| |
└─────┬─────┘
|
v
Envio Multicanal
(SMS + WhatsApp + Email)
|
v
Tracking y Analytics
Implementacion
Servicio de Notificaciones
import Zavudev from '@zavudev/sdk';
class NotificationService {
constructor() {
this.client = new Zavudev({
apiKey: process.env.ZAVUDEV_API_KEY
});
}
// Determinar mejor canal para el cliente
selectChannel(customer, notificationType) {
const preferences = customer.notificationPreferences || {};
// Respetar preferencias del cliente
if (preferences[notificationType]) {
return preferences[notificationType];
}
// Logica de seleccion por defecto
const channelPriority = {
urgent: ['sms', 'whatsapp', 'email'],
transactional: ['whatsapp', 'sms', 'email'],
marketing: ['email', 'whatsapp'],
support: ['whatsapp', 'email', 'sms']
};
const channels = channelPriority[notificationType] || ['auto'];
// Verificar disponibilidad del canal
for (const channel of channels) {
if (this.isChannelAvailable(customer, channel)) {
return channel;
}
}
return 'auto';
}
isChannelAvailable(customer, channel) {
switch (channel) {
case 'sms':
case 'whatsapp':
return !!customer.phone;
case 'email':
return !!customer.email;
default:
return true;
}
}
async send(customer, notification) {
const channel = this.selectChannel(customer, notification.type);
const content = this.formatContent(notification, channel);
const params = {
to: channel === 'email' ? customer.email : customer.phone,
channel,
...content
};
return await this.zavu.messages.send(params);
}
formatContent(notification, channel) {
const templates = notification.templates || {};
switch (channel) {
case 'sms':
return {
text: templates.sms || notification.shortMessage
};
case 'whatsapp':
return {
text: templates.whatsapp || notification.message,
messageType: notification.interactive ? 'buttons' : 'text',
content: notification.buttons ? { buttons: notification.buttons } : undefined
};
case 'email':
return {
subject: notification.subject,
text: templates.email || notification.message,
htmlBody: templates.emailHtml
};
default:
return { text: notification.message };
}
}
}
Notificaciones de E-commerce
class EcommerceNotifications extends NotificationService {
// Confirmacion de pedido
async orderConfirmed(order) {
return this.send(order.customer, {
type: 'transactional',
subject: `Pedido #${order.id} confirmado`,
shortMessage: `Pedido #${order.id} confirmado. Total: ${order.total}`,
message: `Hola ${order.customer.name}!\n\nTu pedido #${order.id} ha sido confirmado.\n\nTotal: ${order.total}\nItems: ${order.items.length}\n\nTe avisaremos cuando sea enviado.`,
templates: {
whatsapp: `Hola ${order.customer.name}! Tu pedido #${order.id} por ${order.total} esta confirmado. Te avisaremos cuando sea enviado.`
},
buttons: [
{ id: 'track', title: 'Ver Pedido' },
{ id: 'help', title: 'Ayuda' }
]
});
}
// Pedido enviado
async orderShipped(order) {
return this.send(order.customer, {
type: 'transactional',
subject: `Tu pedido #${order.id} ha sido enviado`,
shortMessage: `Pedido #${order.id} enviado! Seguimiento: ${order.tracking}`,
message: `Tu pedido #${order.id} va en camino!\n\nNumero de seguimiento: ${order.tracking}\nEntrega estimada: ${order.deliveryDate}`,
templates: {
whatsapp: `Tu pedido #${order.id} va en camino! Seguimiento: ${order.tracking}. Entrega: ${order.deliveryDate}`
},
buttons: [
{ id: 'track', title: 'Rastrear' }
]
});
}
// Pedido entregado
async orderDelivered(order) {
return this.send(order.customer, {
type: 'transactional',
subject: `Pedido #${order.id} entregado`,
shortMessage: `Pedido #${order.id} entregado. Gracias por tu compra!`,
message: `Tu pedido #${order.id} ha sido entregado.\n\nGracias por comprar con nosotros!\n\nNos encantaria conocer tu opinion.`,
buttons: [
{ id: 'review', title: 'Dejar Opinion' },
{ id: 'problem', title: 'Reportar Problema' }
]
});
}
// Carrito abandonado
async abandonedCart(cart) {
// Esperar tiempo configurable
return this.send(cart.customer, {
type: 'marketing',
subject: 'Olvidaste algo en tu carrito',
shortMessage: `Tienes ${cart.items.length} productos esperando. Completa tu compra!`,
message: `Hola ${cart.customer.name}!\n\nNotamos que dejaste algunos productos en tu carrito:\n\n${this.formatCartItems(cart.items)}\n\nTotal: ${cart.total}\n\nCompleta tu compra antes de que se agoten!`,
buttons: [
{ id: 'complete', title: 'Completar Compra' },
{ id: 'later', title: 'Recordar Despues' }
]
});
}
// Producto de nuevo en stock
async backInStock(product, customers) {
for (const customer of customers) {
await this.send(customer, {
type: 'marketing',
subject: `${product.name} esta de vuelta!`,
shortMessage: `${product.name} volvio a stock. Compralo ahora!`,
message: `Buenas noticias! ${product.name} que estabas esperando ya esta disponible.\n\nPrecio: ${product.price}\n\nApurate, el stock es limitado!`,
buttons: [
{ id: 'buy', title: 'Comprar Ahora' }
]
});
}
}
formatCartItems(items) {
return items
.map(item => `- ${item.name} (x${item.quantity}): ${item.price}`)
.join('\n');
}
}
Motor de Reglas
class NotificationRules {
constructor(notificationService) {
this.notifications = notificationService;
this.rules = [];
}
addRule(rule) {
this.rules.push(rule);
}
async processEvent(event) {
for (const rule of this.rules) {
if (rule.condition(event)) {
await rule.action(event, this.notifications);
}
}
}
}
// Configurar reglas
const rules = new NotificationRules(new EcommerceNotifications());
// Regla: Confirmar pedido inmediatamente
rules.addRule({
condition: (event) => event.type === 'order.created',
action: async (event, notif) => {
await notif.orderConfirmed(event.order);
}
});
// Regla: Notificar envio
rules.addRule({
condition: (event) => event.type === 'order.shipped',
action: async (event, notif) => {
await notif.orderShipped(event.order);
}
});
// Regla: Carrito abandonado (despues de 1 hora)
rules.addRule({
condition: (event) =>
event.type === 'cart.abandoned' &&
event.cart.age > 60 * 60 * 1000 && // 1 hora
event.cart.total > 0,
action: async (event, notif) => {
await notif.abandonedCart(event.cart);
}
});
// Regla: Recordatorio de pago pendiente
rules.addRule({
condition: (event) =>
event.type === 'order.payment_pending' &&
event.order.age > 24 * 60 * 60 * 1000, // 24 horas
action: async (event, notif) => {
await notif.paymentReminder(event.order);
}
});
Shopify
const Shopify = require('shopify-api-node');
async function setupShopifyWebhooks(shop) {
const shopify = new Shopify({
shopName: shop.name,
apiKey: shop.apiKey,
password: shop.password
});
// Webhook para pedidos creados
await shopify.webhook.create({
topic: 'orders/create',
address: 'https://tuapi.com/webhooks/shopify/orders',
format: 'json'
});
// Webhook para fulfillments
await shopify.webhook.create({
topic: 'fulfillments/create',
address: 'https://tuapi.com/webhooks/shopify/fulfillments',
format: 'json'
});
}
// Procesar webhook de Shopify
app.post('/webhooks/shopify/orders', async (req, res) => {
const order = transformShopifyOrder(req.body);
await rules.processEvent({ type: 'order.created', order });
res.sendStatus(200);
});
WooCommerce
// Procesar webhook de WooCommerce
app.post('/webhooks/woocommerce', async (req, res) => {
const { topic } = req.headers['x-wc-webhook-topic'];
const data = req.body;
switch (topic) {
case 'order.created':
const order = transformWooOrder(data);
await rules.processEvent({ type: 'order.created', order });
break;
case 'order.updated':
if (data.status === 'completed') {
await rules.processEvent({ type: 'order.shipped', order: transformWooOrder(data) });
}
break;
}
res.sendStatus(200);
});
Personalizacion Avanzada
Segmentacion de Clientes
function segmentCustomer(customer, purchaseHistory) {
if (purchaseHistory.totalSpent > 1000) {
return 'vip';
}
if (purchaseHistory.orderCount > 5) {
return 'loyal';
}
if (purchaseHistory.orderCount === 0) {
return 'new';
}
return 'regular';
}
async function sendSegmentedNotification(customer, notification) {
const segment = segmentCustomer(customer, customer.purchaseHistory);
// Personalizar mensaje segun segmento
const templates = {
vip: {
prefix: `Estimado cliente VIP ${customer.name},`,
suffix: 'Como siempre, tu envio es prioritario y gratuito.'
},
loyal: {
prefix: `Hola ${customer.name}!`,
suffix: 'Gracias por seguir confiando en nosotros.'
},
new: {
prefix: `Bienvenido ${customer.name}!`,
suffix: 'Esperamos que esta sea la primera de muchas compras.'
},
regular: {
prefix: `Hola ${customer.name},`,
suffix: ''
}
};
const template = templates[segment];
notification.message = `${template.prefix}\n\n${notification.message}\n\n${template.suffix}`;
await notificationService.send(customer, notification);
}
Analytics y Optimizacion
async function trackNotificationMetrics(notification, result) {
await analytics.track({
event: 'notification_sent',
properties: {
channel: result.channel,
type: notification.type,
customerId: notification.customerId,
messageId: result.id,
timestamp: new Date().toISOString()
}
});
}
async function getNotificationReport(dateRange) {
return {
byChannel: await getMetricsByChannel(dateRange),
byType: await getMetricsByType(dateRange),
conversionRate: await getConversionRate(dateRange),
optOutRate: await getOptOutRate(dateRange)
};
}
Conclusion
Las notificaciones multicanal son esenciales para cualquier e-commerce moderno. Permiten comunicarse con los clientes en el momento adecuado, por el canal que prefieren, aumentando la satisfaccion y las conversiones.
La clave esta en respetar las preferencias del cliente, personalizar los mensajes y medir constantemente para optimizar.
Recursos