funnelchat20 / wapi-gateway
WAPI Gateway: librería Composer para integrar ZApi, UAZAPI y Meta (sin webhooks)
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
pkg:composer/funnelchat20/wapi-gateway
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.2
- laravel/framework: ^11.0|^12.0
- sentry/sentry-laravel: ^4.7
- spatie/laravel-data: ^3.11|^4.0
This package is auto-updated.
Last update: 2025-12-30 16:37:09 UTC
README
SDK puro para integrar proveedores de WhatsApp soportados por Funnelchat: Z-API, UAZAPI, Funapi (Whatsmeow Bridge) y Meta (WhatsApp Cloud), sin rutas ni middlewares. La app host consume métodos programáticos mediante un Facade y decide si expone endpoints propios.
⚠️ Estado: Esta librería está en desarrollo activo (v0.x.x). La API puede cambiar entre versiones menores. Se recomienda fijar versiones específicas en composer.json hasta v1.0.0.
Requisitos
- PHP ^8.2
- Laravel ^11.0
Instalación
composer require funnelchat20/wapi-gateway
Publicar configuración
php artisan vendor:publish --tag=wapi-config
Configuración
Variables de entorno por proveedor
Z-API
ZAPI_TOKEN=tu_token_aqui ZAPI_CLIENT_TOKEN=tu_client_token ZAPI_TIMEOUT=29 ZAPI_MAX_ATTEMPTS=2 ZAPI_RETRY_DELAY=500
UAZAPI
UAZAPI_BASE_URL=https://funnelchat.uazapi.com UAZAPI_ADMIN_TOKEN=tu_admin_token UAZAPI_TIMEOUT=120
Funapi (Whatsmeow Bridge)
FUNAPI_BASE_URL=https://api.funapi.example.com FUNAPI_TOKEN=tu_token FUNAPI_CLIENT_TOKEN=tu_client_token FUNAPI_TIMEOUT=29 FUNAPI_MAX_ATTEMPTS=2 FUNAPI_RETRY_DELAY=500
Meta (WhatsApp Cloud)
META_APP_ID=tu_app_id AWS_BUCKET_URL=https://tu-bucket.s3.amazonaws.com
Uso básico
use Funnelchat\WapiGateway\Facades\WapiGateway; use Funnelchat\WapiGateway\Enums\ProviderEnum; // Enviar mensaje de texto $response = WapiGateway::messages(ProviderEnum::ZApi) ->sendText($uid, $token, $phone, 'Hola mundo', [ 'delayMessage' => 0, 'delayTyping' => 0, 'retry' => true, // Habilita reintentos automáticos ]); if (isset($response['error'])) { // Manejar error } // Crear instancia $data = WapiGateway::instances(ProviderEnum::ZApi)->create($userId, $deviceId); // $data = ['uid' => '...', 'token' => '...'] o ['error' => '...'] // Obtener estado $status = WapiGateway::instances(ProviderEnum::ZApi)->status($uid, $token); // Incluye 'accountStatus' y 'qrCode' automáticamente
Compatibilidad de Proveedores
📨 Mensajería
| Método | Z-API | UAZAPI | Funapi | Meta |
|---|---|---|---|---|
sendText() |
✅ | ✅ | ✅ | ✅ |
sendFile() |
✅ | ✅ | ✅ | ✅ |
sendLocation() |
✅ | ✅ | ✅ | ✅ |
sendContact() |
✅ | ✅ | ✅ | ✅ |
sendButtons() |
✅ | ✅ | ⚠️ | ✅ |
sendButtonLink() |
✅ | ✅ | ⚠️ | ✅ |
sendOptionList() |
✅ | ✅ | ⚠️ | ✅ |
sendPoll() |
✅ | ✅ | ⚠️ | ✅ |
sendLink() |
✅ | ✅ | ⚠️ | ✅ |
sendEvent() |
✅ | ✅ | ⚠️ | ✅ |
sendTemplate() |
✅ | ✅ | ⚠️ | ✅ |
🔧 Instancias
| Método | Z-API | UAZAPI | Funapi | Meta |
|---|---|---|---|---|
create() |
✅ | ✅ | ✅ | ✅ |
status() |
✅ | ✅ | ✅ | ✅ |
qrCode() |
✅ | ✅ | ✅ | ✅ |
logout() |
✅ | ✅ | ✅ | ✅ |
reboot() |
✅ | ✅ | ✅ | ✅ |
me() |
✅ | ✅ | ✅ | ✅ |
checkPhone() |
✅ | ✅ | ❌ | ✅ |
subscribe() |
✅ | ✅ | ✅ | ✅ |
unsubscribe() |
✅ | ✅ | ✅ | ✅ |
👥 Grupos
| Método | Z-API | UAZAPI | Funapi | Meta |
|---|---|---|---|---|
groups() |
✅ | ✅ | ✅ | ❌ |
group() |
✅ | ✅ | ✅ | ❌ |
createGroup() |
✅ | ✅ | ✅ | ❌ |
updateGroupName() |
✅ | ✅ | ✅ | ❌ |
updateGroupDescription() |
✅ | ✅ | ✅ | ❌ |
updateGroupSettings() |
✅ | ✅ | ✅ | ❌ |
updateGroupPhoto() |
✅ | ✅ | ✅ | ❌ |
addParticipants() |
✅ | ✅ | ✅ | ❌ |
addAdmins() |
✅ | ✅ | ✅ | ❌ |
removeParticipants() |
✅ | ✅ | ✅ | ❌ |
removeAdmins() |
✅ | ✅ | ✅ | ❌ |
leaveGroup() |
✅ | ✅ | ✅ | ❌ |
📋 Cola de Mensajes
| Método | Z-API | UAZAPI | Funapi | Meta |
|---|---|---|---|---|
showQueue() |
✅ | ✅ | ✅ | ❌ |
queueCount() |
✅ | ✅ | ✅ | ❌ |
deleteQueueMessage() |
✅ | ✅ | ✅ | ❌ |
clearQueue() |
✅ | ✅ | ✅ | ❌ |
📝 Templates (Solo Meta)
| Método | Meta |
|---|---|
listTemplates() |
✅ |
getTemplate() |
✅ |
createTemplate() |
✅ |
updateTemplate() |
✅ |
deleteTemplate() |
✅ |
uploadHeaderHandle() |
✅ |
Leyenda:
- ✅ Completamente funcional
- ⚠️ En desarrollo (retorna error descriptivo)
- ❌ No soportado por el proveedor
Funcionalidades Avanzadas
Administración de Templates (Meta/WhatsApp Cloud)
use Funnelchat\WapiGateway\Facades\WapiGateway; use Funnelchat\WapiGateway\Enums\ProviderEnum; // Listar templates $templates = WapiGateway::templates(ProviderEnum::WhatsAppCloud) ->listTemplates($wabaId, $token, [ 'limit' => 20, 'after' => 'cursor123' // Para paginación ]); // Crear template $template = WapiGateway::templates(ProviderEnum::WhatsAppCloud) ->createTemplate($wabaId, $token, [ 'name' => 'welcome_message', 'language_code' => 'es', 'category' => 'MARKETING', 'header' => 'Bienvenido', 'body' => 'Hola {{1}}, gracias por contactarnos', 'footer' => 'Equipo de soporte', 'buttons' => [ ['type' => 'URL', 'text' => 'Visitar sitio', 'url' => 'https://example.com'] ] ]); // Eliminar template $result = WapiGateway::templates(ProviderEnum::WhatsAppCloud) ->deleteTemplate($wabaId, $token, 'welcome_message', $templateUid);
Eliminación Concurrente de Mensajes
$deleteRequests = [ ['messageId' => 'msg1', 'phone' => '123456789', 'owner' => true], ['messageId' => 'msg2', 'phone' => '987654321', 'owner' => true], // ... más mensajes ]; $results = WapiGateway::groups(ProviderEnum::ZApi) ->deleteMessagesConcurrently($uid, $token, $deleteRequests); // Performance: ~2s para 100 mensajes vs ~30s+ secuencial foreach ($results as $messageId => $result) { if (isset($result['error'])) { echo "Error eliminando {$messageId}: {$result['error']}"; } }
Procesamiento Asíncrono de Videos
// Automático para .mp4, .mov, .gif $response = WapiGateway::messages(ProviderEnum::ZApi) ->sendFile($uid, $token, $phone, 'https://example.com/video.mp4', [ 'caption' => 'Mi video', 'retry' => true, // 'async' => false // Desactivar si es necesario ]);
Retry Automático
$response = WapiGateway::messages(ProviderEnum::ZApi) ->sendText($uid, $token, $phone, 'Mensaje importante', [ 'retry' => true // Reintenta automáticamente en errores de conexión ]); // El SDK: // - Solo reintenta en ConnectionException // - NO reintenta en timeouts (evita duplicados) // - Configurable vía ZAPI_MAX_ATTEMPTS y ZAPI_RETRY_DELAY
Sistema de Resources
El SDK transforma las respuestas de cada proveedor para mantener compatibilidad con WAPI original:
// Ejemplo: status() con fetch automático de QR $status = WapiGateway::instances(ProviderEnum::ZApi)->status($uid, $token); // Retorna: ['accountStatus' => 'authenticated', 'qrCode' => null] // o: ['accountStatus' => 'got qr code', 'qrCode' => 'data:image/png;base64,...'] // checkPhone() normalizado $result = WapiGateway::instances(ProviderEnum::ZApi)->checkPhone($uid, $token, $phone); // Retorna: ['result' => true] (no 'exists', sino 'result') // me() con campos adicionales $me = WapiGateway::instances(ProviderEnum::ZApi)->me($uid, $token); // Retorna: ['phone' => '...', 'name' => '...', 'avatar' => '...', 'locale' => 'es', 'isBusiness' => true]
Limitaciones de Funapi
Funapi (Whatsmeow Bridge) tiene las siguientes limitaciones conocidas:
❌ No Soportado
checkPhone()- No existe endpoint equivalente
⚠️ En Desarrollo
Los siguientes métodos retornan error descriptivo indicando que están en desarrollo:
sendButtons()sendButtonLink()sendOptionList()sendPoll()sendLink()sendEvent()sendTemplate()
✅ Totalmente Funcional (36/44 métodos)
- Mensajería básica: texto, archivos, ubicación, contactos
- Gestión de instancias completa
- Operaciones de grupos completas
- Cola de mensajes completa
Manejo de Errores
Todos los métodos retornan arrays con:
- Éxito:
['messageId' => '...', 'status' => 'queued', ...] - Error:
['error' => 'mensaje descriptivo']
$response = WapiGateway::messages(ProviderEnum::ZApi)->sendText(...); if (isset($response['error'])) { // Error normalizado del proveedor Log::error('Error enviando mensaje', ['error' => $response['error']]); return response()->json(['error' => $response['error']], 409); } // Éxito return response()->json($response);
Integración en Controladores
use Funnelchat\WapiGateway\Facades\WapiGateway; use Funnelchat\WapiGateway\Enums\ProviderEnum; class WhatsAppController extends Controller { public function send(Request $request) { $provider = match($request->provider) { 'zapi' => ProviderEnum::ZApi, 'uazapi' => ProviderEnum::Uazapi, 'funapi' => ProviderEnum::Funapi, 'meta' => ProviderEnum::WhatsAppCloud, }; $response = WapiGateway::messages($provider) ->sendText( $request->uid, $request->header('token'), $request->phone, $request->message, ['retry' => true] ); return isset($response['error']) ? response()->json(['error' => $response['error']], 409) : response()->json($response); } }
Changelog
v0.1.0 - 2025-01-XX (En desarrollo)
Added:
- ✨ Sistema completo de Resources para transformación de respuestas
- ✨ Soporte para Funapi (Whatsmeow Bridge) - 36/44 métodos funcionales
- ✨ Fetch automático de QR code en método
status()cuando la instancia está desconectada - ✨ Normalización de respuestas entre proveedores (accountStatus, result, locale, etc.)
- ✨ 20 Resources implementados (10 Z-API + 10 UAZAPI)
- ✨ Administración completa de templates para Meta/WhatsApp Cloud
- ✨ Método
deleteMessagesConcurrently()para eliminación paralela de mensajes - ✨ Retry automático configurable en métodos de envío
- ✨ Procesamiento asíncrono automático para videos
- ✨ Timeouts configurables por proveedor
Fixed:
- 🐛 Corregidos endpoints de Funapi (
/send-imagey/send-documentsin sufijos) - 🐛 Métodos no soportados de Funapi ahora retornan errores descriptivos
Changed:
- 🔧 Timeout por defecto reducido de 120s a 29s (configurable)
- 🔧 Retry inteligente: no reintenta en timeouts, solo en ConnectionException
Performance:
- ⚡ Eliminación de 100 mensajes: ~2s con HTTP Pool vs ~30s+ secuencial
- ⚡ Reducción de timeouts en envíos de videos gracias a procesamiento async
Roadmap
- Completar endpoints faltantes de Funapi (botones, listas, encuestas)
- Tests automatizados para todos los proveedores
- Documentación de DTOs y respuestas por operación
- Soporte para webhooks (opcional)
- v1.0.0 - Release estable cuando todos los proveedores estén 100% completos
Contribución
Esta es una librería privada de Funnelchat. Para reportar bugs o solicitar features, contacta a: soporte@funnelchat.io
Licencia
Privado (Funnelchat). Todos los derechos reservados.