| id |
type |
title |
provider |
status |
integration_type |
created_at |
updated_at |
simco_version |
tags |
| INT-001 |
Integration |
WhatsApp Meta Business API |
WhatsApp/Meta |
Activo |
messaging |
2026-01-04 |
2026-01-10 |
3.8.0 |
| whatsapp |
| messaging |
| webhooks |
| multi-tenant |
|
INT-001: WhatsApp Meta Business API
Metadata
| Campo |
Valor |
| Codigo |
INT-001 |
| Proveedor |
Meta (Facebook) |
| Tipo |
Comunicacion |
| Estado |
Implementado |
| Multi-tenant |
Si |
| Fecha integracion |
2026-01-06 |
| Ultimo update |
2026-01-10 |
| Owner |
Backend Team |
1. Descripcion
WhatsApp Business API es el canal principal de comunicacion de MiChangarrito. Permite a los duenos de tiendas interactuar con el sistema mediante mensajes de texto y voz.
Casos de uso principales:
- Recibir consultas de ventas, inventario y ganancias
- Procesar comandos via chat (agregar producto, registrar venta)
- Recibir pedidos de clientes
- Enviar notificaciones y recordatorios
- Procesar mensajes de voz (transcripcion via Whisper)
2. Credenciales Requeridas
Variables de Entorno
| Variable |
Descripcion |
Tipo |
Obligatorio |
WHATSAPP_PHONE_NUMBER_ID |
ID del numero de telefono en Meta |
string |
SI |
WHATSAPP_ACCESS_TOKEN |
Token de acceso a la API |
string |
SI |
WHATSAPP_VERIFY_TOKEN |
Token para verificar webhooks |
string |
SI |
WHATSAPP_APP_SECRET |
Secret para validar firma de webhooks |
string |
SI |
WHATSAPP_WEBHOOK_URL |
URL del webhook (para referencia) |
string |
NO |
Ejemplo de .env
# WhatsApp Business API
WHATSAPP_PHONE_NUMBER_ID=123456789012345
WHATSAPP_ACCESS_TOKEN=EAABxxxxxxxxxxxxxxx
WHATSAPP_VERIFY_TOKEN=michangarrito_verify_2026
WHATSAPP_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxx
Obtencion de Credenciales
- Crear cuenta en Meta for Developers
- Crear App de tipo "Business"
- Agregar producto "WhatsApp Business Platform"
- Configurar numero de telefono de prueba
- Generar Access Token permanente
- Configurar Webhook URL
3. Endpoints/SDK Utilizados
Operaciones Implementadas
| Operacion |
Metodo |
Endpoint |
Descripcion |
| Enviar mensaje texto |
POST |
/v17.0/{phone_id}/messages |
Mensaje de texto simple |
| Enviar mensaje template |
POST |
/v17.0/{phone_id}/messages |
Mensaje con template aprobado |
| Enviar mensaje interactivo |
POST |
/v17.0/{phone_id}/messages |
Botones, listas |
| Marcar como leido |
POST |
/v17.0/{phone_id}/messages |
Mark as read |
| Descargar media |
GET |
/{media_id} |
Obtener URL de audio/imagen |
SDK/Cliente Utilizado
// No se usa SDK oficial, cliente HTTP custom
import { HttpService } from '@nestjs/axios';
const WHATSAPP_API_URL = 'https://graph.facebook.com/v17.0';
async sendMessage(phoneNumber: string, text: string) {
return this.httpService.post(
`${WHATSAPP_API_URL}/${process.env.WHATSAPP_PHONE_NUMBER_ID}/messages`,
{
messaging_product: 'whatsapp',
to: phoneNumber,
type: 'text',
text: { body: text }
},
{
headers: {
Authorization: `Bearer ${process.env.WHATSAPP_ACCESS_TOKEN}`
}
}
);
}
4. Rate Limits
| Limite |
Valor |
Periodo |
Accion si excede |
| Mensajes iniciados por negocio |
1,000 |
por 24h (tier basico) |
Esperar o upgrade tier |
| Mensajes de respuesta |
Ilimitados |
24h ventana |
N/A |
| Requests API |
200 |
por segundo |
Retry con backoff |
Estrategia de Retry
const delays = [1000, 2000, 4000];
for (let attempt = 0; attempt < 3; attempt++) {
try {
return await this.sendMessage(phone, text);
} catch (error) {
if (error.response?.status === 429) {
await sleep(delays[attempt]);
continue;
}
throw error;
}
}
5. Manejo de Errores
Codigos de Error
| Codigo |
Descripcion |
Accion Recomendada |
Retry |
| 400 |
Formato de mensaje invalido |
Validar payload |
NO |
| 401 |
Token invalido o expirado |
Regenerar token |
NO |
| 403 |
Numero no registrado |
Verificar numero |
NO |
| 429 |
Rate limit excedido |
Backoff exponencial |
SI |
| 500 |
Error de Meta |
Retry 3 veces |
SI |
Ejemplo de Manejo
try {
await whatsappService.sendMessage(phone, message);
} catch (error) {
this.logger.error('WhatsApp error', {
service: 'whatsapp',
operation: 'sendMessage',
code: error.response?.data?.error?.code,
message: error.response?.data?.error?.message,
tenantId: context.tenantId,
});
// Guardar en cola para reintento
await this.queue.add('whatsapp-retry', { phone, message });
}
6. Fallbacks
Estrategia de Fallback
| Escenario |
Fallback |
Tiempo maximo |
| API caida |
Cola Redis para reintentar |
24 horas |
| Rate limited |
Throttle + prioridad |
1 hora |
| Token expirado |
Alerta admin |
Inmediato |
Modo Degradado
Si WhatsApp no esta disponible:
- Mensajes se encolan en Redis
- Usuario puede usar app movil/web
- Notificaciones push como alternativa
7. Multi-tenant
Modelo de Credenciales
Almacenamiento
-- En schema messaging
CREATE TABLE messaging.tenant_whatsapp_config (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID REFERENCES auth.tenants(id) NOT NULL,
phone_number_id VARCHAR(50) NOT NULL,
access_token TEXT NOT NULL, -- Encriptado
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(tenant_id)
);
Contexto en Llamadas
async sendMessageForTenant(tenantId: UUID, phone: string, text: string) {
const config = await this.getWhatsAppConfig(tenantId);
// Usar config del tenant o fallback a global
const phoneNumberId = config?.phone_number_id || process.env.WHATSAPP_PHONE_NUMBER_ID;
const accessToken = config?.access_token || process.env.WHATSAPP_ACCESS_TOKEN;
return this.send(phoneNumberId, accessToken, phone, text);
}
8. Webhooks
Endpoints Registrados
| Evento |
Endpoint Local |
Descripcion |
messages |
/webhooks/whatsapp |
Mensajes entrantes |
message_status |
/webhooks/whatsapp |
Estado de entrega |
Validacion de Webhooks
function verifyWebhookSignature(payload: string, signature: string): boolean {
const expected = crypto
.createHmac('sha256', process.env.WHATSAPP_APP_SECRET)
.update(payload)
.digest('hex');
return signature === `sha256=${expected}`;
}
Configuracion en Meta
- Meta Dashboard → WhatsApp → Configuration
- Webhook URL:
https://api.michangarrito.com/webhooks/whatsapp
- Verify Token:
WHATSAPP_VERIFY_TOKEN
- Suscribir a:
messages, message_status
9. Testing
Modo Sandbox/Test
| Ambiente |
Credenciales |
Datos |
| Sandbox |
Test phone number |
Mensajes a numeros verificados |
| Production |
Business verified |
Mensajes a cualquier numero |
Numeros de Prueba
En sandbox, solo se pueden enviar mensajes a numeros registrados en Meta Dashboard.
Comandos de Test
# Test de conexion
curl -X POST \
"https://graph.facebook.com/v17.0/${PHONE_NUMBER_ID}/messages" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"messaging_product":"whatsapp","to":"521234567890","type":"text","text":{"body":"Test"}}'
# Test de webhook local
curl -X POST http://localhost:3143/webhooks/whatsapp \
-H "Content-Type: application/json" \
-d '{"object":"whatsapp_business_account","entry":[{"changes":[{"value":{"messages":[{"from":"521234567890","text":{"body":"Hola"}}]}}]}]}'
10. Monitoreo
Metricas a Monitorear
| Metrica |
Descripcion |
Alerta |
| Latencia |
Tiempo de respuesta API |
> 3s |
| Error Rate |
% de requests fallidos |
> 5% |
| Messages Sent |
Mensajes enviados por hora |
< 10 (posible caida) |
| Webhook Delay |
Tiempo entre evento y procesamiento |
> 10s |
Logs Estructurados
this.logger.info('WhatsApp message sent', {
service: 'whatsapp',
operation: 'sendMessage',
tenantId: context.tenantId,
messageId: result.messages[0].id,
to: phone,
duration: durationMs,
});
11. Referencias
Documentacion Oficial
Modulos Relacionados
Soporte
Ultima actualizacion: 2026-01-10
Autor: Backend Team