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

v0.1.0 2025-12-19 15:12 UTC

This package is auto-updated.

Last update: 2025-12-30 16:37:09 UTC


README

Latest Version on Packagist Total Downloads

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-image y /send-document sin 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.